1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
# Copyright 2010-2011 Florent Le Coz <louiz@louiz.org>
#
# This file is part of Poezio.
#
# Poezio is free software: you can redistribute it and/or modify
# it under the terms of the zlib license. See the COPYING file.
"""
Defines the Resource and Contact classes, which are used in
the roster.
"""
import logging
log = logging.getLogger(__name__)
from sleekxmpp.xmlstream import JID
class Resource(object):
"""
Defines a roster item.
It's a precise resource.
"""
def __init__(self, jid, data):
"""
data: the dict to use as a source
"""
self._jid = JID(jid) # Full jid
self._data = data
@property
def jid(self):
return self._jid
@property
def priority(self):
return self._data.get('priority') or 0
@property
def presence(self):
return self._data.get('show') or ''
@property
def status(self):
return self._data.get('status') or ''
def __repr__(self):
return '<%s>' % self._jid
class Contact(object):
"""
This a way to gather multiple resources from the same bare JID.
This class contains zero or more Resource object and useful methods
to get the resource with the highest priority, etc
"""
def __init__(self, item):
"""
item: a SleekXMPP RosterItem pointing to that contact
"""
self.__item = item
self.folded = True # Folded by default
@property
def groups(self):
"""Name of the groups the contact is in"""
return self.__item['groups'] or ['none']
@property
def bare_jid(self):
"""The bare jid of the contact"""
return self.__item.jid
@property
def name(self):
"""The name of the contact or an empty string."""
return self.__item['name'] or ''
@property
def ask(self):
if self.__item['pending_out']:
return 'asked'
@property
def pending_in(self):
"""We received a subscribe stanza from this contact."""
return self.__item['pending_in']
@pending_in.setter
def pending_in(self, value):
self.__item['pending_in'] = value
@property
def pending_out(self):
"""We sent a subscribe stanza to this contact."""
return self.__item['pending_out']
@pending_out.setter
def pending_out(self, value):
self.__item['pending_out'] = value
@property
def resources(self):
"""List of the available resources as Resource objects"""
return [Resource(
'%s%s' % (self.bare_jid, ('/' + key) if key else ''),
self.__item.resources[key]
) for key in self.__item.resources.keys()]
@property
def subscription(self):
return self.__item['subscription']
def __contains__(self, value):
return value in self.__item.resources or JID(value).resource in self.__item.resources
def __len__(self):
"""Number of resources"""
return len(self.__item.resources)
def __bool__(self):
"""This contacts exists even when he has no resources"""
return True
def __getitem__(self, key):
"""Return the corresponding Resource object, or None"""
res = JID(key).resource
resources = self.__item.resources
item = resources.get(res, None) or resources.get(key, None)
return Resource(key, item) if item else None
def subscribe(self):
"""Subscribe to this JID"""
self.__item.subscribe()
def authorize(self):
"""Authorize this JID"""
self.__item.authorize()
def unauthorize(self):
"""Unauthorize this JID"""
self.__item.unauthorize()
def unsubscribe(self):
"""Unsubscribe from this JID"""
self.__item.unsubscribe()
def get(self, key, default=None):
"""Same as __getitem__, but with a configurable default"""
return self[key] or default
def get_resources(self):
"""Return all resources, sorted by priority """
compare_resources = lambda x: x.priority
return sorted(self.resources, key=compare_resources, reverse=True)
def get_highest_priority_resource(self):
"""Return the resource with the highest priority"""
resources = self.get_resources()
if resources:
return resources[-1]
return None
def toggle_folded(self):
"""
Fold if it's unfolded, and vice versa
"""
self.folded = not self.folded
def __repr__(self):
ret = '<Contact: %s' % self.bare_jid
for resource in self.resources:
ret += '\n\t\t%s' % resource
return ret + ' />\n'
|