# HG changeset patch # User Goffi # Date 1512070481 -3600 # Node ID 9e692f09f36753f13af8ac7c56e7955373b8d0c7 # Parent bfd1e9d737c4030778dd66547e2119a45544e2f6 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 diff -r bfd1e9d737c4 -r 9e692f09f367 src/plugins/plugin_misc_tickets.py --- 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'):