presence.py 3.13 KB
Newer Older
Philipp Hörist's avatar
Philipp Hörist committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
#
# 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
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# 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 <http://www.gnu.org/licenses/>.

import logging

Philipp Hörist's avatar
Philipp Hörist committed
20
from nbxmpp.protocol import Error as ErrorStanza
Philipp Hörist's avatar
Philipp Hörist committed
21
22
from nbxmpp.protocol import ERR_BAD_REQUEST
from nbxmpp.protocol import NodeProcessed
Philipp Hörist's avatar
Philipp Hörist committed
23
from nbxmpp.structs import StanzaHandler
Philipp Hörist's avatar
Philipp Hörist committed
24
from nbxmpp.structs import ErrorProperties
Philipp Hörist's avatar
Philipp Hörist committed
25
26
from nbxmpp.const import PresenceType
from nbxmpp.const import PresenceShow
Philipp Hörist's avatar
Philipp Hörist committed
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

log = logging.getLogger('nbxmpp.m.presence')


class BasePresence:
    def __init__(self, client):
        self._client = client
        self.handlers = [
            StanzaHandler(name='presence',
                          callback=self._process_presence_base,
                          priority=10),
        ]

    def _process_presence_base(self, _con, stanza, properties):
        properties.type = self._parse_type(stanza)
        properties.priority = self._parse_priority(stanza)
        properties.show = self._parse_show(stanza)
        properties.jid = stanza.getFrom()
        properties.id = stanza.getID()
        properties.status = stanza.getStatus()

Philipp Hörist's avatar
Philipp Hörist committed
48
        if properties.type.is_error:
Philipp Hörist's avatar
Philipp Hörist committed
49
            properties.error = ErrorProperties(stanza)
Philipp Hörist's avatar
Philipp Hörist committed
50
51

        own_jid = self._client.get_bound_jid()
Philipp Hörist's avatar
Philipp Hörist committed
52
53
        properties.self_presence = own_jid == properties.jid
        properties.self_bare = properties.jid.bareMatch(own_jid)
Philipp Hörist's avatar
Philipp Hörist committed
54
55
56
57
58
59
60
61
62
63
64
65
66
67

    @staticmethod
    def _parse_priority(stanza):
        priority = stanza.getPriority()
        if priority is None:
            return 0

        try:
            priority = int(priority)
        except Exception:
            log.warning('Invalid priority value: %s', priority)
            log.warning(stanza)
            return 0

Philipp Hörist's avatar
Philipp Hörist committed
68
        if priority not in range(-129, 128):
Philipp Hörist's avatar
Philipp Hörist committed
69
70
71
72
73
74
75
76
            log.warning('Invalid priority value: %s', priority)
            log.warning(stanza)
            return 0

        return priority

    def _parse_type(self, stanza):
        type_ = stanza.getType()
Philipp Hörist's avatar
Philipp Hörist committed
77
78
79
        try:
            return PresenceType(type_)
        except ValueError:
Philipp Hörist's avatar
Philipp Hörist committed
80
81
            log.warning('Presence with invalid type received')
            log.warning(stanza)
Philipp Hörist's avatar
Philipp Hörist committed
82
            self._client.send(ErrorStanza(stanza, ERR_BAD_REQUEST))
Philipp Hörist's avatar
Philipp Hörist committed
83
84
85
86
            raise NodeProcessed

    @staticmethod
    def _parse_show(stanza):
87
88
89
        show = stanza.getShow()
        if show is None:
            return PresenceShow.ONLINE
Philipp Hörist's avatar
Philipp Hörist committed
90
        try:
91
            return PresenceShow(stanza.getShow())
Philipp Hörist's avatar
Philipp Hörist committed
92
93
94
        except ValueError:
            log.warning('Presence with invalid show')
            log.warning(stanza)
95
            return PresenceShow.ONLINE