Philipp Hörist pushed to branch master at gajim / gajim
Commits: 731aaab6 by Philipp Hörist at 2019-04-19T14:57:12Z Improve module imports
Import modules only on demand instead all on first module import
- - - - - b2b249c6 by Philipp Hörist at 2019-04-19T14:57:12Z Refator DataFormDialog
- - - - -
7 changed files:
- gajim/common/connection.py - gajim/common/modules/__init__.py - gajim/common/zeroconf/connection_zeroconf.py - gajim/dialogs.py - gajim/gtk/dataform.py - gajim/gtk/pep_config.py - gajim/plugins/pluginmanager.py
Changes:
===================================== gajim/common/connection.py ===================================== @@ -492,7 +492,7 @@ class Connection(CommonConnection, ConnectionHandlers): self._sm_resume_data = {}
# Register all modules - modules.register(self) + modules.register_modules(self)
app.ged.register_event_handler('message-outgoing', ged.OUT_CORE, self._nec_message_outgoing) @@ -505,7 +505,7 @@ class Connection(CommonConnection, ConnectionHandlers): # END __init__
def cleanup(self): - modules.unregister(self) + modules.unregister_modules(self) app.ged.remove_event_handler('message-outgoing', ged.OUT_CORE, self._nec_message_outgoing) app.ged.remove_event_handler('gc-message-outgoing', ged.OUT_CORE,
===================================== gajim/common/modules/__init__.py ===================================== @@ -17,9 +17,9 @@ from typing import Dict # pylint: disable=unused-import from typing import List from typing import Tuple
+import sys import logging from importlib import import_module -from pathlib import Path from unittest.mock import MagicMock
from gajim.common.types import ConnectionT @@ -32,6 +32,49 @@ ZEROCONF_MODULES = ['iq', 'discovery', 'chatstates']
+MODULES = [ + 'adhoc_commands', + 'annotations', + 'bits_of_binary', + 'blocking', + 'bookmarks', + 'caps', + 'carbons', + 'chatstates', + 'delimiter', + 'discovery', + 'entity_time', + 'gateway', + 'httpupload', + 'http_auth', + 'iq', + 'last_activity', + 'mam', + 'message', + 'metacontacts', + 'muc', + 'pep', + 'ping', + 'presence', + 'privacylists', + 'pubsub', + 'receipts', + 'register', + 'roster', + 'roster_item_exchange', + 'search', + 'security_labels', + 'software_version', + 'user_activity', + 'user_avatar', + 'user_location', + 'user_mood', + 'user_nickname', + 'user_tune', + 'vcard_avatars', + 'vcard_temp', +] + _imported_modules = [] # type: List[tuple] _modules = {} # type: Dict[str, Dict[str, Any]] _store_publish_modules = [ @@ -41,20 +84,6 @@ _store_publish_modules = [ 'UserTune', ] # type: List[str]
-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) - if file.stem == 'pep': - # Register the PEP module first, because other modules - # depend on it - _imported_modules.insert(0, (_module, file.stem)) - else: - _imported_modules.append((_module, file.stem)) -
class ModuleMock: def __init__(self, name: str) -> None: @@ -84,33 +113,32 @@ class ModuleMock: return MagicMock()
-def register(con: ConnectionT, *args: Any, **kwargs: Any) -> None: +def register_modules(con: ConnectionT, *args: Any, **kwargs: Any) -> None: if con in _modules: return _modules[con.name] = {} - for module in _imported_modules: - mod, name = module + for module_name in MODULES: if con.name == 'Local': - if name not in ZEROCONF_MODULES: + if module_name not in ZEROCONF_MODULES: continue - instance, name = mod.get_instance(con, *args, **kwargs) + instance, name = _load_module(module_name, con, *args, **kwargs) _modules[con.name][name] = instance
-def register_single(con: ConnectionT, instance: Any, name: str) -> None: +def register_single_module(con: ConnectionT, instance: Any, name: str) -> None: if con.name not in _modules: raise ValueError('Unknown account name: %s' % con.name) _modules[con.name][name] = instance
-def unregister(con: ConnectionT) -> None: +def unregister_modules(con: ConnectionT) -> None: for instance in _modules[con.name].values(): if hasattr(instance, 'cleanup'): instance.cleanup() del _modules[con.name]
-def unregister_single(con: ConnectionT, name: str) -> None: +def unregister_single_module(con: ConnectionT, name: str) -> None: if con.name not in _modules: return if name not in _modules[con.name]: @@ -130,6 +158,15 @@ def get(account: str, name: str) -> Any: return ModuleMock(name)
+def _load_module(name: str, con: ConnectionT, *args: Any, **kwargs: Any) -> Any: + if name not in MODULES: + raise ValueError('Module %s does not exist' % name) + module = sys.modules.get(name) + if module is None: + module = import_module('.%s' % name, package='gajim.common.modules') + return module.get_instance(con, *args, **kwargs) # type: ignore + + def get_handlers(con: ConnectionT) -> List[Tuple[Any, ...]]: handlers = [] # type: List[Tuple[Any, ...]] for module in _modules[con.name].values():
===================================== gajim/common/zeroconf/connection_zeroconf.py ===================================== @@ -70,7 +70,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf): self.is_zeroconf = True
# Register all modules - modules.register(self) + modules.register_modules(self)
app.ged.register_event_handler('message-outgoing', ged.OUT_CORE, self._nec_message_outgoing)
===================================== gajim/dialogs.py ===================================== @@ -38,8 +38,6 @@ from gi.repository import Gtk from gi.repository import Gdk from gi.repository import GLib
-from gajim import dataforms_widget - from gajim.common import ged from gajim.common.i18n import _ from gajim.common.const import ACTIVITIES @@ -48,7 +46,6 @@ from gajim.common.const import MOODS from gajim.common import app from gajim.common import helpers from gajim.common import i18n -from gajim.common.modules import dataforms from gajim.common.exceptions import GajimGeneralException
from gajim.gtk.dialogs import ErrorDialog @@ -57,7 +54,6 @@ from gajim.gtk.dialogs import InputDialog from gajim.gtk.dialogs import InformationDialog from gajim.gtk.dialogs import AspellDictError from gajim.gtk.util import get_icon_name -from gajim.gtk.util import resize_window from gajim.gtk.util import get_builder from gajim.gtk.util import get_activity_icon_name
@@ -1355,30 +1351,6 @@ class Dialog(Gtk.Dialog): self.destroy()
-class DataFormWindow(Dialog): - def __init__(self, form, on_response_ok): - self.df_response_ok = on_response_ok - Dialog.__init__(self, None, 'test', [(Gtk.STOCK_CANCEL, - Gtk.ResponseType.CANCEL), (Gtk.STOCK_OK, Gtk.ResponseType.OK)], - on_response_ok=self.on_ok) - self.set_resizable(True) - resize_window(self, 600, 400) - self.dataform_widget = dataforms_widget.DataFormWidget() - self.dataform = dataforms.extend_form(node=form) - self.dataform_widget.set_sensitive(True) - self.dataform_widget.data_form = self.dataform - self.dataform_widget.show_all() - self.get_content_area().pack_start(self.dataform_widget, True, True, 0) - - def on_ok(self): - form = self.dataform_widget.data_form - if isinstance(self.df_response_ok, tuple): - self.df_response_ok[0](form, *self.df_response_ok[1:]) - else: - self.df_response_ok(form) - self.destroy() - - class ResourceConflictDialog(TimeoutDialog, InputDialog): def __init__(self, title, text, resource, ok_handler): TimeoutDialog.__init__(self, 15)
===================================== gajim/gtk/dataform.py ===================================== @@ -21,6 +21,7 @@ from gajim.gtkgui_helpers import scale_pixbuf_from_data
from gajim.common import app from gajim.common.i18n import _ +from gajim.common.modules.dataforms import extend_form
from gajim.gtk.util import MultiLineLabel
@@ -551,3 +552,33 @@ class ImageMediaField():
def add(self, form_grid, row_number): form_grid.attach(self._image, 1, row_number, 1, 1) + + +class DataFormDialog(Gtk.Dialog): + def __init__(self, title, transient_for, form, node, submit_callback): + Gtk.Dialog.__init__(self, + title=title, + transient_for=transient_for, + modal=False) + self.set_default_size(600, 500) + + self._submit_callback = submit_callback + self._form = DataFormWidget(extend_form(node=form)) + self._node = node + + self.get_content_area().get_style_context().add_class('dialog-margin') + self.get_content_area().add(self._form) + + self.add_button(_('Cancel'), Gtk.ResponseType.CANCEL) + + submit_button = self.add_button(_('Submit'), Gtk.ResponseType.OK) + submit_button.get_style_context().add_class('suggested-action') + self.set_default_response(Gtk.ResponseType.OK) + + self.connect('response', self._on_response) + self.show_all() + + def _on_response(self, _dialog, response): + if response == Gtk.ResponseType.OK: + self._submit_callback(self._form.get_submit_form(), self._node) + self.destroy()
===================================== gajim/gtk/pep_config.py ===================================== @@ -20,6 +20,7 @@ from gajim.common.i18n import _
from gajim.gtk.dialogs import ErrorDialog from gajim.gtk.dialogs import WarningDialog +from gajim.gtk.dataform import DataFormDialog from gajim.gtk.util import get_builder
@@ -122,14 +123,14 @@ class ManagePEPServicesWindow: con = app.connections[self.account] con.get_module('PubSub').request_pb_configuration(our_jid, node)
+ def _on_config_submit(self, form, node): + our_jid = app.get_jid_from_account(self.account) + con = app.connections[self.account] + con.get_module('PubSub').send_pb_configure(our_jid, node, form) + def _nec_pep_config_received(self, obj): - def on_ok(form, node): - form.type_ = 'submit' - our_jid = app.get_jid_from_account(self.account) - con = app.connections[self.account] - con.get_module('PubSub').send_pb_configure(our_jid, node, form) - from gajim.dialogs import DataFormWindow - window = DataFormWindow(obj.form, (on_ok, obj.node)) - title = _('Configure %s') % obj.node - window.set_title(title) - window.show_all() + DataFormDialog(_('Configure %s') % obj.node, + self.window, + obj.form, + obj.node, + self._on_config_submit)
===================================== gajim/plugins/pluginmanager.py ===================================== @@ -408,7 +408,7 @@ class PluginManager(metaclass=Singleton): if not module.zeroconf and con.name == 'Local': continue instance, name = module.get_instance(con) - modules.register_single(con, instance, name) + modules.register_single_module(con, instance, name)
# If handlers have been registered, register the # plugin handlers. Otherwise this will be done @@ -424,7 +424,7 @@ class PluginManager(metaclass=Singleton): for con in app.connections.values(): for module in plugin.modules: instance = con.get_module(module.name) - modules.unregister_single(con, module.name) + modules.unregister_single_module(con, module.name)
# Account is still connected and handlers are registered # So just unregister the plugin handlers @@ -562,7 +562,7 @@ class PluginManager(metaclass=Singleton): instance, name = module.get_instance(con) if not module.zeroconf and con.name == 'Local': continue - modules.register_single(con, instance, name) + modules.register_single_module(con, instance, name)
def _plugin_is_active_in_global_config(self, plugin): return app.config.get_per('plugins', plugin.short_name, 'active')
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/e999b74a5bcaee81078b222a72b7689440...