lib/robut/connection.rb in robut-0.2.1 vs lib/robut/connection.rb in robut-0.3.0

- old
+ new

@@ -1,14 +1,19 @@ require 'xmpp4r' require 'xmpp4r/muc/helper/simplemucclient' require 'xmpp4r/roster/helper/roster' require 'ostruct' +if defined?(Encoding) + # Monkey-patch an incompatibility between ejabberd and rexml + require 'rexml_patches' +end + # Handles opening a connection to the HipChat server, and feeds all # messages through our Robut::Plugin list. class Robut::Connection - + # The configuration used by the Robut connection. # # Parameters: # # [+jid+, +password+, +nick+] The HipChat credentials given on @@ -51,45 +56,49 @@ # Sets the instance config to +config+, converting it into an # OpenStruct if necessary. def config=(config) @config = config.kind_of?(Hash) ? OpenStruct.new(config) : config end - + # Initializes the connection. If no +config+ is passed, it defaults # to the class_level +config+ instance variable. def initialize(_config = nil) self.config = _config || self.class.config - + self.client = Jabber::Client.new(self.config.jid) self.muc = Jabber::MUC::SimpleMUCClient.new(client) self.store = self.config.store || Robut::Storage::HashStore # default to in-memory store only if self.config.logger Jabber.logger = self.config.logger Jabber.debug = true end end - + # Send +message+ to the room we're currently connected to, or # directly to the person referenced by +to+. +to+ can be either a # jid or the string name of the person. def reply(message, to = nil) if to unless to.kind_of?(Jabber::JID) to = find_jid_by_name(to) end - + msg = Jabber::Message.new(to || muc.room, message) msg.type = :chat client.send(msg) else muc.send(Jabber::Message.new(muc.room, message)) end end - # Sends the chat message +message+ through +plugins+. + # Sends the chat message +message+ through +plugins+. def handle_message(plugins, time, nick, message) + # ignore all messages sent by robut. If you really want robut to + # reply to itself, you can use +fake_message+. + return if nick == config.nick + plugins.each do |plugin| begin rsp = plugin.handle(time, nick, message) break if rsp == true rescue => e @@ -120,41 +129,41 @@ end # Add the callback from direct messages. Turns out the # on_private_message callback doesn't do what it sounds like, so I # have to go a little deeper into xmpp4r to get this working. - client.add_message_callback(200, self) { |message| + client.add_message_callback(200, self) do |message| if !muc.from_room?(message.from) && message.type == :chat && message.body time = Time.now # TODO: get real timestamp? Doesn't seem like # jabber gives it to us sender_jid = message.from plugins = Robut::Plugin.plugins.map { |p| p.new(self, sender_jid) } handle_message(plugins, time, self.roster[sender_jid].iname, message.body) true else false end - } - + end + muc.join(config.room + '/' + config.nick) trap_signals loop { sleep 1 } end private - + # Since we're entering an infinite loop, we have to trap TERM and # INT. If something like the Rdio plugin has started a server that # has already trapped those signals, we want to run those signal # handlers first. def trap_signals old_signal_callbacks = {} signal_callback = Proc.new do |signal| old_signal_callbacks[signal].call if old_signal_callbacks[signal] exit end - + [:INT, :TERM].each do |sig| old_signal_callbacks[sig] = trap(sig) { signal_callback.call(sig) } end end