From 16ba9f08109ddb911e9aba8518a93d3df710a46b Mon Sep 17 00:00:00 2001
From: Alex Young <alex@bytemark.co.uk>
Date: Mon, 23 Feb 2015 19:22:33 +0000
Subject: Get tests passing on ruby 1.9.3-p551

---
 lib/mauve/alert.rb                         | 150 +++++++++++++------------
 lib/mauve/authentication.rb                |   2 +-
 lib/mauve/configuration_builders/person.rb |  20 ++--
 lib/mauve/datamapper.rb                    |   6 +-
 lib/mauve/notifiers/xmpp.rb                | 169 ++++++++++++++++-------------
 lib/mauve/server.rb                        |  44 ++++----
 lib/rack-flash.rb                          |   2 +-
 7 files changed, 205 insertions(+), 188 deletions(-)

(limited to 'lib')

diff --git a/lib/mauve/alert.rb b/lib/mauve/alert.rb
index 24b9dae..e8647f7 100644
--- a/lib/mauve/alert.rb
+++ b/lib/mauve/alert.rb
@@ -11,16 +11,16 @@ module Mauve
   # alert due to trigger.
   #
   class AlertEarliestDate
- 
+
     include DataMapper::Resource
-    
+
     property :alert_id, Integer, :key => true
     property :earliest, EpochTime
     belongs_to :alert, :model => "Alert"
-    
+
     # 1) Shame we can't get this called automatically from DataMapper.auto_upgrade!
     #
-    # 2) Can't use a neater per-connection TEMPORARY VIEW because the pooling 
+    # 2) Can't use a neater per-connection TEMPORARY VIEW because the pooling
     # function causes the connection to get dropped occasionally, and we can't
     # hook the reconnect function (that I know of).
     #
@@ -30,20 +30,22 @@ module Mauve
       the_distant_future = (Time.now + 2000.days).to_i # it is the year 2000 - the humans are dead
 
       case DataMapper.repository(:default).adapter.class.to_s
-        when "DataMapper::Adapters::PostgresAdapter" 
+        when "DataMapper::Adapters::PostgresAdapter"
           ifnull = "COALESCE"
           min    = "LEAST"
-        else 
+        else
           ifnull = "IFNULL"
           min    = "MIN"
       end
 
       ["BEGIN TRANSACTION",
-       "DROP VIEW IF EXISTS mauve_alert_earliest_dates",
-       "CREATE VIEW 
+       # This was previously a DROP VIEW, but the sqlite adapter complains
+       # about DROP VIEW here.
+       "DROP TABLE IF EXISTS mauve_alert_earliest_dates",
+       "CREATE VIEW
           mauve_alert_earliest_dates
         AS
-        SELECT 
+        SELECT
           id AS alert_id,
           NULLIF(
             #{min}(
@@ -53,7 +55,7 @@ module Mauve
             ),
             #{the_distant_future}
           ) AS earliest
-        FROM mauve_alerts 
+        FROM mauve_alerts
         WHERE
           will_clear_at IS NOT NULL OR
           will_raise_at IS NOT NULL OR
@@ -64,7 +66,7 @@ module Mauve
       end
     end
   end
- 
+
   #
   # Woo! An alert.
   #
@@ -73,11 +75,13 @@ module Mauve
     def bytesize; 99; end
     # @deprecated Not used anymore?
     def size; 99; end
-    
+
     include DataMapper::Resource
-   
+
     #
-    # If a string matches this regex, it is valid UTF8.
+    # If a string matches this regex, it is valid UTF8.  This regex is
+    # in ASCII-8BIT, so we have to force the encoding of the string to
+    # match it.
     #
     UTF8_REGEXP = Regexp.new(/^(?:#{[
          "[\x00-\x7F]",                        # ASCII
@@ -89,7 +93,7 @@ module Mauve
          "[\xF1-\xF3][\x80-\xBF]{3}",          # planes 4-15
          "\xF4[\x80-\x8F][\x80-\xBF]{2}"       # plane 16
         ].join("|")})*$/)
- 
+
     property :id, Serial
     property :alert_id, String, :required => true, :unique_index => :alert_index, :length=>256, :lazy => false
     property :source, String, :required => true, :unique_index => :alert_index, :length=>512, :lazy => false
@@ -105,7 +109,7 @@ module Mauve
     property :acknowledged_at, EpochTime
     property :acknowledged_by, String, :lazy => false
     property :update_type, String, :lazy => false
-    
+
     property :will_clear_at, EpochTime
     property :will_raise_at, EpochTime
     property :will_unacknowledge_at, EpochTime
@@ -124,11 +128,11 @@ module Mauve
     after  :destroy, :destroy_associations
 
     validates_with_method :check_dates
-    
+
     default_scope(:default).update(:order => [:source, :importance])
-    
+
     # @return [String]
-    def to_s 
+    def to_s
       "#<Alert #{id}, alert_id #{alert_id}, source #{source}>"
     end
 
@@ -140,7 +144,7 @@ module Mauve
     #
     # @return [Mauve::AlertGroup] The first matching AlertGroup for this alert
     def alert_group
