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
This commit is contained in:
Goffi 2014-03-22 13:47:33 +01:00
commit bd3890a8f0

View file

@ -18,7 +18,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
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"""