First bits of a basic EntityCapabilities layer above of CapsCache.
This commit is contained in:
parent
0440aec980
commit
499f3dff61
1 changed files with 89 additions and 4 deletions
|
@ -6,7 +6,7 @@
|
|||
## Copyright (C) 2007-2008 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2008 Brendan Taylor <whateley AT gmail.com>
|
||||
## Jonathan Schleifer <js-gajim AT webkeks.org>
|
||||
## Stephan Erb <steve-e AT h3c.de>
|
||||
## Copyright (C) 2008-2009 Stephan Erb <steve-e AT h3c.de>
|
||||
##
|
||||
## This file is part of Gajim.
|
||||
##
|
||||
|
@ -23,9 +23,94 @@
|
|||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
'''
|
||||
Module containing all XEP-115 (Entity Capabilities) related classes
|
||||
|
||||
Basic Idea:
|
||||
CapsCache caches features to hash relationships. The cache is queried
|
||||
through EntityCapabilities objects which are hold by contact instances.
|
||||
|
||||
EntityCapabilities represent the client of contacts. It is set on the receive
|
||||
of a presence. The respective jid is then queried with a disco if the advertised
|
||||
client/hash is unknown.
|
||||
'''
|
||||
|
||||
import gajim
|
||||
import helpers
|
||||
|
||||
|
||||
class AbstractEntityCapabilities(object):
|
||||
'''
|
||||
Base class representing a client and its capabilities as advertised by
|
||||
a caps tag in a presence
|
||||
'''
|
||||
|
||||
def __init__(self, caps_cache, caps_hash, node):
|
||||
self._caps_cache = caps_cache
|
||||
self._hash = caps_hash
|
||||
self._node = node
|
||||
|
||||
def query_client_of_jid_if_unknown(self, connection, jid):
|
||||
'''
|
||||
Asynchronously query the give jid for its (node, ver, exts) caps data
|
||||
using a disco query.
|
||||
|
||||
Query will only be sent if the data is not already cached.
|
||||
'''
|
||||
q = self._lookup_in_cache()
|
||||
if q and q.query_status == q.NOT_QUERIED:
|
||||
q.query_status = q.QUERIED
|
||||
q._discover(connection, jid)
|
||||
|
||||
def _discover(self, connection, jid):
|
||||
''' To be implemented by subclassess '''
|
||||
raise NotImplementedError()
|
||||
|
||||
def _lookup_in_cache(self):
|
||||
''' To be implemented by subclassess '''
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class EntityCapabilities(AbstractEntityCapabilities):
|
||||
''' The current XEP-115 implementation '''
|
||||
|
||||
def __init__(self, caps_cache, caps_hash, node, hash_method):
|
||||
AbstractEntityCapabilities.__init__(self, caps_cache, caps_hash, node)
|
||||
assert hash_method != 'old'
|
||||
self._hash_method = hash_method
|
||||
|
||||
def _lookup_in_cache(self):
|
||||
return self._caps_cache[(self._hash_method, self._hash)]
|
||||
|
||||
def _discover(self, connection, jid):
|
||||
connection.discoverInfo(jid, '%s#%s' % (self._node, self._hash))
|
||||
|
||||
|
||||
class OldEntityCapabilities(AbstractEntityCapabilities):
|
||||
''' Old XEP-115 implemtation. Kept around for background competability. '''
|
||||
|
||||
def __init__(self, caps_cache, caps_hash, node):
|
||||
AbstractEntityCapabilities.__init__(self, caps_cache, caps_hash, node)
|
||||
|
||||
def _lookup_in_cache(self, caps_cache):
|
||||
return caps_cache[('old', self._node + '#' + self._hash)]
|
||||
|
||||
def _discover(self, connection, jid):
|
||||
connection.discoverInfo(jid)
|
||||
|
||||
|
||||
class NullEntityCapabilities(AbstractEntityCapabilities):
|
||||
'''
|
||||
This is a NULL-Object to streamline caps handling is a client has not
|
||||
advertised any caps or has advertised them in an improper way.
|
||||
|
||||
Assumes everything is supported.
|
||||
'''
|
||||
|
||||
def _lookup_in_cache(self):
|
||||
return None
|
||||
|
||||
|
||||
class CapsCache(object):
|
||||
''' This object keeps the mapping between caps data and real disco
|
||||
features they represent, and provides simple way to query that info.
|
||||
|
@ -54,12 +139,9 @@ class CapsCache(object):
|
|||
self.__cache = {}
|
||||
|
||||
class CacheItem(object):
|
||||
''' TODO: logging data into db '''
|
||||
# __names is a string cache; every string long enough is given
|
||||
# another object, and we will have plenty of identical long
|
||||
# strings. therefore we can cache them
|
||||
# TODO: maybe put all known xmpp namespace strings here
|
||||
# (strings given in xmpppy)?
|
||||
__names = {}
|
||||
|
||||
def __init__(self, hash_method, hash_, logger):
|
||||
|
@ -84,6 +166,7 @@ class CapsCache(object):
|
|||
self._features = []
|
||||
for feature in value:
|
||||
self._features.append(self.__names.setdefault(feature, feature))
|
||||
|
||||
features = property(_get_features, _set_features)
|
||||
|
||||
def _get_identities(self):
|
||||
|
@ -100,6 +183,7 @@ class CapsCache(object):
|
|||
d['name'] = i[3]
|
||||
list_.append(d)
|
||||
return list_
|
||||
|
||||
def _set_identities(self, value):
|
||||
self._identities = []
|
||||
for identity in value:
|
||||
|
@ -107,6 +191,7 @@ class CapsCache(object):
|
|||
t = (identity['category'], identity.get('type'),
|
||||
identity.get('xml:lang'), identity.get('name'))
|
||||
self._identities.append(self.__names.setdefault(t, t))
|
||||
|
||||
identities = property(_get_identities, _set_identities)
|
||||
|
||||
def update(self, identities, features):
|
||||
|
|
Loading…
Add table
Reference in a new issue