comparison src/plugins/plugin_exp_events.py @ 2287:ea869f30f204

plugin events: added eventInvite command as a helper for the complex invitation workflow: when this command is used: - an email invitation is sent with the event node set - invitee's jid is affiliated to event - invitee's jid is affiliated to invitee's node as a publisher - invitee's jid is affiliated to blog's node as a member - invitee's jid is affiliated to every blog's item's comments node as a publisher last affiliation complex operation is currently needed because of the way blogs and comments are handled, but this need to be changed in the future with XEP proposal.
author Goffi <goffi@goffi.org>
date Thu, 29 Jun 2017 20:57:12 +0200
parents b5befe7722d3
children c05000d00dbb
comparison
equal deleted inserted replaced
2286:330f8d4e2ad4 2287:ea869f30f204
34 C.PI_NAME: "Event plugin", 34 C.PI_NAME: "Event plugin",
35 C.PI_IMPORT_NAME: "events", 35 C.PI_IMPORT_NAME: "events",
36 C.PI_TYPE: "EXP", 36 C.PI_TYPE: "EXP",
37 C.PI_PROTOCOLS: [], 37 C.PI_PROTOCOLS: [],
38 C.PI_DEPENDENCIES: ["XEP-0060"], 38 C.PI_DEPENDENCIES: ["XEP-0060"],
39 C.PI_RECOMMENDATIONS: ["INVITATIONS", "XEP-0277"],
39 C.PI_MAIN: "Events", 40 C.PI_MAIN: "Events",
40 C.PI_HANDLER: "no", 41 C.PI_HANDLER: "no",
41 C.PI_DESCRIPTION: _("""Experimental implementation of XMPP events management""") 42 C.PI_DESCRIPTION: _("""Experimental implementation of XMPP events management""")
42 } 43 }
43 44
49 50
50 def __init__(self, host): 51 def __init__(self, host):
51 log.info(_(u"Event plugin initialization")) 52 log.info(_(u"Event plugin initialization"))
52 self.host = host 53 self.host = host
53 self._p = self.host.plugins["XEP-0060"] 54 self._p = self.host.plugins["XEP-0060"]
55 self._i = self.host.plugins.get("INVITATIONS")
56 self._b = self.host.plugins.get("XEP-0277")
54 host.bridge.addMethod("eventGet", ".plugin", 57 host.bridge.addMethod("eventGet", ".plugin",
55 in_sign='ssss', out_sign='(ia{ss})', 58 in_sign='ssss', out_sign='(ia{ss})',
56 method=self._eventGet, 59 method=self._eventGet,
57 async=True) 60 async=True)
58 host.bridge.addMethod("eventCreate", ".plugin", 61 host.bridge.addMethod("eventCreate", ".plugin",
68 method=self._eventInviteeGet, 71 method=self._eventInviteeGet,
69 async=True) 72 async=True)
70 host.bridge.addMethod("eventInviteeSet", ".plugin", 73 host.bridge.addMethod("eventInviteeSet", ".plugin",
71 in_sign='ssa{ss}s', out_sign='', 74 in_sign='ssa{ss}s', out_sign='',
72 method=self._eventInviteeSet, 75 method=self._eventInviteeSet,
76 async=True)
77 host.bridge.addMethod("eventInvite", ".plugin", in_sign='sssssssssss', out_sign='',
78 method=self._invite,
73 async=True) 79 async=True)
74 80
75 def _eventGet(self, service, node, id_=u'', profile_key=C.PROF_KEY_NONE): 81 def _eventGet(self, service, node, id_=u'', profile_key=C.PROF_KEY_NONE):
76 service = jid.JID(service) if service else None 82 service = jid.JID(service) if service else None
77 node = node if node else NS_EVENT 83 node = node if node else NS_EVENT
89 - timestamp of the event 95 - timestamp of the event
90 - event metadata where key can be: 96 - event metadata where key can be:
91 location: location of the event 97 location: location of the event
92 image: URL of a picture to use to represent event 98 image: URL of a picture to use to represent event
93 background-image: URL of a picture to use in background 99 background-image: URL of a picture to use in background
94 an empty dict is returned if nothing has been answered yed
95 """ 100 """
96 if not id_: 101 if not id_:
97 id_ = NS_EVENT 102 id_ = NS_EVENT
98 items, metadata = yield self._p.getItems(service, node, item_ids=[id_], profile_key=client.profile) 103 items, metadata = yield self._p.getItems(service, node, item_ids=[id_], profile_key=client.profile)
99 try: 104 try:
312 event_elt[key] = data.pop(key) 317 event_elt[key] = data.pop(key)
313 except KeyError: 318 except KeyError:
314 pass 319 pass
315 item_elt = pubsub.Item(id=client.jid.userhost(), payload=event_elt) 320 item_elt = pubsub.Item(id=client.jid.userhost(), payload=event_elt)
316 return self._p.publish(client, service, node, items=[item_elt]) 321 return self._p.publish(client, service, node, items=[item_elt])
322
323 def _invite(self, service, node, id_=NS_EVENT, email=u'', name=u'', host_name=u'', language=u'', url_template=u'',
324 message_subject=u'', message_body=u'', profile_key=C.PROF_KEY_NONE):
325 client = self.host.getClient(profile_key)
326 kwargs = {u'profile': client.profile}
327 for key in ("email", "name", "host_name", "language", "url_template", "message_subject", "message_body"):
328 value = locals()[key]
329 kwargs[key] = unicode(value)
330 return self.invite(client,
331 jid.JID(service) if service else None,
332 node,
333 id_ or NS_EVENT,
334 **kwargs)
335
336 @defer.inlineCallbacks
337 def invite(self, client, service, node, id_=NS_EVENT, **kwargs):
338 """High level method to create an email invitation to an event
339
340 @param service(unicode, None): PubSub service
341 @param node(unicode): PubSub node of the event
342 @param id_(unicode): id_ with even data
343 """
344 if self._i is None:
345 raise exceptions.FeatureNotFound(_(u'"Invitations" plugin is needed for this feature'))
346 if self._b is None:
347 raise exceptions.FeatureNotFound(_(u'"XEP-0277" (blog) plugin is needed for this feature'))
348 event_service = (service or client.jid.userhostJID())
349 event_uri = uri_parse.buildXMPPUri('pubsub',
350 path=event_service.full(),
351 node=node,
352 item=id_)
353 kwargs['extra'] = {u'event_uri': event_uri}
354 invitation_data = yield self._i.create(**kwargs)
355 invitee_jid = invitation_data[u'jid']
356 log.debug(_(u'invitation created'))
357 yield self._p.setNodeAffiliations(client, event_service, node, {invitee_jid: u'member'})
358 log.debug(_(u'affiliation set on event node'))
359 dummy, event_data = yield self.eventGet(client, service, node, id_)
360 log.debug(_(u'got event data'))
361 invitees_service = jid.JID(event_data['invitees_service'])
362 invitees_node = event_data['invitees_node']
363 blog_service = jid.JID(event_data['blog_service'])
364 blog_node = event_data['blog_node']
365 yield self._p.setNodeAffiliations(client, invitees_service, invitees_node, {invitee_jid: u'publisher'})
366 log.debug(_(u'affiliation set on invitee node'))
367 yield self._p.setNodeAffiliations(client, blog_service, blog_node, {invitee_jid: u'member'})
368 # FIXME: what follow is crazy, we have no good way to handle comments affiliations for blog
369 blog_items, dummy = yield self._b.mbGet(client, blog_service, blog_node, None)
370
371 for item in blog_items:
372 comments_service = jid.JID(item['comments_service'])
373 comments_node = item['comments_node']
374 yield self._p.setNodeAffiliations(client, comments_service, comments_node, {invitee_jid: u'publisher'})
375 log.debug(_(u'affiliation set on blog and comments nodes'))
376
377