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': {},