Register all available modules automatically

This commit is contained in:
Philipp Hörist 2018-07-07 13:52:44 +02:00
parent 3a3b32249c
commit 59428d2f2f
24 changed files with 158 additions and 62 deletions

View File

@ -61,29 +61,9 @@ from gajim.common import gpg
from gajim.common import passwords from gajim.common import passwords
from gajim.common import i18n from gajim.common import i18n
from gajim.common import idle 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.connection_handlers import *
from gajim.common.contacts import GC_Contact from gajim.common.contacts import GC_Contact
from gajim.common import modules
from gajim.gtkgui_helpers import get_action from gajim.gtkgui_helpers import get_action
@ -182,19 +162,7 @@ class CommonConnection:
app.ged.raise_event(event, self.name, data) app.ged.raise_event(event, self.name, data)
def get_module(self, name): def get_module(self, name):
try: return modules.get(self.name, name)
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)
def reconnect(self): def reconnect(self):
""" """
@ -661,26 +629,8 @@ class Connection(CommonConnection, ConnectionHandlers):
self.sm = Smacks(self) # Stream Management self.sm = Smacks(self) # Stream Management
self.register_module('EntityTime', EntityTime, self) # Register all modules
self.register_module('SoftwareVersion', SoftwareVersion, self) modules.register(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)
app.ged.register_event_handler('privacy-list-received', ged.CORE, app.ged.register_event_handler('privacy-list-received', ged.CORE,
self._nec_privacy_list_received) self._nec_privacy_list_received)
@ -700,6 +650,8 @@ class Connection(CommonConnection, ConnectionHandlers):
def cleanup(self): def cleanup(self):
ConnectionHandlers.cleanup(self) ConnectionHandlers.cleanup(self)
modules.unregister(self)
app.ged.remove_event_handler('privacy-list-received', ged.CORE, app.ged.remove_event_handler('privacy-list-received', ged.CORE,
self._nec_privacy_list_received) self._nec_privacy_list_received)
app.ged.remove_event_handler('agent-info-error-received', ged.CORE, app.ged.remove_event_handler('agent-info-error-received', ged.CORE,
@ -780,6 +732,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.terminate_sessions() self.terminate_sessions()
self.remove_all_transfers() self.remove_all_transfers()
self.connection.disconnect() self.connection.disconnect()
ConnectionHandlers._unregister_handlers(self)
self.connection = None self.connection = None
def set_oldst(self): # Set old state def set_oldst(self): # Set old state

View File

@ -37,6 +37,7 @@ from gi.repository import GLib
import nbxmpp import nbxmpp
from gajim.common import caps_cache as capscache from gajim.common import caps_cache as capscache
from gajim.common import modules
from gajim.common import helpers from gajim.common import helpers
from gajim.common import app from gajim.common import app
from gajim.common import jingle_xtls from gajim.common import jingle_xtls
@ -1451,5 +1452,9 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
con.RegisterHandler('iq', self._BlockingResultCB, 'result', con.RegisterHandler('iq', self._BlockingResultCB, 'result',
nbxmpp.NS_BLOCKING) nbxmpp.NS_BLOCKING)
for handler in self.get_module_handlers(): for handler in modules.get_handlers(self):
con.RegisterHandler(*handler) con.RegisterHandler(*handler)
def _unregister_handlers(self):
for handler in modules.get_handlers(self):
self.connection.UnregisterHandler(*handler)

View File

@ -165,13 +165,6 @@ class InvalidFormat(Exception):
pass pass
class ModuleMock:
def __getattr__(self, key):
def _mock(self, *args, **kwargs):
return
return _mock
def decompose_jid(jidstring): def decompose_jid(jidstring):
user = None user = None
server = None server = None

View File

@ -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 <http://www.gnu.org/licenses/>.
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

View File

@ -90,3 +90,7 @@ class Annotations:
log.warning('Storing rosternotes failed: %s', stanza.getError()) log.warning('Storing rosternotes failed: %s', stanza.getError())
return return
log.info('Storing rosternotes successful') log.info('Storing rosternotes successful')
def get_instance(*args, **kwargs):
return Annotations(*args, **kwargs), 'Annotations'

View File

@ -292,3 +292,7 @@ class Bookmarks:
class BookmarksReceivedEvent(NetworkIncomingEvent): class BookmarksReceivedEvent(NetworkIncomingEvent):
name = 'bookmarks-received' name = 'bookmarks-received'
base_network_events = [] base_network_events = []
def get_instance(*args, **kwargs):
return Bookmarks(*args, **kwargs), 'Bookmarks'

View File

@ -162,3 +162,7 @@ class contact_tz(datetime.tzinfo):
def dst(self, dt): def dst(self, dt):
return ZERO return ZERO
def get_instance(*args, **kwargs):
return EntityTime(*args, **kwargs), 'EntityTime'

View File

@ -75,3 +75,7 @@ class HTTPAuth:
class HttpAuthReceivedEvent(NetworkIncomingEvent): class HttpAuthReceivedEvent(NetworkIncomingEvent):
name = 'http-auth-received' name = 'http-auth-received'
base_network_events = [] base_network_events = []
def get_instance(*args, **kwargs):
return HTTPAuth(*args, **kwargs), 'HTTPAuth'

View File

@ -436,3 +436,7 @@ class UploadAbortedException(Exception):
class HTTPUploadProgressEvent(NetworkIncomingEvent): class HTTPUploadProgressEvent(NetworkIncomingEvent):
name = 'httpupload-progress' name = 'httpupload-progress'
base_network_events = [] base_network_events = []
def get_instance(*args, **kwargs):
return HTTPUpload(*args, **kwargs), 'HTTPUpload'

View File

@ -50,3 +50,7 @@ class LastActivity:
self._con.connection.send(iq) self._con.connection.send(iq)
raise nbxmpp.NodeProcessed raise nbxmpp.NodeProcessed
def get_instance(*args, **kwargs):
return LastActivity(*args, **kwargs), 'LastActivity'

View File

@ -212,3 +212,7 @@ class AbstractPEPData:
class PEPReceivedEvent(NetworkIncomingEvent): class PEPReceivedEvent(NetworkIncomingEvent):
name = 'pep-received' name = 'pep-received'
base_network_events = [] base_network_events = []
def get_instance(*args, **kwargs):
return PEP(*args, **kwargs), 'PEP'

View File

@ -120,3 +120,7 @@ class PingReplyEvent(NetworkIncomingEvent):
class PingErrorEvent(NetworkIncomingEvent): class PingErrorEvent(NetworkIncomingEvent):
name = 'ping-error' name = 'ping-error'
base_network_events = [] base_network_events = []
def get_instance(*args, **kwargs):
return Ping(*args, **kwargs), 'Ping'

View File

@ -254,3 +254,7 @@ class PubSub:
class PubSubConfigReceivedEvent(NetworkIncomingEvent): class PubSubConfigReceivedEvent(NetworkIncomingEvent):
name = 'pubsub-config-received' name = 'pubsub-config-received'
base_network_events = [] base_network_events = []
def get_instance(*args, **kwargs):
return PubSub(*args, **kwargs), 'PubSub'

View File

@ -121,3 +121,7 @@ class RosterItemExchange:
class RosterItemExchangeEvent(NetworkIncomingEvent): class RosterItemExchangeEvent(NetworkIncomingEvent):
name = 'roster-item-exchange-received' name = 'roster-item-exchange-received'
base_network_events = [] base_network_events = []
def get_instance(*args, **kwargs):
return RosterItemExchange(*args, **kwargs), 'RosterItemExchange'

View File

@ -112,3 +112,7 @@ class SearchFormReceivedEvent(NetworkIncomingEvent):
class SearchResultReceivedEvent(NetworkIncomingEvent): class SearchResultReceivedEvent(NetworkIncomingEvent):
name = 'search-result-received' name = 'search-result-received'
base_network_events = [] base_network_events = []
def get_instance(*args, **kwargs):
return Search(*args, **kwargs), 'Search'

View File

@ -104,3 +104,7 @@ class VersionResultReceivedEvent(NetworkIncomingEvent):
def generate(self): def generate(self):
return True return True
def get_instance(*args, **kwargs):
return SoftwareVersion(*args, **kwargs), 'SoftwareVersion'

View File

@ -99,3 +99,7 @@ class UserActivity(AbstractPEPModule):
i = item.addChild('text') i = item.addChild('text')
i.addData(message) i.addData(message)
return item return item
def get_instance(*args, **kwargs):
return UserActivity(*args, **kwargs), 'UserActivity'

View File

@ -152,3 +152,7 @@ class UserAvatar(AbstractPEPModule):
def retract(self): def retract(self):
# Not implemented yet # Not implemented yet
return return
def get_instance(*args, **kwargs):
return UserAvatar(*args, **kwargs), 'UserAvatar'

View File

@ -83,3 +83,7 @@ class UserLocation(AbstractPEPModule):
if data.get(field, False): if data.get(field, False):
item.addChild(field, payload=data[field]) item.addChild(field, payload=data[field])
return item return item
def get_instance(*args, **kwargs):
return UserLocation(*args, **kwargs), 'UserLocation'

View File

@ -86,3 +86,7 @@ class UserMood(AbstractPEPModule):
if text: if text:
item.addChild('text', payload=text) item.addChild('text', payload=text)
return item return item
def get_instance(*args, **kwargs):
return UserMood(*args, **kwargs), 'UserMood'

View File

@ -76,3 +76,7 @@ class UserNickname(AbstractPEPModule):
else: else:
app.nicks[self._account] = app.config.get_per( app.nicks[self._account] = app.config.get_per(
'accounts', self._account, 'name') 'accounts', self._account, 'name')
def get_instance(*args, **kwargs):
return UserNickname(*args, **kwargs), 'UserNickname'

View File

@ -96,3 +96,7 @@ class UserTune(AbstractPEPModule):
if length: if length:
item.addChild('length', payload=length) item.addChild('length', payload=length)
return item return item
def get_instance(*args, **kwargs):
return UserTune(*args, **kwargs), 'UserTune'

View File

@ -190,3 +190,7 @@ class VCardAvatars:
node.getTo() or own_jid, sha or 'no sha advertised') node.getTo() or own_jid, sha or 'no sha advertised')
update.setTagData('photo', sha) update.setTagData('photo', sha)
return node return node
def get_instance(*args, **kwargs):
return VCardAvatars(*args, **kwargs), 'VCardAvatars'

View File

@ -306,3 +306,7 @@ class VcardNotPublishedEvent(NetworkIncomingEvent):
class VcardReceivedEvent(NetworkIncomingEvent): class VcardReceivedEvent(NetworkIncomingEvent):
name = 'vcard-received' name = 'vcard-received'
base_network_events = [] base_network_events = []
def get_instance(*args, **kwargs):
return VCardTemp(*args, **kwargs), 'VCardTemp'