plugins schema, merge_requests, tickets*: factorisation

Dode common in plugins using schema have been factorised in pubsub schema plugin, and filters users in tickets handling have been renamed in a more generic way and put there too.
"reporter*" fields in tickets have been renamed to "author*" as it is a more generic term which can be used elsewhere.
The use of new utils.partial function make easy the creation of simple plugins using schema.
This commit is contained in:
Goffi 2018-01-12 15:58:54 +01:00
commit 3e76e826d0

View file

@ -19,15 +19,11 @@
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
from sat.tools import utils
from sat.tools.common import uri
from sat.core.log import getLogger
from sat.tools import utils
import shortuuid
from wokkel import data_form
from sat.core.log import getLogger
log = getLogger(__name__)
NS_TICKETS = 'org.salut-a-toi.tickets:0'
@ -53,10 +49,18 @@ class Tickets(object):
self._p = self.host.plugins["XEP-0060"]
self._s = self.host.plugins["PUBSUB_SCHEMA"]
self._m = self.host.plugins["XEP-0277"]
self._i = self.host.plugins["IDENTITY"]
host.bridge.addMethod("ticketsGet", ".plugin",
in_sign='ssiassa{ss}s', out_sign='(asa{ss})',
method=self._get,
method=utils.partial(
self._s._get,
default_node=NS_TICKETS,
form_ns=NS_TICKETS,
filters = {u'author': self._s.valueOrPublisherFilter,
u'labels': self._s.textbox2ListFilter,
u'created': self._s.dateFilter,
u'updated': self._s.dateFilter,
}),
async=True
)
host.bridge.addMethod("ticketSet", ".plugin",
@ -65,93 +69,11 @@ class Tickets(object):
async=True)
host.bridge.addMethod("ticketsSchemaGet", ".plugin",
in_sign='sss', out_sign='s',
method=self._getSchema,
method=utils.partial(self._s._getUISchema, default_node=NS_TICKETS),
async=True)
def _reporterFilter(self, client, form_xmlui, widget_type, args, kwargs):
if not args[0]:
# if reporter is not filled, we use user part of publisher
# (if we have it)
try:
publisher = jid.JID(form_xmlui.named_widgets['publisher'].value)
except (KeyError, RuntimeError):
pass
else:
args[0] = publisher.user.capitalize()
return widget_type, args, kwargs
def _labelsFilter(self, form_xmlui, widget_type, args, kwargs):
if widget_type != u'textbox':
return widget_type, args, kwargs
widget_type = u'list'
options = [o for o in args.pop(0).split(u'\n') if o]
kwargs = {'options': options,
'name': kwargs.get('name'),
'styles': (u'noselect', u'extensible', u'reducible')}
return widget_type, args, kwargs
def _dateFilter(self, form_xmlui, widget_type, args, kwargs):
if widget_type != u'string' or not args[0]:
return widget_type, args, kwargs
# we convert XMPP date to timestamp
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):
client = self.host.getClient(profile_key)
service = jid.JID(service) if service else None
max_items = None if max_items == C.NO_LIMIT else max_items
extra = self._p.parseExtra(extra_dict)
d = self.get(client, service, node or None, max_items, item_ids, sub_id or None, extra.rsm_request, extra.extra)
d.addCallback(self._p.serItemsData)
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, 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 (tuple(list[unicode], dict[unicode, object])):
- XMLUI of the tickets
- metadata dict
"""
if not node:
node = NS_TICKETS
filters = {u'reporter': lambda *args: self._reporterFilter(client, *args),
u'labels': self._labelsFilter,
u'created': self._dateFilter,
u'updated': self._dateFilter,
}
tickets, metadata = yield self._s.getDataFormItems(
client,
form_ns,
service,
node,
max_items = max_items,
item_ids = item_ids,
sub_id = sub_id,
rsm_request = rsm_request,
extra = extra,
filters = filters,
)
defer.returnValue((tickets, metadata))
def _set(self, service, node, values, schema=None, item_id=None, extra=None, profile_key=C.PROF_KEY_NONE):
client = self.host.getClient(profile_key)
service = None if not service else jid.JID(service)
if schema:
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'])
client, service, schema, extra = self._s.prepareBridgeSet(service, node, schema, item_id, extra)
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
@ -175,9 +97,7 @@ class Tickets(object):
"""
if not node:
node = NS_TICKETS
now = utils.xmpp_date()
if not item_id:
values['created'] = now
comments_service = yield self._m.getCommentsService(client, service)
# we need to use uuid for comments node, because we don't know item id in advance
@ -193,37 +113,5 @@ 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'):
identity = yield self._i.getIdentity(client, client.jid)
values['reporter'] = identity['nick']
if not values.get('reporter_jid'):
values['reporter_jid'] = client.jid.full()
item_id = yield self._s.sendDataFormItem(client, service, node, values, schema, item_id, extra, deserialise)
item_id = yield self._s.set(client, service, node, values, schema, item_id, extra, deserialise, form_ns)
defer.returnValue(item_id)
def _getSchema(self, service, node, profile_key=C.PROF_KEY_NONE):
if not node:
node = NS_TICKETS
return self._s._getUISchema(service, node, profile_key)