Commit c0b49558 authored by Philipp Hörist's avatar Philipp Hörist
Browse files

Add Chat Markers (XEP-0333) support

parent 550decfd
......@@ -70,6 +70,7 @@ from nbxmpp.modules.software_version import SoftwareVersion
from nbxmpp.modules.adhoc import AdHoc
from nbxmpp.modules.ibb import IBB
from nbxmpp.modules.discovery import Discovery
from nbxmpp.modules.chat_markers import ChatMarkers
from nbxmpp.modules.misc import unwrap_carbon
from nbxmpp.modules.misc import unwrap_mam
from nbxmpp.util import get_properties_struct
......@@ -208,6 +209,7 @@ class XMPPDispatcher(PlugIn):
self._modules['AdHoc'] = AdHoc(self._owner)
self._modules['IBB'] = IBB(self._owner)
self._modules['Discovery'] = Discovery(self._owner)
self._modules['ChatMarkers'] = ChatMarkers(self._owner)
for instance in self._modules.values():
for handler in instance.handlers:
# Copyright (C) 2018 Philipp Hörist <philipp AT>
# This file is part of nbxmpp.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; If not, see <>.
import logging
from nbxmpp.protocol import NS_CHATMARKERS
from nbxmpp.structs import StanzaHandler
from nbxmpp.structs import ChatMarker
log = logging.getLogger('nbxmpp.m.chat_marker')
class ChatMarkers:
def __init__(self, client):
self._client = client
self.handlers = [
def _process_message_marker(_con, stanza, properties):
type_ = stanza.getTag('received', NS_CHATMARKERS)
if type_ is not None:
type_ = stanza.getTag('displayed', NS_CHATMARKERS)
if type_ is None:
type_ = stanza.getTag('acknowledged', NS_CHATMARKERS)
if type_ is None:
id_ = type_.getAttr('id')
if id_ is None:
log.warning('Chatmarker without id')
properties.marker = ChatMarker(type_, id_)
......@@ -1346,6 +1346,13 @@ class Message(Protocol):
return attrs
def setMarker(self, type_, id_):
self.setTag(type_, namespace=NS_CHATMARKERS, attrs={'id': id_})
def setMarkable(self):
self.setTag('markable', namespace=NS_CHATMARKERS)
class Presence(Protocol):
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')):
return random.SystemRandom().choice(self.otpks)
class ChatMarker(namedtuple('ChatMarker', 'type id')):
def is_received(self):
return self.type == 'received'
def is_displayed(self):
return self.type == 'displayed'
def is_acknowledged(self):
return self.type == 'acknowledged'
class CommonError:
def __init__(self, stanza):
self._error_node = stanza.getTag('error')
......@@ -497,6 +512,7 @@ class MessageProperties:
self.omemo = None
self.encrypted = None
self.pgp_legacy = None
self.marker = None
def has_user_delay(self):
......@@ -565,6 +581,28 @@ class MessageProperties:
def is_self_message(self):
return self.self_message
def is_marker(self):
return self.marker is not None
def is_acknowledged_marker(self):
if self.marker is None:
return False
return self.marker.is_acknowledged
def is_received_marker(self):
if self.marker is None:
return False
return self.marker.is_received
def is_displayed_marker(self):
if self.marker is None:
return False
return self.marker.is_displayed
class IqProperties:
def __init__(self):
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment