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
This commit is contained in:
Goffi 2017-11-30 20:34:41 +01:00
commit 6d1d17e0cc

View file

@ -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 import utils
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 @@ class Tickets(object):
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 @@ class Tickets(object):
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 @@ class Tickets(object):
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 @@ class Tickets(object):
}
tickets, metadata = yield self._s.getDataFormItems(
client,
NS_TICKETS,
form_ns,
service,
node,
max_items = max_items,
@ -142,12 +150,14 @@ class Tickets(object):
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 @@ class Tickets(object):
'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 @@ class Tickets(object):
}
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'):