comparison src/plugins/plugin_misc_text_commands.py @ 1955:633b5c21aefd

backend, frontend: messages refactoring (huge commit, not finished): /!\ database schema has been modified, do a backup before updating message have been refactored, here are the main changes: - languages are now handled - all messages have an uid (internal to SàT) - message updating is anticipated - subject is now first class - new naming scheme is used newMessage => messageNew, getHistory => historyGet, sendMessage => messageSend - minimal compatibility refactoring in quick_frontend/Primitivus, better refactoring should follow - threads handling - delayed messages are saved into history - info messages may also be saved in history (e.g. to keep track of people joining/leaving a room) - duplicate messages should be avoided - historyGet return messages in right order, no need to sort again - plugins have been updated to follow new features, some of them need to be reworked (e.g. OTR) - XEP-0203 (Delayed Delivery) is now fully handled in core, the plugin just handle disco and creation of a delay element - /!\ jp and Libervia are currently broken, as some features of Primitivus It has been put in one huge commit to avoid breaking messaging between changes. This is the main part of message refactoring, other commits will follow to take profit of the new features/behaviour.
author Goffi <goffi@goffi.org>
date Tue, 24 May 2016 22:11:04 +0200
parents 2daf7b4c6756
children a2bc5089c2eb
comparison
equal deleted inserted replaced
1943:ccfe45302a5c 1955:633b5c21aefd
56 HELP_SUGGESTION = _("Type '/help' to get a list of the available commands. If you didn't want to use a command, please start your message with '//' to escape the slash.") 56 HELP_SUGGESTION = _("Type '/help' to get a list of the available commands. If you didn't want to use a command, please start your message with '//' to escape the slash.")
57 57
58 def __init__(self, host): 58 def __init__(self, host):
59 log.info(_("Text commands initialization")) 59 log.info(_("Text commands initialization"))
60 self.host = host 60 self.host = host
61 host.trigger.add("sendMessage", self.sendMessageTrigger) 61 host.trigger.add("messageSend", self.messageSendTrigger)
62 self._commands = {} 62 self._commands = {}
63 self._whois = [] 63 self._whois = []
64 self.registerTextCommands(self) 64 self.registerTextCommands(self)
65 65
66 def _parseDocString(self, cmd, cmd_name): 66 def _parseDocString(self, cmd, cmd_name):
164 @param priority: priority of the information to show (the highest priority will be displayed first) 164 @param priority: priority of the information to show (the highest priority will be displayed first)
165 """ 165 """
166 self._whois.append((priority, callback)) 166 self._whois.append((priority, callback))
167 self._whois.sort(key=lambda item: item[0], reverse=True) 167 self._whois.sort(key=lambda item: item[0], reverse=True)
168 168
169 def sendMessageTrigger(self, mess_data, pre_xml_treatments, post_xml_treatments, profile): 169 def messageSendTrigger(self, client, mess_data, pre_xml_treatments, post_xml_treatments):
170 """ Install SendMessage command hook """ 170 """Install SendMessage command hook """
171 pre_xml_treatments.addCallback(self._sendMessageCmdHook, profile) 171 pre_xml_treatments.addCallback(self._messageSendCmdHook, client)
172 return True 172 return True
173 173
174 def _sendMessageCmdHook(self, mess_data, profile): 174 def _messageSendCmdHook(self, mess_data, client):
175 """ Check text commands in message, and react consequently 175 """ Check text commands in message, and react consequently
176 176
177 msg starting with / are potential command. If a command is found, it is executed, else and help message is sent 177 msg starting with / are potential command. If a command is found, it is executed, else and help message is sent
178 msg starting with // are escaped: they are sent with a single / 178 msg starting with // are escaped: they are sent with a single /
179 commands can abord message sending (if they return anything evaluating to False), or continue it (if they return True), eventually after modifying the message 179 commands can abord message sending (if they return anything evaluating to False), or continue it (if they return True), eventually after modifying the message
180 an "unparsed" key is added to message, containing part of the message not yet parsed 180 an "unparsed" key is added to message, containing part of the message not yet parsed
181 commands can be deferred or not 181 commands can be deferred or not
182 @param mess_data(dict): data comming from sendMessage trigger 182 @param mess_data(dict): data comming from messageSend trigger
183 @param profile: %(doc_profile)s 183 @param profile: %(doc_profile)s
184 """ 184 """
185 msg = mess_data["message"] 185 profile = client.profile
186 try:
187 msg = mess_data["message"]['']
188 msg_lang = ''
189 except KeyError:
190 try:
191 # we have not default message, we try to take the first found
192 msg_lang, msg = mess_data["message"].iteritems().next()
193 except StopIteration:
194 log.debug(u"No message found, skipping text commands")
195 return mess_data
196
186 try: 197 try:
187 if msg[:2] == '//': 198 if msg[:2] == '//':
188 # we have a double '/', it's the escape sequence 199 # we have a double '/', it's the escape sequence
189 mess_data["message"] = msg[1:] 200 mess_data["message"][msg_lang] = msg[1:]
190 return mess_data 201 return mess_data
191 if msg[0] != '/': 202 if msg[0] != '/':
192 return mess_data 203 return mess_data
193 except IndexError: 204 except IndexError:
194 return mess_data 205 return mess_data
240 return d or mess_data # if a command is detected, we should have a deferred, else we send the message normally 251 return d or mess_data # if a command is detected, we should have a deferred, else we send the message normally
241 252
242 def _contextValid(self, mess_data, cmd_data): 253 def _contextValid(self, mess_data, cmd_data):
243 """Tell if a command can be used in the given context 254 """Tell if a command can be used in the given context
244 255
245 @param mess_data(dict): message data as given in sendMessage trigger 256 @param mess_data(dict): message data as given in messageSend trigger
246 @param cmd_data(dict): command data as returned by self._parseDocString 257 @param cmd_data(dict): command data as returned by self._parseDocString
247 @return (bool): True if command can be used in this context 258 @return (bool): True if command can be used in this context
248 """ 259 """
249 if ((cmd_data['type'] == "group" and mess_data["type"] != "groupchat") or 260 if ((cmd_data['type'] == "group" and mess_data["type"] != "groupchat") or
250 (cmd_data['type'] == 'one2one' and mess_data["type"] == "groupchat")): 261 (cmd_data['type'] == 'one2one' and mess_data["type"] == "groupchat")):
270 if mess_data["type"] == 'groupchat': 281 if mess_data["type"] == 'groupchat':
271 _from = mess_data["to"].userhostJID() 282 _from = mess_data["to"].userhostJID()
272 else: 283 else:
273 _from = self.host.getJidNStream(profile)[0] 284 _from = self.host.getJidNStream(profile)[0]
274 285
275 self.host.bridge.newMessage(unicode(mess_data["to"]), message, C.MESS_TYPE_INFO, unicode(_from), {}, profile=profile) 286 self.host.bridge.messageNew(unicode(mess_data["to"]), {'': message}, {}, C.MESS_TYPE_INFO, unicode(_from), {}, profile=profile)
276 287
277 def cmd_whois(self, mess_data, profile): 288 def cmd_whois(self, mess_data, profile):
278 """show informations on entity 289 """show informations on entity
279 290
280 @command: [JID|ROOM_NICK] 291 @command: [JID|ROOM_NICK]