backend, frontends: message refactoring (huge commit):
/!\ several features are temporarily disabled, like notifications in frontends
next step in refactoring, with the following changes:
- jp: updated jp message to follow changes in backend/bridge
- jp: added --lang, --subject, --subject_lang, and --type options to jp message + fixed unicode handling for jid
- quick_frontend (QuickApp, QuickChat):
- follow backend changes
- refactored chat, message are now handled in OrderedDict and uid are kept so they can be updated
- Message and Occupant classes handle metadata, so frontend just have to display them
- Primitivus (Chat):
- follow backend/QuickFrontend changes
- info & standard messages are handled in the same MessageWidget class
- improved/simplified handling of messages, removed update() method
- user joined/left messages are merged when next to each other
- a separator is shown when message is received while widget is out of focus, so user can quickly see the new messages
- affiliation/role are shown (in a basic way for now) in occupants panel
- removed "/me" messages handling, as it will be done by a backend plugin
- message language is displayed when available (only one language per message for now)
- fixed :history and :search commands
- core (constants): new constants for messages type, XML namespace, entity type
- core: *Message methods renamed to follow new code sytle (e.g. sendMessageToBridge => messageSendToBridge)
- core (messages handling): fixed handling of language
- core (messages handling): mes_data['from'] and ['to'] are now jid.JID
- core (core.xmpp): reorganised message methods, added getNick() method to client.roster
- plugin text commands: fixed plugin and adapted to new messages behaviour. client is now used in arguments instead of profile
- plugins: added information for cancellation reason in CancelError calls
- plugin XEP-0045: various improvments, but this plugin still need work:
- trigger is used to avoid message already handled by the plugin to be handled a second time
- changed the way to handle history, the last message from DB is checked and we request only messages since this one, in seconds (thanks Poezio folks :))
- subject reception is waited before sending the roomJoined signal, this way we are sure that everything including history is ready
- cmd_* method now follow the new convention with client instead of profile
- roomUserJoined and roomUserLeft messages are removed, the events are now handled with info message with a "ROOM_USER_JOINED" info subtype
- probably other forgotten stuffs :p
This commit is contained in:
parent
feadc8c89e
commit
a7de473107
1 changed files with 987 additions and 598 deletions
|
|
@ -46,6 +46,7 @@ class InvalidCommandSyntax(Exception):
|
|||
|
||||
CMD_KEY = "@command"
|
||||
CMD_TYPES = ('group', 'one2one', 'all')
|
||||
FEEDBACK_INFO_TYPE = "TEXT_CMD"
|
||||
|
||||
|
||||
class TextCommands(object):
|
||||
|
|
@ -148,7 +149,7 @@ class TextCommands(object):
|
|||
while (cmd_name + str(suff)) in self._commands:
|
||||
suff+=1
|
||||
new_name = cmd_name + str(suff)
|
||||
log.warning(_(u"Conflict for command [%(old_name)s], renaming it to [%(new_name)s]") % {'old_name': cmd_name, 'new_name': new_name})
|
||||
log.warning(_(u"Conflict for command [{old_name}], renaming it to [{new_name}]").format(old_name=cmd_name, new_name=new_name))
|
||||
cmd_name = new_name
|
||||
self._commands[cmd_name] = cmd_data = OrderedDict({'callback':cmd}) # We use an Ordered dict to keep documenation order
|
||||
cmd_data.update(self._parseDocString(cmd, cmd_name))
|
||||
|
|
@ -182,7 +183,6 @@ class TextCommands(object):
|
|||
@param mess_data(dict): data comming from messageSend trigger
|
||||
@param profile: %(doc_profile)s
|
||||
"""
|
||||
profile = client.profile
|
||||
try:
|
||||
msg = mess_data["message"]['']
|
||||
msg_lang = ''
|
||||
|
|
@ -217,7 +217,7 @@ class TextCommands(object):
|
|||
if ret:
|
||||
return mess_data
|
||||
else:
|
||||
log.debug("text commands took over")
|
||||
log.debug(u"text command detected ({})".format(command))
|
||||
raise failure.Failure(exceptions.CancelError())
|
||||
|
||||
def genericErrback(failure):
|
||||
|
|
@ -225,26 +225,26 @@ class TextCommands(object):
|
|||
msg = u"with condition {}".format(failure.value.condition)
|
||||
except AttributeError:
|
||||
msg = u"with error {}".format(failure.value)
|
||||
self.feedBack(u"Command failed {}".format(msg), mess_data, profile)
|
||||
self.feedBack(client, u"Command failed {}".format(msg), mess_data)
|
||||
return False
|
||||
|
||||
mess_data["unparsed"] = msg[1 + len(command):] # part not yet parsed of the message
|
||||
try:
|
||||
cmd_data = self._commands[command]
|
||||
except KeyError:
|
||||
self.feedBack(_("Unknown command /%s. ") % command + self.HELP_SUGGESTION, mess_data, profile)
|
||||
log.debug("text commands took over")
|
||||
self.feedBack(client, _("Unknown command /%s. ") % command + self.HELP_SUGGESTION, mess_data)
|
||||
log.debug("text command help message")
|
||||
raise failure.Failure(exceptions.CancelError())
|
||||
else:
|
||||
if not self._contextValid(mess_data, cmd_data):
|
||||
# The command is not launched in the right context, we throw a message with help instructions
|
||||
context_txt = _("group discussions") if cmd_data["type"] == "group" else _("one to one discussions")
|
||||
feedback = _("/{command} command only applies in {context}.").format(command=command, context=context_txt)
|
||||
self.feedBack(u"{} {}".format(feedback, self.HELP_SUGGESTION), mess_data, profile)
|
||||
log.debug("text commands took over")
|
||||
self.feedBack(client, u"{} {}".format(feedback, self.HELP_SUGGESTION), mess_data)
|
||||
log.debug("text command invalid message")
|
||||
raise failure.Failure(exceptions.CancelError())
|
||||
else:
|
||||
d = defer.maybeDeferred(cmd_data["callback"], mess_data, profile)
|
||||
d = defer.maybeDeferred(cmd_data["callback"], client, mess_data)
|
||||
d.addErrback(genericErrback)
|
||||
d.addCallback(retHandling)
|
||||
|
||||
|
|
@ -276,16 +276,22 @@ class TextCommands(object):
|
|||
return jid.JID(arg + service_jid)
|
||||
return jid.JID(u"%s@%s" % (arg, service_jid))
|
||||
|
||||
def feedBack(self, message, mess_data, profile):
|
||||
def feedBack(self, client, message, mess_data, info_type=FEEDBACK_INFO_TYPE):
|
||||
"""Give a message back to the user"""
|
||||
if mess_data["type"] == 'groupchat':
|
||||
_from = mess_data["to"].userhostJID()
|
||||
to_ = mess_data["to"].userhostJID()
|
||||
else:
|
||||
_from = self.host.getJidNStream(profile)[0]
|
||||
to_ = client.jid
|
||||
|
||||
self.host.bridge.messageNew(unicode(mess_data["to"]), {'': message}, {}, C.MESS_TYPE_INFO, unicode(_from), {}, profile=profile)
|
||||
# we need to invert send message back, so sender need to original destinee
|
||||
mess_data["from"] = mess_data["to"]
|
||||
mess_data["to"] = to_
|
||||
mess_data["type"] = C.MESS_TYPE_INFO
|
||||
mess_data["message"] = {'': message}
|
||||
mess_data["extra"]["info_type"] = info_type
|
||||
self.host.messageSendToBridge(mess_data, client)
|
||||
|
||||
def cmd_whois(self, mess_data, profile):
|
||||
def cmd_whois(self, client, mess_data):
|
||||
"""show informations on entity
|
||||
|
||||
@command: [JID|ROOM_NICK]
|
||||
|
|
@ -299,7 +305,7 @@ class TextCommands(object):
|
|||
if mess_data['type'] == "groupchat":
|
||||
room = mess_data["to"].userhostJID()
|
||||
try:
|
||||
if self.host.plugins["XEP-0045"].isNickInRoom(room, entity, profile):
|
||||
if self.host.plugins["XEP-0045"].isNickInRoom(room, entity, client.profile):
|
||||
entity = u"%s/%s" % (room, entity)
|
||||
except KeyError:
|
||||
log.warning("plugin XEP-0045 is not present")
|
||||
|
|
@ -312,20 +318,20 @@ class TextCommands(object):
|
|||
if not target_jid.user or not target_jid.host:
|
||||
raise jid.InvalidFormat
|
||||
except (RuntimeError, jid.InvalidFormat, AttributeError):
|
||||
self.feedBack(_("Invalid jid, can't whois"), mess_data, profile)
|
||||
self.feedBack(client, _("Invalid jid, can't whois"), mess_data)
|
||||
return False
|
||||
|
||||
if not target_jid.resource:
|
||||
target_jid.resource = self.host.memory.getMainResource(target_jid, profile)
|
||||
target_jid.resource = self.host.memory.getMainResource(target_jid, client.profile)
|
||||
|
||||
whois_msg = [_(u"whois for %(jid)s") % {'jid': target_jid}]
|
||||
|
||||
d = defer.succeed(None)
|
||||
for ignore, callback in self._whois:
|
||||
d.addCallback(lambda ignore: callback(whois_msg, mess_data, target_jid, profile))
|
||||
d.addCallback(lambda ignore: callback(client, whois_msg, mess_data, target_jid))
|
||||
|
||||
def feedBack(ignore):
|
||||
self.feedBack(u"\n".join(whois_msg), mess_data, profile)
|
||||
self.feedBack(client, u"\n".join(whois_msg), mess_data)
|
||||
return False
|
||||
|
||||
d.addCallback(feedBack)
|
||||
|
|
@ -345,7 +351,7 @@ class TextCommands(object):
|
|||
|
||||
return strings
|
||||
|
||||
def cmd_help(self, mess_data, profile):
|
||||
def cmd_help(self, client, mess_data):
|
||||
"""show help on available commands
|
||||
|
||||
@command: [cmd_name]
|
||||
|
|
@ -355,7 +361,7 @@ class TextCommands(object):
|
|||
if cmd_name and cmd_name[0] == "/":
|
||||
cmd_name = cmd_name[1:]
|
||||
if cmd_name and cmd_name not in self._commands:
|
||||
self.feedBack(_(u"Invalid command name [{}]\n".format(cmd_name)), mess_data, profile)
|
||||
self.feedBack(client, _(u"Invalid command name [{}]\n".format(cmd_name)), mess_data)
|
||||
cmd_name = ""
|
||||
if not cmd_name:
|
||||
# we show the global help
|
||||
|
|
@ -384,13 +390,4 @@ class TextCommands(object):
|
|||
syntax=_(" "*4+"syntax: {}\n").format(syntax) if syntax else "",
|
||||
args_help=u'\n'.join([u" "*8+"{}".format(line) for line in self._getArgsHelp(cmd_data)]))
|
||||
|
||||
self.feedBack(help_mess, mess_data, profile)
|
||||
|
||||
def cmd_me(self, mess_data, profile):
|
||||
"""Display a message at third person
|
||||
|
||||
@command: message
|
||||
- message: message to display at the third person
|
||||
"""
|
||||
# We just catch the method and continue it as the frontends should manage /me display
|
||||
return True
|
||||
self.feedBack(client, help_mess, mess_data)
|
||||
|
|
|
|||
Loading…
Reference in a new issue