Mercurial > libervia-backend
view src/plugins/plugin_misc_tickets.py @ 2434:7fa9456032e7
plugin tickets: specify parent service when using getCommentsService + fill reporter_jid is missing (will be discarded later if not in the schema)
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 15 Nov 2017 08:58:38 +0100 |
parents | 3faf18111d61 |
children | 81a45e7886c9 |
line wrap: on
line source
#!/usr/bin/env python2 # -*- coding: utf-8 -*- # SAT plugin for Pubsub Schemas # Copyright (C) 2009-2017 Jérôme Poisson (goffi@goffi.org) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # 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 sat.core.i18n import _ from sat.core.constants import Const as C 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 import shortuuid log = getLogger(__name__) NS_TICKETS = 'org.salut-a-toi.tickets:0' PLUGIN_INFO = { C.PI_NAME: _("Tickets management"), C.PI_IMPORT_NAME: "TICKETS", C.PI_TYPE: "EXP", C.PI_PROTOCOLS: [], C.PI_DEPENDENCIES: ["XEP-0060", "PUBSUB_SCHEMA", "XEP-0277", "IDENTITY"], C.PI_MAIN: "Tickets", C.PI_HANDLER: "no", C.PI_DESCRIPTION: _("""Tickets management plugin""") } class Tickets(object): def __init__(self, host): log.info(_(u"Tickets plugin initialization")) self.host = host 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, async=True ) host.bridge.addMethod("ticketsSet", ".plugin", in_sign='ssa{sas}ssa{ss}s', out_sign='s', method=self._set, async=True) host.bridge.addMethod("ticketsSchemaGet", ".plugin", in_sign='sss', out_sign='s', method=self._getSchema, 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': return widget_type, args, kwargs # we convert XMPP date to timestamp args[0] = unicode(utils.date_parse(args[0])) 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): """Retrieve tickets and convert them to XMLUI @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 """ 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, NS_TICKETS, 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 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): """Publish a tickets @param node(unicode, None): Pubsub node to use None to use default tickets node @param values(dict[key(unicode), [iterable[object], object]]): values of the ticket if not iterable, will be put in a list '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 other arguments are same as for [self._s.sendDataFormItem] @return (unicode): id of the created item """ 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 # (we don't want to set it ourselves to let the server choose, so we can have # a nicer id if serial ids is activated) comments_node = self._m.getCommentsNode(node + u'_' + unicode(shortuuid.uuid())) options = {self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN, self._p.OPT_PERSIST_ITEMS: 1, self._p.OPT_MAX_ITEMS: -1, self._p.OPT_DELIVER_PAYLOADS: 1, self._p.OPT_SEND_ITEM_SUBSCRIBE: 1, self._p.OPT_PUBLISH_MODEL: self._p.ACCESS_OPEN, } 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) 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) 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)