changeset 7d6e9b014c78 in /home/hg/repos/gajim
details:http://hg.gajim.org/gajim?cmd=changeset;node=7d6e9b014c78
description: Merge changes from refactoring branch back to default
diffstat:
src/chat_control.py | 2 +-
src/common/account.py | 32 +
src/common/caps.py | 83 +++-
src/common/check_paths.py | 3 +-
src/common/connection_handlers.py | 8 +-
src/common/contacts.py | 579
++++++++++++++++-------------
src/common/defs.py | 2 +-
src/common/logger.py | 19 +-
src/common/meta.py | 36 -
src/common/optparser.py | 22 +
src/dialogs.py | 4 +-
src/filetransfers_window.py | 2 +-
src/groupchat_control.py | 16 +-
src/gui_interface.py | 37 +-
src/roster_window.py | 33 +-
src/search_window.py | 4 +-
src/session.py | 5 +-
test/integration/test_gui_event_integration.py | 11 +-
test/integration/test_roster.py | 20 +-
test/runtests.py | 1 +
test/unit/test_account.py | 21 +
test/unit/test_caps.py | 20 +-
test/unit/test_contacts.py | 92 ++++-
23 files changed, 637 insertions(+), 415 deletions(-)
diffs (truncated from 1759 to 300 lines):
diff -r d2ea1076d58e -r 7d6e9b014c78 src/chat_control.py
--- a/src/chat_control.py Tue Nov 10 23:33:39 2009 +0200
+++ b/src/chat_control.py Wed Nov 11 23:38:17 2009 +0100
@@ -2774,7 +2774,7 @@
contact = gajim.contacts.get_contact_with_highest_priority(
self.account, self.contact.jid)
if isinstance(contact, GC_Contact):
- contact =
gajim.contacts.contact_from_gc_contact(contact)
+ contact = contact.as_contact()
if contact:
self.contact = contact
self.draw_banner()
diff -r d2ea1076d58e -r 7d6e9b014c78 src/common/account.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/account.py Wed Nov 11 23:38:17 2009 +0100
@@ -0,0 +1,32 @@
+# -*- coding:utf-8 -*-
+## src/common/contacts.py
+##
+## Copyright (C) 2009 Stephan Erb <steve-e AT h3c.de>
+##
+## This file is part of Gajim.
+##
+## Gajim is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published
+## by the Free Software Foundation; version 3 only.
+##
+## Gajim is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
+##
+
+class Account(object):
+
+ def __init__(self, name, contacts, gc_contacts):
+ self.name = name
+ self.contacts = contacts
+ self.gc_contacts = gc_contacts
+
+ def __repr__(self):
+ return self.name
+
+ def __hash__(self):
+ return self.name.__hash__()
\ No newline at end of file
diff -r d2ea1076d58e -r 7d6e9b014c78 src/common/caps.py
--- a/src/common/caps.py Tue Nov 10 23:33:39 2009 +0200
+++ b/src/common/caps.py Wed Nov 11 23:38:17 2009 +0100
@@ -40,13 +40,34 @@
# Features where we cannot safely assume that the other side supports them
FEATURE_BLACKLIST = [NS_CHATSTATES, NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION]
+# Query entry status codes
+NEW = 0
+QUERIED = 1
+CACHED = 2 # got the answer
+
+################################################################################
+### Public API of this module
+################################################################################
capscache = None
def initialize(logger):
- ''' Initializes the capscache global '''
+ ''' Initializes this module '''
global capscache
capscache = CapsCache(logger)
+def client_supports(client_caps, requested_feature):
+ lookup_item = client_caps.get_cache_lookup_strategy()
+ cache_item = lookup_item(capscache)
+
+ supported_features = cache_item.features
+ if requested_feature in supported_features:
+ return True
+ elif supported_features == [] and cache_item.status in (NEW, QUERIED):
+ # assume feature is supported, if we don't know yet, what the
client
+ # is capable of
+ return requested_feature not in FEATURE_BLACKLIST
+ else:
+ return False
def compute_caps_hash(identities, features, dataforms=[], hash_method='sha-1'):
'''Compute caps hash according to XEP-0115, V1.5
@@ -118,6 +139,10 @@
return base64.b64encode(hash_.digest())
+################################################################################
+### Internal classes of this module
+################################################################################
+
class AbstractClientCaps(object):
'''
Base class representing a client and its capabilities as advertised by
@@ -147,8 +172,8 @@
def _is_hash_valid(self, identities, features, dataforms):
''' To be implemented by subclassess '''
raise NotImplementedError()
-
-
+
+
class ClientCaps(AbstractClientCaps):
''' The current XEP-115 implementation '''
@@ -167,7 +192,7 @@
computed_hash = compute_caps_hash(identities, features,
dataforms=dataforms,
hash_method=self._hash_method)
return computed_hash == self._hash
-
+
class OldClientCaps(AbstractClientCaps):
''' Old XEP-115 implemtation. Kept around for background competability.
'''
@@ -183,7 +208,7 @@
def _is_hash_valid(self, identities, features, dataforms):
return True
-
+
class NullClientCaps(AbstractClientCaps):
'''
@@ -199,7 +224,7 @@
def _lookup_in_cache(self, caps_cache):
# lookup something which does not exist to get a new CacheItem
created
cache_item = caps_cache[('dummy', '')]
- assert cache_item.queried != 2
+ assert cache_item.status != CACHED
return cache_item
def _discover(self, connection, jid):
@@ -236,12 +261,8 @@
self._identities = []
self._logger = logger
- # not cached into db:
- # have we sent the query?
- # 0 == not queried
- # 1 == queried
- # 2 == got the answer
- self.queried = 0
+ self.status = NEW
+ self._recently_seen = False
def _get_features(self):
return self._features
@@ -283,19 +304,28 @@
self.features = features
self._logger.add_caps_entry(self.hash_method,
self.hash,
identities, features)
+ self.status = CACHED
+
+ def update_last_seen(self):
+ if not self._recently_seen:
+ self._recently_seen = True
+
self._logger.update_caps_time(self.hash_method, self.hash)
self.__CacheItem = CacheItem
self.logger = logger
def initialize_from_db(self):
- # get data from logger...
- if self.logger is not None:
- for hash_method, hash_, identities, features in \
- self.logger.iter_caps_data():
- x = self[(hash_method, hash_)]
- x.identities = identities
- x.features = features
- x.queried = 2
+ self._remove_outdated_caps()
+ for hash_method, hash_, identities, features in \
+ self.logger.iter_caps_data():
+ x = self[(hash_method, hash_)]
+ x.identities = identities
+ x.features = features
+ x.status = CACHED
+
+ def _remove_outdated_caps(self):
+ '''Removes outdated values from the db'''
+ self.logger.clean_caps_table()
def __getitem__(self, caps):
if caps in self.__cache:
@@ -315,13 +345,18 @@
lookup_cache_item = client_caps.get_cache_lookup_strategy()
q = lookup_cache_item(self)
- if q.queried == 0:
+ if q.status == NEW:
# do query for bare node+hash pair
# this will create proper object
- q.queried = 1
+ q.status = QUERIED
discover = client_caps.get_discover_strategy()
discover(connection, jid)
+ else:
+ q.update_last_seen()
+################################################################################
+### Caps network coding
+################################################################################
class ConnectionCaps(object):
'''
@@ -366,7 +401,7 @@
client_caps = OldClientCaps(caps_hash, node)
else:
client_caps = ClientCaps(caps_hash, node,
hash_method)
-
+
capscache.query_client_of_jid_if_unknown(self, jid, client_caps)
contact.client_caps = client_caps
@@ -384,7 +419,7 @@
lookup = contact.client_caps.get_cache_lookup_strategy()
cache_item = lookup(capscache)
- if cache_item.queried == 2:
+ if cache_item.status == CACHED:
return
else:
validate =
contact.client_caps.get_hash_validation_strategy()
diff -r d2ea1076d58e -r 7d6e9b014c78 src/common/check_paths.py
--- a/src/common/check_paths.py Tue Nov 10 23:33:39 2009 +0200
+++ b/src/common/check_paths.py Wed Nov 11 23:38:17 2009 +0100
@@ -91,7 +91,8 @@
CREATE TABLE caps_cache (
hash_method TEXT,
hash TEXT,
- data BLOB);
+ data BLOB,
+ last_seen INTEGER);
CREATE TABLE rooms_last_message_time(
jid_id INTEGER PRIMARY KEY UNIQUE,
diff -r d2ea1076d58e -r 7d6e9b014c78 src/common/connection_handlers.py
--- a/src/common/connection_handlers.py Tue Nov 10 23:33:39 2009 +0200
+++ b/src/common/connection_handlers.py Wed Nov 11 23:38:17 2009 +0100
@@ -2468,8 +2468,12 @@
for sess in self.sessions[jid].values():
if not sess.received_thread_id:
contact =
gajim.contacts.get_contact(self.name, jid)
-
- session_supported =
contact.supports(common.xmpp.NS_SSN) or \
+ # FIXME: I don't know if this
is the correct behavior here.
+ # Anyway, it is the old
behavior when we assumed that
+ # not-existing contacts don't
support anything
+ contact_exists = bool(contact)
+ session_supported =
contact_exists and \
+
contact.supports(common.xmpp.NS_SSN) or \
contact.supports(common.xmpp.NS_ESESSION)
if session_supported:
sess.terminate()
diff -r d2ea1076d58e -r 7d6e9b014c78 src/common/contacts.py
--- a/src/common/contacts.py Tue Nov 10 23:33:39 2009 +0200
+++ b/src/common/contacts.py Wed Nov 11 23:38:17 2009 +0100
@@ -29,18 +29,24 @@
##
import common.gajim
+import caps
+from account import Account
+class XMPPEntity(object):
+ '''Base representation of entities in XMPP'''
+
+ def __init__(self, jid, account, resource):
+ self.jid = jid
+ self.resource = resource
+ self.account = account
-from common import caps
-
-
-class CommonContact(object):
+class CommonContact(XMPPEntity):
- def __init__(self, jid, resource, show, status, name, our_chatstate,
+ def __init__(self, jid, account, resource, show, status, name,
our_chatstate,
composing_xep, chatstate, client_caps=None):
- self.jid = jid
- self.resource = resource
+ XMPPEntity.__init__(self, jid, account, resource)
+
self.show = show
self.status = status
self.name = name
@@ -80,35 +86,21 @@
# return caps for a contact that has no resources left.
return False
else:
- return self._client_supports(requested_feature)
-
_______________________________________________
Commits mailing list
[email protected]
http://lists.gajim.org/cgi-bin/listinfo/commits