From c42c7531be1c512846ab8795f331e676ab53f003 Mon Sep 17 00:00:00 2001 From: kaliko Date: Mon, 24 Nov 2014 21:35:37 +0100 Subject: [PATCH] Now handles private msg in MUC --- sid/echo.py | 20 ++++++++++++++------ sid/feeds.py | 10 ++++++---- sid/ping.py | 4 ++-- sid/plugin.py | 24 ++++++++++++++++++------ sid/sid.py | 30 +++++++++++++++++++++++------- 5 files changed, 63 insertions(+), 25 deletions(-) diff --git a/sid/echo.py b/sid/echo.py index cbf2eab..f0e05b8 100644 --- a/sid/echo.py +++ b/sid/echo.py @@ -37,7 +37,9 @@ class Echo(Plugin): self.log.debug(self.presence) if pres['type'] == 'available': while self.inbox.get(nick, []): - self.send(self.inbox.get(nick).pop()) + self.send(self.bot.room, + self.inbox.get(nick).pop(), + mtype='groupchat') self.inbox.pop(nick) @botcmd @@ -46,12 +48,14 @@ class Echo(Plugin): !tell queue : messages in queue !tell : append to in queue""" if not len(args): - self.send('Missing arguments:\n{}'.format(self.tell.__doc__)) + msg = 'Missing arguments:\n{}'.format(self.tell.__doc__) + self.reply(message, msg) return if len(args) == 1: if args[0] == 'queue': - self.send('\n'.join(['{0}:\n\t{1}'.format(k, '\n'.join(v)) - for k, v in self.inbox.items()])) + msg = '\n'.join(['{0}:\n\t{1}'.format(k, '\n'.join(v)) + for k, v in self.inbox.items()]) + self.reply(message, msg) return if args[0] == 'purge': sender = message['from'].resource @@ -59,13 +63,17 @@ class Echo(Plugin): self.online = set() return if len(args) < 2: - self.send('Please provide a message:\n{}'.format(self.tell.__doc__)) + msg = 'Please provide a message:\n{}'.format(self.tell.__doc__) + self.reply(message, msg) return + self._handle_msg(message) + + def _handle_msg(self, message): sender = message['from'].resource recipient = message['body'].split()[1] tell_msg = ' '.join(message['body'].split()[2:]) self.log.debug('{0}: {1}'.format(recipient, tell_msg)) - letter = '{0}, {1} told me to tell you: {2}'.format(recipient, sender, tell_msg) + letter = '{0}, {1} wanted you to know: {2}'.format(recipient, sender, tell_msg) if (self.presence.get(recipient) and self.presence[recipient][1] == 'available'): return diff --git a/sid/feeds.py b/sid/feeds.py index dd3c781..59cf084 100644 --- a/sid/feeds.py +++ b/sid/feeds.py @@ -106,7 +106,9 @@ class FeedMonitor(threading.Thread): # Updating self.seen self.seen[feed_id] = entries if len(text) > 1: - self.plugin.send({'mhtml':'
'.join(xhtml), 'mbody':'\n'.join(text)}) + self.plugin.send(self.plugin.bot.room, + {'mhtml':'
'.join(xhtml), 'mbody':'\n'.join(text)}, + mtype='groupchat') def run(self): while not self.thread_killed: @@ -154,12 +156,12 @@ class Feeds(Plugin): self.th_mon.thread_killed = True @botcmd - def feeds(self, message, args): + def feeds(self, rcv, args): """feeds monitors debian project related feeds. !feeds : registred feeds list !feeds last : last check time""" if 'last' in args: - self.send('Last feeds check: %s' % self.th_mon.last_check) + self.reply(rcv, 'Last feeds check: %s' % self.th_mon.last_check) return html = ['{1}'.format(html_escape(u), html_escape(u[7:]) @@ -168,4 +170,4 @@ class Feeds(Plugin): 'mbody': 'Feeds:\n' + '\n'.join(Feeds.FEEDS), 'mhtml': 'Feeds:
' + '
'.join(html), } - self.send(msg) + self.reply(rcv, msg) diff --git a/sid/ping.py b/sid/ping.py index 827ddb6..96d92c7 100644 --- a/sid/ping.py +++ b/sid/ping.py @@ -23,7 +23,7 @@ class Ping(Plugin): Plugin.__init__(self, bot) @botcmd - def ping(self, message, args): + def ping(self, rcv, args): """ping's answering a pong showing the bot is alive. !ping : You'll get back "pong"! """ @@ -31,7 +31,7 @@ class Ping(Plugin): 'mhtml':'!pong'.format(self), 'mbody':'!pong', } - self.send(msg) + self.reply(rcv, msg) # VIM MODLINE # vim: ai ts=4 sw=4 sts=4 expandtab diff --git a/sid/plugin.py b/sid/plugin.py index 2b49bc9..447e703 100644 --- a/sid/plugin.py +++ b/sid/plugin.py @@ -17,15 +17,18 @@ from .sid import botcmd -class Plugin(object): +class Plugin: + """Simple Plugin object to derive from: + Exposes the bot object and its logger + Provides some send helpers + """ def __init__(self, bot): self.bot = bot self.log = bot.log - def send(self, msg): - """ - Send msg to the current groupchat defined in self.bot.room + def send(self, dest, msg, mtype='chat'): + """Send msg to dest msg = { mbody: 'text', mhtml: 'text, # optional' @@ -34,9 +37,18 @@ class Plugin(object): if isinstance(msg, str): msg = {'mbody':msg} msg.setdefault('mhtml', None) - self.bot.send_message(mto=self.bot.room, - mtype='groupchat', + self.bot.send_message(mto=dest, + mtype=mtype, **msg) + def reply(self, rcv, msg): + """Smart reply to message received. + Replies in private or on the muc depending on + """ + to = rcv['from'] + if rcv['type'] == 'groupchat': + to = rcv['mucroom'] + self.send(to, msg, mtype=rcv['type']) + def shutdown(self): pass diff --git a/sid/sid.py b/sid/sid.py index 1d3383c..1f8cd07 100644 --- a/sid/sid.py +++ b/sid/sid.py @@ -55,6 +55,7 @@ class MUCBot(sleekxmpp.ClientXMPP): self.room = room self.nick = nick self.__set_logger(log_file, log_level) + self.__seen = dict() self.register_plugin('xep_0030') # Service Discovery self.register_plugin('xep_0045') # Multi-User Chat self.register_plugin('xep_0199') # self Ping @@ -64,10 +65,11 @@ class MUCBot(sleekxmpp.ClientXMPP): # and the XML streams are ready for use. We want to # listen for this event so that we we can initialize # our roster. - self.add_event_handler("session_start", self.start) + self.add_event_handler('session_start', self.start) # Handles MUC message and dispatch - self.add_event_handler("groupchat_message", self.muc_message) + self.add_event_handler('message', self.message) + self.add_event_handler('got_online', self._view) # Discover bot internal command (ie. help) for name, value in inspect.getmembers(self): @@ -87,14 +89,19 @@ class MUCBot(sleekxmpp.ClientXMPP): self.log.setLevel(log_level) self.log.debug('set logger, log level : %s' % log_level) - def muc_message(self, msg): - # ignore message from self - body = msg['body'].strip() - mucfrom = msg['mucnic'] + def message(self, msg): + if msg['type'] not in ('groupchat', 'chat'): + self.log.warning('Unhandled message') + return if msg['mucnick'] == self.nick: return + body = msg['body'].strip() if not body.startswith(MUCBot.prefix): return + if msg['from'] not in self.__seen: + self.log.warning('Will not handle message ' + 'from unseen jid: %s' % msg['from']) + #return args = body[1:].split() cmd = args.pop(0) if cmd not in self.commands: @@ -110,6 +117,11 @@ class MUCBot(sleekxmpp.ClientXMPP): if self.log.level < 10 and reply: self.send_message(mto=msg['from'].bare, mbody=reply, mtype='groupchat') + def _view(self, pres): + nick = pres['from'] + status = (pres['type'], pres['status']) + self.__seen.update({nick: status}) + def start(self, event): """ Process the session_start event. @@ -180,4 +192,8 @@ class MUCBot(sleekxmpp.ClientXMPP): text = self.commands[args[0]].__doc__.strip() or 'undocumented' else: text = 'That command is not defined.' - self.send_message(mto=message['from'].bare, mbody=text, mtype='groupchat') + if message['type'] == 'groupchat': + to = message['from'].bare + else: + to = message['from'] + self.send_message(mto=to, mbody=text, mtype=message['type']) -- 2.39.2