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

Commits:

4 changed files:

Changes:

  • nbxmpp/dispatcher.py
    ... ... @@ -72,6 +72,7 @@ from nbxmpp.modules.adhoc import AdHoc
    72 72
     from nbxmpp.modules.ibb import IBB
    
    73 73
     from nbxmpp.modules.discovery import Discovery
    
    74 74
     from nbxmpp.modules.chat_markers import ChatMarkers
    
    75
    +from nbxmpp.modules.receipts import Receipts
    
    75 76
     from nbxmpp.modules.misc import unwrap_carbon
    
    76 77
     from nbxmpp.modules.misc import unwrap_mam
    
    77 78
     from nbxmpp.util import get_properties_struct
    
    ... ... @@ -211,6 +212,7 @@ class XMPPDispatcher(PlugIn):
    211 212
             self._modules['IBB'] = IBB(self._owner)
    
    212 213
             self._modules['Discovery'] = Discovery(self._owner)
    
    213 214
             self._modules['ChatMarkers'] = ChatMarkers(self._owner)
    
    215
    +        self._modules['Receipts'] = Receipts(self._owner)
    
    214 216
     
    
    215 217
             for instance in self._modules.values():
    
    216 218
                 for handler in instance.handlers:
    

  • nbxmpp/modules/receipts.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_RECEIPTS
    
    21
    +from nbxmpp.structs import StanzaHandler
    
    22
    +from nbxmpp.structs import ReceiptData
    
    23
    +
    
    24
    +log = logging.getLogger('nbxmpp.m.receipts')
    
    25
    +
    
    26
    +
    
    27
    +class Receipts:
    
    28
    +    def __init__(self, client):
    
    29
    +        self._client = client
    
    30
    +        self.handlers = [
    
    31
    +            StanzaHandler(name='message',
    
    32
    +                          callback=self._process_message_receipt,
    
    33
    +                          ns=NS_RECEIPTS,
    
    34
    +                          priority=15),
    
    35
    +        ]
    
    36
    +
    
    37
    +    def _process_message_receipt(self, _con, stanza, properties):
    
    38
    +        request = stanza.getTag('request', namespace=NS_RECEIPTS)
    
    39
    +        if request is not None:
    
    40
    +            properties.receipt = ReceiptData(request.getName())
    
    41
    +            return
    
    42
    +
    
    43
    +        received = stanza.getTag('received', namespace=NS_RECEIPTS)
    
    44
    +        if received is not None:
    
    45
    +            id_ = received.getAttr('id')
    
    46
    +            if id_ is None:
    
    47
    +                log.warning('Receipt without id attr')
    
    48
    +                log.warning(stanza)
    
    49
    +                return
    
    50
    +
    
    51
    +            properties.receipt = ReceiptData(received.getName(), id_)

  • nbxmpp/protocol.py
    ... ... @@ -1323,6 +1323,11 @@ class Message(Protocol):
    1323 1323
             """
    
    1324 1324
             self.setTag('origin-id', namespace=NS_SID, attrs={'id': val})
    
    1325 1325
     
    
    1326
    +    def buildReceipt(self):
    
    1327
    +        message = Message(to=self.getFrom().getBare(), typ=self.getType())
    
    1328
    +        message.setReceiptReceived(self.getID())
    
    1329
    +        return message
    
    1330
    +
    
    1326 1331
         def buildReply(self, text=None):
    
    1327 1332
             """
    
    1328 1333
             Builds and returns another message object with specified text. The to,
    
    ... ... @@ -1352,6 +1357,12 @@ class Message(Protocol):
    1352 1357
         def setMarkable(self):
    
    1353 1358
             self.setTag('markable', namespace=NS_CHATMARKERS)
    
    1354 1359
     
    
    1360
    +    def setReceiptRequest(self):
    
    1361
    +        self.setTag('request', namespace=NS_RECEIPTS)
    
    1362
    +
    
    1363
    +    def setReceiptReceived(self, id_):
    
    1364
    +        self.setTag('received', namespace=NS_RECEIPTS, attrs={'id': id_})
    
    1365
    +
    
    1355 1366
     
    
    1356 1367
     class Presence(Protocol):
    
    1357 1368
     
    

  • nbxmpp/structs.py
    ... ... @@ -485,6 +485,22 @@ class CarbonData(namedtuple('MAMData', 'type')):
    485 485
             return self.type == 'received'
    
    486 486
     
    
    487 487
     
    
    488
    +class ReceiptData(namedtuple('ReceiptData', 'type id')):
    
    489
    +
    
    490
    +    __slots__ = []
    
    491
    +
    
    492
    +    def __new__(cls, type, id=None):
    
    493
    +        return super(ReceiptData, cls).__new__(cls, type, id)
    
    494
    +
    
    495
    +    @property
    
    496
    +    def is_request(self):
    
    497
    +        return self.type == 'request'
    
    498
    +
    
    499
    +    @property
    
    500
    +    def is_received(self):
    
    501
    +        return self.type == 'received'
    
    502
    +
    
    503
    +
    
    488 504
     class Properties:
    
    489 505
         pass
    
    490 506
     
    
    ... ... @@ -528,6 +544,7 @@ class MessageProperties:
    528 544
             self.encrypted = None
    
    529 545
             self.pgp_legacy = None
    
    530 546
             self.marker = None
    
    547
    +        self.receipt = None
    
    531 548
     
    
    532 549
         @property
    
    533 550
         def has_user_delay(self):
    
    ... ... @@ -604,6 +621,10 @@ class MessageProperties:
    604 621
         def is_marker(self):
    
    605 622
             return self.marker is not None
    
    606 623
     
    
    624
    +    @property
    
    625
    +    def is_receipt(self):
    
    626
    +        return self.receipt is not None
    
    627
    +
    
    607 628
     
    
    608 629
     class IqProperties:
    
    609 630
         def __init__(self):