summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/api/plugins/xep_0231.rst34
-rw-r--r--itests/test_bob.py2
-rw-r--r--slixmpp/plugins/xep_0231/bob.py50
3 files changed, 64 insertions, 22 deletions
diff --git a/docs/api/plugins/xep_0231.rst b/docs/api/plugins/xep_0231.rst
index 29f403ca..bed0e4bb 100644
--- a/docs/api/plugins/xep_0231.rst
+++ b/docs/api/plugins/xep_0231.rst
@@ -9,6 +9,40 @@ XEP-0231: Bits of Binary
:exclude-members: session_bind, plugin_init, plugin_end
+Internal API methods
+--------------------
+
+The default API handlers for this plugin manage an in-memory cache of
+bits of binary by content-id.
+
+.. glossary::
+
+ set_bob
+ - **jid**: :class:`~.JID` sending the bob
+ - **node**: unused
+ - **ifrom**: :class:`~JID` receiving the bob
+ - **args**: :class:`~.BitsOfBinary` element.
+
+ Set a BoB in the cache.
+
+ get_bob
+ - **jid**: :class:`~.JID` receiving the bob
+ - **node**: unused
+ - **ifrom**: :class:`~JID` sending the bob
+ - **args**: ``str`` content-id of the bob
+ - **returns**: :class:`~.BitsOfBinary` element.
+
+ Get a BoB from the cache.
+
+ del_bob
+ - **jid**: unused
+ - **node**: unused
+ - **ifrom**: :class:`~JID` sending the bob
+ - **args**: ``str`` content-id of the bob
+
+ Delete a BoB from the cache.
+
+
Stanza elements
---------------
diff --git a/itests/test_bob.py b/itests/test_bob.py
index d0827df0..5c95bc89 100644
--- a/itests/test_bob.py
+++ b/itests/test_bob.py
@@ -20,7 +20,7 @@ class TestBOB(SlixIntegration):
async def test_bob(self):
"""Check we can send and receive a BOB."""
- cid = self.clients[0]['xep_0231'].set_bob(
+ cid = await self.clients[0]['xep_0231'].set_bob(
self.data,
'image/jpeg',
)
diff --git a/slixmpp/plugins/xep_0231/bob.py b/slixmpp/plugins/xep_0231/bob.py
index e554c38c..129aca56 100644
--- a/slixmpp/plugins/xep_0231/bob.py
+++ b/slixmpp/plugins/xep_0231/bob.py
@@ -12,7 +12,7 @@ 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
+from slixmpp.xmlstream.handler import CoroutineCallback
from slixmpp.xmlstream.matcher import StanzaPath
from slixmpp.xmlstream import register_stanza_plugin
from slixmpp.plugins.base import BasePlugin
@@ -40,17 +40,17 @@ class XEP_0231(BasePlugin):
register_stanza_plugin(Presence, BitsOfBinary)
self.xmpp.register_handler(
- Callback('Bits of Binary - Iq',
+ CoroutineCallback('Bits of Binary - Iq',
StanzaPath('iq/bob'),
self._handle_bob_iq))
self.xmpp.register_handler(
- Callback('Bits of Binary - Message',
+ CoroutineCallback('Bits of Binary - Message',
StanzaPath('message/bob'),
self._handle_bob))
self.xmpp.register_handler(
- Callback('Bits of Binary - Presence',
+ CoroutineCallback('Bits of Binary - Presence',
StanzaPath('presence/bob'),
self._handle_bob))
@@ -67,13 +67,14 @@ class XEP_0231(BasePlugin):
def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature('urn:xmpp:bob')
- def set_bob(self, data: bytes, mtype: str, cid: Optional[str] = None,
- max_age: Optional[int] = None) -> str:
+ async 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.
+ This function is now a coroutine.
:param data: Data to register.
:param mtype: Mime Type of the data (e.g. ``image/jpeg``).
@@ -90,27 +91,27 @@ class XEP_0231(BasePlugin):
bob['cid'] = cid
bob['max_age'] = max_age
- self.api['set_bob'](args=bob)
+ await 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: Optional[JID] = None, cid: Optional[str] = None,
- cached: bool = True, ifrom: Optional[JID] = None,
- **iqkwargs) -> Future:
+ async def get_bob(self, jid: Optional[JID] = None, cid: Optional[str] = None,
+ cached: bool = True, ifrom: Optional[JID] = None,
+ **iqkwargs) -> Iq:
"""Get a BOB.
.. versionchanged:: 1.8.0
Results not in cache do not raise an error when ``cached`` is True.
+ This function is now a coroutine.
: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)
+ data = await self.api['get_bob'](None, None, ifrom, args=cid)
if data is not None:
if not isinstance(data, Iq):
iq = self.xmpp.Iq()
@@ -120,19 +121,24 @@ class XEP_0231(BasePlugin):
iq = self.xmpp.make_iq_get(ito=jid, ifrom=ifrom)
iq['bob']['cid'] = cid
- return iq.send(**iqkwargs)
+ return await iq.send(**iqkwargs)
- def del_bob(self, cid: str):
- self.api['del_bob'](args=cid)
+ def del_bob(self, cid: str) -> Future:
+ """Delete a stored BoB.
- def _handle_bob_iq(self, iq: Iq):
+ .. versionchanged:: 1.8.0
+ This function now returns a Future.
+ """
+ return self.api['del_bob'](args=cid)
+
+ async def _handle_bob_iq(self, iq: Iq):
cid = iq['bob']['cid']
if iq['type'] == 'result':
- self.api['set_bob'](iq['from'], None, iq['to'], args=iq['bob'])
+ await self.api['set_bob'](iq['from'], None, iq['to'], args=iq['bob'])
self.xmpp.event('bob', iq)
elif iq['type'] == 'get':
- data = self.api['get_bob'](iq['to'], None, iq['from'], args=cid)
+ data = await self.api['get_bob'](iq['to'], None, iq['from'], args=cid)
if isinstance(data, Iq):
data['id'] = iq['id']
data.send()
@@ -142,9 +148,11 @@ class XEP_0231(BasePlugin):
iq.append(data)
iq.send()
- def _handle_bob(self, stanza):
- self.api['set_bob'](stanza['from'], None,
- stanza['to'], args=stanza['bob'])
+ async def _handle_bob(self, stanza):
+ await self.api['set_bob'](
+ stanza['from'], None,
+ stanza['to'], args=stanza['bob']
+ )
self.xmpp.event('bob', stanza)
# =================================================================