From 5a6f03dea47b958024bbb369766cdd9006516924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Fri, 27 Jul 2018 15:46:02 +0200 Subject: [PATCH] Add connect_maschine() Add method that sequentially works the steps we have to do before sending first presence - Move Delimiter into own module - Move Metacontacts into own module --- gajim/common/app.py | 4 +- gajim/common/connection.py | 150 +++--------------- gajim/common/connection_handlers.py | 33 ---- gajim/common/connection_handlers_events.py | 31 ---- gajim/common/contacts.py | 17 +- gajim/common/helpers.py | 8 + gajim/common/modules/__init__.py | 5 +- gajim/common/modules/bookmarks.py | 3 + gajim/common/modules/delimiter.py | 71 +++++++++ gajim/common/modules/discovery.py | 2 +- gajim/common/modules/metacontacts.py | 107 +++++++++++++ gajim/common/modules/roster.py | 45 +++--- .../zeroconf/connection_handlers_zeroconf.py | 8 - gajim/groupchat_control.py | 2 +- gajim/gtk/join_groupchat.py | 5 +- gajim/roster_window.py | 15 +- gajim/statusicon.py | 13 +- test/lib/gajim_mocks.py | 1 - 18 files changed, 270 insertions(+), 250 deletions(-) create mode 100644 gajim/common/modules/delimiter.py create mode 100644 gajim/common/modules/metacontacts.py diff --git a/gajim/common/app.py b/gajim/common/app.py index 0fd18d923..3e2a73697 100644 --- a/gajim/common/app.py +++ b/gajim/common/app.py @@ -415,7 +415,9 @@ def account_is_zeroconf(account): return connections[account].is_zeroconf def account_supports_private_storage(account): - return connections[account].private_storage_supported + # If Delimiter module is not available we can assume + # Private Storage is not available + return connections[account].get_module('Delimiter').available def account_is_connected(account): if account not in connections: diff --git a/gajim/common/connection.py b/gajim/common/connection.py index 30a6bb94e..fe6c0ab71 100644 --- a/gajim/common/connection.py +++ b/gajim/common/connection.py @@ -115,7 +115,6 @@ class CommonConnection: # the fake jid self.groupchat_jids = {} # {ID : groupchat_jid} - self.private_storage_supported = False self.roster_supported = True self.addressing_supported = False @@ -124,7 +123,8 @@ class CommonConnection: self.awaiting_cids = {} # Used for XEP-0231 - self.nested_group_delimiter = '::' + # Tracks the calls of the connect_maschine() method + self._connect_maschine_calls = 0 self.get_config_values_or_default() @@ -412,12 +412,6 @@ class CommonConnection: def account_changed(self, new_name): self.name = new_name - def get_metacontacts(self): - """ - To be implemented by derived classes - """ - raise NotImplementedError - def send_agent_status(self, agent, ptype): """ To be implemented by derived classes @@ -546,8 +540,7 @@ class Connection(CommonConnection, ConnectionHandlers): self.retrycount = 0 self.available_transports = {} # list of available transports on this # server {'icq': ['icq.server.com', 'icq2.server.com'], } - self.private_storage_supported = True - self.privacy_rules_requested = False + self.streamError = '' self.secret_hmac = str(random.random())[2:].encode('utf-8') self.removing_account = False @@ -644,7 +637,6 @@ class Connection(CommonConnection, ConnectionHandlers): self.on_purpose = on_purpose self.connected = 0 self.time_to_reconnect = None - self.get_module('PrivacyLists').supported = False self.get_module('VCardAvatars').avatar_advertised = False if on_purpose: self.sm = Smacks(self) @@ -1427,6 +1419,9 @@ class Connection(CommonConnection, ConnectionHandlers): # Get annotations self.get_module('Annotations').get_annotations() + # Blocking + self.get_module('Blocking').get_blocking_list() + # Inform GUI we just signed in app.nec.push_incoming_event(SignedInEvent(None, conn=self)) @@ -1455,60 +1450,39 @@ class Connection(CommonConnection, ConnectionHandlers): self.pingalives, self.get_module('Ping').send_keepalive_ping) self.connection.onreceive(None) - self.privacy_rules_requested = False - # If we are not resuming, we ask for discovery info # and archiving preferences if not self.sm.supports_sm or (not self.sm.resuming and self.sm.enabled): - our_server = app.config.get_per('accounts', self.name, 'hostname') - self.get_module('Discovery').discover_account_info() + # This starts the connect_maschine self.get_module('Discovery').discover_server_info() - else: - self.request_roster(resume=True) + self.get_module('Discovery').discover_account_info() - self.sm.resuming = False # back to previous state + self.sm.resuming = False # back to previous state # Discover Stun server(s) if self._proxy is None: hostname = app.config.get_per('accounts', self.name, 'hostname') - app.resolver.resolve('_stun._udp.' + helpers.idn_to_ascii(hostname), - self._on_stun_resolved) + app.resolver.resolve( + '_stun._udp.' + helpers.idn_to_ascii(hostname), + self._on_stun_resolved) def _on_stun_resolved(self, host, result_array): if len(result_array) != 0: self._stun_servers = self._hosts = [i for i in result_array] - def _continue_connection_request_privacy(self): - if self.get_module('PrivacyLists').supported: - if not self.privacy_rules_requested: - self.privacy_rules_requested = True - self.get_module('PrivacyLists').get_privacy_lists( - self._received_privacy) - else: - # Privacy lists not supported - log.info('Privacy Lists not supported') - self._received_privacy(False) - - def _received_privacy(self, result): - if not result: - if (self.continue_connect_info and - self.continue_connect_info[0] == 'invisible'): - # Trying to login as invisible but privacy list not - # supported - self.disconnect(on_purpose=True) - app.nec.push_incoming_event(OurShowEvent( - None, conn=self, show='offline')) - app.nec.push_incoming_event(InformationEvent( - None, dialog_name='invisibility-not-supported', - args=self.name)) - return - - self.get_module('Blocking').get_blocking_list() - - # Ask metacontacts before roster - self.get_metacontacts() + @helpers.call_counter + def connect_maschine(self, restart=False): + log.info('Connect maschine state: %s', self._connect_maschine_calls) + if self._connect_maschine_calls == 1: + self.get_module('MetaContacts').get_metacontacts() + elif self._connect_maschine_calls == 2: + self.get_module('Delimiter').get_roster_delimiter() + elif self._connect_maschine_calls == 3: + self.get_module('Roster').request_roster() + elif self._connect_maschine_calls == 4: + self.send_first_presence() def send_custom_status(self, show, msg, jid): - if not show in app.SHOW_LIST: + if show not in app.SHOW_LIST: return -1 if not app.account_is_connected(self.name): return @@ -1677,85 +1651,9 @@ class Connection(CommonConnection, ConnectionHandlers): query.setTagData('prompt', prompt) self.connection.SendAndCallForResponse(iq, _on_prompt_result) - def bookmarks_available(self): - if self.private_storage_supported: - return True - if self.get_module('PubSub').publish_options: - return True - return False - - def get_roster_delimiter(self): - """ - Get roster group delimiter from storage as described in XEP 0083 - """ - if not app.account_is_connected(self.name): - return - iq = nbxmpp.Iq(typ='get') - iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE) - iq2.addChild(name='roster', namespace='roster:delimiter') - id_ = self.connection.getAnID() - iq.setID(id_) - self.awaiting_answers[id_] = (DELIMITER_ARRIVED, ) - self.connection.send(iq) - - def set_roster_delimiter(self, delimiter='::'): - """ - Set roster group delimiter to the storage namespace - """ - if not app.account_is_connected(self.name): - return - iq = nbxmpp.Iq(typ='set') - iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE) - iq3 = iq2.addChild(name='roster', namespace='roster:delimiter') - iq3.setData(delimiter) - - self.connection.send(iq) - - def get_metacontacts(self): - """ - Get metacontacts list from storage as described in XEP 0049 - """ - if not app.account_is_connected(self.name): - return - iq = nbxmpp.Iq(typ='get') - iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE) - iq2.addChild(name='storage', namespace='storage:metacontacts') - id_ = self.connection.getAnID() - iq.setID(id_) - self.awaiting_answers[id_] = (METACONTACTS_ARRIVED, ) - self.connection.send(iq) - - def store_metacontacts(self, tags_list): - """ - Send meta contacts to the storage namespace - """ - if not app.account_is_connected(self.name): - return - iq = nbxmpp.Iq(typ='set') - iq2 = iq.addChild(name='query', namespace=nbxmpp.NS_PRIVATE) - iq3 = iq2.addChild(name='storage', namespace='storage:metacontacts') - for tag in tags_list: - for data in tags_list[tag]: - jid = data['jid'] - dict_ = {'jid': jid, 'tag': tag} - if 'order' in data: - dict_['order'] = data['order'] - iq3.addChild(name='meta', attrs=dict_) - self.connection.send(iq) - def getRoster(self): return self.get_module('Roster') - def request_roster(self, resume=False): - version = None - features = self.connection.Dispatcher.Stream.features - if features and features.getTag('ver', namespace=nbxmpp.NS_ROSTER_VER): - version = app.config.get_per( - 'accounts', self.name, 'roster_version') - - if not resume: - self.get_module('Roster').request_roster(version) - def send_agent_status(self, agent, ptype): if not app.account_is_connected(self.name): return diff --git a/gajim/common/connection_handlers.py b/gajim/common/connection_handlers.py index 1575438c6..edba6c4d6 100644 --- a/gajim/common/connection_handlers.py +++ b/gajim/common/connection_handlers.py @@ -53,10 +53,6 @@ log = logging.getLogger('gajim.c.connection_handlers') # kind of events we can wait for an answer AGENT_REMOVED = 'agent_removed' -METACONTACTS_ARRIVED = 'metacontacts_arrived' -ROSTER_ARRIVED = 'roster_arrived' -DELIMITER_ARRIVED = 'delimiter_arrived' -PRIVACY_ARRIVED = 'privacy_arrived' class ConnectionDisco: @@ -518,35 +514,6 @@ class ConnectionHandlers(ConnectionSocks5Bytestream, ConnectionDisco, app.nec.push_incoming_event(AgentRemovedEvent(None, conn=self, agent=jid)) del self.awaiting_answers[id_] - elif self.awaiting_answers[id_][0] == METACONTACTS_ARRIVED: - if not self.connection: - return - if iq_obj.getType() == 'result': - app.nec.push_incoming_event(MetacontactsReceivedEvent(None, - conn=self, stanza=iq_obj)) - else: - if iq_obj.getErrorCode() not in ('403', '406', '404'): - self.private_storage_supported = False - self.get_roster_delimiter() - del self.awaiting_answers[id_] - elif self.awaiting_answers[id_][0] == DELIMITER_ARRIVED: - del self.awaiting_answers[id_] - if not self.connection: - return - if iq_obj.getType() == 'result': - query = iq_obj.getTag('query') - if not query: - return - delimiter = query.getTagData('roster') - if delimiter: - self.nested_group_delimiter = delimiter - else: - self.set_roster_delimiter('::') - else: - self.private_storage_supported = False - - # We can now continue connection by requesting the roster - self.request_roster() def _dispatch_gc_msg_with_captcha(self, stanza, msg_obj): msg_obj.stanza = stanza diff --git a/gajim/common/connection_handlers_events.py b/gajim/common/connection_handlers_events.py index 81216256f..6c72a05c3 100644 --- a/gajim/common/connection_handlers_events.py +++ b/gajim/common/connection_handlers_events.py @@ -852,37 +852,6 @@ class UpdateRoomAvatarEvent(nec.NetworkIncomingEvent): def generate(self): return True -class MetacontactsReceivedEvent(nec.NetworkIncomingEvent): - name = 'metacontacts-received' - base_network_events = [] - - def generate(self): - # Metacontact tags - # http://www.xmpp.org/extensions/xep-0209.html - self.meta_list = {} - query = self.stanza.getTag('query') - storage = query.getTag('storage') - metas = storage.getTags('meta') - for meta in metas: - try: - jid = helpers.parse_jid(meta.getAttr('jid')) - except helpers.InvalidFormat: - continue - tag = meta.getAttr('tag') - data = {'jid': jid} - order = meta.getAttr('order') - try: - order = int(order) - except Exception: - order = 0 - if order is not None: - data['order'] = order - if tag in self.meta_list: - self.meta_list[tag].append(data) - else: - self.meta_list[tag] = [data] - return True - class ZeroconfNameConflictEvent(nec.NetworkIncomingEvent): name = 'zeroconf-name-conflict' base_network_events = [] diff --git a/gajim/common/contacts.py b/gajim/common/contacts.py index 9eed0be86..ab3bbddaf 100644 --- a/gajim/common/contacts.py +++ b/gajim/common/contacts.py @@ -732,8 +732,9 @@ class MetacontactManager(): self._metacontacts_tags[brother_account][tag] = [{'jid': brother_jid, 'tag': tag}] if brother_account != account: - common.app.connections[brother_account].store_metacontacts( - self._metacontacts_tags[brother_account]) + con = common.app.connections[brother_account] + con.get_module('MetaContacts').store_metacontacts( + self._metacontacts_tags[brother_account]) # be sure jid has no other tag old_tag = self._get_metacontacts_tag(account, jid) while old_tag: @@ -748,11 +749,12 @@ class MetacontactManager(): else: self._metacontacts_tags[account][tag].append({'jid': jid, 'tag': tag}) - common.app.connections[account].store_metacontacts( - self._metacontacts_tags[account]) + con = common.app.connections[account] + con.get_module('MetaContacts').store_metacontacts( + self._metacontacts_tags[account]) def remove_metacontact(self, account, jid): - if not account in self._metacontacts_tags: + if account not in self._metacontacts_tags: return found = None @@ -763,8 +765,9 @@ class MetacontactManager(): break if found: self._metacontacts_tags[account][tag].remove(found) - common.app.connections[account].store_metacontacts( - self._metacontacts_tags[account]) + con = common.app.connections[account] + con.get_module('MetaContacts').store_metacontacts( + self._metacontacts_tags[account]) break def has_brother(self, account, jid, accounts): diff --git a/gajim/common/helpers.py b/gajim/common/helpers.py index aad03bcbc..692576c25 100644 --- a/gajim/common/helpers.py +++ b/gajim/common/helpers.py @@ -1508,3 +1508,11 @@ def get_emoticon_theme_path(theme): emoticons_user_path = os.path.join(configpaths.get('MY_EMOTS'), theme) if os.path.exists(emoticons_user_path): return emoticons_user_path + +def call_counter(func): + def helper(self, restart=False): + if restart: + self._connect_maschine_calls = 0 + self._connect_maschine_calls += 1 + return func(self, restart=False) + return helper diff --git a/gajim/common/modules/__init__.py b/gajim/common/modules/__init__.py index 5c5a0b2dc..3aef57ac5 100644 --- a/gajim/common/modules/__init__.py +++ b/gajim/common/modules/__init__.py @@ -43,7 +43,7 @@ class ModuleMock: def __init__(self, name): self._name = name - # HTTPUpload + # HTTPUpload, .. self.available = False # Blocking @@ -54,6 +54,9 @@ class ModuleMock: self.blocked_groups = [] self.blocked_all = False + # Delimiter + self.delimiter = '::' + # Bookmarks self.bookmarks = {} diff --git a/gajim/common/modules/bookmarks.py b/gajim/common/modules/bookmarks.py index d95b0594f..9f1a056f5 100644 --- a/gajim/common/modules/bookmarks.py +++ b/gajim/common/modules/bookmarks.py @@ -31,6 +31,7 @@ class Bookmarks: self._con = con self._account = con.name self.bookmarks = {} + self.available = False self.handlers = [] @@ -65,6 +66,7 @@ class Bookmarks: self._request_private_bookmarks() return + self.available = True log.info('Received Bookmarks (PubSub)') self._parse_bookmarks(stanza) self._request_private_bookmarks() @@ -84,6 +86,7 @@ class Bookmarks: if not nbxmpp.isResultNode(stanza): log.info('No private bookmarks: %s', stanza.getError()) else: + self.available = True log.info('Received Bookmarks (PrivateStorage)') merged = self._parse_bookmarks(stanza, check_merge=True) if merged and self._pubsub_support(): diff --git a/gajim/common/modules/delimiter.py b/gajim/common/modules/delimiter.py new file mode 100644 index 000000000..2f04d5d4e --- /dev/null +++ b/gajim/common/modules/delimiter.py @@ -0,0 +1,71 @@ +# 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 . + +# XEP-0083: Nested Roster Groups + +import logging + +import nbxmpp + +log = logging.getLogger('gajim.c.m.delimiter') + + +class Delimiter: + def __init__(self, con): + self._con = con + self._account = con.name + self.available = False + + self.delimiter = '::' + + self.handlers = [] + + def get_roster_delimiter(self): + log.info('Request') + node = nbxmpp.Node('storage', attrs={'xmlns': 'roster:delimiter'}) + iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVATE, payload=node) + + self._con.connection.SendAndCallForResponse( + iq, self._delimiter_received) + + def _delimiter_received(self, stanza): + if not nbxmpp.isResultNode(stanza): + log.info('Request error: %s', stanza.getError()) + else: + delimiter = stanza.getQuery().getTagData('roster') + self.available = True + log.info('Delimiter received: %s', delimiter) + if delimiter: + self.delimiter = delimiter + else: + self.set_roster_delimiter() + + self._con.connect_maschine() + + def set_roster_delimiter(self): + log.info('Set delimiter') + iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVATE) + roster = iq.getQuery().addChild('roster', namespace='roster:delimiter') + roster.setData('::') + + self._con.connection.SendAndCallForResponse( + iq, self._set_delimiter_response) + + def _set_delimiter_response(self, stanza): + if not nbxmpp.isResultNode(stanza): + log.info('Store error: %s', stanza.getError()) + + +def get_instance(*args, **kwargs): + return Delimiter(*args, **kwargs), 'Delimiter' diff --git a/gajim/common/modules/discovery.py b/gajim/common/modules/discovery.py index de6f1eb27..22c5bd0cd 100644 --- a/gajim/common/modules/discovery.py +++ b/gajim/common/modules/discovery.py @@ -199,7 +199,7 @@ class Discovery: if nbxmpp.NS_ADDRESS in features: self._con.addressing_supported = True - self._con._continue_connection_request_privacy() + self._con.connect_maschine() def _parse_transports(self, from_, identities, features, data, node): for identity in identities: diff --git a/gajim/common/modules/metacontacts.py b/gajim/common/modules/metacontacts.py new file mode 100644 index 000000000..ac921c6d4 --- /dev/null +++ b/gajim/common/modules/metacontacts.py @@ -0,0 +1,107 @@ +# 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 . + +# XEP-0209: Metacontacts + +import logging + +import nbxmpp + +from gajim.common import app +from gajim.common import helpers +from gajim.common.nec import NetworkEvent + +log = logging.getLogger('gajim.c.m.metacontacts') + + +class MetaContacts: + def __init__(self, con): + self._con = con + self._account = con.name + self.available = False + + self.handlers = [] + + def get_metacontacts(self): + log.info('Request') + node = nbxmpp.Node('storage', attrs={'xmlns': 'storage:metacontacts'}) + iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVATE, payload=node) + + self._con.connection.SendAndCallForResponse( + iq, self._metacontacts_received) + + def _metacontacts_received(self, stanza): + if not nbxmpp.isResultNode(stanza): + log.info('Request error: %s', stanza.getError()) + else: + self.available = True + meta_list = self._parse_metacontacts(stanza) + + log.info('Received: %s', meta_list) + + app.nec.push_incoming_event(NetworkEvent( + 'metacontacts-received', conn=self._con, meta_list=meta_list)) + + self._con.connect_maschine() + + @staticmethod + def _parse_metacontacts(stanza): + meta_list = {} + query = stanza.getQuery() + storage = query.getTag('storage') + metas = storage.getTags('meta') + for meta in metas: + try: + jid = helpers.parse_jid(meta.getAttr('jid')) + except helpers.InvalidFormat: + continue + tag = meta.getAttr('tag') + data = {'jid': jid} + order = meta.getAttr('order') + try: + order = int(order) + except Exception: + order = 0 + if order is not None: + data['order'] = order + if tag in meta_list: + meta_list[tag].append(data) + else: + meta_list[tag] = [data] + return meta_list + + def store_metacontacts(self, tags_list): + if not app.account_is_connected(self._account): + return + iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVATE) + meta = iq.getQuery().addChild('storage', + namespace='storage:metacontacts') + for tag in tags_list: + for data in tags_list[tag]: + jid = data['jid'] + dict_ = {'jid': jid, 'tag': tag} + if 'order' in data: + dict_['order'] = data['order'] + meta.addChild(name='meta', attrs=dict_) + log.info('Store: %s', tags_list) + self._con.connection.SendAndCallForResponse( + iq, self._store_response_received) + + def _store_response_received(self, stanza): + if not nbxmpp.isResultNode(stanza): + log.info('Store error: %s', stanza.getError()) + + +def get_instance(*args, **kwargs): + return MetaContacts(*args, **kwargs), 'MetaContacts' diff --git a/gajim/common/modules/roster.py b/gajim/common/modules/roster.py index 735fb65b2..bdf68c108 100644 --- a/gajim/common/modules/roster.py +++ b/gajim/common/modules/roster.py @@ -24,10 +24,6 @@ from gajim.common.nec import NetworkEvent log = logging.getLogger('gajim.c.m.roster') - -# TODO: Error IQs -# What if roster not supported on server -> error - RosterItem = namedtuple('RosterItem', 'jid data') @@ -65,7 +61,13 @@ class Roster: app.config.set_per( 'accounts', self._account, 'roster_version', '') - def request_roster(self, version): + def request_roster(self): + version = None + features = self._con.connection.Dispatcher.Stream.features + if features and features.getTag('ver', namespace=nbxmpp.NS_ROSTER_VER): + version = app.config.get_per( + 'accounts', self._account, 'roster_version') + log.info('Requested from server') iq = nbxmpp.Iq('get', nbxmpp.NS_ROSTER) if version is not None: @@ -77,27 +79,26 @@ class Roster: def _roster_received(self, stanza): if not nbxmpp.isResultNode(stanza): log.warning('Unable to retrive roster: %s', stanza.getError()) - return + else: + log.info('Received Roster') + received_from_server = False + if stanza.getTag('query') is not None: + # clear Roster + self._data = {} + version = self._parse_roster(stanza) - log.info('Received Roster') - received_from_server = False - if stanza.getTag('query') is not None: - # clear Roster - self._data = {} - version = self._parse_roster(stanza) + log.info('New version: %s', version) + app.logger.replace_roster(self._account, version, self._data) - log.info('New version: %s', version) - app.logger.replace_roster(self._account, version, self._data) + received_from_server = True - received_from_server = True + app.nec.push_incoming_event(NetworkEvent( + 'roster-received', + conn=self._con, + roster=self._data.copy(), + received_from_server=received_from_server)) - app.nec.push_incoming_event(NetworkEvent( - 'roster-received', - conn=self._con, - roster=self._data.copy(), - received_from_server=received_from_server)) - - self._con.send_first_presence() + self._con.connect_maschine() def _roster_push_received(self, con, stanza): log.info('Push received') diff --git a/gajim/common/zeroconf/connection_handlers_zeroconf.py b/gajim/common/zeroconf/connection_handlers_zeroconf.py index d9333aaee..04181787a 100644 --- a/gajim/common/zeroconf/connection_handlers_zeroconf.py +++ b/gajim/common/zeroconf/connection_handlers_zeroconf.py @@ -183,11 +183,3 @@ connection_handlers.ConnectionJingle): app.nec.push_incoming_event( DecryptedMessageReceivedEvent(None, **vars(event))) - - def store_metacontacts(self, tags): - """ - Fake empty method - """ - # serverside metacontacts are not supported with zeroconf - # (there is no server) - pass diff --git a/gajim/groupchat_control.py b/gajim/groupchat_control.py index 6c8847f2d..4504b91e6 100644 --- a/gajim/groupchat_control.py +++ b/gajim/groupchat_control.py @@ -592,7 +592,7 @@ class GroupchatControl(ChatControlBase): # Bookmarks con = app.connections[self.account] - bookmark_support = con.bookmarks_available() + bookmark_support = con.get_module('Bookmarks').available bookmarked = self.room_jid in con.get_module('Bookmarks').bookmarks win.lookup_action('bookmark-' + self.control_id).set_enabled( online and bookmark_support and not bookmarked) diff --git a/gajim/gtk/join_groupchat.py b/gajim/gtk/join_groupchat.py index 22dc2e7c7..f94e9f498 100644 --- a/gajim/gtk/join_groupchat.py +++ b/gajim/gtk/join_groupchat.py @@ -111,7 +111,8 @@ class JoinGroupchatWindow(Gtk.ApplicationWindow): # Set bookmark switch sensitive if server supports bookmarks acc = self.account_combo.get_active_id() - if not app.connections[acc].private_storage_supported: + con = app.connections[acc] + if not con.get_module('Bookmarks').available: self.bookmark_switch.set_sensitive(False) self.autojoin_switch.set_sensitive(False) @@ -256,8 +257,6 @@ class JoinGroupchatWindow(Gtk.ApplicationWindow): def _add_bookmark(self, account, nickname, password): con = app.connections[account] - if not con.private_storage_supported: - return add_bookmark = self.bookmark_switch.get_active() if not add_bookmark: diff --git a/gajim/roster_window.py b/gajim/roster_window.py index 9d130ccea..081159cef 100644 --- a/gajim/roster_window.py +++ b/gajim/roster_window.py @@ -343,7 +343,7 @@ class RosterWindow: account_group = 'MERGED' else: account_group = account - delimiter = app.connections[account].nested_group_delimiter + delimiter = app.connections[account].get_module('Delimiter').delimiter group_splited = group.split(delimiter) parent_group = delimiter.join(group_splited[:-1]) if len(group_splited) > 1 and parent_group in self._iters[account_group]['groups']: @@ -1347,7 +1347,7 @@ class RosterWindow: self.draw_parent_contact(jid, account) if visible: - delimiter = app.connections[account].nested_group_delimiter + delimiter = app.connections[account].get_module('Delimiter').delimiter for group in contact.get_shown_groups(): group_splited = group.split(delimiter) i = 1 @@ -1600,7 +1600,7 @@ class RosterWindow: return if account not in app.connections: return - delimiter = app.connections[account].nested_group_delimiter + delimiter = app.connections[account].get_module('Delimiter').delimiter group_splited = group.split(delimiter) i = 1 while i < len(group_splited) + 1: @@ -4159,9 +4159,10 @@ class RosterWindow: def on_drop_in_contact(self, widget, account_source, c_source, account_dest, c_dest, was_big_brother, context, etime): - - if not app.connections[account_source].private_storage_supported or \ - not app.connections[account_dest].private_storage_supported: + con_source = app.connections[account_source] + con_dest = app.connections[account_dest] + if (not con_source.get_module('MetaContacts').available or + not con_dest.get_module('MetaContacts').available): WarningDialog(_('Metacontacts storage not supported by ' 'your server'), _('Your server does not support storing metacontacts ' @@ -4433,7 +4434,7 @@ class RosterWindow: # drop on another account return grp_source = model[iter_source][Column.JID] - delimiter = app.connections[account_source].nested_group_delimiter + delimiter = app.connections[account_source].get_module('Delimiter').delimiter grp_source_list = grp_source.split(delimiter) new_grp = None if type_dest == 'account': diff --git a/gajim/statusicon.py b/gajim/statusicon.py index 747e79d0f..db8356b43 100644 --- a/gajim/statusicon.py +++ b/gajim/statusicon.py @@ -221,8 +221,6 @@ class StatusIcon: if connected_accounts < 1: item.set_sensitive(False) - connected_accounts_with_private_storage = 0 - item = Gtk.SeparatorMenuItem.new() sub_menu.append(item) @@ -271,8 +269,6 @@ class StatusIcon: for account in app.connections: if app.account_is_connected(account) and \ not app.config.get_per('accounts', account, 'is_zeroconf'): - if app.connections[account].private_storage_supported: - connected_accounts_with_private_storage += 1 # for single message single_message_menuitem.set_submenu(None) @@ -296,8 +292,6 @@ class StatusIcon: if app.connections[account].is_zeroconf or \ not app.account_is_connected(account): continue - if app.connections[account].private_storage_supported: - connected_accounts_with_private_storage += 1 # for single message item = Gtk.MenuItem.new_with_label( _('using account %s') % account_label) @@ -320,9 +314,12 @@ class StatusIcon: newitem = Gtk.MenuItem.new_with_mnemonic(_('_Manage Bookmarks…')) newitem.connect('activate', app.interface.roster.on_manage_bookmarks_menuitem_activate) + newitem.set_sensitive(False) gc_sub_menu.append(newitem) - if connected_accounts_with_private_storage == 0: - newitem.set_sensitive(False) + for account in accounts_list: + if app.account_supports_private_storage(account): + newitem.set_sensitive(True) + break sounds_mute_menuitem.set_active(not app.config.get('sounds_on')) diff --git a/test/lib/gajim_mocks.py b/test/lib/gajim_mocks.py index 713529bdc..6dabcb290 100644 --- a/test/lib/gajim_mocks.py +++ b/test/lib/gajim_mocks.py @@ -21,7 +21,6 @@ class MockConnection(Mock, ConnectionHandlers): self.connected = 2 self.pep = {} self.sessions = {} - self.nested_group_delimiter = '::' self.server_resource = 'Gajim' app.interface.instances[account] = {'infos': {}, 'disco': {},