Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits:
-
c0b49558
by Philipp Hörist at 2019-10-01T21:33:41Z
4 changed files:
Changes:
| ... | ... | @@ -70,6 +70,7 @@ from nbxmpp.modules.software_version import SoftwareVersion |
| 70 | 70 |
from nbxmpp.modules.adhoc import AdHoc
|
| 71 | 71 |
from nbxmpp.modules.ibb import IBB
|
| 72 | 72 |
from nbxmpp.modules.discovery import Discovery
|
| 73 |
+from nbxmpp.modules.chat_markers import ChatMarkers
|
|
| 73 | 74 |
from nbxmpp.modules.misc import unwrap_carbon
|
| 74 | 75 |
from nbxmpp.modules.misc import unwrap_mam
|
| 75 | 76 |
from nbxmpp.util import get_properties_struct
|
| ... | ... | @@ -208,6 +209,7 @@ class XMPPDispatcher(PlugIn): |
| 208 | 209 |
self._modules['AdHoc'] = AdHoc(self._owner)
|
| 209 | 210 |
self._modules['IBB'] = IBB(self._owner)
|
| 210 | 211 |
self._modules['Discovery'] = Discovery(self._owner)
|
| 212 |
+ self._modules['ChatMarkers'] = ChatMarkers(self._owner)
|
|
| 211 | 213 |
|
| 212 | 214 |
for instance in self._modules.values():
|
| 213 | 215 |
for handler in instance.handlers:
|
| 1 |
+# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
|
|
| 2 |
+#
|
|
| 3 |
+# This file is part of nbxmpp.
|
|
| 4 |
+#
|
|
| 5 |
+# This program is free software; you can redistribute it and/or
|
|
| 6 |
+# modify it under the terms of the GNU General Public License
|
|
| 7 |
+# as published by the Free Software Foundation; either version 3
|
|
| 8 |
+# of the License, or (at your option) any later version.
|
|
| 9 |
+#
|
|
| 10 |
+# This program is distributed in the hope that it will be useful,
|
|
| 11 |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
| 12 |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
| 13 |
+# GNU General Public License for more details.
|
|
| 14 |
+#
|
|
| 15 |
+# You should have received a copy of the GNU General Public License
|
|
| 16 |
+# along with this program; If not, see <http://www.gnu.org/licenses/>.
|
|
| 17 |
+ |
|
| 18 |
+import logging
|
|
| 19 |
+ |
|
| 20 |
+from nbxmpp.protocol import NS_CHATMARKERS
|
|
| 21 |
+from nbxmpp.structs import StanzaHandler
|
|
| 22 |
+from nbxmpp.structs import ChatMarker
|
|
| 23 |
+ |
|
| 24 |
+log = logging.getLogger('nbxmpp.m.chat_marker')
|
|
| 25 |
+ |
|
| 26 |
+ |
|
| 27 |
+class ChatMarkers:
|
|
| 28 |
+ def __init__(self, client):
|
|
| 29 |
+ self._client = client
|
|
| 30 |
+ self.handlers = [
|
|
| 31 |
+ StanzaHandler(name='message',
|
|
| 32 |
+ callback=self._process_message_marker,
|
|
| 33 |
+ ns=NS_CHATMARKERS,
|
|
| 34 |
+ priority=15),
|
|
| 35 |
+ ]
|
|
| 36 |
+ |
|
| 37 |
+ @staticmethod
|
|
| 38 |
+ def _process_message_marker(_con, stanza, properties):
|
|
| 39 |
+ type_ = stanza.getTag('received', NS_CHATMARKERS)
|
|
| 40 |
+ if type_ is not None:
|
|
| 41 |
+ type_ = stanza.getTag('displayed', NS_CHATMARKERS)
|
|
| 42 |
+ if type_ is None:
|
|
| 43 |
+ type_ = stanza.getTag('acknowledged', NS_CHATMARKERS)
|
|
| 44 |
+ if type_ is None:
|
|
| 45 |
+ return
|
|
| 46 |
+ |
|
| 47 |
+ id_ = type_.getAttr('id')
|
|
| 48 |
+ if id_ is None:
|
|
| 49 |
+ log.warning('Chatmarker without id')
|
|
| 50 |
+ log.warning(stanza)
|
|
| 51 |
+ return
|
|
| 52 |
+ |
|
| 53 |
+ properties.marker = ChatMarker(type_, id_)
|
| ... | ... | @@ -1346,6 +1346,13 @@ class Message(Protocol): |
| 1346 | 1346 |
attrs.append(child.getAttr('code'))
|
| 1347 | 1347 |
return attrs
|
| 1348 | 1348 |
|
| 1349 |
+ def setMarker(self, type_, id_):
|
|
| 1350 |
+ self.setTag(type_, namespace=NS_CHATMARKERS, attrs={'id': id_})
|
|
| 1351 |
+ |
|
| 1352 |
+ def setMarkable(self):
|
|
| 1353 |
+ self.setTag('markable', namespace=NS_CHATMARKERS)
|
|
| 1354 |
+ |
|
| 1355 |
+ |
|
| 1349 | 1356 |
class Presence(Protocol):
|
| 1350 | 1357 |
|
| 1351 | 1358 |
def __init__(self, to=None, typ=None, priority=None, show=None, status=None,
|
| ... | ... | @@ -361,6 +361,21 @@ class OMEMOBundle(namedtuple('OMEMOBundle', 'spk spk_signature ik otpks')): |
| 361 | 361 |
return random.SystemRandom().choice(self.otpks)
|
| 362 | 362 |
|
| 363 | 363 |
|
| 364 |
+class ChatMarker(namedtuple('ChatMarker', 'type id')):
|
|
| 365 |
+ |
|
| 366 |
+ @property
|
|
| 367 |
+ def is_received(self):
|
|
| 368 |
+ return self.type == 'received'
|
|
| 369 |
+ |
|
| 370 |
+ @property
|
|
| 371 |
+ def is_displayed(self):
|
|
| 372 |
+ return self.type == 'displayed'
|
|
| 373 |
+ |
|
| 374 |
+ @property
|
|
| 375 |
+ def is_acknowledged(self):
|
|
| 376 |
+ return self.type == 'acknowledged'
|
|
| 377 |
+ |
|
| 378 |
+ |
|
| 364 | 379 |
class CommonError:
|
| 365 | 380 |
def __init__(self, stanza):
|
| 366 | 381 |
self._error_node = stanza.getTag('error')
|
| ... | ... | @@ -497,6 +512,7 @@ class MessageProperties: |
| 497 | 512 |
self.omemo = None
|
| 498 | 513 |
self.encrypted = None
|
| 499 | 514 |
self.pgp_legacy = None
|
| 515 |
+ self.marker = None
|
|
| 500 | 516 |
|
| 501 | 517 |
@property
|
| 502 | 518 |
def has_user_delay(self):
|
| ... | ... | @@ -565,6 +581,28 @@ class MessageProperties: |
| 565 | 581 |
def is_self_message(self):
|
| 566 | 582 |
return self.self_message
|
| 567 | 583 |
|
| 584 |
+ @property
|
|
| 585 |
+ def is_marker(self):
|
|
| 586 |
+ return self.marker is not None
|
|
| 587 |
+ |
|
| 588 |
+ @property
|
|
| 589 |
+ def is_acknowledged_marker(self):
|
|
| 590 |
+ if self.marker is None:
|
|
| 591 |
+ return False
|
|
| 592 |
+ return self.marker.is_acknowledged
|
|
| 593 |
+ |
|
| 594 |
+ @property
|
|
| 595 |
+ def is_received_marker(self):
|
|
| 596 |
+ if self.marker is None:
|
|
| 597 |
+ return False
|
|
| 598 |
+ return self.marker.is_received
|
|
| 599 |
+ |
|
| 600 |
+ @property
|
|
| 601 |
+ def is_displayed_marker(self):
|
|
| 602 |
+ if self.marker is None:
|
|
| 603 |
+ return False
|
|
| 604 |
+ return self.marker.is_displayed
|
|
| 605 |
+ |
|
| 568 | 606 |
|
| 569 | 607 |
class IqProperties:
|
| 570 | 608 |
def __init__(self):
|