diff sat/plugins/plugin_exp_pubsub_schema.py @ 2959:989b622faff6

plugins schema, tickets, merge_requests: use serialised data for extra dict + some cosmetic changes
author Goffi <goffi@goffi.org>
date Fri, 14 Jun 2019 12:37:34 +0200
parents e2cb04b381bb
children ab2696e34d29
line wrap: on
line diff
--- a/sat/plugins/plugin_exp_pubsub_schema.py	Wed Jun 12 09:11:28 2019 +0200
+++ b/sat/plugins/plugin_exp_pubsub_schema.py	Fri Jun 14 12:37:34 2019 +0200
@@ -17,37 +17,38 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+from collections import Iterable
+import copy
+import itertools
+from zope.interface import implements
+from twisted.words.protocols.jabber import jid
+from twisted.words.protocols.jabber.xmlstream import XMPPHandler
+from twisted.internet import defer
+from wokkel import disco, iwokkel
+from wokkel import data_form
+from wokkel import generic
 from sat.core.i18n import _
 from sat.core import exceptions
 from sat.core.constants import Const as C
 from sat.tools import xml_tools
 from sat.tools import utils
 from sat.tools.common import date_utils
-from twisted.words.protocols.jabber import jid
-from twisted.words.protocols.jabber.xmlstream import XMPPHandler
-from twisted.internet import defer
+from sat.tools.common import data_format
 from sat.core.log import getLogger
 
 log = getLogger(__name__)
-from wokkel import disco, iwokkel
-from wokkel import data_form
-from wokkel import generic
-from zope.interface import implements
-from collections import Iterable
-import copy
-import itertools
 
-NS_SCHEMA = "https://salut-a-toi/protocol/schema:0"
+NS_SCHEMA = u"https://salut-a-toi/protocol/schema:0"
 
 PLUGIN_INFO = {
-    C.PI_NAME: "PubSub Schema",
-    C.PI_IMPORT_NAME: "PUBSUB_SCHEMA",
-    C.PI_TYPE: "EXP",
+    C.PI_NAME: u"PubSub Schema",
+    C.PI_IMPORT_NAME: u"PUBSUB_SCHEMA",
+    C.PI_TYPE: u"EXP",
     C.PI_PROTOCOLS: [],
-    C.PI_DEPENDENCIES: ["XEP-0060", "IDENTITY"],
-    C.PI_MAIN: "PubsubSchema",
-    C.PI_HANDLER: "yes",
-    C.PI_DESCRIPTION: _("""Handle Pubsub data schemas"""),
+    C.PI_DEPENDENCIES: [u"XEP-0060", u"IDENTITY"],
+    C.PI_MAIN: u"PubsubSchema",
+    C.PI_HANDLER: u"yes",
+    C.PI_DESCRIPTION: _(u"""Handle Pubsub data schemas"""),
 }
 
 
@@ -510,10 +511,49 @@
             schema = generic.parseXml(schema.encode("utf-8"))
         else:
             schema = None
-        if extra and u"update" in extra:
-            extra[u"update"] = C.bool(extra[u"update"])
+        extra = data_format.deserialise(extra)
         return client, service, node or None, schema, item_id or None, extra
 
+    @defer.inlineCallbacks
+    def copyMissingValues(self, client, service, node, item_id, form_ns, values):
+        """Retrieve values existing in original item and missing in update
+
+        Existing item will be retrieve, and values not already specified in values will
+        be filled
+        @param service: same as for [XEP_0060.getItems]
+        @param node: same as for [XEP_0060.getItems]
+        @param item_id(unicode): id of the item to retrieve
+        @param form_ns (unicode, None): namespace of the form
+        @param values(dict): values to fill
+            This dict will be modified *in place* to fill value present in existing
+            item and missing in the dict.
+        """
+        try:
+            # we get previous item
+            items_data = yield self._p.getItems(
+                client, service, node, item_ids=[item_id]
+            )
+            item_elt = items_data[0][0]
+        except Exception as e:
+            log.warning(
+                _(u"Can't get previous item, update ignored: {reason}").format(
+                    reason=e
+                )
+            )
+        else:
+            # and parse it
+            form = data_form.findForm(item_elt, form_ns)
+            if form is None:
+                log.warning(
+                    _(
+                        u"Can't parse previous item, update ignored: data form not found"
+                    ).format(reason=e)
+                )
+            else:
+                for name, field in form.fields.iteritems():
+                    if name not in values:
+                        values[name] = u"\n".join(unicode(v) for v in field.values)
+
     def _set(self, service, node, values, schema=None, item_id=None, extra=None,
              default_node=None, form_ns=None, fill_author=True,
              profile_key=C.PROF_KEY_NONE):
@@ -561,6 +601,8 @@
         other arguments are same as for [self._s.sendDataFormItem]
         @return (unicode): id of the created item
         """
+        if extra is None:
+            extra = {}
         if not node:
             if default_node is None:
                 raise ValueError(_(u"default_node must be set if node is not set"))
@@ -573,31 +615,7 @@
                 raise exceptions.DataError(
                     _(u'if extra["update"] is set, item_id must be set too')
                 )
-            try:
-                # we get previous item
-                items_data = yield self._p.getItems(
-                    client, service, node, item_ids=[item_id]
-                )
-                item_elt = items_data[0][0]
-            except Exception as e:
-                log.warning(
-                    _(u"Can't get previous item, update ignored: {reason}").format(
-                        reason=e
-                    )
-                )
-            else:
-                # and parse it
-                form = data_form.findForm(item_elt, form_ns)
-                if form is None:
-                    log.warning(
-                        _(
-                            u"Can't parse previous item, update ignored: data form not found"
-                        ).format(reason=e)
-                    )
-                else:
-                    for name, field in form.fields.iteritems():
-                        if name not in values:
-                            values[name] = u"\n".join(unicode(v) for v in field.values)
+            yield self.copyMissingValues(client, service, node, item_id, form_ns, values)
 
         values["updated"] = now
         if fill_author: