diff --git a/gajim/common/connection.py b/gajim/common/connection.py index d5f051aa9..d5abf673d 100644 --- a/gajim/common/connection.py +++ b/gajim/common/connection.py @@ -61,29 +61,9 @@ from gajim.common import gpg from gajim.common import passwords from gajim.common import i18n from gajim.common import idle -from gajim.common.helpers import ModuleMock -from gajim.common.modules.entity_time import EntityTime -from gajim.common.modules.software_version import SoftwareVersion -from gajim.common.modules.ping import Ping -from gajim.common.modules.search import Search -from gajim.common.modules.annotations import Annotations -from gajim.common.modules.roster_item_exchange import RosterItemExchange -from gajim.common.modules.last_activity import LastActivity -from gajim.common.modules.http_auth import HTTPAuth -from gajim.common.modules.vcard_temp import VCardTemp -from gajim.common.modules.vcard_avatars import VCardAvatars -from gajim.common.modules.pubsub import PubSub -from gajim.common.modules.bookmarks import Bookmarks -from gajim.common.modules.pep import PEP -from gajim.common.modules.user_avatar import UserAvatar -from gajim.common.modules.user_activity import UserActivity -from gajim.common.modules.user_tune import UserTune -from gajim.common.modules.user_mood import UserMood -from gajim.common.modules.user_location import UserLocation -from gajim.common.modules.user_nickname import UserNickname -from gajim.common.modules.httpupload import HTTPUpload from gajim.common.connection_handlers import * from gajim.common.contacts import GC_Contact +from gajim.common import modules from gajim.gtkgui_helpers import get_action @@ -182,19 +162,7 @@ class CommonConnection: app.ged.raise_event(event, self.name, data) def get_module(self, name): - try: - return self._modules[name] - except KeyError: - return ModuleMock() - - def get_module_handlers(self): - handlers = [] - for module in self._modules.values(): - handlers += module.handlers - return handlers - - def register_module(self, name, cls, *args, **kwargs): - self._modules[name] = cls(*args, **kwargs) + return modules.get(self.name, name) def reconnect(self): """ @@ -661,26 +629,8 @@ class Connection(CommonConnection, ConnectionHandlers): self.sm = Smacks(self) # Stream Management - self.register_module('EntityTime', EntityTime, self) - self.register_module('SoftwareVersion', SoftwareVersion, self) - self.register_module('Ping', Ping, self) - self.register_module('Search', Search, self) - self.register_module('Annotations', Annotations, self) - self.register_module('RosterItemExchange', RosterItemExchange, self) - self.register_module('LastActivity', LastActivity, self) - self.register_module('HTTPAuth', HTTPAuth, self) - self.register_module('VCardTemp', VCardTemp, self) - self.register_module('VCardAvatars', VCardAvatars, self) - self.register_module('PubSub', PubSub, self) - self.register_module('PEP', PEP, self) - self.register_module('Bookmarks', Bookmarks, self) - self.register_module('UserAvatar', UserAvatar, self) - self.register_module('UserActivity', UserActivity, self) - self.register_module('UserTune', UserTune, self) - self.register_module('UserMood', UserMood, self) - self.register_module('UserLocation', UserLocation, self) - self.register_module('UserNickname', UserNickname, self) - self.register_module('HTTPUpload', HTTPUpload, self) + # Register all modules + modules.register(self) app.ged.register_event_handler('privacy-list-received', ged.CORE, self._nec_privacy_list_received) @@ -700,6 +650,8 @@ class Connection(CommonConnection, ConnectionHandlers): def cleanup(self): ConnectionHandlers.cleanup(self) + modules.unregister(self) + app.ged.remove_event_handler('privacy-list-received', ged.CORE, self._nec_privacy_list_received) app.ged.remove_event_handler('agent-info-error-received', ged.CORE, @@ -780,6 +732,7 @@ class Connection(CommonConnection, ConnectionHandlers): self.terminate_sessions() self.remove_all_transfers() self.connection.disconnect() + ConnectionHandlers._unregister_handlers(self) self.connection = None def set_oldst(self): # Set old state diff --git a/gajim/common/connection_handlers.py b/gajim/common/connection_handlers.py index af282c060..3dcddc855 100644 --- a/gajim/common/connection_handlers.py +++ b/gajim/common/connection_handlers.py @@ -37,6 +37,7 @@ from gi.repository import GLib import nbxmpp from gajim.common import caps_cache as capscache +from gajim.common import modules from gajim.common import helpers from gajim.common import app from gajim.common import jingle_xtls @@ -1451,5 +1452,9 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream): con.RegisterHandler('iq', self._BlockingResultCB, 'result', nbxmpp.NS_BLOCKING) - for handler in self.get_module_handlers(): + for handler in modules.get_handlers(self): con.RegisterHandler(*handler) + + def _unregister_handlers(self): + for handler in modules.get_handlers(self): + self.connection.UnregisterHandler(*handler) diff --git a/gajim/common/helpers.py b/gajim/common/helpers.py index db6664aad..7ed97bd63 100644 --- a/gajim/common/helpers.py +++ b/gajim/common/helpers.py @@ -165,13 +165,6 @@ class InvalidFormat(Exception): pass -class ModuleMock: - def __getattr__(self, key): - def _mock(self, *args, **kwargs): - return - return _mock - - def decompose_jid(jidstring): user = None server = None diff --git a/gajim/common/modules/__init__.py b/gajim/common/modules/__init__.py index e69de29bb..294d3bf87 100644 --- a/gajim/common/modules/__init__.py +++ b/gajim/common/modules/__init__.py @@ -0,0 +1,65 @@ +# 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 . + +import logging +from importlib import import_module +from pathlib import Path + +log = logging.getLogger('gajim.c.m') + +imported_modules = [] +_modules = {} + +for file in Path(__file__).parent.iterdir(): + if file.stem == '__init__': + continue + + module = import_module('.%s' % file.stem, package='gajim.common.modules') + if hasattr(module, 'get_instance'): + log.info('Load module: %s', file.stem) + imported_modules.append(module) + + +class ModuleMock: + def __getattr__(self, key): + def _mock(self, *args, **kwargs): + return + return _mock + + +def register(con, *args, **kwargs): + if con in _modules: + return + _modules[con.name] = {} + for module in imported_modules: + instance, name = module.get_instance(con, *args, **kwargs) + _modules[con.name][name] = instance + + +def unregister(con): + del _modules[con.name] + + +def get(account, name): + try: + return _modules[account][name] + except KeyError: + return ModuleMock() + + +def get_handlers(con): + handlers = [] + for module in _modules[con.name].values(): + handlers += module.handlers + return handlers diff --git a/gajim/common/modules/annotations.py b/gajim/common/modules/annotations.py index e0fafde7a..fc25a156c 100644 --- a/gajim/common/modules/annotations.py +++ b/gajim/common/modules/annotations.py @@ -90,3 +90,7 @@ class Annotations: log.warning('Storing rosternotes failed: %s', stanza.getError()) return log.info('Storing rosternotes successful') + + +def get_instance(*args, **kwargs): + return Annotations(*args, **kwargs), 'Annotations' diff --git a/gajim/common/modules/bookmarks.py b/gajim/common/modules/bookmarks.py index 7aa5b23a0..9b85588e3 100644 --- a/gajim/common/modules/bookmarks.py +++ b/gajim/common/modules/bookmarks.py @@ -292,3 +292,7 @@ class Bookmarks: class BookmarksReceivedEvent(NetworkIncomingEvent): name = 'bookmarks-received' base_network_events = [] + + +def get_instance(*args, **kwargs): + return Bookmarks(*args, **kwargs), 'Bookmarks' diff --git a/gajim/common/modules/entity_time.py b/gajim/common/modules/entity_time.py index d9d314385..44e50db9b 100644 --- a/gajim/common/modules/entity_time.py +++ b/gajim/common/modules/entity_time.py @@ -162,3 +162,7 @@ class contact_tz(datetime.tzinfo): def dst(self, dt): return ZERO + + +def get_instance(*args, **kwargs): + return EntityTime(*args, **kwargs), 'EntityTime' diff --git a/gajim/common/modules/http_auth.py b/gajim/common/modules/http_auth.py index 52b22e277..1060f69e8 100644 --- a/gajim/common/modules/http_auth.py +++ b/gajim/common/modules/http_auth.py @@ -75,3 +75,7 @@ class HTTPAuth: class HttpAuthReceivedEvent(NetworkIncomingEvent): name = 'http-auth-received' base_network_events = [] + + +def get_instance(*args, **kwargs): + return HTTPAuth(*args, **kwargs), 'HTTPAuth' diff --git a/gajim/common/modules/httpupload.py b/gajim/common/modules/httpupload.py index 1f2afd504..db454adb8 100644 --- a/gajim/common/modules/httpupload.py +++ b/gajim/common/modules/httpupload.py @@ -436,3 +436,7 @@ class UploadAbortedException(Exception): class HTTPUploadProgressEvent(NetworkIncomingEvent): name = 'httpupload-progress' base_network_events = [] + + +def get_instance(*args, **kwargs): + return HTTPUpload(*args, **kwargs), 'HTTPUpload' diff --git a/gajim/common/modules/last_activity.py b/gajim/common/modules/last_activity.py index 71e6b596e..d2268203b 100644 --- a/gajim/common/modules/last_activity.py +++ b/gajim/common/modules/last_activity.py @@ -50,3 +50,7 @@ class LastActivity: self._con.connection.send(iq) raise nbxmpp.NodeProcessed + + +def get_instance(*args, **kwargs): + return LastActivity(*args, **kwargs), 'LastActivity' diff --git a/gajim/common/modules/pep.py b/gajim/common/modules/pep.py index ac7e698a6..01edf4833 100644 --- a/gajim/common/modules/pep.py +++ b/gajim/common/modules/pep.py @@ -212,3 +212,7 @@ class AbstractPEPData: class PEPReceivedEvent(NetworkIncomingEvent): name = 'pep-received' base_network_events = [] + + +def get_instance(*args, **kwargs): + return PEP(*args, **kwargs), 'PEP' diff --git a/gajim/common/modules/ping.py b/gajim/common/modules/ping.py index 8324dbde0..5804c7444 100644 --- a/gajim/common/modules/ping.py +++ b/gajim/common/modules/ping.py @@ -120,3 +120,7 @@ class PingReplyEvent(NetworkIncomingEvent): class PingErrorEvent(NetworkIncomingEvent): name = 'ping-error' base_network_events = [] + + +def get_instance(*args, **kwargs): + return Ping(*args, **kwargs), 'Ping' diff --git a/gajim/common/modules/pubsub.py b/gajim/common/modules/pubsub.py index dacc9053e..b26f24ef3 100644 --- a/gajim/common/modules/pubsub.py +++ b/gajim/common/modules/pubsub.py @@ -254,3 +254,7 @@ class PubSub: class PubSubConfigReceivedEvent(NetworkIncomingEvent): name = 'pubsub-config-received' base_network_events = [] + + +def get_instance(*args, **kwargs): + return PubSub(*args, **kwargs), 'PubSub' diff --git a/gajim/common/modules/roster_item_exchange.py b/gajim/common/modules/roster_item_exchange.py index 2bf902ff9..9cb69fb4b 100644 --- a/gajim/common/modules/roster_item_exchange.py +++ b/gajim/common/modules/roster_item_exchange.py @@ -121,3 +121,7 @@ class RosterItemExchange: class RosterItemExchangeEvent(NetworkIncomingEvent): name = 'roster-item-exchange-received' base_network_events = [] + + +def get_instance(*args, **kwargs): + return RosterItemExchange(*args, **kwargs), 'RosterItemExchange' diff --git a/gajim/common/modules/search.py b/gajim/common/modules/search.py index 35342c124..7d111d03c 100644 --- a/gajim/common/modules/search.py +++ b/gajim/common/modules/search.py @@ -112,3 +112,7 @@ class SearchFormReceivedEvent(NetworkIncomingEvent): class SearchResultReceivedEvent(NetworkIncomingEvent): name = 'search-result-received' base_network_events = [] + + +def get_instance(*args, **kwargs): + return Search(*args, **kwargs), 'Search' diff --git a/gajim/common/modules/software_version.py b/gajim/common/modules/software_version.py index 6fc35f20a..8eeabda03 100644 --- a/gajim/common/modules/software_version.py +++ b/gajim/common/modules/software_version.py @@ -104,3 +104,7 @@ class VersionResultReceivedEvent(NetworkIncomingEvent): def generate(self): return True + + +def get_instance(*args, **kwargs): + return SoftwareVersion(*args, **kwargs), 'SoftwareVersion' diff --git a/gajim/common/modules/user_activity.py b/gajim/common/modules/user_activity.py index 048b7da6a..ea2834921 100644 --- a/gajim/common/modules/user_activity.py +++ b/gajim/common/modules/user_activity.py @@ -99,3 +99,7 @@ class UserActivity(AbstractPEPModule): i = item.addChild('text') i.addData(message) return item + + +def get_instance(*args, **kwargs): + return UserActivity(*args, **kwargs), 'UserActivity' diff --git a/gajim/common/modules/user_avatar.py b/gajim/common/modules/user_avatar.py index 814216a5f..cbc541c53 100644 --- a/gajim/common/modules/user_avatar.py +++ b/gajim/common/modules/user_avatar.py @@ -152,3 +152,7 @@ class UserAvatar(AbstractPEPModule): def retract(self): # Not implemented yet return + + +def get_instance(*args, **kwargs): + return UserAvatar(*args, **kwargs), 'UserAvatar' diff --git a/gajim/common/modules/user_location.py b/gajim/common/modules/user_location.py index e4ded1713..d0a12a2c1 100644 --- a/gajim/common/modules/user_location.py +++ b/gajim/common/modules/user_location.py @@ -83,3 +83,7 @@ class UserLocation(AbstractPEPModule): if data.get(field, False): item.addChild(field, payload=data[field]) return item + + +def get_instance(*args, **kwargs): + return UserLocation(*args, **kwargs), 'UserLocation' diff --git a/gajim/common/modules/user_mood.py b/gajim/common/modules/user_mood.py index f4f4cc968..3ebabc256 100644 --- a/gajim/common/modules/user_mood.py +++ b/gajim/common/modules/user_mood.py @@ -86,3 +86,7 @@ class UserMood(AbstractPEPModule): if text: item.addChild('text', payload=text) return item + + +def get_instance(*args, **kwargs): + return UserMood(*args, **kwargs), 'UserMood' diff --git a/gajim/common/modules/user_nickname.py b/gajim/common/modules/user_nickname.py index 46d2150b3..9471dffee 100644 --- a/gajim/common/modules/user_nickname.py +++ b/gajim/common/modules/user_nickname.py @@ -76,3 +76,7 @@ class UserNickname(AbstractPEPModule): else: app.nicks[self._account] = app.config.get_per( 'accounts', self._account, 'name') + + +def get_instance(*args, **kwargs): + return UserNickname(*args, **kwargs), 'UserNickname' diff --git a/gajim/common/modules/user_tune.py b/gajim/common/modules/user_tune.py index 8c343da97..371c9626a 100644 --- a/gajim/common/modules/user_tune.py +++ b/gajim/common/modules/user_tune.py @@ -96,3 +96,7 @@ class UserTune(AbstractPEPModule): if length: item.addChild('length', payload=length) return item + + +def get_instance(*args, **kwargs): + return UserTune(*args, **kwargs), 'UserTune' diff --git a/gajim/common/modules/vcard_avatars.py b/gajim/common/modules/vcard_avatars.py index 317a27d8b..9817f8a4d 100644 --- a/gajim/common/modules/vcard_avatars.py +++ b/gajim/common/modules/vcard_avatars.py @@ -190,3 +190,7 @@ class VCardAvatars: node.getTo() or own_jid, sha or 'no sha advertised') update.setTagData('photo', sha) return node + + +def get_instance(*args, **kwargs): + return VCardAvatars(*args, **kwargs), 'VCardAvatars' diff --git a/gajim/common/modules/vcard_temp.py b/gajim/common/modules/vcard_temp.py index 9a71602a1..9b532a6f4 100644 --- a/gajim/common/modules/vcard_temp.py +++ b/gajim/common/modules/vcard_temp.py @@ -306,3 +306,7 @@ class VcardNotPublishedEvent(NetworkIncomingEvent): class VcardReceivedEvent(NetworkIncomingEvent): name = 'vcard-received' base_network_events = [] + + +def get_instance(*args, **kwargs): + return VCardTemp(*args, **kwargs), 'VCardTemp'