changeset 2447:9e692f09f367

plugin tickets: handle "update" flag + various improvments: - ticketsSet renamed to ticketSet as only one ticket is set at a time - dateFilter is not crashing anymore if value can't be parsed: the value is then return unmodified - form_ns can be specified in get, so the method can be used by other plugins - new "update" flag: if set in extra, an previous ticket of the same id will be retrieved, and used as a basis for an update
author Goffi <goffi@goffi.org>
date Thu, 30 Nov 2017 20:34:41 +0100
parents bfd1e9d737c4
children 637ac234424f
files src/plugins/plugin_misc_tickets.py
diffstat 1 files changed, 40 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_misc_tickets.py	Thu Nov 30 20:29:25 2017 +0100
+++ b/src/plugins/plugin_misc_tickets.py	Thu Nov 30 20:34:41 2017 +0100
@@ -19,6 +19,7 @@
 
 from sat.core.i18n import _
 from sat.core.constants import Const as C
+from sat.core import exceptions
 from twisted.words.protocols.jabber import jid
 from twisted.internet import defer
 from wokkel import generic
@@ -26,6 +27,7 @@
 from sat.tools.common import uri
 from sat.core.log import getLogger
 import shortuuid
+from wokkel import data_form
 log = getLogger(__name__)
 
 NS_TICKETS = 'org.salut-a-toi.tickets:0'
@@ -57,7 +59,7 @@
                               method=self._get,
                               async=True
                               )
-        host.bridge.addMethod("ticketsSet", ".plugin",
+        host.bridge.addMethod("ticketSet", ".plugin",
                               in_sign='ssa{sas}ssa{ss}s', out_sign='s',
                               method=self._set,
                               async=True)
@@ -89,10 +91,13 @@
         return widget_type, args, kwargs
 
     def _dateFilter(self, form_xmlui, widget_type, args, kwargs):
-        if widget_type != u'string':
+        if widget_type != u'string' or not args[0]:
             return widget_type, args, kwargs
         # we convert XMPP date to timestamp
-        args[0] = unicode(utils.date_parse(args[0]))
+        try:
+            args[0] = unicode(utils.date_parse(args[0]))
+        except Exception as e:
+            log.warning(_(u"Can't parse date field: {msg}").format(msg=e))
         return widget_type, args, kwargs
 
     def _get(self, service='', node='', max_items=10, item_ids=None, sub_id=None, extra_dict=None, profile_key=C.PROF_KEY_NONE):
@@ -105,13 +110,16 @@
         return d
 
     @defer.inlineCallbacks
-    def get(self, client, service=None, node=None, max_items=None, item_ids=None, sub_id=None, rsm_request=None, extra=None):
+    def get(self, client, service=None, node=None, max_items=None, item_ids=None, sub_id=None, rsm_request=None, extra=None, form_ns=NS_TICKETS):
         """Retrieve tickets and convert them to XMLUI
 
+        @param service(None, jid.JID): Pubsub service to use
         @param node(unicode, None): PubSub node to use
             if None, default ticket node will be used
         other parameters as the same as for [XEP_0060.getItems]
-        @return (list[unicode]): XMLUI of the tickets
+        @return (tuple(list[unicode], dict[unicode, object])):
+            - XMLUI of the tickets
+            - metadata dict
         """
         if not node:
             node = NS_TICKETS
@@ -122,7 +130,7 @@
                    }
         tickets, metadata = yield self._s.getDataFormItems(
             client,
-            NS_TICKETS,
+            form_ns,
             service,
             node,
             max_items = max_items,
@@ -142,12 +150,14 @@
             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'])
         d = self.set(client, service, node or None, values, schema, item_id or None, extra, deserialise=True)
         d.addCallback(lambda ret: ret or u'')
         return d
 
     @defer.inlineCallbacks
-    def set(self, client, service, node, values, schema=None, item_id=None, extra=None, deserialise=False):
+    def set(self, client, service, node, values, schema=None, item_id=None, extra=None, deserialise=False, form_ns=NS_TICKETS):
         """Publish a tickets
 
         @param node(unicode, None): Pubsub node to use
@@ -157,6 +167,9 @@
             'created' and 'updated' will be forced to current time:
                 - 'created' is set if item_id is None, i.e. if it's a new ticket
                 - 'updated' is set everytime
+        @param extra(dict, None): same as for [XEP-0060.sendItem] with additional keys:
+            - update(bool): if True, get previous item data to merge with current one
+                if True, item_id must be None
         other arguments are same as for [self._s.sendDataFormItem]
         @return (unicode): id of the created item
         """
@@ -180,6 +193,26 @@
                        }
             yield self._p.createNode(client, comments_service, comments_node, options)
             values['comments_uri'] = uri.buildXMPPUri(u'pubsub', subtype='microblog', path=comments_service.full(), node=comments_node)
+        elif extra.get(u'update', False):
+            if item_id is None:
+                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)
 
         values['updated'] = now
         if not values.get('reporter'):