Philipp Hörist pushed to branch master at gajim / python-nbxmpp

Commits:

4 changed files:

Changes:

  • nbxmpp/dispatcher.py
    ... ... @@ -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:
    

  • nbxmpp/modules/chat_markers.py
    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_)

  • nbxmpp/protocol.py
    ... ... @@ -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,
    

  • nbxmpp/structs.py
    ... ... @@ -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):