From bd3890a8f0c090a2355697aefc8298363aa1e09a Mon Sep 17 00:00:00 2001 From: Goffi Date: Sat, 22 Mar 2014 13:47:33 +0100 Subject: [PATCH] plugin text commands: refactoring: - commands can now return a deferred - if commands return True, message is sent, else it is cancelled - the escape sequence is now '//' instead of '\/' - added software version to /whois command --- src/plugins/plugin_misc_text_commands.py | 96 ++++++++++++++++++------ 1 file changed, 74 insertions(+), 22 deletions(-) diff --git a/src/plugins/plugin_misc_text_commands.py b/src/plugins/plugin_misc_text_commands.py index d7723eb3..e3c578ca 100755 --- a/src/plugins/plugin_misc_text_commands.py +++ b/src/plugins/plugin_misc_text_commands.py @@ -18,7 +18,10 @@ # along with this program. If not, see . from sat.core.i18n import _ +from sat.core.sat_main import MessageSentAndStored from twisted.words.protocols.jabber import jid +from twisted.internet import defer +from twisted.python.failure import Failure from logging import debug, info, warning, error PLUGIN_INFO = { @@ -26,7 +29,7 @@ PLUGIN_INFO = { "import_name": "TEXT-COMMANDS", "type": "Misc", "protocols": [], - "dependencies": ["XEP-0045", "EXP-PARROT"], + "dependencies": ["XEP-0045", "EXP-PARROT", "XEP-0092"], "main": "TextCommands", "handler": "no", "description": _("""IRC like text commands""") @@ -44,26 +47,55 @@ class TextCommands(object): host.trigger.add("sendMessage", self.sendMessageTrigger) def sendMessageTrigger(self, mess_data, treatments, profile): - """ Check text commands in message, and react consequently """ - msg = mess_data["message"] - if msg: - if msg[0] == '/': - command = msg[1:].partition(' ')[0].lower() - if command.isalpha(): - # looks like an actual command, we try to call the corresponding method - try: - mess_data["unparsed"] = msg[1 + len(command):] # part not yet parsed of the message - return getattr(self, "cmd_%s" % command)(mess_data, profile) - except AttributeError: - pass - elif msg[0] == '\\': # we have escape char - try: - if msg[1] in ('/', '\\'): # we have '\/' or '\\', we escape to '/' or '\' - mess_data["message"] = msg[1:] - except IndexError: - pass + """ Install SendMessage command hook """ + treatments.addCallback(self._sendMessageCmdHook, profile) return True + def _sendMessageCmdHook(self, mess_data, profile): + """ Check text commands in message, and react consequently + msg starting with / are potential command. If a command is found, it is executed, else message is sent normally + msg starting with // are escaped: they are sent with a single / + commands can abord message sending (if they return anything evaluating to False), or continue it (if they return True), eventually after modifying the message + an "unparsed" key is added to message, containing part of the message not yet parsed + commands can be deferred or not + + """ + msg = mess_data["message"] + try: + if msg[:2] == '//': + # we have a double '/', it's the escape sequence + mess_data["message"] = msg[1:] + return mess_data + if msg[0] != '/': + return mess_data + except IndexError: + return mess_data + + # we have a command + d = None + command = msg[1:].partition(' ')[0].lower() + if command.isalpha(): + # looks like an actual command, we try to call the corresponding method + def retHandling(ret): + """ Handle command return value: + if ret is True, normally send message (possibly modified by command) + else, abord message sending + + """ + if ret: + return mess_data + else: + return Failure(MessageSentAndStored("text commands took over", mess_data)) + + try: + mess_data["unparsed"] = msg[1 + len(command):] # part not yet parsed of the message + d = defer.maybeDeferred(getattr(self, "cmd_%s" % command), mess_data, profile) + d.addCallback(retHandling) + except AttributeError: + pass + + return d or mess_data # if a command is detected, we should have a deferred, else be send the message normally + def _getRoomJID(self, arg, service_jid): """Return a room jid with a shortcut @param arg: argument: can be a full room jid (e.g.: sat@chat.jabberfr.org) @@ -230,12 +262,32 @@ class TextCommands(object): self._feedBack(_("Invalid jid, can't whois"), mess_data, profile) return False + if not target_jid.resource: + target_jid.resource = self.host.memory.getLastResource(target_jid, profile) + whois_msg = [_(u"whois for %(jid)s") % {'jid': target_jid}] - #TODO: add informations here (client version, vcard, etc) - self._feedBack(u"\n".join(whois_msg), mess_data, profile) + # version + def versionCb(version_data): + name, version, os = version_data + if name: + whois_msg.append(_("Client name: %s") % name) + if version: + whois_msg.append(_("Client version: %s") % version) + if os: + whois_msg.append(_("Operating system: %s") % os) - return False + d = self.host.plugins['XEP-0092'].getVersion(target_jid, profile) + d.addCallback(versionCb) + + #TODO: add informations here (vcard, etc) + + def feedBack(ignore): + self._feedBack(u"\n".join(whois_msg), mess_data, profile) + return False + + d.addCallback(feedBack) + return d def cmd_help(self, mess_data, profile): """show help on available commands"""