-      # 
+      #
       # Find the AlertGroup by name if we've got a cached value
       #
       ag = AlertGroup.find{|a| self.cached_alert_group == a.name} if self.cached_alert_group
@@ -154,8 +158,8 @@ module Mauve
         ag = AlertGroup.all.last if ag.nil?
         self.cached_alert_group = ag.name unless ag.nil?
       end
-      
-      ag 
+
+      ag
     end
 
     # Pick out the source lists that match this alert by subject.
@@ -176,16 +180,16 @@ module Mauve
       source_list.includes?(self.subject)
     end
 
-    # Returns the alert level 
+    # Returns the alert level
     #
     # @return [Symbol] The alert level, as per its AlertGroup.
     def level
       @level ||= self.alert_group.level
     end
-  
+
     # An array used to sort compare
-    # 
-    # @return [Array] 
+    #
+    # @return [Array]
     def sort_tuple
       [AlertGroup::LEVELS.index(self.level), (self.raised_at || self.cleared_at || Time.now)]
     end
@@ -198,14 +202,14 @@ module Mauve
     def <=>(other)
       other.sort_tuple <=> self.sort_tuple
     end
- 
+
     # The alert subject
     #
     # @return [String]
     def subject; super || self.source || "not set" ; end
 
     # The alert detail
-    # 
+    #
     # @return [String]
     def detail;  super || "_No detail set._" ; end
 
@@ -215,7 +219,7 @@ module Mauve
     def subject=(s)
       self.cached_alert_group = nil
       attribute_set(:subject, s)
-    end 
+    end
 
     #
     # Set the detail -- this clears the cached_alert_group.
@@ -225,14 +229,14 @@ module Mauve
       attribute_set(:detail, s)
     end
 
-    # 
+    #
     # Set the source -- this clears the cached_alert_group.
     #
     def source=(s)
       self.cached_alert_group = nil
       attribute_set(:source, s)
-    end 
-    
+    end
+
     #
     # Set the summary -- this clears the cached_alert_group.
     #
@@ -240,7 +244,7 @@ module Mauve
       self.cached_alert_group = nil
       attribute_set(:summary, s)
     end
- 
+
     protected
 
     # This cleans the HTML before saving.
@@ -274,7 +278,7 @@ module Mauve
         next unless prop.is_a?(DataMapper::Property::String)
         next unless val.is_a?(String)
         #
-        # Truncate 
+        # Truncate
         #
         max_length = prop.length
         if val.length > max_length
@@ -287,7 +291,7 @@ module Mauve
     def do_set_timestamps(context = :default)
       self.updated_at = Time.now if self.dirty?
     end
-   
+
     # This is to stop datamapper inserting duff dates into the database.
     #
     def check_dates
@@ -310,7 +314,7 @@ module Mauve
     end
 
     public
-    
+
     # Send a notification for this alert.
     #
     # @return [Boolean] Showing if an alert has been sent.
@@ -319,7 +323,7 @@ module Mauve
     end
 
     # Save an alert, creating a history and notifications, as needed.
-    # 
+    #
     #
     def save
       #
@@ -328,11 +332,11 @@ module Mauve
       #  * the alert has just been raised
       #  * the alert is raised and its acknowledged status has changed
       #  * the alert has just been cleared, and wasn't suppressed before the clear.
-      # 
+      #
       #
       should_notify = (
         (self.raised?  and self.was_cleared?) or
-        (self.raised?  and self.was_acknowledged? != self.acknowledged?) or 
+        (self.raised?  and self.was_acknowledged? != self.acknowledged?) or
         (self.cleared? and self.was_raised? and !self.was_suppressed?)
       )
 
@@ -340,7 +344,7 @@ module Mauve
       # Set the update type.
       #
       ut = if self.cleared? and !self.was_cleared?
-        "cleared" 
+        "cleared"
       elsif self.raised? and !self.was_raised?
         "raised"
       elsif self.raised? and self.acknowledged? and !self.was_acknowledged?
@@ -369,7 +373,7 @@ module Mauve
         #
         # Add a note saying that notifications have been suppressed
         #
-        if !should_notify 
+        if !should_notify
           history.event += " (notifications not required)"
         elsif self.suppressed?
           history.event += " (notifications suppressed until #{self.suppress_until.to_s_human})"
@@ -397,7 +401,7 @@ module Mauve
         # Success
         #
         return true
-      rescue DataMapper::SaveFailureError => err 
+      rescue DataMapper::SaveFailureError => err
         logger.error "Failed to save #{self} due to #{err.inspect}"
       end
 
@@ -421,14 +425,14 @@ module Mauve
       #
       limit = Time.now + Configuration.current.max_acknowledgement_time
       ack_until = limit if ack_until > limit
- 
+
       self.acknowledged_by = person.username
       self.acknowledged_at = Time.now
       self.will_unacknowledge_at = ack_until
 
       self.save
     end
- 
+
     # Unacknowledge an alert
     #
     # @return [Boolean] showing the unacknowledgment has been successful
@@ -446,9 +450,9 @@ module Mauve
 
       self.save
     end
-   
+
     # Raise an alert at a specified time
-    #    
+    #
     # @param [Time] at The time at which the alert should be raised.
     #
     # @return [Boolean] showing the raise has been successful
