| ... |
... |
@@ -33,6 +33,12 @@ |
|
33
|
33
|
|
|
34
|
34
|
|
|
35
|
35
|
class Presence(BaseModule):
|
|
|
36
|
+
|
|
|
37
|
+ _nbxmpp_extends = 'BasePresence'
|
|
|
38
|
+ _nbxmpp_methods = [
|
|
|
39
|
+ 'subscribed',
|
|
|
40
|
+ ]
|
|
|
41
|
+
|
|
36
|
42
|
def __init__(self, con):
|
|
37
|
43
|
BaseModule.__init__(self, con)
|
|
38
|
44
|
|
| ... |
... |
@@ -140,101 +146,11 @@ def _presence_received(self, _con, stanza, properties): |
|
140
|
146
|
'contact': None,
|
|
141
|
147
|
}
|
|
142
|
148
|
|
|
143
|
|
- event_ = NetworkEvent('presence-received', **event_attrs)
|
|
144
|
|
-
|
|
145
|
|
- # self._update_contact(event_, properties)
|
|
146
|
|
-
|
|
147
|
|
- app.nec.push_incoming_event(event_)
|
|
148
|
|
-
|
|
149
|
|
- def _update_contact(self, event, properties):
|
|
150
|
|
- # Note: A similar method also exists in connection_zeroconf
|
|
151
|
|
- jid = properties.jid.bare
|
|
152
|
|
- resource = properties.jid.resource
|
|
153
|
|
-
|
|
154
|
|
- status_strings = ['offline', 'error', 'online', 'chat', 'away',
|
|
155
|
|
- 'xa', 'dnd']
|
|
|
149
|
+ app.nec.push_incoming_event(
|
|
|
150
|
+ NetworkEvent('presence-received', **event_attrs))
|
|
156
|
151
|
|
|
157
|
|
- event.new_show = status_strings.index(event.show)
|
|
158
|
|
-
|
|
159
|
|
- # Update contact
|
|
160
|
|
- contact_list = app.contacts.get_contacts(self._account, jid)
|
|
161
|
|
- if not contact_list:
|
|
162
|
|
- self._log.warning('No contact found')
|
|
163
|
|
- return
|
|
164
|
|
-
|
|
165
|
|
- event.contact_list = contact_list
|
|
166
|
|
-
|
|
167
|
|
- contact = app.contacts.get_contact_strict(self._account,
|
|
168
|
|
- properties.jid.bare,
|
|
169
|
|
- properties.jid.resource)
|
|
170
|
|
- if contact is None:
|
|
171
|
|
- contact = app.contacts.get_first_contact_from_jid(self._account,
|
|
172
|
|
- jid)
|
|
173
|
|
- if contact is None:
|
|
174
|
|
- self._log.warning('First contact not found')
|
|
175
|
|
- return
|
|
176
|
|
-
|
|
177
|
|
- if (self._is_resource_known(contact_list) and
|
|
178
|
|
- not app.jid_is_transport(jid)):
|
|
179
|
|
- # Another resource of an existing contact connected
|
|
180
|
|
- # Add new contact
|
|
181
|
|
- event.old_show = 0
|
|
182
|
|
- contact = app.contacts.copy_contact(contact)
|
|
183
|
|
- contact.resource = resource
|
|
184
|
|
- app.contacts.add_contact(self._account, contact)
|
|
185
|
|
- else:
|
|
186
|
|
- # Convert the initial roster contact to a contact with resource
|
|
187
|
|
- contact.resource = resource
|
|
188
|
|
- event.old_show = 0
|
|
189
|
|
- if contact.show in status_strings:
|
|
190
|
|
- event.old_show = status_strings.index(contact.show)
|
|
191
|
|
-
|
|
192
|
|
- event.need_add_in_roster = True
|
|
193
|
|
-
|
|
194
|
|
- elif contact.show in status_strings:
|
|
195
|
|
- event.old_show = status_strings.index(contact.show)
|
|
196
|
|
-
|
|
197
|
|
- # Update contact with presence data
|
|
198
|
|
- contact.show = event.show
|
|
199
|
|
- contact.status = properties.status
|
|
200
|
|
- contact.priority = properties.priority
|
|
201
|
|
- contact.idle_time = properties.idle_timestamp
|
|
202
|
|
-
|
|
203
|
|
- event.contact = contact
|
|
204
|
|
-
|
|
205
|
|
- if not app.jid_is_transport(jid) and len(contact_list) == 1:
|
|
206
|
|
- # It's not an agent
|
|
207
|
|
- if event.old_show == 0 and event.new_show > 1:
|
|
208
|
|
- if not jid in app.newly_added[self._account]:
|
|
209
|
|
- app.newly_added[self._account].append(jid)
|
|
210
|
|
- if jid in app.to_be_removed[self._account]:
|
|
211
|
|
- app.to_be_removed[self._account].remove(jid)
|
|
212
|
|
- elif event.old_show > 1 and event.new_show == 0 and \
|
|
213
|
|
- self._con.state.is_available:
|
|
214
|
|
- if not jid in app.to_be_removed[self._account]:
|
|
215
|
|
- app.to_be_removed[self._account].append(jid)
|
|
216
|
|
- if jid in app.newly_added[self._account]:
|
|
217
|
|
- app.newly_added[self._account].remove(jid)
|
|
218
|
|
-
|
|
219
|
|
- if app.jid_is_transport(jid):
|
|
220
|
|
- return
|
|
221
|
|
-
|
|
222
|
|
- if properties.type.is_unavailable:
|
|
223
|
|
- # TODO: This causes problems when another
|
|
224
|
|
- # resource signs off!
|
|
225
|
|
- self._con.get_module('Bytestream').stop_all_active_file_transfers(
|
|
226
|
|
- contact)
|
|
227
|
152
|
self._log_presence(properties)
|
|
228
|
153
|
|
|
229
|
|
- @staticmethod
|
|
230
|
|
- def _is_resource_known(contact_list):
|
|
231
|
|
- if len(contact_list) > 1:
|
|
232
|
|
- return True
|
|
233
|
|
-
|
|
234
|
|
- if contact_list[0].resource == '':
|
|
235
|
|
- return False
|
|
236
|
|
- return contact_list[0].show not in ('not in roster', 'offline')
|
|
237
|
|
-
|
|
238
|
154
|
def _log_presence(self, properties):
|
|
239
|
155
|
if not app.settings.get('log_contact_status_changes'):
|
|
240
|
156
|
return
|
| ... |
... |
@@ -265,9 +181,8 @@ def _subscribe_received(self, _con, _stanza, properties): |
|
265
|
181
|
auto_auth, properties.nickname)
|
|
266
|
182
|
|
|
267
|
183
|
if auto_auth or jid in self._jids_for_auto_auth:
|
|
268
|
|
- self.send_presence(fjid, 'subscribed')
|
|
269
|
|
- self._jids_for_auto_auth.discard(jid)
|
|
270
|
184
|
self._log.info('Auto respond with subscribed: %s', jid)
|
|
|
185
|
+ self.subscribed(jid)
|
|
271
|
186
|
return
|
|
272
|
187
|
|
|
273
|
188
|
status = (properties.status or
|
| ... |
... |
@@ -276,6 +191,7 @@ def _subscribe_received(self, _con, _stanza, properties): |
|
276
|
191
|
app.nec.push_incoming_event(NetworkEvent(
|
|
277
|
192
|
'subscribe-presence-received',
|
|
278
|
193
|
conn=self._con,
|
|
|
194
|
+ account=self._account,
|
|
279
|
195
|
jid=jid,
|
|
280
|
196
|
fjid=fjid,
|
|
281
|
197
|
status=status,
|
| ... |
... |
@@ -305,59 +221,31 @@ def _unsubscribed_received(self, _con, _stanza, properties): |
|
305
|
221
|
self._log.info('Received Unsubscribed: %s', properties.jid)
|
|
306
|
222
|
app.nec.push_incoming_event(NetworkEvent(
|
|
307
|
223
|
'unsubscribed-presence-received',
|
|
308
|
|
- conn=self._con, jid=properties.jid.bare))
|
|
|
224
|
+ conn=self._con,
|
|
|
225
|
+ account=self._account,
|
|
|
226
|
+ jid=properties.jid.bare))
|
|
309
|
227
|
raise nbxmpp.NodeProcessed
|
|
310
|
228
|
|
|
311
|
|
- def subscribed(self, jid):
|
|
312
|
|
- if not app.account_is_available(self._account):
|
|
313
|
|
- return
|
|
314
|
|
- self._log.info('Subscribed: %s', jid)
|
|
315
|
|
- self.send_presence(jid, 'subscribed')
|
|
316
|
|
-
|
|
317
|
229
|
def unsubscribed(self, jid):
|
|
318
|
|
- if not app.account_is_available(self._account):
|
|
319
|
|
- return
|
|
320
|
|
-
|
|
321
|
230
|
self._log.info('Unsubscribed: %s', jid)
|
|
322
|
231
|
self._jids_for_auto_auth.discard(jid)
|
|
323
|
|
- self.send_presence(jid, 'unsubscribed')
|
|
|
232
|
+ self._nbxmpp('BasePresence').unsubscribed(jid)
|
|
324
|
233
|
|
|
325
|
|
- def unsubscribe(self, jid, remove_auth=True):
|
|
326
|
|
- if not app.account_is_available(self._account):
|
|
327
|
|
- return
|
|
328
|
|
- if remove_auth:
|
|
329
|
|
- self._con.get_module('Roster').del_item(jid)
|
|
330
|
|
- else:
|
|
331
|
|
- self._log.info('Unsubscribe from %s', jid)
|
|
332
|
|
- self._jids_for_auto_auth.discard(jid)
|
|
333
|
|
- self._con.get_module('Roster').unsubscribe(jid)
|
|
334
|
|
- self._con.get_module('Roster').set_item(jid)
|
|
335
|
|
-
|
|
336
|
|
- def subscribe(self, jid, msg=None, name='', groups=None, auto_auth=False):
|
|
337
|
|
- if not app.account_is_available(self._account):
|
|
338
|
|
- return
|
|
339
|
|
- if groups is None:
|
|
340
|
|
- groups = []
|
|
|
234
|
+ def unsubscribe(self, jid):
|
|
|
235
|
+ self._log.info('Unsubscribe from %s', jid)
|
|
|
236
|
+ self._jids_for_auto_auth.discard(jid)
|
|
|
237
|
+ self._nbxmpp('BasePresence').unsubscribe(jid)
|
|
341
|
238
|
|
|
|
239
|
+ def subscribe(self, jid, msg=None, name=None, groups=None, auto_auth=False):
|
|
342
|
240
|
self._log.info('Request Subscription to %s', jid)
|
|
343
|
241
|
|
|
344
|
242
|
if auto_auth:
|
|
345
|
243
|
self._jids_for_auto_auth.add(jid)
|
|
346
|
244
|
|
|
347
|
|
- infos = {'jid': jid}
|
|
348
|
|
- if name:
|
|
349
|
|
- infos['name'] = name
|
|
350
|
|
- iq = nbxmpp.Iq('set', Namespace.ROSTER)
|
|
351
|
|
- query = iq.setQuery()
|
|
352
|
|
- item = query.addChild('item', attrs=infos)
|
|
353
|
|
- for group in groups:
|
|
354
|
|
- item.addChild('group').setData(group)
|
|
355
|
|
- self._con.connection.send(iq)
|
|
356
|
|
-
|
|
357
|
|
- self.send_presence(jid,
|
|
358
|
|
- 'subscribe',
|
|
359
|
|
- status=msg,
|
|
360
|
|
- nick=app.nicks[self._account])
|
|
|
245
|
+ self._con.get_module('Roster').set_item(jid, name, groups=groups)
|
|
|
246
|
+ self._nbxmpp('BasePresence').subscribe(jid,
|
|
|
247
|
+ status=msg,
|
|
|
248
|
+ nick=app.nicks[self._account])
|
|
361
|
249
|
|
|
362
|
250
|
def get_presence(self, to=None, typ=None, priority=None,
|
|
363
|
251
|
show=None, status=None, nick=None, caps=True,
|