XEP-0441: Split MAM preferences into a separate plugin

This commit is contained in:
mathieui 2021-03-08 22:01:16 +01:00
parent e5f4794a36
commit 7d2b245bb0
10 changed files with 204 additions and 84 deletions

View file

@ -92,6 +92,5 @@ Plugin index
xep_0428
xep_0437
xep_0439
xep_0441
xep_0444

View file

@ -0,0 +1,18 @@
XEP-0441: Message Archive Management Preferences
================================================
.. module:: slixmpp.plugins.xep_0441
.. autoclass:: XEP_0441
:members:
:exclude-members: session_bind, plugin_init, plugin_end
Stanza elements
---------------
.. automodule:: slixmpp.plugins.xep_0441.stanza
:members:
:undoc-members:

View file

@ -110,5 +110,6 @@ __all__ = [
'xep_0428', # Message Fallback
'xep_0437', # Room Activity Indicators
'xep_0439', # Quick Response
'xep_0441', # Message Archive Management Preferences
'xep_0444', # Message Reactions
]

View file

@ -5,8 +5,10 @@
# See the file LICENSE for copying permissio
from slixmpp.plugins.base import register_plugin
from slixmpp.plugins.xep_0313.stanza import Result, MAM, Preferences
from slixmpp.plugins.xep_0313.stanza import Result, MAM
from slixmpp.plugins.xep_0313.mam import XEP_0313
register_plugin(XEP_0313)
__all__ = ['XEP_0313', 'Result', 'MAM']

View file

