XEP-0231: Add typing, docs, and new-style kwargs

Also add content deletion scheduling if specified.
This commit is contained in:
mathieui 2021-02-13 17:40:06 +01:00
parent 654178b960
commit 02262679e9

View File

@ -1,4 +1,3 @@
# Slixmpp: The Slick XMPP Library # Slixmpp: The Slick XMPP Library
# Copyright (C) 2012 Nathanael C. Fritz, # Copyright (C) 2012 Nathanael C. Fritz,
# Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> # Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
@ -7,7 +6,10 @@
import logging import logging
import hashlib 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.stanza import Iq, Message, Presence
from slixmpp.exceptions import XMPPError from slixmpp.exceptions import XMPPError
from slixmpp.xmlstream.handler import Callback from slixmpp.xmlstream.handler import Callback
@ -65,7 +67,20 @@ class XEP_0231(BasePlugin):
def session_bind(self, jid): def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature('urn:xmpp:bob') 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: if cid is None:
cid = 'sha1+%s@bob.xmpp.org' % hashlib.sha1(data).hexdigest() cid = 'sha1+%s@bob.xmpp.org' % hashlib.sha1(data).hexdigest()
@ -76,12 +91,24 @@ class XEP_0231(BasePlugin):
bob['max_age'] = max_age bob['max_age'] = max_age
self.api['set_bob'](args=bob) 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 return cid
@future_wrapper @future_wrapper
def get_bob(self, jid=None, cid=None, cached=True, ifrom=None, def get_bob(self, jid: Optional[JID] = None, cid: Optional[str] = None,
timeout=None, callback=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: if cached:
data = self.api['get_bob'](None, None, ifrom, args=cid) data = self.api['get_bob'](None, None, ifrom, args=cid)
if data is not None: if data is not None:
@ -91,17 +118,14 @@ class XEP_0231(BasePlugin):
return iq return iq
return data return data
iq = self.xmpp.Iq() iq = self.xmpp.make_iq_get(ito=jid, ifrom=ifrom)
iq['to'] = jid
iq['from'] = ifrom
iq['type'] = 'get'
iq['bob']['cid'] = cid 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) self.api['del_bob'](args=cid)
def _handle_bob_iq(self, iq): def _handle_bob_iq(self, iq: Iq):
cid = iq['bob']['cid'] cid = iq['bob']['cid']
if iq['type'] == 'result': if iq['type'] == 'result':
@ -131,7 +155,6 @@ class XEP_0231(BasePlugin):
def _get_bob(self, jid, node, ifrom, cid): def _get_bob(self, jid, node, ifrom, cid):
if cid in self._cids: if cid in self._cids:
return self._cids[cid] return self._cids[cid]
raise XMPPError('item-not-found')
def _del_bob(self, jid, node, ifrom, cid): def _del_bob(self, jid, node, ifrom, cid):
if cid in self._cids: if cid in self._cids: