XEP-0231: API changes
- ``get_bob`` and ``set_bob`` are now coroutines. - ``del_bob`` returns a Future.
This commit is contained in:
parent
ab87b25030
commit
9947d3db85
3 changed files with 64 additions and 22 deletions
|
@ -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
|
||||
---------------
|
||||
|
||||
|
|
|
@ -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',
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
||||
# =================================================================
|
||||
|
|
Loading…
Reference in a new issue