summaryrefslogtreecommitdiff
path: root/slixmpp
diff options
context:
space:
mode:
Diffstat (limited to 'slixmpp')
-rw-r--r--slixmpp/plugins/__init__.py2
-rw-r--r--slixmpp/plugins/protoxep_reactions/stanza.py31
-rw-r--r--slixmpp/plugins/xep_0444/__init__.py (renamed from slixmpp/plugins/protoxep_reactions/__init__.py)6
-rw-r--r--slixmpp/plugins/xep_0444/reactions.py (renamed from slixmpp/plugins/protoxep_reactions/reactions.py)39
-rw-r--r--slixmpp/plugins/xep_0444/stanza.py60
5 files changed, 88 insertions, 50 deletions
diff --git a/slixmpp/plugins/__init__.py b/slixmpp/plugins/__init__.py
index c7736adc..c21cc343 100644
--- a/slixmpp/plugins/__init__.py
+++ b/slixmpp/plugins/__init__.py
@@ -86,6 +86,6 @@ __all__ = [
'xep_0325', # IoT Systems Control
'xep_0332', # HTTP Over XMPP Transport
'xep_0377', # Spam reporting
- 'protoxep_reactions', # https://dino.im/xeps/reactions.html
+ 'xep_0444', # Message Reactions
'protoxep_occupantid', # https://dino.im/xeps/occupant-id.html
]
diff --git a/slixmpp/plugins/protoxep_reactions/stanza.py b/slixmpp/plugins/protoxep_reactions/stanza.py
deleted file mode 100644
index 45414a37..00000000
--- a/slixmpp/plugins/protoxep_reactions/stanza.py
+++ /dev/null
@@ -1,31 +0,0 @@
-"""
- Slixmpp: The Slick XMPP Library
- Copyright (C) 2019 Mathieu Pasquet
- This file is part of Slixmpp.
-
- See the file LICENSE for copying permission.
-"""
-
-from slixmpp.xmlstream import ElementBase, register_stanza_plugin
-
-
-class Reactions(ElementBase):
- name = 'reactions'
- plugin_attrib = 'reactions'
- namespace = 'urn:xmpp:reactions:0'
- interfaces = {'to'}
-
-
-class Reaction(ElementBase):
- name = 'reaction'
- namespace = 'urn:xmpp:reactions:0'
- interfaces = {'value'}
-
- def get_value(self) -> str:
- return self.xml.text
-
- def set_value(self, value: str):
- self.xml.text = value
-
-
-register_stanza_plugin(Reactions, Reaction, iterable=True)
diff --git a/slixmpp/plugins/protoxep_reactions/__init__.py b/slixmpp/plugins/xep_0444/__init__.py
index e107bd16..dff4287c 100644
--- a/slixmpp/plugins/protoxep_reactions/__init__.py
+++ b/slixmpp/plugins/xep_0444/__init__.py
@@ -1,11 +1,11 @@
"""
Slixmpp: The Slick XMPP Library
- Copyright (C) 2019 Mathieu Pasquet
+ Copyright (C) 2020 Mathieu Pasquet
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from slixmpp.plugins.base import register_plugin
-from slixmpp.plugins.protoxep_reactions.reactions import XEP_Reactions
+from slixmpp.plugins.xep_0444.reactions import XEP_0444
-register_plugin(XEP_Reactions)
+register_plugin(XEP_0444)
diff --git a/slixmpp/plugins/protoxep_reactions/reactions.py b/slixmpp/plugins/xep_0444/reactions.py
index e7af8fcb..bfd12499 100644
--- a/slixmpp/plugins/protoxep_reactions/reactions.py
+++ b/slixmpp/plugins/xep_0444/reactions.py
@@ -1,26 +1,28 @@
"""
Slixmpp: The Slick XMPP Library
- Copyright (C) 2019 Mathieu Pasquet
+ Copyright (C) 2020 Mathieu Pasquet
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from typing import Iterable
+from slixmpp import JID
from slixmpp.plugins import BasePlugin
from slixmpp.stanza import Message
from slixmpp.xmlstream import register_stanza_plugin
from slixmpp.xmlstream.matcher import MatchXMLMask
from slixmpp.xmlstream.handler import Callback
-from slixmpp.plugins.protoxep_reactions import stanza
+from slixmpp.plugins.xep_0444 import stanza
-class XEP_Reactions(BasePlugin):
- name = 'protoxep_reactions'
- description = 'XEP-XXXX: Message Reactions'
- dependencies = {'xep_0030'}
+class XEP_0444(BasePlugin):
+ name = 'xep_0444'
+ description = 'XEP-0444: Message Reactions'
+ dependencies = {'xep_0030', 'xep_0334'}
stanza = stanza
+ namespace = stanza.NS
def plugin_init(self):
self.xmpp.register_handler(
@@ -30,25 +32,32 @@ class XEP_Reactions(BasePlugin):
self._handle_reactions,
)
)
- self.xmpp['xep_0030'].add_feature('urn:xmpp:reactions:0')
register_stanza_plugin(Message, stanza.Reactions)
+ register_stanza_plugin(stanza.Reactions, stanza.Reaction, iterable=True)
+
+ def session_bind(self, event):
+ self.xmpp['xep_0030'].add_feature(stanza.NS)
def plugin_end(self):
self.xmpp.remove_handler('Reaction received')
- self.xmpp['xep_0030'].remove_feature('urn:xmpp:reactions:0')
+ self.xmpp['xep_0030'].remove_feature(stanza.NS)
def _handle_reactions(self, message: Message):
self.xmpp.event('reactions', message)
+ def send_reactions(self, to: JID, to_id: str, reactions: Iterable[str], *, store=True):
+ """Send reactions related to a message"""
+ msg = self.xmpp.make_message(mto=to)
+ self.set_reactions(msg, to_id, reactions)
+ if store:
+ msg.enable('store')
+ msg.send()
+
@staticmethod
def set_reactions(message: Message, to_id: str, reactions: Iterable[str]):
- """
- Add reactions to a Message object.
- """
- reactions_stanza = stanza.Reactions()
- reactions_stanza['to'] = to_id
+ """Add reactions to a Message object."""
+ message['reactions']['id'] = to_id
for reaction in reactions:
reaction_stanza = stanza.Reaction()
reaction_stanza['value'] = reaction
- reactions_stanza.append(reaction_stanza)
- message.append(reactions_stanza)
+ message['reactions'].append(reaction_stanza)
diff --git a/slixmpp/plugins/xep_0444/stanza.py b/slixmpp/plugins/xep_0444/stanza.py
new file mode 100644
index 00000000..338a244e
--- /dev/null
+++ b/slixmpp/plugins/xep_0444/stanza.py
@@ -0,0 +1,60 @@
+"""
+ Slixmpp: The Slick XMPP Library
+ Copyright (C) 2020 Mathieu Pasquet
+ This file is part of Slixmpp.
+
+ See the file LICENSE for copying permission.
+"""
+
+from typing import Set, Iterable
+from slixmpp.xmlstream import ElementBase
+try:
+ from emoji import UNICODE_EMOJI
+except ImportError:
+ UNICODE_EMOJI = None
+
+
+NS = 'urn:xmpp:reactions:0'
+
+class Reactions(ElementBase):
+ name = 'reactions'
+ plugin_attrib = 'reactions'
+ namespace = NS
+ interfaces = {'id', 'values'}
+
+ def get_values(self, *, all_chars=False) -> Set[str]:
+ """"Get all reactions as str"""
+ reactions = set()
+ for reaction in self:
+ value = reaction['value']
+ if UNICODE_EMOJI and not all_chars:
+ if value in UNICODE_EMOJI:
+ reactions.add(reaction['value'])
+ else:
+ reactions.add(reaction['value'])
+ return reactions
+
+ def set_values(self, values: Iterable[str], *, all_chars=False):
+ """"Set all reactions as str"""
+ for element in self.xml.findall('reaction'):
+ self.xml.remove(element)
+ for reaction_txt in values:
+ reaction = Reaction()
+ reaction.set_value(reaction_txt, all_chars=all_chars)
+ self.append(reaction)
+
+
+class Reaction(ElementBase):
+ name = 'reaction'
+ namespace = NS
+ interfaces = {'value'}
+
+ def get_value(self) -> str:
+ return self.xml.text
+
+ def set_value(self, value: str, *, all_chars=False):
+ if UNICODE_EMOJI and not all_chars:
+ if not value in UNICODE_EMOJI:
+ raise ValueError("%s is not a valid emoji" % value)
+ self.xml.text = value
+