diff --git a/src/plugins/plugin_exp_pubsub_schema.py b/src/plugins/plugin_exp_pubsub_schema.py index b64e6ae9..3f69ac56 100755 --- a/src/plugins/plugin_exp_pubsub_schema.py +++ b/src/plugins/plugin_exp_pubsub_schema.py @@ -261,7 +261,7 @@ class PubsubSchema(object): def sendDataFormItem(self, client, service, nodeIdentifier, values, schema=None, item_id=None, extra=None, deserialise=False): """Publish an item as a dataform when we know that there is a schema - @param values(dict[[iterable[object], object]): values set for the form + @param values(dict[key(unicode), [iterable[object], object]]): values set for the form if not iterable, will be put in a list @param schema(domish.Element, data_form.Form, None): data schema None to retrieve data schema from node (need to do a additional XMPP call) @@ -270,6 +270,7 @@ class PubsubSchema(object): This is done in this method and not directly in _sendDataFormItem because we need to know the data type which is in the form, not availablable in _sendDataFormItem other parameters as the same as for [self._p.sendItem] + @return (unicode): id of the created item """ form = yield self.getSchemaForm(client, service, nodeIdentifier, schema, form_type='submit') diff --git a/src/plugins/plugin_misc_tickets.py b/src/plugins/plugin_misc_tickets.py index 6bd1ebf1..bda77d09 100755 --- a/src/plugins/plugin_misc_tickets.py +++ b/src/plugins/plugin_misc_tickets.py @@ -21,8 +21,11 @@ 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' @@ -32,7 +35,7 @@ PLUGIN_INFO = { C.PI_IMPORT_NAME: "TICKETS", C.PI_TYPE: "EXP", C.PI_PROTOCOLS: [], - C.PI_DEPENDENCIES: ["XEP-0060", "PUBSUB_SCHEMA"], + C.PI_DEPENDENCIES: ["XEP-0060", "PUBSUB_SCHEMA", "XEP-0277"], C.PI_MAIN: "Tickets", C.PI_HANDLER: "no", C.PI_DESCRIPTION: _("""Tickets management plugin""") @@ -46,11 +49,20 @@ class Tickets(object): self.host = host self._p = self.host.plugins["XEP-0060"] self._s = self.host.plugins["PUBSUB_SCHEMA"] + self._m = self.host.plugins["XEP-0277"] 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 _labelsFilter(self, widget_type, args, kwargs): if widget_type != u'textbox': @@ -107,3 +119,58 @@ class Tickets(object): ) 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 = self._m.getCommentsService(client) + + # 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 + 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)