@@ -457,7 +461,7 @@ module Mauve
       # OK if this is an alert updated in the last run, do not raise, just postpone.
       #
       if (self.will_raise_at or self.will_unacknowledge_at) and
-          Server.instance.in_initial_sleep? and 
+          Server.instance.in_initial_sleep? and
           self.updated_at and
           self.updated_at < Server.instance.started_at
 
@@ -470,7 +474,7 @@ module Mauve
         if self.will_unacknowledge_at and self.will_unacknowledge_at <= Time.now
           self.will_unacknowledge_at = postpone_until
         end
-        
+
         logger.info("Postponing raise of #{self} until #{postpone_until} as it was last updated in a prior run of Mauve.")
       else
         self.acknowledged_by = nil
@@ -487,7 +491,7 @@ module Mauve
     end
 
     # Clear an alert at a specified time
-    #    
+    #
     # @param [Time] at The time at which the alert should be cleared.
     #
     # @return [Boolean] showing the clear has been successful
@@ -496,10 +500,10 @@ module Mauve
       # Postpone clearance if we're in the sleep period.
       #
       if self.will_clear_at and
-          Server.instance.in_initial_sleep? and 
+          Server.instance.in_initial_sleep? and
           self.updated_at and
           self.updated_at < Server.instance.started_at
-        
+
         self.will_clear_at = Server.instance.started_at + Server.instance.initial_sleep
 
         logger.info("Postponing clear of #{self} until #{self.will_clear_at} as it was last updated in a prior run of Mauve.")
@@ -543,7 +547,7 @@ module Mauve
     def due_at
       [will_clear_at, will_raise_at, will_unacknowledge_at].compact.sort.first
     end
-    
+
     # Polls the alert, raising or clearing as needed.
     #
     # @return [Boolean] showing the poll was successful
@@ -610,7 +614,7 @@ module Mauve
     def cleared?
       !raised?
     end
- 
+
     # Was the alert cleared before the current changes?
     #
     # @return [Boolean]
@@ -696,6 +700,8 @@ module Mauve
       end
 
       def clean_utf8(str)
+        # We're explicitly throwing away non-valid data here.
+        forced = str.force_encoding("ASCII-8BIT")
         unless UTF8_REGEXP.match(str)
           str.gsub(/[^\x00-\x7F]/,'?')
         else
@@ -709,7 +715,7 @@ module Mauve
       def all_raised
         all(:raised_at.not => nil, :order => [:raised_at.asc]) & (all(:cleared_at => nil) | all(:conditions => ['"raised_at" >= "cleared_at"']))
       end
-      
+
       # All alerts currently raised and unacknowledged
       #
       # @return [Array]
@@ -763,7 +769,7 @@ module Mauve
           earliest_alert ? earliest_alert.alert : nil
         end
       end
-     
+
       # Receive an AlertUpdate buffer from the wire.
       #
       # @param [String] update The update string, as received over UDP
@@ -780,14 +786,14 @@ module Mauve
         end
 
         alerts_updated = []
-        
+
         # logger.debug("Alert update received from wire: #{update.inspect.split("\n").join(" ")}")
-        
+
         #
         # Transmission time helps us determine any time offset
         #
         if update.transmission_time and update.transmission_time > 0
-          transmission_time = Time.at(update.transmission_time) 
+          transmission_time = Time.at(update.transmission_time)
         else
           transmission_time = reception_time
         end
@@ -796,14 +802,14 @@ module Mauve
 
         #
         # Make sure there is no HTML in the update source.  Need to do this
-        # here because we use the html-free version in the database save hook. 
+        # here because we use the html-free version in the database save hook.
         #
         update.source = Alert.remove_html(update.source.to_s)
 
         # Update each alert supplied
         #
         update.alert.each do |alert|
-          # 
+          #
           # Infer some actions from our pure data structure (hmm, wonder if
           # this belongs in our protobuf-derived class?
           #
@@ -814,7 +820,7 @@ module Mauve
             #
             # Make sure that we raise if neither raise nor clear is set
             #
-            raise_time = reception_time 
+            raise_time = reception_time
           end
 
           #
@@ -823,7 +829,7 @@ module Mauve
           # search to fail.
           #
           alert.id = Alert.remove_html(alert.id.to_s)
- 
+
           #
           # Load the database alert, and all its properties, since we're updating.
           #
@@ -881,10 +887,10 @@ module Mauve
           #
           # Set the subject
           #
-          if alert.subject and !alert.subject.empty? 
+          if alert.subject and !alert.subject.empty?
             alert_db.subject = alert.subject
 
-          elsif alert_db.subject.nil? 
+          elsif alert_db.subject.nil?
             #
             # Use the source, Luke, but only when the subject hasn't already been set.
             #
@@ -895,7 +901,7 @@ module Mauve
 
           alert_db.detail = alert.detail   if alert.detail  && !alert.detail.empty?
 
-          alert_db.importance = alert.importance if alert.importance != 0 
+          alert_db.importance = alert.importance if alert.importance != 0
 
           alert_db.updated_at = reception_time
 
@@ -905,19 +911,19 @@ module Mauve
           #  * the alert is not already suppressed
           #  * the alert has changed state.
           #
