Mercurial > libervia-backend
comparison sat/plugins/plugin_exp_events.py @ 2624:56f94936df1e
code style reformatting using black
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 27 Jun 2018 20:14:46 +0200 |
parents | 1cc88adb5142 |
children | 378188abe941 |
comparison
equal
deleted
inserted
replaced
2623:49533de4540b | 2624:56f94936df1e |
---|---|
19 | 19 |
20 from sat.core.i18n import _ | 20 from sat.core.i18n import _ |
21 from sat.core import exceptions | 21 from sat.core import exceptions |
22 from sat.core.constants import Const as C | 22 from sat.core.constants import Const as C |
23 from sat.core.log import getLogger | 23 from sat.core.log import getLogger |
24 | |
24 log = getLogger(__name__) | 25 log = getLogger(__name__) |
25 from sat.tools import utils | 26 from sat.tools import utils |
26 from sat.tools.common import uri as xmpp_uri | 27 from sat.tools.common import uri as xmpp_uri |
27 from sat.tools.common import date_utils | 28 from sat.tools.common import date_utils |
28 from twisted.internet import defer | 29 from twisted.internet import defer |
43 C.PI_PROTOCOLS: [], | 44 C.PI_PROTOCOLS: [], |
44 C.PI_DEPENDENCIES: ["XEP-0060"], | 45 C.PI_DEPENDENCIES: ["XEP-0060"], |
45 C.PI_RECOMMENDATIONS: ["INVITATIONS", "XEP-0277"], | 46 C.PI_RECOMMENDATIONS: ["INVITATIONS", "XEP-0277"], |
46 C.PI_MAIN: "Events", | 47 C.PI_MAIN: "Events", |
47 C.PI_HANDLER: "yes", | 48 C.PI_HANDLER: "yes", |
48 C.PI_DESCRIPTION: _("""Experimental implementation of XMPP events management""") | 49 C.PI_DESCRIPTION: _("""Experimental implementation of XMPP events management"""), |
49 } | 50 } |
50 | 51 |
51 NS_EVENT = 'org.salut-a-toi.event:0' | 52 NS_EVENT = "org.salut-a-toi.event:0" |
52 NS_EVENT_LIST = NS_EVENT + '#list' | 53 NS_EVENT_LIST = NS_EVENT + "#list" |
53 NS_EVENT_INVIT = NS_EVENT + '#invitation' | 54 NS_EVENT_INVIT = NS_EVENT + "#invitation" |
54 INVITATION = '/message[@type="chat"]/invitation[@xmlns="{ns_invit}"]'.format( | 55 INVITATION = '/message[@type="chat"]/invitation[@xmlns="{ns_invit}"]'.format( |
55 ns_invit=NS_EVENT_INVIT) | 56 ns_invit=NS_EVENT_INVIT |
57 ) | |
56 | 58 |
57 | 59 |
58 class Events(object): | 60 class Events(object): |
59 """Q&D module to handle event attendance answer, experimentation only""" | 61 """Q&D module to handle event attendance answer, experimentation only""" |
60 | 62 |
62 log.info(_(u"Event plugin initialization")) | 64 log.info(_(u"Event plugin initialization")) |
63 self.host = host | 65 self.host = host |
64 self._p = self.host.plugins["XEP-0060"] | 66 self._p = self.host.plugins["XEP-0060"] |
65 self._i = self.host.plugins.get("INVITATIONS") | 67 self._i = self.host.plugins.get("INVITATIONS") |
66 self._b = self.host.plugins.get("XEP-0277") | 68 self._b = self.host.plugins.get("XEP-0277") |
67 host.bridge.addMethod("eventGet", ".plugin", | 69 host.bridge.addMethod( |
68 in_sign='ssss', out_sign='(ia{ss})', | 70 "eventGet", |
69 method=self._eventGet, | 71 ".plugin", |
70 async=True) | 72 in_sign="ssss", |
71 host.bridge.addMethod("eventCreate", ".plugin", | 73 out_sign="(ia{ss})", |
72 in_sign='ia{ss}ssss', out_sign='s', | 74 method=self._eventGet, |
73 method=self._eventCreate, | 75 async=True, |
74 async=True) | 76 ) |
75 host.bridge.addMethod("eventModify", ".plugin", | 77 host.bridge.addMethod( |
76 in_sign='sssia{ss}s', out_sign='', | 78 "eventCreate", |
77 method=self._eventModify, | 79 ".plugin", |
78 async=True) | 80 in_sign="ia{ss}ssss", |
79 host.bridge.addMethod("eventsList", ".plugin", | 81 out_sign="s", |
80 in_sign='sss', out_sign='aa{ss}', | 82 method=self._eventCreate, |
81 method=self._eventsList, | 83 async=True, |
82 async=True) | 84 ) |
83 host.bridge.addMethod("eventInviteeGet", ".plugin", | 85 host.bridge.addMethod( |
84 in_sign='sss', out_sign='a{ss}', | 86 "eventModify", |
85 method=self._eventInviteeGet, | 87 ".plugin", |
86 async=True) | 88 in_sign="sssia{ss}s", |
87 host.bridge.addMethod("eventInviteeSet", ".plugin", | 89 out_sign="", |
88 in_sign='ssa{ss}s', out_sign='', | 90 method=self._eventModify, |
89 method=self._eventInviteeSet, | 91 async=True, |
90 async=True) | 92 ) |
91 host.bridge.addMethod("eventInviteesList", ".plugin", | 93 host.bridge.addMethod( |
92 in_sign='sss', out_sign='a{sa{ss}}', | 94 "eventsList", |
93 method=self._eventInviteesList, | 95 ".plugin", |
94 async=True), | 96 in_sign="sss", |
95 host.bridge.addMethod("eventInvite", ".plugin", in_sign='sssss', out_sign='', | 97 out_sign="aa{ss}", |
96 method=self._invite, | 98 method=self._eventsList, |
97 async=True) | 99 async=True, |
98 host.bridge.addMethod("eventInviteByEmail", ".plugin", in_sign='ssssassssssss', out_sign='', | 100 ) |
99 method=self._inviteByEmail, | 101 host.bridge.addMethod( |
100 async=True) | 102 "eventInviteeGet", |
103 ".plugin", | |
104 in_sign="sss", | |
105 out_sign="a{ss}", | |
106 method=self._eventInviteeGet, | |
107 async=True, | |
108 ) | |
109 host.bridge.addMethod( | |
110 "eventInviteeSet", | |
111 ".plugin", | |
112 in_sign="ssa{ss}s", | |
113 out_sign="", | |
114 method=self._eventInviteeSet, | |
115 async=True, | |
116 ) | |
117 host.bridge.addMethod( | |
118 "eventInviteesList", | |
119 ".plugin", | |
120 in_sign="sss", | |
121 out_sign="a{sa{ss}}", | |
122 method=self._eventInviteesList, | |
123 async=True, | |
124 ), | |
125 host.bridge.addMethod( | |
126 "eventInvite", | |
127 ".plugin", | |
128 in_sign="sssss", | |
129 out_sign="", | |
130 method=self._invite, | |
131 async=True, | |
132 ) | |
133 host.bridge.addMethod( | |
134 "eventInviteByEmail", | |
135 ".plugin", | |
136 in_sign="ssssassssssss", | |
137 out_sign="", | |
138 method=self._inviteByEmail, | |
139 async=True, | |
140 ) | |
101 | 141 |
102 def getHandler(self, client): | 142 def getHandler(self, client): |
103 return EventsHandler(self) | 143 return EventsHandler(self) |
104 | 144 |
105 def _parseEventElt(self, event_elt): | 145 def _parseEventElt(self, event_elt): |
113 except StopIteration: | 153 except StopIteration: |
114 timestamp = -1 | 154 timestamp = -1 |
115 | 155 |
116 data = {} | 156 data = {} |
117 | 157 |
118 for key in (u'name',): | 158 for key in (u"name",): |
119 try: | 159 try: |
120 data[key] = event_elt[key] | 160 data[key] = event_elt[key] |
121 except KeyError: | 161 except KeyError: |
122 continue | 162 continue |
123 | 163 |
124 for elt_name in (u'description',): | 164 for elt_name in (u"description",): |
125 try: | 165 try: |
126 elt = next(event_elt.elements(NS_EVENT, elt_name)) | 166 elt = next(event_elt.elements(NS_EVENT, elt_name)) |
127 except StopIteration: | 167 except StopIteration: |
128 continue | 168 continue |
129 else: | 169 else: |
130 data[elt_name] = unicode(elt) | 170 data[elt_name] = unicode(elt) |
131 | 171 |
132 for elt_name in (u'image', 'background-image'): | 172 for elt_name in (u"image", "background-image"): |
133 try: | 173 try: |
134 image_elt = next(event_elt.elements(NS_EVENT, elt_name)) | 174 image_elt = next(event_elt.elements(NS_EVENT, elt_name)) |
135 data[elt_name] = image_elt['src'] | 175 data[elt_name] = image_elt["src"] |
136 except StopIteration: | 176 except StopIteration: |
137 continue | 177 continue |
138 except KeyError: | 178 except KeyError: |
139 log.warning(_(u'no src found for image')) | 179 log.warning(_(u"no src found for image")) |
140 | 180 |
141 for uri_type in (u'invitees', u'blog'): | 181 for uri_type in (u"invitees", u"blog"): |
142 try: | 182 try: |
143 elt = next(event_elt.elements(NS_EVENT, uri_type)) | 183 elt = next(event_elt.elements(NS_EVENT, uri_type)) |
144 uri = data[uri_type + u'_uri'] = elt['uri'] | 184 uri = data[uri_type + u"_uri"] = elt["uri"] |
145 uri_data = xmpp_uri.parseXMPPUri(uri) | 185 uri_data = xmpp_uri.parseXMPPUri(uri) |
146 if uri_data[u'type'] != u'pubsub': | 186 if uri_data[u"type"] != u"pubsub": |
147 raise ValueError | 187 raise ValueError |
148 except StopIteration: | 188 except StopIteration: |
149 log.warning(_(u"no {uri_type} element found!").format(uri_type=uri_type)) | 189 log.warning(_(u"no {uri_type} element found!").format(uri_type=uri_type)) |
150 except KeyError: | 190 except KeyError: |
151 log.warning(_(u"incomplete {uri_type} element").format(uri_type=uri_type)) | 191 log.warning(_(u"incomplete {uri_type} element").format(uri_type=uri_type)) |
152 except ValueError: | 192 except ValueError: |
153 log.warning(_(u"bad {uri_type} element").format(uri_type=uri_type)) | 193 log.warning(_(u"bad {uri_type} element").format(uri_type=uri_type)) |
154 else: | 194 else: |
155 data[uri_type + u'_service'] = uri_data[u'path'] | 195 data[uri_type + u"_service"] = uri_data[u"path"] |
156 data[uri_type + u'_node'] = uri_data[u'node'] | 196 data[uri_type + u"_node"] = uri_data[u"node"] |
157 | 197 |
158 for meta_elt in event_elt.elements(NS_EVENT, 'meta'): | 198 for meta_elt in event_elt.elements(NS_EVENT, "meta"): |
159 key = meta_elt[u'name'] | 199 key = meta_elt[u"name"] |
160 if key in data: | 200 if key in data: |
161 log.warning(u'Ignoring conflicting meta element: {xml}'.format(xml=meta_elt.toXml())) | 201 log.warning( |
202 u"Ignoring conflicting meta element: {xml}".format( | |
203 xml=meta_elt.toXml() | |
204 ) | |
205 ) | |
162 continue | 206 continue |
163 data[key] = unicode(meta_elt) | 207 data[key] = unicode(meta_elt) |
164 if event_elt.link: | 208 if event_elt.link: |
165 link_elt = event_elt.link | 209 link_elt = event_elt.link |
166 data['service'] = link_elt['service'] | 210 data["service"] = link_elt["service"] |
167 data['node'] = link_elt['node'] | 211 data["node"] = link_elt["node"] |
168 data['item'] = link_elt['item'] | 212 data["item"] = link_elt["item"] |
169 if event_elt.getAttribute('creator') == 'true': | 213 if event_elt.getAttribute("creator") == "true": |
170 data['creator'] = True | 214 data["creator"] = True |
171 return timestamp, data | 215 return timestamp, data |
172 | 216 |
173 @defer.inlineCallbacks | 217 @defer.inlineCallbacks |
174 def getEventElement(self, client, service, node, id_): | 218 def getEventElement(self, client, service, node, id_): |
175 """Retrieve event element | 219 """Retrieve event element |
182 """ | 226 """ |
183 if not id_: | 227 if not id_: |
184 id_ = NS_EVENT | 228 id_ = NS_EVENT |
185 items, metadata = yield self._p.getItems(client, service, node, item_ids=[id_]) | 229 items, metadata = yield self._p.getItems(client, service, node, item_ids=[id_]) |
186 try: | 230 try: |
187 event_elt = next(items[0].elements(NS_EVENT, u'event')) | 231 event_elt = next(items[0].elements(NS_EVENT, u"event")) |
188 except IndexError: | 232 except IndexError: |
189 raise exceptions.NotFound(_(u"No event with this id has been found")) | 233 raise exceptions.NotFound(_(u"No event with this id has been found")) |
190 defer.returnValue(event_elt) | 234 defer.returnValue(event_elt) |
191 | 235 |
192 @defer.inlineCallbacks | 236 @defer.inlineCallbacks |
202 """ | 246 """ |
203 # we save a link to the event in our local list | 247 # we save a link to the event in our local list |
204 try: | 248 try: |
205 # TODO: check auto-create, no need to create node first if available | 249 # TODO: check auto-create, no need to create node first if available |
206 options = {self._p.OPT_ACCESS_MODEL: self._p.ACCESS_WHITELIST} | 250 options = {self._p.OPT_ACCESS_MODEL: self._p.ACCESS_WHITELIST} |
207 yield self._p.createNode(client, | 251 yield self._p.createNode( |
208 client.jid.userhostJID(), | 252 client, |
209 nodeIdentifier=NS_EVENT_LIST, | 253 client.jid.userhostJID(), |
210 options=options) | 254 nodeIdentifier=NS_EVENT_LIST, |
255 options=options, | |
256 ) | |
211 except error.StanzaError as e: | 257 except error.StanzaError as e: |
212 if e.condition == u'conflict': | 258 if e.condition == u"conflict": |
213 log.debug(_(u"requested node already exists")) | 259 log.debug(_(u"requested node already exists")) |
214 link_elt = event_elt.addElement((NS_EVENT_LIST, 'link')) | 260 link_elt = event_elt.addElement((NS_EVENT_LIST, "link")) |
215 link_elt["service"] = service.full() | 261 link_elt["service"] = service.full() |
216 link_elt["node"] = node | 262 link_elt["node"] = node |
217 link_elt["item"] = event_id | 263 link_elt["item"] = event_id |
218 item_id = xmpp_uri.buildXMPPUri(u'pubsub', | 264 item_id = xmpp_uri.buildXMPPUri( |
219 path=service.full(), | 265 u"pubsub", path=service.full(), node=node, item=event_id |
220 node=node, | 266 ) |
221 item=event_id) | |
222 if creator: | 267 if creator: |
223 event_elt['creator'] = 'true' | 268 event_elt["creator"] = "true" |
224 item_elt = pubsub.Item(id=item_id, payload=event_elt) | 269 item_elt = pubsub.Item(id=item_id, payload=event_elt) |
225 yield self._p.publish(client, | 270 yield self._p.publish( |
226 client.jid.userhostJID(), | 271 client, client.jid.userhostJID(), NS_EVENT_LIST, items=[item_elt] |
227 NS_EVENT_LIST, | 272 ) |
228 items=[item_elt]) | 273 |
229 | 274 def _eventGet(self, service, node, id_=u"", profile_key=C.PROF_KEY_NONE): |
230 def _eventGet(self, service, node, id_=u'', profile_key=C.PROF_KEY_NONE): | |
231 service = jid.JID(service) if service else None | 275 service = jid.JID(service) if service else None |
232 node = node if node else NS_EVENT | 276 node = node if node else NS_EVENT |
233 client = self.host.getClient(profile_key) | 277 client = self.host.getClient(profile_key) |
234 return self.eventGet(client, service, node, id_) | 278 return self.eventGet(client, service, node, id_) |
235 | 279 |
249 """ | 293 """ |
250 event_elt = yield self.getEventElement(client, service, node, id_) | 294 event_elt = yield self.getEventElement(client, service, node, id_) |
251 | 295 |
252 defer.returnValue(self._parseEventElt(event_elt)) | 296 defer.returnValue(self._parseEventElt(event_elt)) |
253 | 297 |
254 def _eventCreate(self, timestamp, data, service, node, id_=u'', profile_key=C.PROF_KEY_NONE): | 298 def _eventCreate( |
299 self, timestamp, data, service, node, id_=u"", profile_key=C.PROF_KEY_NONE | |
300 ): | |
255 service = jid.JID(service) if service else None | 301 service = jid.JID(service) if service else None |
256 node = node or None | 302 node = node or None |
257 client = self.host.getClient(profile_key) | 303 client = self.host.getClient(profile_key) |
258 data[u'register'] = C.bool(data.get(u'register', C.BOOL_FALSE)) | 304 data[u"register"] = C.bool(data.get(u"register", C.BOOL_FALSE)) |
259 return self.eventCreate(client, timestamp, data, service, node, id_ or NS_EVENT) | 305 return self.eventCreate(client, timestamp, data, service, node, id_ or NS_EVENT) |
260 | 306 |
261 @defer.inlineCallbacks | 307 @defer.inlineCallbacks |
262 def eventCreate(self, client, timestamp, data, service, node=None, event_id=NS_EVENT): | 308 def eventCreate(self, client, timestamp, data, service, node=None, event_id=NS_EVENT): |
263 """Create or replace an event | 309 """Create or replace an event |
280 if not event_id: | 326 if not event_id: |
281 raise ValueError(_(u"event_id must be set")) | 327 raise ValueError(_(u"event_id must be set")) |
282 if not service: | 328 if not service: |
283 service = client.jid.userhostJID() | 329 service = client.jid.userhostJID() |
284 if not node: | 330 if not node: |
285 node = NS_EVENT + u'__' + shortuuid.uuid() | 331 node = NS_EVENT + u"__" + shortuuid.uuid() |
286 event_elt = domish.Element((NS_EVENT, 'event')) | 332 event_elt = domish.Element((NS_EVENT, "event")) |
287 if timestamp is not None and timestamp != -1: | 333 if timestamp is not None and timestamp != -1: |
288 formatted_date = utils.xmpp_date(timestamp) | 334 formatted_date = utils.xmpp_date(timestamp) |
289 event_elt.addElement((NS_EVENT, 'date'), content=formatted_date) | 335 event_elt.addElement((NS_EVENT, "date"), content=formatted_date) |
290 register = data.pop('register', False) | 336 register = data.pop("register", False) |
291 for key in (u'name',): | 337 for key in (u"name",): |
292 if key in data: | 338 if key in data: |
293 event_elt[key] = data.pop(key) | 339 event_elt[key] = data.pop(key) |
294 for key in (u'description',): | 340 for key in (u"description",): |
295 if key in data: | 341 if key in data: |
296 event_elt.addElement((NS_EVENT, key), content=data.pop(key)) | 342 event_elt.addElement((NS_EVENT, key), content=data.pop(key)) |
297 for key in (u'image', u'background-image'): | 343 for key in (u"image", u"background-image"): |
298 if key in data: | 344 if key in data: |
299 elt = event_elt.addElement((NS_EVENT, key)) | 345 elt = event_elt.addElement((NS_EVENT, key)) |
300 elt['src'] = data.pop(key) | 346 elt["src"] = data.pop(key) |
301 | 347 |
302 # we first create the invitees and blog nodes (if not specified in data) | 348 # we first create the invitees and blog nodes (if not specified in data) |
303 for uri_type in (u'invitees', u'blog'): | 349 for uri_type in (u"invitees", u"blog"): |
304 key = uri_type + u'_uri' | 350 key = uri_type + u"_uri" |
305 for to_delete in (u'service', u'node'): | 351 for to_delete in (u"service", u"node"): |
306 k = uri_type + u'_' + to_delete | 352 k = uri_type + u"_" + to_delete |
307 if k in data: | 353 if k in data: |
308 del data[k] | 354 del data[k] |
309 if key not in data: | 355 if key not in data: |
310 # FIXME: affiliate invitees | 356 # FIXME: affiliate invitees |
311 uri_node = yield self._p.createNode(client, service) | 357 uri_node = yield self._p.createNode(client, service) |
312 yield self._p.setConfiguration(client, service, uri_node, {self._p.OPT_ACCESS_MODEL: self._p.ACCESS_WHITELIST}) | 358 yield self._p.setConfiguration( |
359 client, | |
360 service, | |
361 uri_node, | |
362 {self._p.OPT_ACCESS_MODEL: self._p.ACCESS_WHITELIST}, | |
363 ) | |
313 uri_service = service | 364 uri_service = service |
314 else: | 365 else: |
315 uri = data.pop(key) | 366 uri = data.pop(key) |
316 uri_data = xmpp_uri.parseXMPPUri(uri) | 367 uri_data = xmpp_uri.parseXMPPUri(uri) |
317 if uri_data[u'type'] != u'pubsub': | 368 if uri_data[u"type"] != u"pubsub": |
318 raise ValueError(_(u'The given URI is not valid: {uri}').format(uri=uri)) | 369 raise ValueError( |
319 uri_service = jid.JID(uri_data[u'path']) | 370 _(u"The given URI is not valid: {uri}").format(uri=uri) |
320 uri_node = uri_data[u'node'] | 371 ) |
372 uri_service = jid.JID(uri_data[u"path"]) | |
373 uri_node = uri_data[u"node"] | |
321 | 374 |
322 elt = event_elt.addElement((NS_EVENT, uri_type)) | 375 elt = event_elt.addElement((NS_EVENT, uri_type)) |
323 elt['uri'] = xmpp_uri.buildXMPPUri('pubsub', path=uri_service.full(), node=uri_node) | 376 elt["uri"] = xmpp_uri.buildXMPPUri( |
377 "pubsub", path=uri_service.full(), node=uri_node | |
378 ) | |
324 | 379 |
325 # remaining data are put in <meta> elements | 380 # remaining data are put in <meta> elements |
326 for key in data.keys(): | 381 for key in data.keys(): |
327 elt = event_elt.addElement((NS_EVENT, 'meta'), content = data.pop(key)) | 382 elt = event_elt.addElement((NS_EVENT, "meta"), content=data.pop(key)) |
328 elt['name'] = key | 383 elt["name"] = key |
329 | 384 |
330 item_elt = pubsub.Item(id=event_id, payload=event_elt) | 385 item_elt = pubsub.Item(id=event_id, payload=event_elt) |
331 try: | 386 try: |
332 # TODO: check auto-create, no need to create node first if available | 387 # TODO: check auto-create, no need to create node first if available |
333 node = yield self._p.createNode(client, service, nodeIdentifier=node) | 388 node = yield self._p.createNode(client, service, nodeIdentifier=node) |
334 except error.StanzaError as e: | 389 except error.StanzaError as e: |
335 if e.condition == u'conflict': | 390 if e.condition == u"conflict": |
336 log.debug(_(u"requested node already exists")) | 391 log.debug(_(u"requested node already exists")) |
337 | 392 |
338 yield self._p.publish(client, service, node, items=[item_elt]) | 393 yield self._p.publish(client, service, node, items=[item_elt]) |
339 | 394 |
340 if register: | 395 if register: |
341 yield self.register(client, service, node, event_id, event_elt, creator=True) | 396 yield self.register(client, service, node, event_id, event_elt, creator=True) |
342 defer.returnValue(node) | 397 defer.returnValue(node) |
343 | 398 |
344 def _eventModify(self, service, node, id_, timestamp_update, data_update, profile_key=C.PROF_KEY_NONE): | 399 def _eventModify( |
400 self, | |
401 service, | |
402 node, | |
403 id_, | |
404 timestamp_update, | |
405 data_update, | |
406 profile_key=C.PROF_KEY_NONE, | |
407 ): | |
345 service = jid.JID(service) if service else None | 408 service = jid.JID(service) if service else None |
346 node = node if node else NS_EVENT | 409 node = node if node else NS_EVENT |
347 client = self.host.getClient(profile_key) | 410 client = self.host.getClient(profile_key) |
348 return self.eventModify(client, service, node, id_ or NS_EVENT, timestamp_update or None, data_update) | 411 return self.eventModify( |
349 | 412 client, service, node, id_ or NS_EVENT, timestamp_update or None, data_update |
350 @defer.inlineCallbacks | 413 ) |
351 def eventModify(self, client, service, node, id_=NS_EVENT, timestamp_update=None, data_update=None): | 414 |
415 @defer.inlineCallbacks | |
416 def eventModify( | |
417 self, client, service, node, id_=NS_EVENT, timestamp_update=None, data_update=None | |
418 ): | |
352 """Update an event | 419 """Update an event |
353 | 420 |
354 Similar as create instead that it update existing item instead of | 421 Similar as create instead that it update existing item instead of |
355 creating or replacing it. Params are the same as for [eventCreate]. | 422 creating or replacing it. Params are the same as for [eventCreate]. |
356 """ | 423 """ |
362 new_data[k] = v | 429 new_data[k] = v |
363 yield self.eventCreate(client, new_timestamp, new_data, service, node, id_) | 430 yield self.eventCreate(client, new_timestamp, new_data, service, node, id_) |
364 | 431 |
365 def _eventsListSerialise(self, events): | 432 def _eventsListSerialise(self, events): |
366 for timestamp, data in events: | 433 for timestamp, data in events: |
367 data['date'] = unicode(timestamp) | 434 data["date"] = unicode(timestamp) |
368 data['creator'] = C.boolConst(data.get('creator', False)) | 435 data["creator"] = C.boolConst(data.get("creator", False)) |
369 return [e[1] for e in events] | 436 return [e[1] for e in events] |
370 | 437 |
371 def _eventsList(self, service, node, profile): | 438 def _eventsList(self, service, node, profile): |
372 service = jid.JID(service) if service else None | 439 service = jid.JID(service) if service else None |
373 node = node or None | 440 node = node or None |
386 node = NS_EVENT_LIST | 453 node = NS_EVENT_LIST |
387 items = yield self._p.getItems(client, service, node) | 454 items = yield self._p.getItems(client, service, node) |
388 events = [] | 455 events = [] |
389 for item in items[0]: | 456 for item in items[0]: |
390 try: | 457 try: |
391 event_elt = next(item.elements(NS_EVENT, u'event')) | 458 event_elt = next(item.elements(NS_EVENT, u"event")) |
392 except IndexError: | 459 except IndexError: |
393 log.error(_(u"No event found in item {item_id}").format( | 460 log.error( |
394 item_id = item['id'])) | 461 _(u"No event found in item {item_id}").format(item_id=item["id"]) |
462 ) | |
395 timestamp, data = self._parseEventElt(event_elt) | 463 timestamp, data = self._parseEventElt(event_elt) |
396 events.append((timestamp, data)) | 464 events.append((timestamp, data)) |
397 defer.returnValue(events) | 465 defer.returnValue(events) |
398 | 466 |
399 def _eventInviteeGet(self, service, node, profile_key): | 467 def _eventInviteeGet(self, service, node, profile_key): |
409 @param service(unicode, None): PubSub service | 477 @param service(unicode, None): PubSub service |
410 @param node(unicode): PubSub node of the event | 478 @param node(unicode): PubSub node of the event |
411 @return (dict): a dict with current attendance status, | 479 @return (dict): a dict with current attendance status, |
412 an empty dict is returned if nothing has been answered yed | 480 an empty dict is returned if nothing has been answered yed |
413 """ | 481 """ |
414 items, metadata = yield self._p.getItems(client, service, node, item_ids=[client.jid.userhost()]) | 482 items, metadata = yield self._p.getItems( |
483 client, service, node, item_ids=[client.jid.userhost()] | |
484 ) | |
415 try: | 485 try: |
416 event_elt = next(items[0].elements(NS_EVENT, u'invitee')) | 486 event_elt = next(items[0].elements(NS_EVENT, u"invitee")) |
417 except IndexError: | 487 except IndexError: |
418 # no item found, event data are not set yet | 488 # no item found, event data are not set yet |
419 defer.returnValue({}) | 489 defer.returnValue({}) |
420 data = {} | 490 data = {} |
421 for key in (u'attend', u'guests'): | 491 for key in (u"attend", u"guests"): |
422 try: | 492 try: |
423 data[key] = event_elt[key] | 493 data[key] = event_elt[key] |
424 except KeyError: | 494 except KeyError: |
425 continue | 495 continue |
426 defer.returnValue(data) | 496 defer.returnValue(data) |
427 | 497 |
428 def _eventInviteeSet(self, service, node, event_data, profile_key): | 498 def _eventInviteeSet(self, service, node, event_data, profile_key): |
429 service = jid.JID(service) if service else None | 499 service = jid.JID(service) if service else None |
430 node = node if node else NS_EVENT | 500 node = node if node else NS_EVENT |
431 client = self.host.getClient(profile_key) | 501 client = self.host.getClient(profile_key) |
432 return self.eventInviteeSet(client, service, node, event_data) | 502 return self.eventInviteeSet(client, service, node, event_data) |
433 | 503 |
439 @param data(dict[unicode, unicode]): data to update | 509 @param data(dict[unicode, unicode]): data to update |
440 key can be: | 510 key can be: |
441 attend: one of "yes", "no", "maybe" | 511 attend: one of "yes", "no", "maybe" |
442 guests: an int | 512 guests: an int |
443 """ | 513 """ |
444 event_elt = domish.Element((NS_EVENT, 'invitee')) | 514 event_elt = domish.Element((NS_EVENT, "invitee")) |
445 for key in (u'attend', u'guests'): | 515 for key in (u"attend", u"guests"): |
446 try: | 516 try: |
447 event_elt[key] = data.pop(key) | 517 event_elt[key] = data.pop(key) |
448 except KeyError: | 518 except KeyError: |
449 pass | 519 pass |
450 item_elt = pubsub.Item(id=client.jid.userhost(), payload=event_elt) | 520 item_elt = pubsub.Item(id=client.jid.userhost(), payload=event_elt) |
467 """ | 537 """ |
468 items, metadata = yield self._p.getItems(client, service, node) | 538 items, metadata = yield self._p.getItems(client, service, node) |
469 invitees = {} | 539 invitees = {} |
470 for item in items: | 540 for item in items: |
471 try: | 541 try: |
472 event_elt = next(item.elements(NS_EVENT, u'invitee')) | 542 event_elt = next(item.elements(NS_EVENT, u"invitee")) |
473 except StopIteration: | 543 except StopIteration: |
474 # no item found, event data are not set yet | 544 # no item found, event data are not set yet |
475 log.warning(_(u"no data found for {item_id} (service: {service}, node: {node})".format( | 545 log.warning( |
476 item_id=item['id'], | 546 _( |
477 service=service, | 547 u"no data found for {item_id} (service: {service}, node: {node})".format( |
478 node=node | 548 item_id=item["id"], service=service, node=node |
479 ))) | 549 ) |
550 ) | |
551 ) | |
480 else: | 552 else: |
481 data = {} | 553 data = {} |
482 for key in (u'attend', u'guests'): | 554 for key in (u"attend", u"guests"): |
483 try: | 555 try: |
484 data[key] = event_elt[key] | 556 data[key] = event_elt[key] |
485 except KeyError: | 557 except KeyError: |
486 continue | 558 continue |
487 invitees[item['id']] = data | 559 invitees[item["id"]] = data |
488 defer.returnValue(invitees) | 560 defer.returnValue(invitees) |
489 | 561 |
490 def sendMessageInvitation(self, client, invitee_jid, service, node, item_id): | 562 def sendMessageInvitation(self, client, invitee_jid, service, node, item_id): |
491 """Send an invitation in a <message> stanza | 563 """Send an invitation in a <message> stanza |
492 | 564 |
494 @param service(jid.JID): pubsub service of the event | 566 @param service(jid.JID): pubsub service of the event |
495 @param node(unicode): node of the event | 567 @param node(unicode): node of the event |
496 @param item_id(unicode): id of the event | 568 @param item_id(unicode): id of the event |
497 """ | 569 """ |
498 mess_data = { | 570 mess_data = { |
499 'from': client.jid, | 571 "from": client.jid, |
500 'to': invitee_jid, | 572 "to": invitee_jid, |
501 'uid': '', | 573 "uid": "", |
502 'message': {}, | 574 "message": {}, |
503 'type': C.MESS_TYPE_CHAT, | 575 "type": C.MESS_TYPE_CHAT, |
504 'subject': {}, | 576 "subject": {}, |
505 'extra': {}, | 577 "extra": {}, |
506 } | 578 } |
507 client.generateMessageXML(mess_data) | 579 client.generateMessageXML(mess_data) |
508 event_elt = mess_data['xml'].addElement('invitation', NS_EVENT_INVIT) | 580 event_elt = mess_data["xml"].addElement("invitation", NS_EVENT_INVIT) |
509 event_elt['service'] = service.full() | 581 event_elt["service"] = service.full() |
510 event_elt['node'] = node | 582 event_elt["node"] = node |
511 event_elt['item'] = item_id | 583 event_elt["item"] = item_id |
512 client.send(mess_data['xml']) | 584 client.send(mess_data["xml"]) |
513 | 585 |
514 def _invite(self, invitee_jid, service, node, item_id, profile): | 586 def _invite(self, invitee_jid, service, node, item_id, profile): |
515 client = self.host.getClient(profile) | 587 client = self.host.getClient(profile) |
516 service = jid.JID(service) if service else None | 588 service = jid.JID(service) if service else None |
517 node = node or None | 589 node = node or None |
529 None to use client's PEP | 601 None to use client's PEP |
530 @param node(unicode): event node | 602 @param node(unicode): event node |
531 @param item_id(unicode): event id | 603 @param item_id(unicode): event id |
532 """ | 604 """ |
533 if self._b is None: | 605 if self._b is None: |
534 raise exceptions.FeatureNotFound(_(u'"XEP-0277" (blog) plugin is needed for this feature')) | 606 raise exceptions.FeatureNotFound( |
607 _(u'"XEP-0277" (blog) plugin is needed for this feature') | |
608 ) | |
535 if item_id is None: | 609 if item_id is None: |
536 item_id = NS_EVENT | 610 item_id = NS_EVENT |
537 | 611 |
538 # first we authorize our invitee to see the nodes of interest | 612 # first we authorize our invitee to see the nodes of interest |
539 yield self._p.setNodeAffiliations(client, service, node, {invitee_jid: u'member'}) | 613 yield self._p.setNodeAffiliations(client, service, node, {invitee_jid: u"member"}) |
540 log.debug(_(u'affiliation set on event node')) | 614 log.debug(_(u"affiliation set on event node")) |
541 dummy, event_data = yield self.eventGet(client, service, node, item_id) | 615 dummy, event_data = yield self.eventGet(client, service, node, item_id) |
542 log.debug(_(u'got event data')) | 616 log.debug(_(u"got event data")) |
543 invitees_service = jid.JID(event_data['invitees_service']) | 617 invitees_service = jid.JID(event_data["invitees_service"]) |
544 invitees_node = event_data['invitees_node'] | 618 invitees_node = event_data["invitees_node"] |
545 blog_service = jid.JID(event_data['blog_service']) | 619 blog_service = jid.JID(event_data["blog_service"]) |
546 blog_node = event_data['blog_node'] | 620 blog_node = event_data["blog_node"] |
547 yield self._p.setNodeAffiliations(client, invitees_service, invitees_node, {invitee_jid: u'publisher'}) | 621 yield self._p.setNodeAffiliations( |
548 log.debug(_(u'affiliation set on invitee node')) | 622 client, invitees_service, invitees_node, {invitee_jid: u"publisher"} |
549 yield self._p.setNodeAffiliations(client, blog_service, blog_node, {invitee_jid: u'member'}) | 623 ) |
624 log.debug(_(u"affiliation set on invitee node")) | |
625 yield self._p.setNodeAffiliations( | |
626 client, blog_service, blog_node, {invitee_jid: u"member"} | |
627 ) | |
550 blog_items, dummy = yield self._b.mbGet(client, blog_service, blog_node, None) | 628 blog_items, dummy = yield self._b.mbGet(client, blog_service, blog_node, None) |
551 | 629 |
552 for item in blog_items: | 630 for item in blog_items: |
553 try: | 631 try: |
554 comments_service = jid.JID(item['comments_service']) | 632 comments_service = jid.JID(item["comments_service"]) |
555 comments_node = item['comments_node'] | 633 comments_node = item["comments_node"] |
556 except KeyError: | 634 except KeyError: |
557 log.debug(u"no comment service set for itemĀ {item_id}".format(item_id=item['id'])) | 635 log.debug( |
636 u"no comment service set for itemĀ {item_id}".format( | |
637 item_id=item["id"] | |
638 ) | |
639 ) | |
558 else: | 640 else: |
559 yield self._p.setNodeAffiliations(client, comments_service, comments_node, {invitee_jid: u'publisher'}) | 641 yield self._p.setNodeAffiliations( |
560 log.debug(_(u'affiliation set on blog and comments nodes')) | 642 client, comments_service, comments_node, {invitee_jid: u"publisher"} |
643 ) | |
644 log.debug(_(u"affiliation set on blog and comments nodes")) | |
561 | 645 |
562 # now we send the invitation | 646 # now we send the invitation |
563 self.sendMessageInvitation(client, invitee_jid, service, node, item_id) | 647 self.sendMessageInvitation(client, invitee_jid, service, node, item_id) |
564 | 648 |
565 def _inviteByEmail(self, service, node, id_=NS_EVENT, email=u'', emails_extra=None, name=u'', host_name=u'', language=u'', url_template=u'', | 649 def _inviteByEmail( |
566 message_subject=u'', message_body=u'', profile_key=C.PROF_KEY_NONE): | 650 self, |
651 service, | |
652 node, | |
653 id_=NS_EVENT, | |
654 email=u"", | |
655 emails_extra=None, | |
656 name=u"", | |
657 host_name=u"", | |
658 language=u"", | |
659 url_template=u"", | |
660 message_subject=u"", | |
661 message_body=u"", | |
662 profile_key=C.PROF_KEY_NONE, | |
663 ): | |
567 client = self.host.getClient(profile_key) | 664 client = self.host.getClient(profile_key) |
568 kwargs = {u'profile': client.profile, | 665 kwargs = { |
569 u'emails_extra': [unicode(e) for e in emails_extra] | 666 u"profile": client.profile, |
570 } | 667 u"emails_extra": [unicode(e) for e in emails_extra], |
571 for key in ("email", "name", "host_name", "language", "url_template", "message_subject", "message_body"): | 668 } |
669 for key in ( | |
670 "email", | |
671 "name", | |
672 "host_name", | |
673 "language", | |
674 "url_template", | |
675 "message_subject", | |
676 "message_body", | |
677 ): | |
572 value = locals()[key] | 678 value = locals()[key] |
573 kwargs[key] = unicode(value) | 679 kwargs[key] = unicode(value) |
574 return self.inviteByEmail(client, | 680 return self.inviteByEmail( |
575 jid.JID(service) if service else None, | 681 client, jid.JID(service) if service else None, node, id_ or NS_EVENT, **kwargs |
576 node, | 682 ) |
577 id_ or NS_EVENT, | |
578 **kwargs) | |
579 | 683 |
580 @defer.inlineCallbacks | 684 @defer.inlineCallbacks |
581 def inviteByEmail(self, client, service, node, id_=NS_EVENT, **kwargs): | 685 def inviteByEmail(self, client, service, node, id_=NS_EVENT, **kwargs): |
582 """High level method to create an email invitation to an event | 686 """High level method to create an email invitation to an event |
583 | 687 |
584 @param service(unicode, None): PubSub service | 688 @param service(unicode, None): PubSub service |
585 @param node(unicode): PubSub node of the event | 689 @param node(unicode): PubSub node of the event |
586 @param id_(unicode): id_ with even data | 690 @param id_(unicode): id_ with even data |
587 """ | 691 """ |
588 if self._i is None: | 692 if self._i is None: |
589 raise exceptions.FeatureNotFound(_(u'"Invitations" plugin is needed for this feature')) | 693 raise exceptions.FeatureNotFound( |
694 _(u'"Invitations" plugin is needed for this feature') | |
695 ) | |
590 if self._b is None: | 696 if self._b is None: |
591 raise exceptions.FeatureNotFound(_(u'"XEP-0277" (blog) plugin is needed for this feature')) | 697 raise exceptions.FeatureNotFound( |
698 _(u'"XEP-0277" (blog) plugin is needed for this feature') | |
699 ) | |
592 service = service or client.jid.userhostJID() | 700 service = service or client.jid.userhostJID() |
593 event_uri = xmpp_uri.buildXMPPUri('pubsub', | 701 event_uri = xmpp_uri.buildXMPPUri( |
594 path=service.full(), | 702 "pubsub", path=service.full(), node=node, item=id_ |
595 node=node, | 703 ) |
596 item=id_) | 704 kwargs["extra"] = {u"event_uri": event_uri} |
597 kwargs['extra'] = {u'event_uri': event_uri} | |
598 invitation_data = yield self._i.create(**kwargs) | 705 invitation_data = yield self._i.create(**kwargs) |
599 invitee_jid = invitation_data[u'jid'] | 706 invitee_jid = invitation_data[u"jid"] |
600 log.debug(_(u'invitation created')) | 707 log.debug(_(u"invitation created")) |
601 # now that we have a jid, we can send normal invitation | 708 # now that we have a jid, we can send normal invitation |
602 yield self.invite(client, invitee_jid, service, node, id_) | 709 yield self.invite(client, invitee_jid, service, node, id_) |
603 | 710 |
604 @defer.inlineCallbacks | 711 @defer.inlineCallbacks |
605 def onInvitation(self, message_elt, client): | 712 def onInvitation(self, message_elt, client): |
606 invitation_elt = message_elt.invitation | 713 invitation_elt = message_elt.invitation |
607 try: | 714 try: |
608 service = jid.JID(invitation_elt['service']) | 715 service = jid.JID(invitation_elt["service"]) |
609 node = invitation_elt['node'] | 716 node = invitation_elt["node"] |
610 event_id = invitation_elt['item'] | 717 event_id = invitation_elt["item"] |
611 except (RuntimeError, KeyError): | 718 except (RuntimeError, KeyError): |
612 log.warning(_(u"Bad invitation: {xml}").format(xml=message_elt.toXml())) | 719 log.warning(_(u"Bad invitation: {xml}").format(xml=message_elt.toXml())) |
613 | 720 |
614 event_elt = yield self.getEventElement(client, service, node, event_id) | 721 event_elt = yield self.getEventElement(client, service, node, event_id) |
615 yield self.register(client, service, node, event_id, event_elt, creator=False) | 722 yield self.register(client, service, node, event_id, event_elt, creator=False) |
624 @property | 731 @property |
625 def host(self): | 732 def host(self): |
626 return self.plugin_parent.host | 733 return self.plugin_parent.host |
627 | 734 |
628 def connectionInitialized(self): | 735 def connectionInitialized(self): |
629 self.xmlstream.addObserver(INVITATION, | 736 self.xmlstream.addObserver( |
630 self.plugin_parent.onInvitation, | 737 INVITATION, self.plugin_parent.onInvitation, client=self.parent |
631 client=self.parent) | 738 ) |
632 | 739 |
633 def getDiscoInfo(self, requestor, target, nodeIdentifier=''): | 740 def getDiscoInfo(self, requestor, target, nodeIdentifier=""): |
634 return [disco.DiscoFeature(NS_EVENT), | 741 return [ |
635 disco.DiscoFeature(NS_EVENT_LIST), | 742 disco.DiscoFeature(NS_EVENT), |
636 disco.DiscoFeature(NS_EVENT_INVIT)] | 743 disco.DiscoFeature(NS_EVENT_LIST), |
637 | 744 disco.DiscoFeature(NS_EVENT_INVIT), |
638 def getDiscoItems(self, requestor, target, nodeIdentifier=''): | 745 ] |
746 | |
747 def getDiscoItems(self, requestor, target, nodeIdentifier=""): | |
639 return [] | 748 return [] |