diff src/plugins/plugin_xep_0050.py @ 1110:36c1bbb8ca24

plugin XEP-0050: notes are now managed: - a note without payload in a completed command appear in a dialog. If there is a unique note, it's level is used, else info dialog is used with merged notes - if there is a data form payload, notes are added to form's instructions
author Goffi <goffi@goffi.org>
date Wed, 20 Aug 2014 21:22:06 +0200
parents c0ef97002ef4
children 069ad98b360d
line wrap: on
line diff
--- a/src/plugins/plugin_xep_0050.py	Wed Aug 20 21:16:14 2014 +0200
+++ b/src/plugins/plugin_xep_0050.py	Wed Aug 20 21:22:06 2014 +0200
@@ -242,6 +242,33 @@
         form_ui.addList("node", options)
         return form_ui
 
+    def _getDataLvl(self, type_):
+        """Return the constant corresponding to <note/> type attribute value
+
+        @param type_: note type (see XEP-0050 ยง4.3)
+        @return: a C.XMLUI_DATA_LVL_* constant
+        """
+        if type_ == 'error':
+            return C.XMLUI_DATA_LVL_ERROR
+        elif type_ == 'warn':
+            return C.XMLUI_DATA_LVL_WARNING
+        else:
+            if type_ != 'info':
+                log.warning(_("Invalid note type [%s], using info") % type_)
+            return C.XMLUI_DATA_LVL_INFO
+
+    def _mergeNotes(self, notes):
+        """Merge notes with level prefix (e.g. "ERROR: the message")
+
+        @param notes (list): list of tuple (level, message)
+        @return: list of messages
+        """
+        lvl_map = {C.XMLUI_DATA_LVL_INFO: '',
+                   C.XMLUI_DATA_LVL_WARNING: "%s: " % _("WARNING"),
+                   C.XMLUI_DATA_LVL_ERROR: "%s: " % _("ERROR")
+                  }
+        return [u"%s%s" % (lvl_map[lvl], msg) for lvl, msg in notes]
+
     def _commandsAnswer2XMLUI(self, iq_elt, session_id, session_data):
         """
         Convert command answer to an ui for frontend
@@ -262,11 +289,44 @@
         remote_session_id = command_elt.getAttribute('sessionid')
         if remote_session_id:
             session_data['remote_id'] = remote_session_id
-        data_elt = command_elt.elements(data_form.NS_X_DATA, 'x').next()
+        notes = []
+        for note_elt in command_elt.elements(NS_COMMANDS, 'note'):
+            notes.append((self._getDataLvl(note_elt.getAttribute('type', 'info')),
+                          unicode(note_elt)))
+        try:
+            data_elt = command_elt.elements(data_form.NS_X_DATA, 'x').next()
+        except StopIteration:
+            if status != XEP_0050.STATUS.COMPLETED:
+                log.warning(_("No known payload found in ad-hoc command result, aborting"))
+                del self.requesting[session_id]
+                return xml_tools.XMLUI(C.XMLUI_DIALOG,
+                                       dialog_opt = {C.XMLUI_DATA_TYPE: C.XMLUI_DIALOG_NOTE,
+                                                     C.XMLUI_DATA_MESS: _("No payload found"),
+                                                     C.XMLUI_DATA_LVL: C.XMLUI_DATA_LVL_ERROR,
+                                                    }
+                                      )
+            if not notes:
+                # the status is completed, and we have no note to show
+                return None
+
+            # if we have only one note, we show a dialog with the level of the note
+            # if we have more, we show a dialog with "info" level, and all notes merged
+            dlg_level = notes[0][0] if len(notes) == 1 else C.XMLUI_DATA_LVL_INFO
+            return xml_tools.XMLUI(
+                                   C.XMLUI_DIALOG,
+                                   dialog_opt = {C.XMLUI_DATA_TYPE: C.XMLUI_DIALOG_NOTE,
+                                                 C.XMLUI_DATA_MESS: u'\n'.join(self._mergeNotes(notes)),
+                                                 C.XMLUI_DATA_LVL: dlg_level,
+                                                },
+                                   session_id = session_id
+                                  )
+
         if session_id is None:
             return xml_tools.dataFormResult2XMLUI(data_elt)
         form = data_form.Form.fromElement(data_elt)
-        return  xml_tools.dataForm2XMLUI(form, self.__requesting_id, session_id=session_id)
+        # we add any present note to the instructions
+        form.instructions.extend(self._mergeNotes(notes))
+        return xml_tools.dataForm2XMLUI(form, self.__requesting_id, session_id=session_id)
 
     def _requestingEntity(self, data, profile):
         """
@@ -302,11 +362,11 @@
             session_id = data["session_id"]
             entity = session_data['jid']
             try:
-                node = session_data['node']
+                session_data['node']
                 # node has already been received
             except KeyError:
                 # it's the first time we know the node, we save it in session data
-                node = session_data['node'] = data[xml_tools.SAT_FORM_PREFIX+'node']
+                session_data['node'] = data[xml_tools.SAT_FORM_PREFIX+'node']
 
             client = self.host.getClient(profile)
 
@@ -402,9 +462,7 @@
 
     def addAdHocCommand(self, callback, label, node="", features = None, timeout = 600, allowed_jids = None, allowed_groups = None,
                         allowed_magics = None, forbidden_jids = None, forbidden_groups = None, profile_key=C.PROF_KEY_NONE):
-        """
-
-        Add an ad-hoc command for the current profile
+        """Add an ad-hoc command for the current profile
 
         @param callback: method associated with this ad-hoc command which return the payload data (see AdHocCommand._sendAnswer), can return a deferred
         @param label: label associated with this command on the main menu