Move CapsCache global from gajim.capscache to caps.capscache.
This commit is contained in:
parent
bd714f66fc
commit
47f875a4bc
|
@ -39,6 +39,13 @@ from common.xmpp import NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION, NS_CHATSTATES
|
||||||
FEATURE_BLACKLIST = [NS_CHATSTATES, NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION]
|
FEATURE_BLACKLIST = [NS_CHATSTATES, NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION]
|
||||||
|
|
||||||
|
|
||||||
|
capscache = None
|
||||||
|
def initialize(logger):
|
||||||
|
''' Initializes the capscache global '''
|
||||||
|
global capscache
|
||||||
|
capscache = CapsCache(logger)
|
||||||
|
|
||||||
|
|
||||||
class AbstractClientCaps(object):
|
class AbstractClientCaps(object):
|
||||||
'''
|
'''
|
||||||
Base class representing a client and its capabilities as advertised by
|
Base class representing a client and its capabilities as advertised by
|
||||||
|
@ -66,6 +73,7 @@ class AbstractClientCaps(object):
|
||||||
return self._is_hash_valid
|
return self._is_hash_valid
|
||||||
|
|
||||||
def _is_hash_valid(self, identities, features, dataforms):
|
def _is_hash_valid(self, identities, features, dataforms):
|
||||||
|
''' To be implemented by subclassess '''
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,7 +125,10 @@ class NullClientCaps(AbstractClientCaps):
|
||||||
AbstractClientCaps.__init__(self, None, None)
|
AbstractClientCaps.__init__(self, None, None)
|
||||||
|
|
||||||
def _lookup_in_cache(self, caps_cache):
|
def _lookup_in_cache(self, caps_cache):
|
||||||
return caps_cache[('old', '')]
|
# lookup something which does not exist to get a new CacheItem created
|
||||||
|
cache_item = caps_cache[('old', '')]
|
||||||
|
assert cache_item.queried == 0
|
||||||
|
return cache_item
|
||||||
|
|
||||||
def _discover(self, connection, jid):
|
def _discover(self, connection, jid):
|
||||||
pass
|
pass
|
||||||
|
@ -202,15 +213,6 @@ class CapsCache(object):
|
||||||
identities, features)
|
identities, features)
|
||||||
|
|
||||||
self.__CacheItem = CacheItem
|
self.__CacheItem = CacheItem
|
||||||
|
|
||||||
# prepopulate data which we are sure of; note: we do not log these info
|
|
||||||
for account in gajim.connections:
|
|
||||||
gajimcaps = self[('sha-1', gajim.caps_hash[account])]
|
|
||||||
gajimcaps.identities = [gajim.gajim_identity]
|
|
||||||
gajimcaps.features = gajim.gajim_common_features + \
|
|
||||||
gajim.gajim_optional_features[account]
|
|
||||||
|
|
||||||
# start logging data from the net
|
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
|
|
||||||
def initialize_from_db(self):
|
def initialize_from_db(self):
|
||||||
|
@ -248,8 +250,6 @@ class CapsCache(object):
|
||||||
discover = client_caps.get_discover_strategy()
|
discover = client_caps.get_discover_strategy()
|
||||||
discover(connection, jid)
|
discover(connection, jid)
|
||||||
|
|
||||||
gajim.capscache = CapsCache(gajim.logger)
|
|
||||||
|
|
||||||
|
|
||||||
class ConnectionCaps(object):
|
class ConnectionCaps(object):
|
||||||
'''
|
'''
|
||||||
|
@ -295,7 +295,7 @@ class ConnectionCaps(object):
|
||||||
else:
|
else:
|
||||||
client_caps = ClientCaps(caps_hash, node, hash_method)
|
client_caps = ClientCaps(caps_hash, node, hash_method)
|
||||||
|
|
||||||
gajim.capscache.query_client_of_jid_if_unknown(self, jid, client_caps)
|
capscache.query_client_of_jid_if_unknown(self, jid, client_caps)
|
||||||
contact.client_caps = client_caps
|
contact.client_caps = client_caps
|
||||||
|
|
||||||
if pm_ctrl:
|
if pm_ctrl:
|
||||||
|
@ -310,7 +310,7 @@ class ConnectionCaps(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
lookup = contact.client_caps.get_cache_lookup_strategy()
|
lookup = contact.client_caps.get_cache_lookup_strategy()
|
||||||
cache_item = lookup(gajim.capscache)
|
cache_item = lookup(capscache)
|
||||||
|
|
||||||
if cache_item.queried == 2:
|
if cache_item.queried == 2:
|
||||||
return
|
return
|
||||||
|
|
|
@ -30,13 +30,14 @@
|
||||||
|
|
||||||
import common.gajim
|
import common.gajim
|
||||||
|
|
||||||
from common.caps import NullClientCaps, FEATURE_BLACKLIST
|
|
||||||
|
from common import caps
|
||||||
|
|
||||||
|
|
||||||
class CommonContact(object):
|
class CommonContact(object):
|
||||||
|
|
||||||
def __init__(self, jid, resource, show, status, name, our_chatstate,
|
def __init__(self, jid, resource, show, status, name, our_chatstate,
|
||||||
composing_xep, chatstate, client_caps=None, caps_cache=None):
|
composing_xep, chatstate, client_caps=None):
|
||||||
|
|
||||||
self.jid = jid
|
self.jid = jid
|
||||||
self.resource = resource
|
self.resource = resource
|
||||||
|
@ -44,8 +45,7 @@ class CommonContact(object):
|
||||||
self.status = status
|
self.status = status
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
self.client_caps = client_caps or NullClientCaps()
|
self.client_caps = client_caps or caps.NullClientCaps()
|
||||||
self._caps_cache = caps_cache or common.gajim.capscache
|
|
||||||
|
|
||||||
# please read xep-85 http://www.xmpp.org/extensions/xep-0085.html
|
# please read xep-85 http://www.xmpp.org/extensions/xep-0085.html
|
||||||
# we keep track of xep85 support with the peer by three extra states:
|
# we keep track of xep85 support with the peer by three extra states:
|
||||||
|
@ -84,7 +84,7 @@ class CommonContact(object):
|
||||||
|
|
||||||
def _client_supports(self, requested_feature):
|
def _client_supports(self, requested_feature):
|
||||||
lookup_item = self.client_caps.get_cache_lookup_strategy()
|
lookup_item = self.client_caps.get_cache_lookup_strategy()
|
||||||
cache_item = lookup_item(self._caps_cache)
|
cache_item = lookup_item(caps.capscache)
|
||||||
|
|
||||||
supported_features = cache_item.features
|
supported_features = cache_item.features
|
||||||
if requested_feature in supported_features:
|
if requested_feature in supported_features:
|
||||||
|
@ -92,7 +92,7 @@ class CommonContact(object):
|
||||||
elif supported_features == [] and cache_item.queried in (0, 1):
|
elif supported_features == [] and cache_item.queried in (0, 1):
|
||||||
# assume feature is supported, if we don't know yet, what the client
|
# assume feature is supported, if we don't know yet, what the client
|
||||||
# is capable of
|
# is capable of
|
||||||
return requested_feature not in FEATURE_BLACKLIST
|
return requested_feature not in caps.FEATURE_BLACKLIST
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -100,13 +100,12 @@ class CommonContact(object):
|
||||||
class Contact(CommonContact):
|
class Contact(CommonContact):
|
||||||
'''Information concerning each contact'''
|
'''Information concerning each contact'''
|
||||||
def __init__(self, jid='', name='', groups=[], show='', status='', sub='',
|
def __init__(self, jid='', name='', groups=[], show='', status='', sub='',
|
||||||
ask='', resource='', priority=0, keyID='', client_caps=None, caps_cache=None,
|
ask='', resource='', priority=0, keyID='', client_caps=None,
|
||||||
our_chatstate=None, chatstate=None, last_status_time=None, msg_id = None,
|
our_chatstate=None, chatstate=None, last_status_time=None, msg_id = None,
|
||||||
composing_xep=None, mood={}, tune={}, activity={}):
|
composing_xep=None, mood={}, tune={}, activity={}):
|
||||||
|
|
||||||
CommonContact.__init__(self, jid, resource, show, status, name,
|
CommonContact.__init__(self, jid, resource, show, status, name,
|
||||||
our_chatstate, composing_xep, chatstate, client_caps=client_caps,
|
our_chatstate, composing_xep, chatstate, client_caps=client_caps)
|
||||||
caps_cache=caps_cache)
|
|
||||||
|
|
||||||
self.contact_name = '' # nick choosen by contact
|
self.contact_name = '' # nick choosen by contact
|
||||||
self.groups = groups
|
self.groups = groups
|
||||||
|
@ -236,9 +235,8 @@ class Contacts:
|
||||||
|
|
||||||
def create_contact(self, jid='', name='', groups=[], show='', status='',
|
def create_contact(self, jid='', name='', groups=[], show='', status='',
|
||||||
sub='', ask='', resource='', priority=0, keyID='', client_caps=None,
|
sub='', ask='', resource='', priority=0, keyID='', client_caps=None,
|
||||||
caps_cache=None, our_chatstate=None,
|
our_chatstate=None, chatstate=None, last_status_time=None,
|
||||||
chatstate=None, last_status_time=None, composing_xep=None,
|
composing_xep=None, mood={}, tune={}, activity={}):
|
||||||
mood={}, tune={}, activity={}):
|
|
||||||
|
|
||||||
# We don't want duplicated group values
|
# We don't want duplicated group values
|
||||||
groups_unique = []
|
groups_unique = []
|
||||||
|
@ -248,18 +246,16 @@ class Contacts:
|
||||||
|
|
||||||
return Contact(jid=jid, name=name, groups=groups_unique, show=show,
|
return Contact(jid=jid, name=name, groups=groups_unique, show=show,
|
||||||
status=status, sub=sub, ask=ask, resource=resource, priority=priority,
|
status=status, sub=sub, ask=ask, resource=resource, priority=priority,
|
||||||
keyID=keyID, client_caps=client_caps, caps_cache=caps_cache,
|
keyID=keyID, client_caps=client_caps, our_chatstate=our_chatstate,
|
||||||
our_chatstate=our_chatstate, chatstate=chatstate,
|
chatstate=chatstate, last_status_time=last_status_time,
|
||||||
last_status_time=last_status_time, composing_xep=composing_xep,
|
composing_xep=composing_xep, mood=mood, tune=tune, activity=activity)
|
||||||
mood=mood, tune=tune, activity=activity)
|
|
||||||
|
|
||||||
def copy_contact(self, contact):
|
def copy_contact(self, contact):
|
||||||
return self.create_contact(jid=contact.jid, name=contact.name,
|
return self.create_contact(jid=contact.jid, name=contact.name,
|
||||||
groups=contact.groups, show=contact.show, status=contact.status,
|
groups=contact.groups, show=contact.show, status=contact.status,
|
||||||
sub=contact.sub, ask=contact.ask, resource=contact.resource,
|
sub=contact.sub, ask=contact.ask, resource=contact.resource,
|
||||||
priority=contact.priority, keyID=contact.keyID,
|
priority=contact.priority, keyID=contact.keyID,
|
||||||
client_caps=contact.client_caps, caps_cache=contact._caps_cache,
|
client_caps=contact.client_caps, our_chatstate=contact.our_chatstate,
|
||||||
our_chatstate=contact.our_chatstate,
|
|
||||||
chatstate=contact.chatstate, last_status_time=contact.last_status_time)
|
chatstate=contact.chatstate, last_status_time=contact.last_status_time)
|
||||||
|
|
||||||
def add_contact(self, account, contact):
|
def add_contact(self, account, contact):
|
||||||
|
@ -629,8 +625,7 @@ class Contacts:
|
||||||
jid = gc_contact.get_full_jid()
|
jid = gc_contact.get_full_jid()
|
||||||
return Contact(jid=jid, resource=gc_contact.resource,
|
return Contact(jid=jid, resource=gc_contact.resource,
|
||||||
name=gc_contact.name, groups=[], show=gc_contact.show,
|
name=gc_contact.name, groups=[], show=gc_contact.show,
|
||||||
status=gc_contact.status, sub='none', client_caps=gc_contact.client_caps,
|
status=gc_contact.status, sub='none', client_caps=gc_contact.client_caps)
|
||||||
caps_cache=gc_contact._caps_cache)
|
|
||||||
|
|
||||||
def create_gc_contact(self, room_jid='', name='', show='', status='',
|
def create_gc_contact(self, room_jid='', name='', show='', status='',
|
||||||
role='', affiliation='', jid='', resource=''):
|
role='', affiliation='', jid='', resource=''):
|
||||||
|
|
|
@ -205,6 +205,9 @@ gajim_optional_features = {}
|
||||||
# Capabilities hash per account
|
# Capabilities hash per account
|
||||||
caps_hash = {}
|
caps_hash = {}
|
||||||
|
|
||||||
|
import caps
|
||||||
|
caps.initialize(logger)
|
||||||
|
|
||||||
def get_nick_from_jid(jid):
|
def get_nick_from_jid(jid):
|
||||||
pos = jid.find('@')
|
pos = jid.find('@')
|
||||||
return jid[:pos]
|
return jid[:pos]
|
||||||
|
|
|
@ -255,6 +255,7 @@ from common import optparser
|
||||||
from common import dataforms
|
from common import dataforms
|
||||||
from common import passwords
|
from common import passwords
|
||||||
from common import pep
|
from common import pep
|
||||||
|
from common import caps
|
||||||
|
|
||||||
gajimpaths = common.configpaths.gajimpaths
|
gajimpaths = common.configpaths.gajimpaths
|
||||||
|
|
||||||
|
@ -3536,6 +3537,12 @@ class Interface:
|
||||||
gajim.caps_hash[a] = ''
|
gajim.caps_hash[a] = ''
|
||||||
|
|
||||||
helpers.update_optional_features()
|
helpers.update_optional_features()
|
||||||
|
# prepopulate data which we are sure of; note: we do not log these info
|
||||||
|
for account in gajim.connections:
|
||||||
|
gajimcaps = caps.capscache[('sha-1', gajim.caps_hash[account])]
|
||||||
|
gajimcaps.identities = [gajim.gajim_identity]
|
||||||
|
gajimcaps.features = gajim.gajim_common_features + \
|
||||||
|
gajim.gajim_optional_features[account]
|
||||||
|
|
||||||
self.remote_ctrl = None
|
self.remote_ctrl = None
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ lib.setup_env()
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from common.xmpp import NS_MUC, NS_PING, NS_XHTML_IM
|
from common.xmpp import NS_MUC, NS_PING, NS_XHTML_IM
|
||||||
from common.caps import CapsCache, ClientCaps, OldClientCaps
|
from common import caps
|
||||||
from common.contacts import Contact
|
from common.contacts import Contact
|
||||||
|
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
|
@ -34,11 +34,8 @@ class CommonCapsTest(unittest.TestCase):
|
||||||
('old', self.node + '#' + self.caps_hash, self.identities, self.features)]
|
('old', self.node + '#' + self.caps_hash, self.identities, self.features)]
|
||||||
self.logger = Mock(returnValues={"iter_caps_data":db_caps_cache})
|
self.logger = Mock(returnValues={"iter_caps_data":db_caps_cache})
|
||||||
|
|
||||||
self.cc = CapsCache(self.logger)
|
self.cc = caps.CapsCache(self.logger)
|
||||||
# This is a temporary hack required by the way contacts rely on the
|
caps.capscache = self.cc
|
||||||
# existance of a cache. Hopefully this can be refactored to work via
|
|
||||||
# dependency injection
|
|
||||||
gajim.capscache = self.cc
|
|
||||||
|
|
||||||
|
|
||||||
class TestCapsCache(CommonCapsTest):
|
class TestCapsCache(CommonCapsTest):
|
||||||
|
@ -78,7 +75,7 @@ class TestCapsCache(CommonCapsTest):
|
||||||
def test_preload_triggering_query(self):
|
def test_preload_triggering_query(self):
|
||||||
''' Make sure that preload issues a disco '''
|
''' Make sure that preload issues a disco '''
|
||||||
connection = Mock()
|
connection = Mock()
|
||||||
client_caps = ClientCaps(self.caps_hash, self.node, self.caps_method)
|
client_caps = caps.ClientCaps(self.caps_hash, self.node, self.caps_method)
|
||||||
|
|
||||||
self.cc.query_client_of_jid_if_unknown(connection, "test@gajim.org",
|
self.cc.query_client_of_jid_if_unknown(connection, "test@gajim.org",
|
||||||
client_caps)
|
client_caps)
|
||||||
|
@ -88,7 +85,7 @@ class TestCapsCache(CommonCapsTest):
|
||||||
def test_no_preload_query_if_cashed(self):
|
def test_no_preload_query_if_cashed(self):
|
||||||
''' Preload must not send a query if the data is already cached '''
|
''' Preload must not send a query if the data is already cached '''
|
||||||
connection = Mock()
|
connection = Mock()
|
||||||
client_caps = ClientCaps(self.caps_hash, self.node, self.caps_method)
|
client_caps = caps.ClientCaps(self.caps_hash, self.node, self.caps_method)
|
||||||
|
|
||||||
self.cc.initialize_from_db()
|
self.cc.initialize_from_db()
|
||||||
self.cc.query_client_of_jid_if_unknown(connection, "test@gajim.org",
|
self.cc.query_client_of_jid_if_unknown(connection, "test@gajim.org",
|
||||||
|
@ -106,7 +103,7 @@ class TestClientCaps(CommonCapsTest):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
CommonCapsTest.setUp(self)
|
CommonCapsTest.setUp(self)
|
||||||
self.client_caps = ClientCaps(self.caps_hash, self.node, self.caps_method)
|
self.client_caps = caps.ClientCaps(self.caps_hash, self.node, self.caps_method)
|
||||||
|
|
||||||
def test_query_by_get_discover_strategy(self):
|
def test_query_by_get_discover_strategy(self):
|
||||||
''' Client must be queried if the data is unkown '''
|
''' Client must be queried if the data is unkown '''
|
||||||
|
@ -118,7 +115,7 @@ class TestClientCaps(CommonCapsTest):
|
||||||
"http://gajim.org#m3P2WeXPMGVH2tZPe7yITnfY0Dw=")
|
"http://gajim.org#m3P2WeXPMGVH2tZPe7yITnfY0Dw=")
|
||||||
|
|
||||||
def test_client_supports(self):
|
def test_client_supports(self):
|
||||||
contact = Contact(caps_cache=self.cc, client_caps=self.client_caps)
|
contact = Contact(client_caps=self.client_caps)
|
||||||
|
|
||||||
self.assertTrue(contact.supports(NS_PING),
|
self.assertTrue(contact.supports(NS_PING),
|
||||||
msg="Assume supported, if we don't have caps")
|
msg="Assume supported, if we don't have caps")
|
||||||
|
@ -142,7 +139,7 @@ class TestOldClientCaps(TestClientCaps):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
TestClientCaps.setUp(self)
|
TestClientCaps.setUp(self)
|
||||||
self.client_caps = OldClientCaps(self.caps_hash, self.node)
|
self.client_caps = caps.OldClientCaps(self.caps_hash, self.node)
|
||||||
|
|
||||||
def test_query_by_get_discover_strategy(self):
|
def test_query_by_get_discover_strategy(self):
|
||||||
''' Client must be queried if the data is unknown '''
|
''' Client must be queried if the data is unknown '''
|
||||||
|
|
|
@ -7,26 +7,27 @@ import lib
|
||||||
lib.setup_env()
|
lib.setup_env()
|
||||||
|
|
||||||
from common.contacts import CommonContact, Contact, GC_Contact
|
from common.contacts import CommonContact, Contact, GC_Contact
|
||||||
from common.caps import NullClientCaps
|
|
||||||
from common.xmpp import NS_MUC
|
from common.xmpp import NS_MUC
|
||||||
|
|
||||||
|
from common import caps
|
||||||
|
|
||||||
class TestCommonContact(unittest.TestCase):
|
class TestCommonContact(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.contact = CommonContact(jid='', resource='', show='', status='',
|
self.contact = CommonContact(jid='', resource='', show='', status='',
|
||||||
name='', our_chatstate=None, composing_xep=None, chatstate=None,
|
name='', our_chatstate=None, composing_xep=None, chatstate=None,
|
||||||
client_caps=None, caps_cache=None)
|
client_caps=None)
|
||||||
|
|
||||||
def test_default_client_supports(self):
|
def test_default_client_supports(self):
|
||||||
'''
|
'''
|
||||||
Test the caps support method of contacts.
|
Test the caps support method of contacts.
|
||||||
See test_caps for more enhanced tests.
|
See test_caps for more enhanced tests.
|
||||||
'''
|
'''
|
||||||
|
caps.capscache = caps.CapsCache()
|
||||||
self.assertTrue(self.contact.supports(NS_MUC),
|
self.assertTrue(self.contact.supports(NS_MUC),
|
||||||
msg="Must not backtrace on simple check for supported feature")
|
msg="Must not backtrace on simple check for supported feature")
|
||||||
|
|
||||||
self.contact.client_caps = NullClientCaps()
|
self.contact.client_caps = caps.NullClientCaps()
|
||||||
|
|
||||||
self.assertTrue(self.contact.supports(NS_MUC),
|
self.assertTrue(self.contact.supports(NS_MUC),
|
||||||
msg="Must not backtrace on simple check for supported feature")
|
msg="Must not backtrace on simple check for supported feature")
|
||||||
|
|
Loading…
Reference in New Issue