-          if !alert_db.suppressed? and 
+          if !alert_db.suppressed? and
             ((alert_db.was_raised? and !alert_db.raised?) or (alert_db.was_cleared? and !alert_db.cleared?))
             alert_db.suppress_until = Time.at(alert.suppress_until + time_offset)
           end
 
-          if alert_db.raised? 
+          if alert_db.raised?
             #
             # If we're acknowledged, just save.
             #
             if alert_db.acknowledged?
               alert_db.save
             else
-              alert_db.raise! 
+              alert_db.raise!
             end
           else
             alert_db.clear!
@@ -929,7 +935,7 @@ module Mauve
           logger.info("Received update from #{ip_source} for #{alert_db}")
 
         end
-        
+
         # If this is a complete replacement update, find the other alerts
         # from this source and clear them.
         #
@@ -940,14 +946,14 @@ module Mauve
           # The to_a is used here to make sure datamapper runs the query now,
           # rather than at some point in the future.
           #
-          Alert.all(:source => update.source, 
+          Alert.all(:source => update.source,
               :alert_id.not => alert_ids_mentioned
               ).to_a.each do |alert_db|
             alert_db.clear! unless alert_db.cleared?
           end
         end
-      
-        return nil 
+
+        return nil
       end
 
       #
diff --git a/lib/mauve/authentication.rb b/lib/mauve/authentication.rb
index ad7bf60..73c503a 100644
--- a/lib/mauve/authentication.rb
+++ b/lib/mauve/authentication.rb
@@ -1,5 +1,5 @@
 # encoding: UTF-8
-require 'sha1'
+require 'digest/sha1'
 require 'xmlrpc/client'
 
 #
diff --git a/lib/mauve/configuration_builders/person.rb b/lib/mauve/configuration_builders/person.rb
index 9cc09ab..5f08d19 100644
--- a/lib/mauve/configuration_builders/person.rb
+++ b/lib/mauve/configuration_builders/person.rb
@@ -27,10 +27,10 @@ module Mauve
 
       is_flag_attribute "notify_when_on_holiday"
       is_flag_attribute "notify_when_off_sick"
-     
+
       # Sets the block for all levels of alert
       #
-      # @param [Block] block 
+      # @param [Block] block
       def all(&block); urgent(&block); normal(&block); low(&block); end
 
       #
@@ -56,8 +56,8 @@ module Mauve
 
           @result.suppress_notifications_after[in_period] = number_of_alerts
           # History.all(
-          # :limit => number_of_alerts, 
-          # :order => :created_at.desc, 
+          # :limit => number_of_alerts,
+          # :order => :created_at.desc,
           # :type => "notification",
           # :event.like => '% succeeded')
         end
@@ -93,14 +93,14 @@ module Mauve
       # Add a default notification threshold
       #
       person.suppress_notifications_after[600] = 5 if person.suppress_notifications_after.empty?
-      
+
       #
       # Add a default notify clause
       #
       if person.notifications.empty?
         default_notification = Notification.new(person)
         default_notification.every = 30.minutes
-        default_notification.during = lambda { working_hours? }
+        default_notification.during = Proc.new { working_hours? }
         person.notifications << default_notification
       end
 
@@ -108,11 +108,11 @@ module Mauve
       # Set up some default notify levels.
       #
       if person.urgent.nil? and person.normal.nil? and person.low.nil?
-        person.urgent = lambda { sms ; xmpp ; email }
-        person.normal = lambda { xmpp ; email }
-        person.low    = lambda { email }
+        person.urgent = Proc.new { sms ; xmpp ; email }
+        person.normal = Proc.new { xmpp ; email }
+        person.low    = Proc.new { email }
       end
-      
+
       @result.people[person.username] = person
     end
 
diff --git a/lib/mauve/datamapper.rb b/lib/mauve/datamapper.rb
index 52f37c1..1f3522c 100644
--- a/lib/mauve/datamapper.rb
+++ b/lib/mauve/datamapper.rb
@@ -7,11 +7,7 @@ require 'dm-core'
 require 'dm-migrations'
 require 'dm-aggregates'
 %w(dm-sqlite-adapter-with-mutex dm-postgres-adapter).each do |req|
-  begin
-    require req
-  rescue LoadError => err
-    # do not a lot.
-  end
+  require req
 end
 require 'dm-transactions'
 require 'dm-types'
diff --git a/lib/mauve/notifiers/xmpp.rb b/lib/mauve/notifiers/xmpp.rb
index f14f508..8ab6d48 100644
--- a/lib/mauve/notifiers/xmpp.rb
+++ b/lib/mauve/notifiers/xmpp.rb
@@ -28,19 +28,19 @@ module Jabber
       10.times do
         pr = 0
         @tbcbmutex.synchronize { pr = @processing }
-        break if pr = 0
+        break if pr == 0
         Thread::pass if pr > 0
         sleep 1
       end
 
-      # Order Matters here! If this method is called from within 
-      # @parser_thread then killing @parser_thread first would 
-      # mean the other parts of the method fail to execute. 
+      # Order Matters here! If this method is called from within
+      # @parser_thread then killing @parser_thread first would
+      # mean the other parts of the method fail to execute.
       # That would be bad. So kill parser_thread last
       @tbcbmutex.synchronize { @processing = 0 }
       if @fd and !@fd.closed?
-        @fd.close 
-        stop 
+        @fd.close
+        stop
       end
       @status = DISCONNECTED
     end
@@ -52,7 +52,7 @@ end
 
 module Mauve
   module Notifiers
- 
+
     #
     # This is the Jabber/XMMP notifiers module.
     #
@@ -73,7 +73,7 @@ module Mauve
         attr_accessor :password
 
         def initialize(name)
-          Jabber::logger = self.logger       
+          Jabber::logger = self.logger
 #         Jabber::debug = true
 #          Jabber::warnings = true
 
@@ -85,13 +85,13 @@ module Mauve
         end
 
         # The logger instance
-        # 
+        #
         # @return [Log4r::Logger]
         def logger
           # Give the logger a sane name
           @logger ||= Log4r::Logger.new self.class.to_s.sub(/::Default$/,"")
         end
-       
+
         # Sets the client's JID
         #
         # @param [String] jid The JID required.
@@ -109,7 +109,7 @@ module Mauve
           # Make sure we're disconnected.
           self.close if @client.is_a?(Client)
 
-          @client = Client.new(@jid) 
+          @client = Client.new(@jid)
 
           @closing = false
           @client.connect
@@ -147,7 +147,7 @@ module Mauve
             # The XMPP4R exception clauses in Stream all close the stream, so
             # we just need to reconnect.
             #
-          #   unless ex.nil? or @closing 
+          #   unless ex.nil? or @closing
           #     logger.warn(["Caught",ex.class,ex.to_s,"during XMPP",where].join(" "))
           #     logger.debug ex.backtrace.join("\n")
           #     self.close
@@ -158,23 +158,23 @@ module Mauve
           logger.debug ex.backtrace.join("\n")
           self.close
           @client = nil
-        end  
+        end
 
         def stop
           @client.stop
         end
-  
+
         #
         # Closes the XMPP connection, if possible.  Sets @client to nil.
         #
         # @return [NilClass]
         def close
           @closing = true
-          if @client 
+          if @client
             if  @client.is_connected?
               @mucs.each do |jid, muc|
                 muc[:client].exit("Goodbye!") if muc[:client].active?
-              end 
+              end
               @client.send(Presence.new(nil, "Goodbye!").set_type(:unavailable))
             end
             @client.close!
@@ -188,8 +188,8 @@ module Mauve
         def ready?
           @client.is_a?(Jabber::Client) and @client.is_connected?
         end
-        
-        # Attempt to send an alert using XMPP. 
+
+        # Attempt to send an alert using XMPP.
         #
         # @param [String] destination The JID you're sending the alert to. This should be
         #   a bare JID in the case of an individual, or +muc:room@server+ for
@@ -207,21 +207,21 @@ module Mauve
         #   has a presence matching one or more of the choices - see
         #   Mauve::Notifiers::Xmpp::Default#check_jid_has_presence for options.
         #
-        # @return [Boolean] 
+        # @return [Boolean]
         def send_alert(destination, alert, all_alerts, conditions = {})
-          destination_jid = JID.new(destination)         
- 
+          destination_jid = JID.new(destination)
+
           was_suppressed = conditions[:was_suppressed] || false
           will_suppress  = conditions[:will_suppress]  || false
-          
-          if conditions && !check_alert_conditions(destination_jid, conditions) 
+
+          if conditions && !check_alert_conditions(destination_jid, conditions)
             logger.info("Alert conditions not met, not sending XMPP alert to #{destination_jid}")
             return false
           end
-         
+
           template_file = File.join(File.dirname(__FILE__),"templates","xmpp.txt.erb")
 
-          txt = if File.exists?(template_file) 
+          txt = if File.exists?(template_file)
             ERB.new(File.read(template_file)).result(binding).chomp
           else
             logger.error("Could not find xmpp.txt.erb template")
@@ -250,10 +250,10 @@ module Mauve
 
           message = Message.new(jid)
           message.body = msg
-          if html_msg 
+          if html_msg
             begin
               html_msg = REXML::Document.new(html_msg) unless html_msg.is_a?(REXML::Document)
-              message.add_element(html_msg) 
+              message.add_element(html_msg)
             rescue REXML::ParseException
               logger.error "Bad XHTML: #{html_msg.inspect}"
             end
@@ -295,11 +295,11 @@ module Mauve
           self.connect unless self.ready?
 
           return unless self.ready?
- 
+
           if jid.is_a?(String) and jid =~ /^muc:(.*)/
-            jid = JID.new($1) 
+            jid = JID.new($1)
           end
-            
+
           unless jid.is_a?(JID)
             logger.warn "#{jid} is not a MUC"
             return
@@ -310,9 +310,9 @@ module Mauve
           if !@mucs[jid.strip]
 
             logger.debug("Adding new MUC client for #{jid}")
-            
+
             @mucs[jid.strip] = {:jid => jid, :password => password, :client => Jabber::MUC::MUCClient.new(@client)}
-            
+
             # Add some callbacks
             @mucs[jid.strip][:client].add_message_callback do |m|
               receive_message(m)
@@ -339,10 +339,10 @@ module Mauve
           # Return the JID object
           #
           jid.strip
-        end 
-        
-        # 
-        # Checks whether the destination JID is a MUC. 
+        end
+
+        #
+        # Checks whether the destination JID is a MUC.
         #
         def is_muc?(jid)
           (jid.is_a?(JID)    and @mucs.keys.include?(jid.strip)) or
@@ -366,7 +366,7 @@ module Mauve
           # end
         end
 
-        # 
+        #
         # Checks to see if the JID is in our roster, and whether we are
         # subscribed to it or not. Will add to the roster and subscribe as
         # is necessary to ensure both are true.
@@ -381,7 +381,7 @@ module Mauve
           jid = JID.new(jid) unless jid.is_a?(JID)
 
           ri = @roster.find(jid).values.first
-          @roster.add(jid, nil, true) if ri.nil? 
+          @roster.add(jid, nil, true) if ri.nil?
 
           ri = @roster.find(jid).values.first
           ri.subscribe unless [:to, :both, :remove].include?(ri.subscription)
@@ -399,7 +399,7 @@ module Mauve
           #
           if @jid == msg.from or @mucs.any?{|jid, muc| muc.is_a?(Hash) and muc.has_key?(:client) and muc[:client].jid == msg.from}
             return nil
-          end 
+          end
 
           # We only want to hear messages from known contacts.
           unless is_known_contact?(msg.from)
@@ -419,7 +419,7 @@ module Mauve
         end
 
         def receive_error_message(msg)
-          logger.warn("Caught XMPP error #{msg}") 
+          logger.warn("Caught XMPP error #{msg}")
           nil
         end
 
@@ -437,7 +437,7 @@ module Mauve
             unless join_muc(jid)
               logger.warn "Failed to join MUC #{jid} following invitation"
               return nil
-            end            
+            end
           elsif msg.body
             #
             # Received a message with a body.
@@ -445,7 +445,7 @@ module Mauve
             jid = msg.from
           end
 
-          if jid 
+          if jid
             reply = parse_command(msg)
             send_message(jid, reply, nil, msg.type)
           end
@@ -458,11 +458,11 @@ module Mauve
           # match our resource or node in the body.
           #
           if @mucs[msg.from.strip][:client].is_a?(MUC::MUCClient) and
-                msg.x("jabber:x:delay") == nil and 
+                msg.x("jabber:x:delay") == nil and
                 (msg.body =~ /\b#{Regexp.escape(@mucs[msg.from.strip][:client].jid.resource)}\b/i or
                 msg.body =~ /\b#{Regexp.escape(@client.jid.node)}\b/i)
 
-            receive_normal_message(msg) 
+            receive_normal_message(msg)
           end
         end
 
@@ -480,13 +480,13 @@ module Mauve
               "Sorry -- destroy has been disabled.  Try \"clear\" instead."
             else
               File.executable?('/usr/games/fortune') ? `/usr/games/fortune -s -n 60`.chomp : "I'd love to stay and chat, but I'm really quite busy"
-          end          
+          end
         end
 
         def do_parse_help(msg)
           msg.body =~ /help\s+(\w+)/i
           cmd = $1
-          
+
           return case cmd
             when /^show/
                <<EOF
@@ -532,7 +532,7 @@ EOF
 
             else
               "I am Mauve #{Mauve::VERSION}.  I understand \"help\", \"show\", \"acknowledge\", and \"destroy\" commands.  Try \"help show\"."
-          end       
+          end
         end
 
         def do_parse_show(msg)
@@ -544,25 +544,25 @@ EOF
 
           type = $3 || "raised"
           type = "acknowledged" if type =~ /^ack/
-          
+
           msg = []
-          
+
           items = case type
             when "acknowledged"
               Alert.all_acknowledged.all(:order => [:acknowledged_at.asc])
             when "events"
               History.all(:created_at.gte => Time.now - 24.hours)
-            else 
+            else
               Alert.all_unacknowledged.all(:order => [:raised_at.asc])
           end
 
           if first_or_last == "first"
-            items = items.first(n_items) if n_items >= 0 
+            items = items.first(n_items) if n_items >= 0
           elsif first_or_last == "last"
-            items = items.last(n_items) if n_items >= 0 
+            items = items.last(n_items) if n_items >= 0
           end
 
-          return "Nothing to show" if items.length == 0          
+          return "Nothing to show" if items.length == 0
 
           template_file = File.join(File.dirname(__FILE__),"templates","xmpp.txt.erb")
           if File.exists?(template_file)
@@ -570,9 +570,9 @@ EOF
           else
             logger.error("Could not find xmpp.txt.erb template")
             template = nil
-          end 
+          end
 
-          (["Alerts #{type}:"] + items.collect do |alert| 
+          (["Alerts #{type}:"] + items.collect do |alert|
             ERB.new(template).result(binding).chomp
           end).join("\n")
         end
@@ -580,7 +580,7 @@ EOF
         def do_parse_ack(msg)
           return "Sorry -- I don't understand your acknowledge command." unless
              msg.body =~ /ack(?:nowledge)?\s+([\d\D]+)\s+for\s+(\d+(?:\.\d+)?)\s+(work(?:ing)?|day(?:time)?|wall(?:-?clock)?)?\s*(day|hour|min(?:ute)?|sec(?:ond))s?(?:\s+(?:cos|cause|as|because)?\s*(.*))?/i
-          
+
           alerts, n_hours, type_hours, dhms, note = [$1,$2, $3, $4, $5]
 
           alerts = alerts.split(/\D+/)
@@ -608,7 +608,7 @@ EOF
           begin
             now = Time.now
             ack_until = now.in_x_hours(n_hours, type_hours)
-          rescue RangeError 
+          rescue RangeError
             return "I'm sorry, you tried to acknowedge for far too long, and my buffers overflowed!"
           end
 
@@ -627,7 +627,7 @@ EOF
             alert = Alert.get(alert_id)
 
             if alert.nil?
-              msg << "#{alert_id}: alert not found" 
+              msg << "#{alert_id}: alert not found"
               next
             end
 
@@ -643,7 +643,7 @@ EOF
               msg << "#{alert_id}: Acknowledgement failed."
             end
           end
-  
+
           #
           # Add the note.
           #
@@ -662,7 +662,7 @@ EOF
 
           alerts = $1.split(/\D+/)
           note   = $2
-          
+
           username = get_username_for(msg.from)
 
           if is_muc?(Configuration.current.people[username].xmpp)
@@ -683,7 +683,7 @@ EOF
             if alert.cleared?
               msg << "#{alert_id}: alert already cleared."
               next
-            end 
+            end
 
             if alert.clear!
               msg << "#{alert.to_s} cleared."
@@ -691,7 +691,7 @@ EOF
               msg << "#{alert.to_s}: clearing failed."
             end
           end
-          
+
           #
           # Add the note.
           #
@@ -707,19 +707,20 @@ EOF
         def check_alert_conditions(destination, conditions)
           any_failed = conditions.keys.collect do |key|
             case key
-              when :if_presence : check_jid_has_presence(destination, conditions[:if_presence])
-              else 
+            when :if_presence
+              check_jid_has_presence(destination, conditions[:if_presence])
+            else
                 #raise ArgumentError.new("Unknown alert condition, #{key} => #{conditions[key]}")
                 # FIXME - clean up this use of :conditions to pass arbitrary
-                # parameters to notifiers; for now we need to ignore this. 
+                # parameters to notifiers; for now we need to ignore this.
                 true
             end
           end.include?(false)
           !any_failed
         end
-        
-        # Checks our roster to see whether the jid has a resource with at least 
-        # one of the included presences. Acceptable +presence+ types and their 
+
+        # Checks our roster to see whether the jid has a resource with at least
+        # one of the included presences. Acceptable +presence+ types and their
         # meanings for individuals:
         #
         #   :online, :offline               - user is logged in or out
@@ -747,14 +748,28 @@ EOF
 
           results = presences.collect do |need_presence|
             case need_presence
-              when :online      : (roster_item && [:to, :both].include?(roster_item.subscription) && roster_item.online?)
-              when :offline     : (roster_item && [:to, :both].include?(roster_item.subscription) && !roster_item.online?)
-              when :available   : (roster_item && [:to, :both].include?(roster_item.subscription) && (resource_presences.include?(nil) ||
-                                                                                                      resource_presences.include?(:chat)))
+            when :online
+              (roster_item &&
+               [:to, :both].include?(roster_item.subscription) &&
+               roster_item.online?)
+            when :offline
+              (roster_item &&
+               [:to, :both].include?(roster_item.subscription) &&
+               !roster_item.online?)
+            when :available
+              (roster_item &&
+               [:to, :both].include?(roster_item.subscription) &&
+               (resource_presences.include?(nil) ||
+                resource_presences.include?(:chat)))
               # No resources are nil or chat
-              when :unavailable : (roster_item && [:to, :both].include?(roster_item.subscription) && (resource_presences - [:away, :dnd, :xa]).empty?)
+            when :unavailable
+              (roster_item &&
+               [:to, :both].include?(roster_item.subscription) &&
+               (resource_presences - [:away, :dnd, :xa]).empty?)
               # Not in roster or don't know subscription
-              when :unknown     : (roster_item.nil? || [:none, :from].include?(roster_item.subscription)) 
+            when :unknown
+              (roster_item.nil? ||
+               [:none, :from].include?(roster_item.subscription))
             else
               raise ArgumentError.new("Unknown presence possibility: #{need_presence}")
             end
@@ -767,7 +782,7 @@ EOF
         #
         def get_username_for(jid)
           jid = JID.new(jid) unless jid.is_a?(JID)
-       
+
           #
           # Resolve MUC JIDs.
           #
@@ -775,7 +790,7 @@ EOF
             muc_jid = get_jid_from_muc_jid(jid)
             jid = muc_jid unless muc_jid.nil?
           end
- 
+
           ans = Configuration.current.people.find do |username, person|
             next unless person.xmpp.is_a?(JID)
             person.xmpp.strip == jid.strip
@@ -814,7 +829,7 @@ EOF
         def is_known_contact?(jid)
           !get_username_for(jid).nil?
         end
-        
+
       end
     end
   end
diff --git a/lib/mauve/server.rb b/lib/mauve/server.rb
index 8f8cec4..0a63737 100644
--- a/lib/mauve/server.rb
+++ b/lib/mauve/server.rb
@@ -38,10 +38,10 @@ module Mauve
       super
       @hostname    = Socket.gethostname
       @database    = "sqlite3::memory:"
-      
+
       @started_at = Time.now
       @initial_sleep = 300
-      
+
       #
       # Keep these queues here to prevent a crash in a subthread losing all the
       # subsquent things in the queue.
@@ -53,7 +53,7 @@ module Mauve
       # Bank Holidays -- this list is kept here, because I can't think of
       # anywhere else to put it.
       #
-      @bank_holidays = nil 
+      @bank_holidays = nil
 
       #
       # Turn off unwanted reverse DNS lookups across the board.
@@ -94,7 +94,7 @@ module Mauve
 
       @packet_buffer
     end
- 
+
     # Sets up the notification buffer (or not).  The argument can be "false" or
     # "no" or a FalseClass object for no.  Anything else makes no change.
     #
@@ -149,13 +149,13 @@ module Mauve
 
     # This sorts out the Server.  It empties the notification and packet
     # buffers.  It configures and migrates the database.
-    #  
+    #
     # @return [NilClass]
     def setup
       #
       # Set up the database
       #
-      DataMapper.logger = Log4r::Logger.new("Mauve::DataMapper") 
+      DataMapper.logger = Log4r::Logger.new("Mauve::DataMapper")
       DataMapper.setup(:default, @database)
 
       #
@@ -166,7 +166,7 @@ module Mauve
         m = Mauve.const_get(c)
         next unless m.respond_to?("auto_upgrade!")
         m.auto_upgrade!
-        # 
+        #
         # Don't want to use automigrate, since this trashes the tables.
         #
         # m.auto_migrate! if m.respond_to?("auto_migrate!")
@@ -194,12 +194,12 @@ module Mauve
 #      self.state = :starting
 
       setup
-      
+
       run_thread { main_loop }
     end
 
-    alias run start 
-    
+    alias run start
+
     #
     # This stops the main loop, and all the threads that are defined in THREAD_CLASSES above.
     #
@@ -207,7 +207,7 @@ module Mauve
       if self.state == :stopping
         # uh-oh already told to stop.
         logger.error "Stop already called.  Killing self!"
-        Kernel.exit 1 
+        Kernel.exit 1
       end
 
       self.state = :stopping
@@ -215,13 +215,13 @@ module Mauve
       THREAD_CLASSES.each do |klass|
         klass.instance.stop unless klass.instance.nil?
       end
-      
-      thread_list = Thread.list 
+
+      thread_list = Thread.list
       thread_list.delete(Thread.current)
 
       thread_list.each do |t|
         t.exit
-      end      
+      end
 
       self.state = :stopped
     end
@@ -229,7 +229,7 @@ module Mauve
     private
 
     def main_loop
-      thread_list = Thread.list 
+      thread_list = Thread.list
 
       thread_list.delete(Thread.current)
 
@@ -239,7 +239,7 @@ module Mauve
       if self.class.notification_buffer_size >= 10
         logger.info "Notification buffer has #{self.class.notification_buffer_size} messages in it"
       end
-      
+
       if self.class.packet_buffer_size >= 100
         logger.info "Packet buffer has #{self.class.packet_buffer_size} updates in it"
       end
@@ -259,12 +259,12 @@ module Mauve
           klass.instance.stop
         end
 
-        # 
+        #
         # Do nothing if we're frozen or supposed to be stopping or still alive!
         #
         next if self.should_stop? or klass.instance.alive?
 
-        # 
+        #
         # ugh something is beginnging to smell.
         #
         begin
@@ -304,7 +304,7 @@ module Mauve
       #
       sleep 5
     end
-    
+
 
     class << self
 
@@ -316,7 +316,7 @@ module Mauve
       #
 
       # Push a packet onto the back of the +packet_buffer+
-      # 
+      #
       # @param [String] a Packet from the UDP server
       def packet_enq(a)
         instance.packet_buffer.push(a)
@@ -342,7 +342,7 @@ module Mauve
 
       alias packet_push packet_enq
       alias packet_pop  packet_deq
-      
+
       # Push a notification on to the back of the +notification_buffer+
       #
       # @param [Array] a Notification array, consisting of a Person and the args to Mauve::Person#send_alert
@@ -367,7 +367,7 @@ module Mauve
       rescue NoMethodError
         0
       end
-      
+
       alias notification_push notification_enq
       alias notification_pop  notification_deq
 
diff --git a/lib/rack-flash.rb b/lib/rack-flash.rb
index bc95b21..7a235d2 100644
--- a/lib/rack-flash.rb
+++ b/lib/rack-flash.rb
@@ -12,7 +12,7 @@ module Rack
       def middleware.rack_builder
         @rack_builder
       end
-      @ins << lambda { |app|
+      @ins << Proc.new { |app|
         middleware.new(app, *args, &block)
       }
     end
-- 
cgit v1.2.3