aboutsummaryrefslogtreecommitdiff
path: root/lib/mauve/notifiers
diff options
context:
space:
mode:
authorPatrick J Cherry <patrick@bytemark.co.uk>2011-07-13 16:02:50 +0100
committerPatrick J Cherry <patrick@bytemark.co.uk>2011-07-13 16:02:50 +0100
commite140af144e987ff7f6d767f2dc48b9cf685803fd (patch)
tree4a01971890865b4b3ca837d563bc673cbb787de8 /lib/mauve/notifiers
parentd28af4ec946c6aa4b645b73cef47d7e0c680bc0d (diff)
Big commit
* Added manpages for all binaries * Added log-reopening for mauvealert-server, and logrotate snippet * mauveserver now adds a user on install, and runs as that user * Big logging tidy-up * Alert subjects are only overwritten by the source, when the subject in the databse is empty * Removed various attr_writer methods that were being redifined * Added a notes box to the acknowledge form, but this doesn't work yet
Diffstat (limited to 'lib/mauve/notifiers')
-rw-r--r--lib/mauve/notifiers/email.rb17
-rw-r--r--lib/mauve/notifiers/sms_aql.rb5
-rw-r--r--lib/mauve/notifiers/xmpp-smack.rb395
-rw-r--r--lib/mauve/notifiers/xmpp.rb26
4 files changed, 10 insertions, 433 deletions
diff --git a/lib/mauve/notifiers/email.rb b/lib/mauve/notifiers/email.rb
index 129afec..77b10f1 100644
--- a/lib/mauve/notifiers/email.rb
+++ b/lib/mauve/notifiers/email.rb
@@ -7,17 +7,9 @@ module Mauve
module Notifiers
module Email
-
- class Default
+ class Default
attr_reader :name
- attr :server, true
- attr :port, true
- attr :username, true
- attr :password, true
- attr :login_method, true
- attr :from, true
- attr :subject_prefix, true
- attr :email_suffix, true
+ attr_writer :server, :port, :password, :login_method, :from, :subject_prefix, :email_suffix
def username=(username)
@login_method ||= :plain
@@ -47,20 +39,15 @@ module Mauve
message = prepare_message(destination, alert, all_alerts, conditions)
args = [@server, @port]
args += [@username, @password, @login_method.to_sym] if @login_method
- history = Mauve::History.new(:alert => alert, :type => :notification)
begin
Net::SMTP.start(*args) do |smtp|
smtp.send_message(message, @from, destination)
end
- history.event = "Sent mail to #{destination}."
- history.save
true
rescue StandardError => ex
logger.error "SMTP failure: #{ex.to_s}"
logger.debug ex.backtrace.join("\n")
- history.event = "Failed to send mail to #{destination} due to #{ex.to_s}"
- history.save
false
end
end
diff --git a/lib/mauve/notifiers/sms_aql.rb b/lib/mauve/notifiers/sms_aql.rb
index b295e6c..dbda229 100644
--- a/lib/mauve/notifiers/sms_aql.rb
+++ b/lib/mauve/notifiers/sms_aql.rb
@@ -41,17 +41,12 @@ module Mauve
'Content-Length' => opts_string.length.to_s
})
- history = Mauve::History.new(:alert => alert, :type => :notification)
if response.kind_of?(Net::HTTPSuccess)
- history.event = "Sent SMS via AQL to #{destination}"
- history.save
#
# Woo -- return true!
#
true
else
- history.event = "Failed to send SMS via AQL to #{destination} due to #{response.class.to_s}"
- history.save
false
end
end
diff --git a/lib/mauve/notifiers/xmpp-smack.rb b/lib/mauve/notifiers/xmpp-smack.rb
deleted file mode 100644
index a160a35..0000000
--- a/lib/mauve/notifiers/xmpp-smack.rb
+++ /dev/null
@@ -1,395 +0,0 @@
-# encoding: utf-8
-
-# Ruby.
-require 'pp'
-require 'log4r'
-require 'monitor'
-
-# Java. Note that paths are mangeled in jmauve_starter.
-require 'java'
-require 'smack.jar'
-require 'smackx.jar'
-include_class "org.jivesoftware.smack.XMPPConnection"
-include_class "org.jivesoftware.smackx.muc.MultiUserChat"
-include_class "org.jivesoftware.smack.RosterListener"
-
-module Mauve
-
- module Notifiers
-
- module Xmpp
-
- class XMPPSmackException < StandardError
- end
-
- ## Main wrapper to smack java library.
- #
- # @author Yann Golanski
- # @see http://www.igniterealtime.org/builds/smack/docs/3.1.0/javadoc/
- #
- # This is a singleton which is not idea but works well for mauve's
- # configuration file set up.
- #
- # In general, this class is meant to be intialized then the method
- # create_slave_thread must be called. The latter will spawn a new
- # thread that will do the connecting and sending of messages to
- # the XMPP server. Once this is done, messages can be send via the
- # send_msg() method. Those will be queued and depending on the load,
- # should be send quickly enough. This is done so that the main thread
- # can not worry about sending messages and can do important work.
- #
- # @example
- # bot = Mauve::Notifiers::Xmpp::XMPPSmack.new()
- # bot.run_slave_thread("chat.bytemark.co.uk", 'mauvealert', 'TopSecret')
- # msg = "What fresh hell is this? -- Dorothy Parker."
- # bot.send_msg("yann@chat.bytemark.co.uk", msg)
- # bot.send_msg("muc:test@conference.chat.bytemark.co.uk", msg)
- #
- # @FIXME This won't quiet work with how mauve is set up.
- #
- class XMPPSmack
-
- # Globals are evil.
- @@instance = nil
-
- # Default constructor.
- #
- # A queue (@queue) is used to pass information between master/slave.
- def initialize ()
- extend(MonitorMixin)
- @logger = Log4r::Logger.new "mauve::XMPP_smack<#{Process.pid}>"
- @queue = Queue.new
- @xmpp = nil
- @name = "mauve alert"
- @slave_thread = nil
- @regexp_muc = Regexp.compile(/^muc\:/)
- @regexp_tail = Regexp.compile(/\/.*$/)
- @jid_created_chat = Hash.new()
- @separator = '<->'
- @logger.info("Created XMPPSmack singleton")
- end
-
- # Returns the instance of the XMPPSmack singleton.
- #
- # @param [String] login The JID as a full address.
- # @param [String] pwd The password corresponding to the JID.
- # @return [XMPPSmack] The singleton instance.
- def self.instance (login, pwd)
- if true == @@instance.nil?
- @@instance = XMPPSmack.new
- jid, tmp = login.split(/@/)
- srv, name = tmp.split(/\//)
- name = "Mauve Alert Bot" if true == name.nil?
- @@instance.run_slave_thread(srv, jid, pwd, name)
- sleep 5 # FIXME: This really should be synced... But how?
- end
- return @@instance
- end
-
- # Create the thread that sends messages to the server.
- #
- # @param [String] srv The server address.
- # @param [String] jid The JID.
- # @param [String] pwd The password corresponding to the JID.
- # @param [String] name The bot name.
- # @return [NULL] nada
- def run_slave_thread (srv, jid, pwd, name)
- @srv = srv
- @jid = jid
- @pwd = pwd
- @name = name
- @logger.info("Creating slave thread on #{@jid}@#{@srv}/#{@name}.")
- @slave_thread = Thread.new do
- self.create_slave_thread()
- end
- return nil
- end
-
- # Returns whether instance is connected and authenticated.
- #
- # @return [Boolean] True or false.
- def is_connected_and_authenticated? ()
- return false if true == @xmpp.nil?
- return (@xmpp.isConnected() and @xmpp.isAuthenticated())
- end
-
- # Creates the thread that does the actual sending to XMPP.
- # @return [NULL] nada
- def create_slave_thread ()
- begin
- @logger.info("Slave thread is now alive.")
- self.open()
- loop do
- rcp, msg = @queue.deq().split(@separator, 2)
- @logger.debug("New message for '#{rcp}' saying '#{msg}'.")
- if rcp.match(@regexp_muc)
- room = rcp.gsub(@regexp_muc, '').gsub(@regexp_tail, '')
- self.send_to_muc(room, msg)
- else
- self.send_to_jid(rcp, msg)
- end
- end
- rescue XMPPSmackException
- @logger.fatal("Something is wrong")
- ensure
- @logger.info("XMPP bot disconnect.")
- @xmpp.disconnect()
- end
- return nil
- end
-
- # Send a message to the recipient.
- #
- # @param [String] rcp The recipent MUC or JID.
- # @param [String] msg The message.
- # @return [NULL] nada
- def send_msg(rcp, msg)
- #if @slave_thread.nil? or not self.is_connected_and_authenticated?()
- # str = "There is either no slave thread running or a disconnect..."
- # @logger.warn(str)
- # self.reconnect()
- #end
- @queue.enq(rcp + @separator + msg)
- return nil
- end
-
- # Sends a message to a room.
- #
- # @param [String] room The name of the room.
- # @param [String] mgs The message to send.
- # @return [NULL] nada
- def send_to_muc (room, msg)
- if not @jid_created_chat.has_key?(room)
- @jid_created_chat[room] = MultiUserChat.new(@xmpp, room)
- @jid_created_chat[room].join(@name)
- end
- @logger.debug("Sending to MUC '#{room}' message '#{msg}'.")
- @jid_created_chat[room].sendMessage(msg)
- return nil
- end
-
- # Sends a message to a jid.
- #
- # Do not destroy the chat, we can reuse it when the user log back in again.
- # Maybe?
- #
- # @param [String] jid The JID of the recipient.
- # @param [String] mgs The message to send.
- # @return [NULL] nada
- def send_to_jid (jid, msg)
- if true == jid_is_available?(jid)
- if not @jid_created_chat.has_key?(jid)
- @jid_created_chat[jid] = @xmpp.getChatManager.createChat(jid, nil)
- end
- @logger.debug("Sending to JID '#{jid}' message '#{msg}'.")
- @jid_created_chat[jid].sendMessage(msg)
- end
- return nil
- end
-
- # Check to see if the jid is available or not.
- #
- # @param [String] jid The JID of the recipient.
- # @return [Boolean] Whether we can send a message or not.
- def jid_is_available?(jid)
- if true == @xmpp.getRoster().getPresence(jid).isAvailable()
- @logger.debug("#{jid} is available. Status is " +
- "#{@xmpp.getRoster().getPresence(jid).getStatus()}")
- return true
- else
- @logger.warn("#{jid} is not available. Status is " +
- "#{@xmpp.getRoster().getPresence(jid).getStatus()}")
- return false
- end
- end
-
- # Opens a connection to the xmpp server at given port.
- #
- # @return [NULL] nada
- def open()
- @logger.info("XMPP bot is being created.")
- self.open_connection()
- self.open_authentication()
- self.create_roster()
- sleep 5
- return nil
- end
-
- # Connect to server.
- #
- # @return [NULL] nada
- def open_connection()
- @xmpp = XMPPConnection.new(@srv)
- if false == self.connect()
- str = "Connection refused"
- @logger.error(str)
- raise XMPPSmackException.new(str)
- end
- @logger.debug("XMPP bot connected successfully.")
- return nil
- end
-
- # Authenticat connection.
- #
- # @return [NULL] nada
- def open_authentication()
- if false == self.login(@jid, @pwd)
- str = "Authentication failed"
- @logger.error(str)
- raise XMPPSmackException.new(str)
- end
- @logger.debug("XMPP bot authenticated successfully.")
- return nil
- end
-
- # Create a new roster and listener.
- #
- # @return [NULL] nada
- def create_roster
- @xmpp.getRoster().addRosterListener(RosterListener.new())
- @xmpp.getRoster().reload()
- @xmpp.getRoster().getPresence(@xmpp.getUser).setStatus(
- "Purple alert! Purple alert!")
- @logger.debug("XMPP bot roster aquired successfully.")
- return nil
- end
-
- # Connects to the server.
- #
- # @return [Boolean] true (aka sucess) or false (aka failure).
- def connect ()
- @xmpp.connect()
- return @xmpp.isConnected()
- end
-
- # Login onto the server.
- #
- # @param [String] jid The JID.
- # @param [String] pwd The password corresponding to the JID.
- # @return [Boolean] true (aka sucess) or false (aka failure).
- def login (jid, pwd)
- @xmpp.login(jid, pwd, @name)
- return @xmpp.isAuthenticated()
- end
-
- # Reconnects in case of errors.
- #
- # @return [NULL] nada
- def reconnect()
- @xmpp.disconnect
- @slave_thread = Thread.new do
- self.create_slave_thread()
- end
- return nil
- end
-
- def presenceChanged ()
- end
-
- end # XMPPSmack
-
-
- ## This is the class that gets called in person.rb.
- #
- # This class is a wrapper to XMPPSmack which does the hard work. It is
- # done this way to conform to the mauve configuration file way of
- # defining notifications.
- #
- # @author Yann Golanski
- class Default
-
- # Name of the class.
- attr_reader :name
-
- # Atrtribute.
- attr_accessor :jid
-
- # Atrtribute.
- attr_accessor :password
-
- # Atrtribute.
- attr_accessor :initial_jid
-
- # Atrtribute.
- attr_accessor :initial_messages
-
- # Default constructor.
- #
- # @param [String] name The name of the notifier.
- def initialize (name)
- extend(MonitorMixin)
- @name = name
- @logger = Log4r::Logger.new "mauve::XMPP_default<#{Process.pid}>"
- end
-
- # Sends a message to the relevant jid or muc.
- #
- # We have no way to know if a messages was recieved, only that
- # we send it.
- #
- # @param [String] destionation
- # @param [Alert] alert A mauve alert class
- # @param [Array] all_alerts subset of current alerts
- # @param [Hash] conditions Supported conditions, see above.
- # @return [Boolean] Whether a message can be send or not.
- def send_alert(destination, alert, all_alerts, conditions = nil)
- synchronize {
- client = XMPPSmack.instance(@jid, @password)
- if not destination.match(/^muc:/)
- if false == client.jid_is_available?(destination.gsub(/^muc:/, ''))
- return false
- end
- end
- client.send_msg(destination, convert_alert_to_message(alert))
- return true
- }
- end
-
- # Takes an alert and converts it into a message.
- #
- # @param [Alert] alert The alert to convert.
- # @return [String] The message, either as HTML.
- def convert_alert_to_message(alert)
- arr = alert.summary_three_lines
- str = arr[0] + ": " + arr[1]
- str += " -- " + arr[2] if false == arr[2].nil?
- str += "."
- return str
- #return alert.summary_two_lines.join(" -- ")
- #return "<p>" + alert.summary_two_lines.join("<br />") + "</p>"
- end
-
- # This is so unit tests can run fine.
- include Debug
-
- end # Default
-
- end
- end
-end
-
-# This is a simple example of usage. Run with:
-# ../../../jmauve_starter.rb xmpp-smack.rb
-# Clearly, the mauve jabber password is not correct.
-#
-# /!\ WARNING: DO NOT COMMIT THE REAL PASSWORD TO MERCURIAL!!!
-#
-def send_msg()
- bot = Mauve::Notifiers::Xmpp::XMPPSmack.instance(
- "mauvealert@chat.bytemark.co.uk/testing1234", '')
- msg = "What fresh hell is this? -- Dorothy Parker."
- bot.send_msg("yann@chat.bytemark.co.uk", msg)
- bot.send_msg("muc:test@conference.chat.bytemark.co.uk", msg)
- sleep 2
-end
-
-if __FILE__ == './'+$0
- Thread.abort_on_exception = true
- logger = Log4r::Logger.new('mauve')
- logger.level = Log4r::DEBUG
- logger.add Log4r::Outputter.stdout
- send_msg()
- send_msg()
- logger.info("START")
- logger.info("END")
-end
diff --git a/lib/mauve/notifiers/xmpp.rb b/lib/mauve/notifiers/xmpp.rb
index c4e1785..8131096 100644
--- a/lib/mauve/notifiers/xmpp.rb
+++ b/lib/mauve/notifiers/xmpp.rb
@@ -66,10 +66,10 @@ module Mauve
include Jabber
# Atrtribute.
- attr_reader :name
+ attr_reader :name, :jid
# Atrtribute.
- attr_accessor :jid, :password
+ attr_accessor :password
def initialize(name)
Jabber::logger = self.logger
@@ -80,7 +80,7 @@ module Mauve
@mucs = {}
@roster = nil
@closing = false
-
+ @client = nil
end
def logger
@@ -93,7 +93,7 @@ module Mauve
end
def connect
- logger.info "Jabber starting connection to #{@jid}"
+ logger.debug "Starting connection to #{@jid}"
# Make sure we're disconnected.
self.close if @client.is_a?(Client)
@@ -110,7 +110,6 @@ module Mauve
# already
@roster.add_subscription_request_callback do |ri, presence|
Thread.new do
- logger.debug "Known? #{is_known_contact?(presence.from).inspect}"
if is_known_contact?(presence.from)
logger.info("Accepting subscription request from #{presence.from}")
@roster.accept_subscription(presence.from)
@@ -127,10 +126,11 @@ module Mauve
end
@roster.wait_for_roster
- logger.debug "Jabber authenticated, setting presence"
@client.send(Presence.new(nil, "Woo!").set_type(nil))
+ logger.info "Connected as #{@jid}"
+
@client.on_exception do |ex, stream, where|
#
# The XMPP4R exception clauses in Stream all close the stream, so
@@ -203,17 +203,7 @@ module Mauve
alert.to_s
end
- history = Mauve::History.new(:alert_id => alert.id, :type => :notification)
-
- if send_message(destination_jid, txt)
- history.event = "Sent XMPP message to #{destination_jid}"
- history.save
- true
- else
- history.event = "Failed to send XMPP message to #{destination_jid}"
- history.save
- false
- end
+ send_message(destination_jid, txt)
end
# Sends a message to the destionation.
@@ -297,12 +287,12 @@ module Mauve
end
if !@mucs[jid.strip].active?
- logger.info("Joining #{jid}")
#
# Make sure we have a resource.
#
@mucs[jid.strip].join(jid, password)
+ logger.info("Joined #{jid}")
else
logger.debug("Already joined #{jid}.")
end