6 attr_accessor :name, :group, :info
8 def self.generate(kind)
9 sym = kind.to_s.capitalize.gsub(/_(.)/){$1.upcase}.intern
10 c = God::Contacts.const_get(sym).new
12 unless c.kind_of?(Contact)
13 abort "Contact '#{c.class.name}' must subclass God::Contact"
18 raise NoSuchContactError.new("No Contact found with the class name God::Contacts::#{sym}")
21 def self.valid?(contact)
23 valid &= Configurable.complain("Attribute 'name' must be specified", contact) if contact.name.nil?
27 # Normalize the given notify specification into canonical form.
28 # +spec+ is the notify spec as a String, Array of Strings, or Hash
30 # Canonical form looks like:
31 # {:contacts => ['fred', 'john'], :priority => '1', :category => 'awesome'}
32 # Where :contacts will be present and point to an Array of Strings. Both
33 # :priority and :category may not be present but if they are, they will each
34 # contain a single String.
36 # Returns normalized notify spec
37 # Raises ArgumentError on invalid spec (message contains details)
38 def self.normalize(spec)
41 {:contacts => Array(spec)}
43 unless spec.select { |x| !x.instance_of?(String) }.empty?
44 raise ArgumentError.new("contains non-String elements")
51 if contacts = copy.delete(:contacts)
56 unless contacts.select { |x| !x.instance_of?(String) }.empty?
57 raise ArgumentError.new("has a :contacts key containing non-String elements")
61 raise ArgumentError.new("must have a :contacts key pointing to a String or Array of Strings")
64 raise ArgumentError.new("must have a :contacts key")
67 # remove priority and category
68 copy.delete(:priority)
69 copy.delete(:category)
71 # check for invalid keys
73 raise ArgumentError.new("contains extra elements: #{copy.inspect}")
77 spec[:contacts] &&= Array(spec[:contacts])
78 spec[:priority] &&= spec[:priority].to_s
79 spec[:category] &&= spec[:category].to_s
83 raise ArgumentError.new("must be a String (contact name), Array (of contact names), or Hash (contact specification)")
88 # Send the message to the external source
89 # +message+ is the message body returned from the condition
90 # +time+ is the Time at which the notification was made
91 # +priority+ is the arbitrary priority String
92 # +category+ is the arbitrary category String
93 # +host+ is the hostname of the server
94 def notify(message, time, priority, category, host)
95 raise AbstractMethodNotOverriddenError.new("Contact#notify must be overridden in subclasses")
98 # Construct the friendly name of this Contact, looks like:
102 super + " Contact '#{self.name}'"