Mercurial > libervia-backend
comparison sat/plugins/plugin_xep_0470.py @ 3956:3cb9ade2ab84
plugin pubsub signing: pubsub items signature implementation:
- this is based on a protoXEP, not yet an official XEP: https://github.com/xsf/xeps/pull/1228
- XEP-0470: `set` attachment handler can now be async
rel 381
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 28 Oct 2022 18:47:17 +0200 |
parents | 2b2856ae5eeb |
children | 722c25818778 |
comparison
equal
deleted
inserted
replaced
3955:323017a4e4d2 | 3956:3cb9ade2ab84 |
---|---|
28 from sat.core.i18n import _ | 28 from sat.core.i18n import _ |
29 from sat.core.log import getLogger | 29 from sat.core.log import getLogger |
30 from sat.core.core_types import SatXMPPEntity | 30 from sat.core.core_types import SatXMPPEntity |
31 from sat.core import exceptions | 31 from sat.core import exceptions |
32 from sat.tools.common import uri, data_format, date_utils | 32 from sat.tools.common import uri, data_format, date_utils |
33 from sat.tools.utils import xmpp_date | 33 from sat.tools.utils import asDeferred, xmpp_date |
34 | 34 |
35 | 35 |
36 log = getLogger(__name__) | 36 log = getLogger(__name__) |
37 | 37 |
38 IMPORT_NAME = "XEP-0470" | 38 IMPORT_NAME = "XEP-0470" |
61 host.registerNamespace("pubsub-attachments", NS_PUBSUB_ATTACHMENTS) | 61 host.registerNamespace("pubsub-attachments", NS_PUBSUB_ATTACHMENTS) |
62 self.host = host | 62 self.host = host |
63 self._p = host.plugins["XEP-0060"] | 63 self._p = host.plugins["XEP-0060"] |
64 self.handlers: Dict[Tuple[str, str], dict[str, Any]] = {} | 64 self.handlers: Dict[Tuple[str, str], dict[str, Any]] = {} |
65 host.trigger.add("XEP-0277_send", self.onMBSend) | 65 host.trigger.add("XEP-0277_send", self.onMBSend) |
66 self.registerAttachmentHandler( | 66 self.register_attachment_handler( |
67 "noticed", NS_PUBSUB_ATTACHMENTS, self.noticedGet, self.noticedSet | 67 "noticed", NS_PUBSUB_ATTACHMENTS, self.noticedGet, self.noticedSet |
68 ) | 68 ) |
69 self.registerAttachmentHandler( | 69 self.register_attachment_handler( |
70 "reactions", NS_PUBSUB_ATTACHMENTS, self.reactionsGet, self.reactionsSet | 70 "reactions", NS_PUBSUB_ATTACHMENTS, self.reactionsGet, self.reactionsSet |
71 ) | 71 ) |
72 host.bridge.addMethod( | 72 host.bridge.addMethod( |
73 "psAttachmentsGet", | 73 "psAttachmentsGet", |
74 ".plugin", | 74 ".plugin", |
87 ) | 87 ) |
88 | 88 |
89 def getHandler(self, client): | 89 def getHandler(self, client): |
90 return PubsubAttachments_Handler() | 90 return PubsubAttachments_Handler() |
91 | 91 |
92 def registerAttachmentHandler( | 92 def register_attachment_handler( |
93 self, | 93 self, |
94 name: str, | 94 name: str, |
95 namespace: str, | 95 namespace: str, |
96 get_cb: Callable[ | 96 get_cb: Callable[ |
97 [SatXMPPEntity, domish.Element, Dict[str, Any]], | 97 [SatXMPPEntity, domish.Element, Dict[str, Any]], |
111 parsed data | 111 parsed data |
112 @param set: method to call when the attachment need to be set or udpated | 112 @param set: method to call when the attachment need to be set or udpated |
113 it will be called with (client, data, former_elt of None if there was no | 113 it will be called with (client, data, former_elt of None if there was no |
114 former element). When suitable, ``operation`` should be used to check if we | 114 former element). When suitable, ``operation`` should be used to check if we |
115 request an ``update`` or a ``replace``. | 115 request an ``update`` or a ``replace``. |
116 The callback can be either a blocking method, a Deferred or a coroutine | |
116 """ | 117 """ |
117 key = (name, namespace) | 118 key = (name, namespace) |
118 if key in self.handlers: | 119 if key in self.handlers: |
119 raise exceptions.ConflictError( | 120 raise exceptions.ConflictError( |
120 f"({name}, {namespace}) attachment handlers are already registered" | 121 f"({name}, {namespace}) attachment handlers are already registered" |
297 @param extra: extra data, will be used as ``extra`` argument when doing | 298 @param extra: extra data, will be used as ``extra`` argument when doing |
298 ``getItems`` call. | 299 ``getItems`` call. |
299 @return: A tuple with: | 300 @return: A tuple with: |
300 - the list of attachments data, one item per found sender. The attachments | 301 - the list of attachments data, one item per found sender. The attachments |
301 data are dict containing attachment, no ``extra`` field is used here | 302 data are dict containing attachment, no ``extra`` field is used here |
302 (contrarily to attachments data used with ``setAttachments``). | 303 (contrarily to attachments data used with ``set_attachements``). |
303 - metadata returned by the call to ``getItems`` | 304 - metadata returned by the call to ``getItems`` |
304 """ | 305 """ |
305 if extra is None: | 306 if extra is None: |
306 extra = {} | 307 extra = {} |
307 attachment_node = self.getAttachmentNodeName(service, node, item) | 308 attachment_node = self.getAttachmentNodeName(service, node, item) |
318 attachments_s: str, | 319 attachments_s: str, |
319 profile_key: str | 320 profile_key: str |
320 ) -> None: | 321 ) -> None: |
321 client = self.host.getClient(profile_key) | 322 client = self.host.getClient(profile_key) |
322 attachments = data_format.deserialise(attachments_s) or {} | 323 attachments = data_format.deserialise(attachments_s) or {} |
323 return defer.ensureDeferred(self.setAttachments(client, attachments)) | 324 return defer.ensureDeferred(self.set_attachements(client, attachments)) |
324 | 325 |
325 def applySetHandler( | 326 async def apply_set_handler( |
326 self, | 327 self, |
327 client: SatXMPPEntity, | 328 client: SatXMPPEntity, |
328 attachments_data: dict, | 329 attachments_data: dict, |
329 item_elt: Optional[domish.Element], | 330 item_elt: Optional[domish.Element], |
330 handlers: Optional[List[Tuple[str, str]]] = None, | 331 handlers: Optional[List[Tuple[str, str]]] = None, |
373 continue | 374 continue |
374 try: | 375 try: |
375 former_elt = next(attachments_elt.elements(namespace, name)) | 376 former_elt = next(attachments_elt.elements(namespace, name)) |
376 except StopIteration: | 377 except StopIteration: |
377 former_elt = None | 378 former_elt = None |
378 new_elt = handler["set"](client, attachments_data, former_elt) | 379 new_elt = await asDeferred( |
380 handler["set"], client, attachments_data, former_elt | |
381 ) | |
379 if new_elt != former_elt: | 382 if new_elt != former_elt: |
380 if former_elt is not None: | 383 if former_elt is not None: |
381 attachments_elt.children.remove(former_elt) | 384 attachments_elt.children.remove(former_elt) |
382 if new_elt is not None: | 385 if new_elt is not None: |
383 attachments_elt.addChild(new_elt) | 386 attachments_elt.addChild(new_elt) |
384 return item_elt | 387 return item_elt |
385 | 388 |
386 async def setAttachments( | 389 async def set_attachements( |
387 self, | 390 self, |
388 client: SatXMPPEntity, | 391 client: SatXMPPEntity, |
389 attachments_data: Dict[str, Any] | 392 attachments_data: Dict[str, Any] |
390 ) -> None: | 393 ) -> None: |
391 """Set or update attachments | 394 """Set or update attachments |
423 if not items: | 426 if not items: |
424 item_elt = None | 427 item_elt = None |
425 else: | 428 else: |
426 item_elt = items[0] | 429 item_elt = items[0] |
427 | 430 |
428 item_elt = self.applySetHandler( | 431 item_elt = await self.apply_set_handler( |
429 client, | 432 client, |
430 attachments_data, | 433 attachments_data, |
431 item_elt=item_elt, | 434 item_elt=item_elt, |
432 ) | 435 ) |
433 | 436 |