diff options
author | Patrick J Cherry <patrick@bytemark.co.uk> | 2011-07-13 16:02:50 +0100 |
---|---|---|
committer | Patrick J Cherry <patrick@bytemark.co.uk> | 2011-07-13 16:02:50 +0100 |
commit | e140af144e987ff7f6d767f2dc48b9cf685803fd (patch) | |
tree | 4a01971890865b4b3ca837d563bc673cbb787de8 /lib/mauve/notifiers/xmpp-smack.rb | |
parent | d28af4ec946c6aa4b645b73cef47d7e0c680bc0d (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/xmpp-smack.rb')
-rw-r--r-- | lib/mauve/notifiers/xmpp-smack.rb | 395 |
1 files changed, 0 insertions, 395 deletions
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 |