2011-09-06 00:45:53 +00:00
|
|
|
# Copyright 2010-2011 Florent Le Coz <louiz@louiz.org>
|
2010-09-16 17:57:27 +00:00
|
|
|
#
|
|
|
|
# This file is part of Poezio.
|
|
|
|
#
|
|
|
|
# Poezio is free software: you can redistribute it and/or modify
|
2011-09-11 15:10:05 +00:00
|
|
|
# it under the terms of the zlib license. See the COPYING file.
|
2010-09-16 17:57:27 +00:00
|
|
|
|
2010-10-27 22:49:52 +00:00
|
|
|
"""
|
2010-11-15 11:59:09 +00:00
|
|
|
Defines the Resource and Contact classes, which are used in
|
2012-05-21 00:14:25 +00:00
|
|
|
the roster.
|
2010-10-27 22:49:52 +00:00
|
|
|
"""
|
2010-11-15 11:59:09 +00:00
|
|
|
|
2010-11-10 21:15:08 +00:00
|
|
|
import logging
|
|
|
|
log = logging.getLogger(__name__)
|
2010-09-16 17:57:27 +00:00
|
|
|
|
2012-08-06 13:38:09 +00:00
|
|
|
from sleekxmpp import JID
|
|
|
|
from common import safeJID
|
2013-02-03 22:31:27 +00:00
|
|
|
from collections import defaultdict
|
2010-11-15 11:59:09 +00:00
|
|
|
|
2010-10-17 17:27:07 +00:00
|
|
|
class Resource(object):
|
2010-09-16 17:57:27 +00:00
|
|
|
"""
|
2010-10-17 17:27:07 +00:00
|
|
|
Defines a roster item.
|
|
|
|
It's a precise resource.
|
2010-09-16 17:57:27 +00:00
|
|
|
"""
|
2012-04-27 18:50:00 +00:00
|
|
|
def __init__(self, jid, data):
|
2012-05-21 00:14:25 +00:00
|
|
|
"""
|
|
|
|
data: the dict to use as a source
|
|
|
|
"""
|
2012-10-14 13:31:48 +00:00
|
|
|
self._jid = jid # Full jid
|
2012-04-27 18:50:00 +00:00
|
|
|
self._data = data
|
2010-10-04 00:27:40 +00:00
|
|
|
|
2011-11-09 21:00:38 +00:00
|
|
|
@property
|
|
|
|
def jid(self):
|
2010-09-16 17:57:27 +00:00
|
|
|
return self._jid
|
2010-09-26 18:01:38 +00:00
|
|
|
|
2011-11-09 21:00:38 +00:00
|
|
|
@property
|
|
|
|
def priority(self):
|
2012-07-31 18:51:18 +00:00
|
|
|
return self._data.get('priority') or 0
|
2010-09-26 18:01:38 +00:00
|
|
|
|
2011-11-09 21:00:38 +00:00
|
|
|
@property
|
|
|
|
def presence(self):
|
2012-07-31 18:51:18 +00:00
|
|
|
return self._data.get('show') or ''
|
2011-11-09 21:00:38 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def status(self):
|
2012-07-31 18:51:18 +00:00
|
|
|
return self._data.get('status') or ''
|
2010-10-04 00:27:40 +00:00
|
|
|
|
2012-04-27 18:50:00 +00:00
|
|
|
def __repr__(self):
|
|
|
|
return '<%s>' % self._jid
|
2010-10-04 00:27:40 +00:00
|
|
|
|
2013-01-21 18:23:23 +00:00
|
|
|
def __eq__(self, value):
|
|
|
|
if not isinstance(value, Resource):
|
|
|
|
return False
|
|
|
|
return self.jid == value.jid and self._data == value._data
|
|
|
|
|
2010-10-17 17:27:07 +00:00
|
|
|
class Contact(object):
|
|
|
|
"""
|
|
|
|
This a way to gather multiple resources from the same bare JID.
|
2010-10-27 22:49:52 +00:00
|
|
|
This class contains zero or more Resource object and useful methods
|
2010-10-17 17:27:07 +00:00
|
|
|
to get the resource with the highest priority, etc
|
|
|
|
"""
|
2012-04-27 18:50:00 +00:00
|
|
|
def __init__(self, item):
|
|
|
|
"""
|
|
|
|
item: a SleekXMPP RosterItem pointing to that contact
|
|
|
|
"""
|
|
|
|
self.__item = item
|
2013-02-03 22:31:27 +00:00
|
|
|
self.folded_states = defaultdict(lambda: True)
|
2013-03-11 16:54:29 +00:00
|
|
|
self._name = ''
|
2013-03-03 12:13:15 +00:00
|
|
|
self.error = None
|
2013-03-11 01:04:20 +00:00
|
|
|
self.tune = {}
|
2013-03-12 15:12:47 +00:00
|
|
|
self.gaming = {}
|
2013-03-11 22:06:52 +00:00
|
|
|
self.mood = ''
|
|
|
|
self.activity = ''
|
2010-10-17 17:27:07 +00:00
|
|
|
|
2011-11-09 21:00:38 +00:00
|
|
|
@property
|
|
|
|
def groups(self):
|
2012-04-27 18:50:00 +00:00
|
|
|
"""Name of the groups the contact is in"""
|
|
|
|
return self.__item['groups'] or ['none']
|
2011-10-01 12:26:19 +00:00
|
|
|
|
2011-11-09 21:00:38 +00:00
|
|
|
@property
|
|
|
|
def bare_jid(self):
|
2012-05-21 00:14:25 +00:00
|
|
|
"""The bare jid of the contact"""
|
2012-04-27 18:50:00 +00:00
|
|
|
return self.__item.jid
|
2010-10-17 17:27:07 +00:00
|
|
|
|
2012-04-27 18:50:00 +00:00
|
|
|
@property
|
|
|
|
def name(self):
|
2012-05-21 00:14:25 +00:00
|
|
|
"""The name of the contact or an empty string."""
|
2013-03-11 16:54:29 +00:00
|
|
|
return self.__item['name'] or self._name or ''
|
|
|
|
|
|
|
|
@name.setter
|
|
|
|
def name(self, value):
|
|
|
|
"""Set the name of the contact with user nickname"""
|
|
|
|
self._name = value
|
2010-10-17 17:27:07 +00:00
|
|
|
|
2012-04-27 18:50:00 +00:00
|
|
|
@property
|
|
|
|
def ask(self):
|
|
|
|
if self.__item['pending_out']:
|
|
|
|
return 'asked'
|
2010-10-17 17:27:07 +00:00
|
|
|
|
2012-04-27 18:50:00 +00:00
|
|
|
@property
|
|
|
|
def pending_in(self):
|
2012-05-21 00:14:25 +00:00
|
|
|
"""We received a subscribe stanza from this contact."""
|
2012-04-27 18:50:00 +00:00
|
|
|
return self.__item['pending_in']
|
2010-10-27 22:49:52 +00:00
|
|
|
|
2012-04-27 18:50:00 +00:00
|
|
|
@pending_in.setter
|
|
|
|
def pending_in(self, value):
|
|
|
|
self.__item['pending_in'] = value
|
2010-10-17 17:27:07 +00:00
|
|
|
|
2011-11-09 21:00:38 +00:00
|
|
|
@property
|
2012-04-27 18:50:00 +00:00
|
|
|
def pending_out(self):
|
2012-05-21 00:14:25 +00:00
|
|
|
"""We sent a subscribe stanza to this contact."""
|
2012-04-27 18:50:00 +00:00
|
|
|
return self.__item['pending_out']
|
2010-10-17 17:27:07 +00:00
|
|
|
|
2012-04-27 18:50:00 +00:00
|
|
|
@pending_out.setter
|
|
|
|
def pending_out(self, value):
|
|
|
|
self.__item['pending_out'] = value
|
2010-10-17 17:27:07 +00:00
|
|
|
|
2011-11-09 21:00:38 +00:00
|
|
|
@property
|
2012-04-27 18:50:00 +00:00
|
|
|
def resources(self):
|
|
|
|
"""List of the available resources as Resource objects"""
|
2012-10-14 13:31:48 +00:00
|
|
|
return (Resource(
|
2012-08-01 18:10:00 +00:00
|
|
|
'%s%s' % (self.bare_jid, ('/' + key) if key else ''),
|
|
|
|
self.__item.resources[key]
|
2012-10-14 13:31:48 +00:00
|
|
|
) for key in self.__item.resources.keys())
|
2010-10-17 17:27:07 +00:00
|
|
|
|
2011-11-09 21:00:38 +00:00
|
|
|
@property
|
|
|
|
def subscription(self):
|
2012-04-27 18:50:00 +00:00
|
|
|
return self.__item['subscription']
|
2010-10-17 17:27:07 +00:00
|
|
|
|
2012-04-27 18:50:00 +00:00
|
|
|
def __contains__(self, value):
|
2012-08-06 13:38:09 +00:00
|
|
|
return value in self.__item.resources or safeJID(value).resource in self.__item.resources
|
2011-11-09 21:00:38 +00:00
|
|
|
|
2012-04-27 18:50:00 +00:00
|
|
|
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"""
|
2012-08-06 13:38:09 +00:00
|
|
|
res = safeJID(key).resource
|
2012-04-27 18:50:00 +00:00
|
|
|
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
|
2010-10-17 17:27:07 +00:00
|
|
|
|
|
|
|
def get_resources(self):
|
2012-04-27 18:50:00 +00:00
|
|
|
"""Return all resources, sorted by priority """
|
|
|
|
compare_resources = lambda x: x.priority
|
2012-08-01 13:45:10 +00:00
|
|
|
return sorted(self.resources, key=compare_resources, reverse=True)
|
2012-04-27 18:50:00 +00:00
|
|
|
|
|
|
|
def get_highest_priority_resource(self):
|
|
|
|
"""Return the resource with the highest priority"""
|
|
|
|
resources = self.get_resources()
|
|
|
|
if resources:
|
|
|
|
return resources[-1]
|
|
|
|
return None
|
|
|
|
|
2013-02-03 22:31:27 +00:00
|
|
|
def folded(self, group_name='none'):
|
|
|
|
"""
|
|
|
|
Return the Folded state of a contact for this group
|
|
|
|
"""
|
|
|
|
return self.folded_states[group_name]
|
|
|
|
|
|
|
|
def toggle_folded(self, group='none'):
|
2010-10-17 17:27:07 +00:00
|
|
|
"""
|
2012-04-27 18:50:00 +00:00
|
|
|
Fold if it's unfolded, and vice versa
|
2010-10-17 17:27:07 +00:00
|
|
|
"""
|
2013-02-03 22:31:27 +00:00
|
|
|
self.folded_states[group] = not self.folded_states[group]
|
2010-10-17 17:27:07 +00:00
|
|
|
|
|
|
|
def __repr__(self):
|
2012-04-27 18:50:00 +00:00
|
|
|
ret = '<Contact: %s' % self.bare_jid
|
|
|
|
for resource in self.resources:
|
2011-06-04 18:15:18 +00:00
|
|
|
ret += '\n\t\t%s' % resource
|
2010-10-17 17:27:07 +00:00
|
|
|
return ret + ' />\n'
|