@ -37,7 +37,6 @@ class XEP_0313(BasePlugin):
def plugin_init(self):
register_stanza_plugin(stanza.MAM, Form)
register_stanza_plugin(Iq, stanza.MAM)
register_stanza_plugin(Iq, stanza.Preferences)
register_stanza_plugin(Message, stanza.Result)
register_stanza_plugin(Iq, stanza.Fin)
register_stanza_plugin(

View file

@ -169,86 +169,6 @@ class MAM(ElementBase):
self._results = []
class Preferences(ElementBase):
"""MAM Preferences payload.
.. code-block:: xml
<iq type='set' id='juliet3'>
<prefs xmlns='urn:xmpp:mam:2' default='roster'>
<always>
<jid>romeo@montague.lit</jid>
</always>
<never>
<jid>montague@montague.lit</jid>
</never>
</prefs>
</iq>
"""
name = 'prefs'
namespace = 'urn:xmpp:mam:2'
plugin_attrib = 'mam_prefs'
#: Available interfaces:
#:
#: - ``default``: Default MAM policy (must be one of 'roster', 'always',
#: 'never'
#: - ``always`` (``List[JID]``): list of JIDs to always store
#: conversations with.
#: - ``never`` (``List[JID]``): list of JIDs to never store
#: conversations with.
interfaces = {'default', 'always', 'never'}
sub_interfaces = {'always', 'never'}
def get_always(self) -> Set[JID]:
results = set()
jids = self.xml.findall('{%s}always/{%s}jid' % (
self.namespace, self.namespace))
for jid in jids:
results.add(JID(jid.text))
return results
def set_always(self, value: Iterable[JID]):
self._set_sub_text('always', '', keep=True)
always = self.xml.find('{%s}always' % self.namespace)
always.clear()
if not isinstance(value, (list, set)):
value = [value]
for jid in value:
jid_xml = ET.Element('{%s}jid' % self.namespace)
jid_xml.text = str(jid)
always.append(jid_xml)
def get_never(self) -> Set[JID]:
results = set()
jids = self.xml.findall('{%s}never/{%s}jid' % (
self.namespace, self.namespace))
for jid in jids:
results.add(JID(jid.text))
return results
def set_never(self, value: Iterable[JID]):
self._set_sub_text('never', '', keep=True)
never = self.xml.find('{%s}never' % self.namespace)
never.clear()
if not isinstance(value, (list, set)):
value = [value]
for jid in value:
jid_xml = ET.Element('{%s}jid' % self.namespace)
jid_xml.text = str(jid)
never.append(jid_xml)
class Fin(ElementBase):
name = 'fin'
namespace = 'urn:xmpp:mam:2'

View file

@ -0,0 +1,13 @@
# Slixmpp: The Slick XMPP Library
# Copyright (C) 2021 Mathieu Pasquet
# This file is part of Slixmpp.
# See the file LICENSE for copying permissio
from slixmpp.plugins.base import register_plugin
from slixmpp.plugins.xep_0441.stanza import Preferences
from slixmpp.plugins.xep_0441.mam_prefs import XEP_0441
register_plugin(XEP_0441)
__all__ = ['XEP_0441', 'Preferences']

View file

@ -0,0 +1,75 @@
# Slixmpp: The Slick XMPP Library
# Copyright (C) 2021 Mathieu Pasquet
# This file is part of Slixmpp.
# See the file LICENSE for copying permission
import logging
from asyncio import Future
from typing import (
List,
Optional,
Tuple,
)
from slixmpp import JID
from slixmpp.types import MAMDefault
from slixmpp.stanza import Iq
from slixmpp.xmlstream import register_stanza_plugin
from slixmpp.plugins import BasePlugin
from slixmpp.plugins.xep_0441 import stanza
log = logging.getLogger(__name__)
class XEP_0441(BasePlugin):
"""
XEP-0441: Message Archive Management Preferences
"""
name = 'xep_0441'
description = 'XEP-0441: Message Archive Management Preferences'
dependencies = {'xep_0313'}
stanza = stanza
def plugin_init(self):
register_stanza_plugin(Iq, stanza.Preferences)
async def get_preferences(self, **iqkwargs
) -> Tuple[MAMDefault, List[JID], List[JID]]:
"""Get the current MAM preferences.
:returns: A tuple of MAM preferences with (default, always, never)
"""
ifrom = iqkwargs.pop('ifrom', None)
ito = iqkwargs.pop('ito', None)
iq = self.xmpp.make_iq_get(ito=ito, ifrom=ifrom)
iq['type'] = 'get'
query_id = iq['id']
iq['mam_prefs']['query_id'] = query_id
result = await iq.send(**iqkwargs)
return (
result['mam_prefs']['default'],
result['mam_prefs']['always'],
result['mam_prefs']['never']
)
def set_preferences(self, default: Optional[MAMDefault] = 'roster',
always: Optional[List[JID]] = None,
never: Optional[List[JID]] = None, *,
ito: Optional[JID] = None, ifrom: Optional[JID] = None,
**iqkwargs) -> Future:
"""Set MAM Preferences.
The server answer MAY contain different items.
:param default: Default behavior (one of 'always', 'never', 'roster').
:param always: List of JIDs whose messages will always be stored.
:param never: List of JIDs whose messages will never be stored.
"""
iq = self.xmpp.make_iq_set(ito=ito, ifrom=ifrom)
iq['mam_prefs']['default'] = default
iq['mam_prefs']['always'] = always
iq['mam_prefs']['never'] = never
return iq.send(**iqkwargs)

View file

@ -0,0 +1,91 @@
# Slixmpp: The Slick XMPP Library
# Copyright (C) 2021 Mathieu Pasquet
# This file is part of Slixmpp.
# See the file LICENSE for copying permissio
from typing import (
Iterable,
Set,
)
from slixmpp.jid import JID
from slixmpp.xmlstream import ElementBase, ET
class Preferences(ElementBase):
"""MAM Preferences payload.
.. code-block:: xml
<iq type='set' id='juliet3'>
<prefs xmlns='urn:xmpp:mam:2' default='roster'>
<always>
<jid>romeo@montague.lit</jid>
</always>
<never>
<jid>montague@montague.lit</jid>
</never>
</prefs>
</iq>
"""
name = 'prefs'
namespace = 'urn:xmpp:mam:2'
plugin_attrib = 'mam_prefs'
#: Available interfaces:
#:
#: - ``default``: Default MAM policy (must be one of 'roster', 'always',
#: 'never'
#: - ``always`` (``List[JID]``): list of JIDs to always store
#: conversations with.
#: - ``never`` (``List[JID]``): list of JIDs to never store
#: conversations with.
interfaces = {'default', 'always', 'never'}
sub_interfaces = {'always', 'never'}
def get_always(self) -> Set[JID]:
results = set()
jids = self.xml.findall('{%s}always/{%s}jid' % (
self.namespace, self.namespace))
for jid in jids:
results.add(JID(jid.text))
return results
def set_always(self, value: Iterable[JID]):
self._set_sub_text('always', '', keep=True)
always = self.xml.find('{%s}always' % self.namespace)
always.clear()
if not isinstance(value, (list, set)):
value = [value]
for jid in value:
jid_xml = ET.Element('{%s}jid' % self.namespace)
jid_xml.text = str(jid)
always.append(jid_xml)
def get_never(self) -> Set[JID]:
results = set()
jids = self.xml.findall('{%s}never/{%s}jid' % (
self.namespace, self.namespace))
for jid in jids:
results.add(JID(jid.text))
return results
def set_never(self, value: Iterable[JID]):
self._set_sub_text('never', '', keep=True)
never = self.xml.find('{%s}never' % self.namespace)
never.clear()
if not isinstance(value, (list, set)):
value = [value]
for jid in value:
jid_xml = ET.Element('{%s}jid' % self.namespace)
jid_xml.text = str(jid)
never.append(jid_xml)

View file

@ -76,3 +76,5 @@ MucRoomItemKeys = Literal[
OptJid = Optional[JID]
JidStr = Union[str, JID]
OptJidStr = Optional[Union[str, JID]]
MAMDefault = Literal['always', 'never', 'roster']