aboutsummaryrefslogtreecommitdiff
path: root/lib/mauve/alert_changed.rb
diff options
context:
space:
mode:
authorPatrick J Cherry <patrick@bytemark.co.uk>2011-04-13 17:03:16 +0100
committerPatrick J Cherry <patrick@bytemark.co.uk>2011-04-13 17:03:16 +0100
commit89a67770e66d11740948e90a41db6cee0482cf8e (patch)
treebe858515fb789a89d68f94975690ab019813726c /lib/mauve/alert_changed.rb
new version.
Diffstat (limited to 'lib/mauve/alert_changed.rb')
-rw-r--r--lib/mauve/alert_changed.rb144
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/mauve/alert_changed.rb b/lib/mauve/alert_changed.rb
new file mode 100644
index 0000000..4668fd7
--- /dev/null
+++ b/lib/mauve/alert_changed.rb
@@ -0,0 +1,144 @@
+# encoding: UTF-8
+require 'mauve/datamapper'
+require 'log4r'
+
+module Mauve
+ class AlertChanged
+ include DataMapper::Resource
+
+ # so .first always returns the most recent update
+ default_scope(:default).update(:order => [:at.desc, :id.desc])
+
+ property :id, Serial
+ property :alert_id, Integer, :required => true
+ property :person, String, :required => true
+ property :at, DateTime, :required => true
+ property :was_relevant, Boolean, :required => true, :default => true
+ property :level, String, :required => true
+ property :update_type, String, :required => true
+ property :remind_at, DateTime
+ property :updated_at, DateTime
+
+
+ def to_s
+ "#<AlertChanged:#{id} of #{alert_id} for #{person} update_type #{update_type}>"
+ end
+
+ belongs_to :alert
+
+ # There is a bug there. You could have two reminders for the same
+ # person if that person has two different notify clauses.
+ #
+ # See the test cases test_Bug_reminders_get_trashed() in ./test/
+ after :create do
+ old_changed = AlertChanged.first(
+ :alert_id => alert_id,
+ :person => person,
+ :id.not => id,
+ :remind_at.not => nil
+ )
+ if old_changed
+ if !old_changed.update(:remind_at => nil)
+ logger.error "Couldn't save #{old_changed}, will get duplicate reminders"
+ end
+ end
+ end
+
+ def was_relevant=(value)
+ attribute_set(:was_relevant, value)
+ end
+
+ def logger
+ Log4r::Logger.new self.class.to_s
+ end
+
+## def initialize
+# logger = Log4r::Logger.new self.class.to_s
+# end
+
+ ## Checks to see if a raise was send to the person.
+ #
+ # @TODO: Recurence is broken in ruby, change this so that it does not
+ # use it.
+ #
+ # @author Matthew Bloch
+ # @return [Boolean] true if it was relevant, false otherwise.
+ def was_relevant_when_raised?
+ if :acknowledged == update_type.to_sym and true == was_relevant
+ return true
+ end
+ return was_relevant if update_type.to_sym == :raised
+ previous = AlertChanged.first(:id.lt => id,
+ :alert_id => alert_id,
+ :person => person)
+ if previous
+ previous.was_relevant_when_raised?
+ else
+ # a bug, but hardly inconceivable :)
+ logger.warn("Could not see that #{alert} was raised with #{person} "+
+ "but further updates exist (e.g. #{self}) "+
+ "- you may see spurious notifications as a result")
+ true
+ end
+ end
+
+ # Sends a reminder about this alert state change, or forget about it if
+ # the alert has been acknowledged
+ #
+ def remind
+ logger.debug "Reminding someone about #{self.inspect}"
+
+ alert_group = AlertGroup.matches(alert)[0]
+
+ if !alert_group || alert.acknowledged?
+ logger.debug((alert_group ?
+ "Alert already acknowledged" :
+ "No alert group matches any more"
+ ) + ", no reminder due"
+ )
+ self.remind_at = nil
+ save
+ else
+ saved = false
+
+ alert_group.notifications.each do |notification|
+ notification.people.each do |person|
+ if person.username == self.person
+ person.remind(alert, level)
+ self.remind_at = notification.remind_at_next(alert)
+ save
+ saved = true
+ end
+ end
+ end
+
+ if !saved
+ logger.warn("#{self.inspect} did not match any people, maybe configuration has changed but I'm going to delete this and not try to remind anyone again")
+ destroy!
+ end
+ end
+ end
+
+ def due_at # mimic interface from Alert
+ remind_at ? remind_at.to_time : nil
+ end
+
+ def poll # mimic interface from Alert
+ remind if remind_at.to_time <= MauveTime.now
+ end
+
+ class << self
+ def next_reminder
+ first(:remind_at.not => nil, :order => [:remind_at])
+ end
+
+ def find_next_with_event # mimic interface from Alert
+ next_reminder
+ end
+
+ def all_overdue(at = MauveTime.now)
+ all(:remind_at.not => nil, :remind_at.lt => at, :order => [:remind_at]).to_a
+ end
+ end
+ end
+end