From 02262679e9ae6d4553b9c8bca3f7a59a99232c50 Mon Sep 17 00:00:00 2001 From: mathieui Date: Sat, 13 Feb 2021 17:40:06 +0100 Subject: XEP-0231: Add typing, docs, and new-style kwargs Also add content deletion scheduling if specified. --- slixmpp/plugins/xep_0231/bob.py | 51 ++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/slixmpp/plugins/xep_0231/bob.py b/slixmpp/plugins/xep_0231/bob.py index b7e990b3..e554c38c 100644 --- a/slixmpp/plugins/xep_0231/bob.py +++ b/slixmpp/plugins/xep_0231/bob.py @@ -1,4 +1,3 @@ - # Slixmpp: The Slick XMPP Library # Copyright (C) 2012 Nathanael C. Fritz, # Emmanuel Gil Peyrot @@ -7,7 +6,10 @@ import logging import hashlib -from slixmpp import future_wrapper +from asyncio import Future +from typing import Optional + +from slixmpp import future_wrapper, JID from slixmpp.stanza import Iq, Message, Presence from slixmpp.exceptions import XMPPError from slixmpp.xmlstream.handler import Callback @@ -65,7 +67,20 @@ class XEP_0231(BasePlugin): def session_bind(self, jid): self.xmpp['xep_0030'].add_feature('urn:xmpp:bob') - def set_bob(self, data, mtype, cid=None, max_age=None): + def set_bob(self, data: bytes, mtype: str, cid: Optional[str] = None, + max_age: Optional[int] = None) -> str: + """Register a blob of binary data as a BOB. + + .. versionchanged:: 1.8.0 + If ``max_age`` is specified, the registered data will be destroyed + after that time. + + :param data: Data to register. + :param mtype: Mime Type of the data (e.g. ``image/jpeg``). + :param cid: Content-ID (will be auto-generated if left out). + :param max_age: Duration of content availability. + :returns: The cid value. + """ if cid is None: cid = 'sha1+%s@bob.xmpp.org' % hashlib.sha1(data).hexdigest() @@ -76,12 +91,24 @@ class XEP_0231(BasePlugin): bob['max_age'] = max_age self.api['set_bob'](args=bob) - + # Schedule destruction of the data + if max_age is not None and max_age > 0: + self.xmpp.loop.call_later(max_age, self.del_bob, cid) return cid @future_wrapper - def get_bob(self, jid=None, cid=None, cached=True, ifrom=None, - timeout=None, callback=None): + def get_bob(self, jid: Optional[JID] = None, cid: Optional[str] = None, + cached: bool = True, ifrom: Optional[JID] = None, + **iqkwargs) -> Future: + """Get a BOB. + + .. versionchanged:: 1.8.0 + Results not in cache do not raise an error when ``cached`` is True. + + :param jid: JID to fetch the BOB from. + :param cid: Content ID (actually required). + :param cached: To fetch the BOB from the local cache first (from CID only) + """ if cached: data = self.api['get_bob'](None, None, ifrom, args=cid) if data is not None: @@ -91,17 +118,14 @@ class XEP_0231(BasePlugin): return iq return data - iq = self.xmpp.Iq() - iq['to'] = jid - iq['from'] = ifrom - iq['type'] = 'get' + iq = self.xmpp.make_iq_get(ito=jid, ifrom=ifrom) iq['bob']['cid'] = cid - return iq.send(timeout=timeout, callback=callback) + return iq.send(**iqkwargs) - def del_bob(self, cid): + def del_bob(self, cid: str): self.api['del_bob'](args=cid) - def _handle_bob_iq(self, iq): + def _handle_bob_iq(self, iq: Iq): cid = iq['bob']['cid'] if iq['type'] == 'result': @@ -131,7 +155,6 @@ class XEP_0231(BasePlugin): def _get_bob(self, jid, node, ifrom, cid): if cid in self._cids: return self._cids[cid] - raise XMPPError('item-not-found') def _del_bob(self, jid, node, ifrom, cid): if cid in self._cids: -- cgit v1.2.3