Philipp Hörist pushed to branch master at gajim / gajim
Commits:
-
731aaab6
by Philipp Hörist at 2019-04-19T14:57:12Z
-
b2b249c6
by Philipp Hörist at 2019-04-19T14:57:12Z
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:
| ... | ... | @@ -492,7 +492,7 @@ class Connection(CommonConnection, ConnectionHandlers): |
| 492 | 492 |
self._sm_resume_data = {}
|
| 493 | 493 |
|
| 494 | 494 |
# Register all modules
|
| 495 |
- modules.register(self)
|
|
| 495 |
+ modules.register_modules(self)
|
|
| 496 | 496 |
|
| 497 | 497 |
app.ged.register_event_handler('message-outgoing', ged.OUT_CORE,
|
| 498 | 498 |
self._nec_message_outgoing)
|
| ... | ... | @@ -505,7 +505,7 @@ class Connection(CommonConnection, ConnectionHandlers): |
| 505 | 505 |
# END __init__
|
| 506 | 506 |
|
| 507 | 507 |
def cleanup(self):
|
| 508 |
- modules.unregister(self)
|
|
| 508 |
+ modules.unregister_modules(self)
|
|
| 509 | 509 |
app.ged.remove_event_handler('message-outgoing', ged.OUT_CORE,
|
| 510 | 510 |
self._nec_message_outgoing)
|
| 511 | 511 |
app.ged.remove_event_handler('gc-message-outgoing', ged.OUT_CORE,
|
| ... | ... | @@ -17,9 +17,9 @@ from typing import Dict # pylint: disable=unused-import |
| 17 | 17 |
from typing import List
|
| 18 | 18 |
from typing import Tuple
|
| 19 | 19 |
|
| 20 |
+import sys
|
|
| 20 | 21 |
import logging
|
| 21 | 22 |
from importlib import import_module
|
| 22 |
-from pathlib import Path
|
|
| 23 | 23 |
from unittest.mock import MagicMock
|
| 24 | 24 |
|
| 25 | 25 |
from gajim.common.types import ConnectionT
|
| ... | ... | @@ -32,6 +32,49 @@ ZEROCONF_MODULES = ['iq', |
| 32 | 32 |
'discovery',
|
| 33 | 33 |
'chatstates']
|
| 34 | 34 |
|
| 35 |
+MODULES = [
|
|
| 36 |
+ 'adhoc_commands',
|
|
| 37 |
+ 'annotations',
|
|
| 38 |
+ 'bits_of_binary',
|
|
| 39 |
+ 'blocking',
|
|
| 40 |
+ 'bookmarks',
|
|
| 41 |
+ 'caps',
|
|
| 42 |
+ 'carbons',
|
|
| 43 |
+ 'chatstates',
|
|
| 44 |
+ 'delimiter',
|
|
| 45 |
+ 'discovery',
|
|
| 46 |
+ 'entity_time',
|
|
| 47 |
+ 'gateway',
|
|
| 48 |
+ 'httpupload',
|
|
| 49 |
+ 'http_auth',
|
|
| 50 |
+ 'iq',
|
|
| 51 |
+ 'last_activity',
|
|
| 52 |
+ 'mam',
|
|
| 53 |
+ 'message',
|
|
| 54 |
+ 'metacontacts',
|
|
| 55 |
+ 'muc',
|
|
| 56 |
+ 'pep',
|
|
| 57 |
+ 'ping',
|
|
| 58 |
+ 'presence',
|
|
| 59 |
+ 'privacylists',
|
|
| 60 |
+ 'pubsub',
|
|
| 61 |
+ 'receipts',
|
|
| 62 |
+ 'register',
|
|
| 63 |
+ 'roster',
|
|
| 64 |
+ 'roster_item_exchange',
|
|
| 65 |
+ 'search',
|
|
| 66 |
+ 'security_labels',
|
|
| 67 |
+ 'software_version',
|
|
| 68 |
+ 'user_activity',
|
|
| 69 |
+ 'user_avatar',
|
|
| 70 |
+ 'user_location',
|
|
| 71 |
+ 'user_mood',
|
|
| 72 |
+ 'user_nickname',
|
|
| 73 |
+ 'user_tune',
|
|
| 74 |
+ 'vcard_avatars',
|
|
| 75 |
+ 'vcard_temp',
|
|
| 76 |
+]
|
|
| 77 |
+ |
|
| 35 | 78 |
_imported_modules = [] # type: List[tuple]
|
| 36 | 79 |
_modules = {} # type: Dict[str, Dict[str, Any]]
|
| 37 | 80 |
_store_publish_modules = [
|
| ... | ... | @@ -41,20 +84,6 @@ _store_publish_modules = [ |
| 41 | 84 |
'UserTune',
|
| 42 | 85 |
] # type: List[str]
|
| 43 | 86 |
|
| 44 |
-for file in Path(__file__).parent.iterdir():
|
|
| 45 |
- if file.stem == '__init__':
|
|
| 46 |
- continue
|
|
| 47 |
- |
|
| 48 |
- _module = import_module('.%s' % file.stem, package='gajim.common.modules')
|
|
| 49 |
- if hasattr(_module, 'get_instance'):
|
|
| 50 |
- log.info('Load module: %s', file.stem)
|
|
| 51 |
- if file.stem == 'pep':
|
|
| 52 |
- # Register the PEP module first, because other modules
|
|
| 53 |
- # depend on it
|
|
| 54 |
- _imported_modules.insert(0, (_module, file.stem))
|
|
| 55 |
- else:
|
|
| 56 |
- _imported_modules.append((_module, file.stem))
|
|
| 57 |
- |
|
| 58 | 87 |
|
| 59 | 88 |
class ModuleMock:
|
| 60 | 89 |
def __init__(self, name: str) -> None:
|
| ... | ... | @@ -84,33 +113,32 @@ class ModuleMock: |
| 84 | 113 |
return MagicMock()
|
| 85 | 114 |
|
| 86 | 115 |
|
| 87 |
-def register(con: ConnectionT, *args: Any, **kwargs: Any) -> None:
|
|
| 116 |
+def register_modules(con: ConnectionT, *args: Any, **kwargs: Any) -> None:
|
|
| 88 | 117 |
if con in _modules:
|
| 89 | 118 |
return
|
| 90 | 119 |
_modules[con.name] = {}
|
| 91 |
- for module in _imported_modules:
|
|
| 92 |
- mod, name = module
|
|
| 120 |
+ for module_name in MODULES:
|
|
| 93 | 121 |
if con.name == 'Local':
|
| 94 |
- if name not in ZEROCONF_MODULES:
|
|
| 122 |
+ if module_name not in ZEROCONF_MODULES:
|
|
| 95 | 123 |
continue
|
| 96 |
- instance, name = mod.get_instance(con, *args, **kwargs)
|
|
| 124 |
+ instance, name = _load_module(module_name, con, *args, **kwargs)
|
|
| 97 | 125 |
_modules[con.name][name] = instance
|
| 98 | 126 |
|
| 99 | 127 |
|
| 100 |
-def register_single(con: ConnectionT, instance: Any, name: str) -> None:
|
|
| 128 |
+def register_single_module(con: ConnectionT, instance: Any, name: str) -> None:
|
|
| 101 | 129 |
if con.name not in _modules:
|
| 102 | 130 |
raise ValueError('Unknown account name: %s' % con.name)
|
| 103 | 131 |
_modules[con.name][name] = instance
|
| 104 | 132 |
|
| 105 | 133 |
|
| 106 |
-def unregister(con: ConnectionT) -> None:
|
|
| 134 |
+def unregister_modules(con: ConnectionT) -> None:
|
|
| 107 | 135 |
for instance in _modules[con.name].values():
|
| 108 | 136 |
if hasattr(instance, 'cleanup'):
|
| 109 | 137 |
instance.cleanup()
|
| 110 | 138 |
del _modules[con.name]
|
| 111 | 139 |
|
| 112 | 140 |
|
| 113 |
-def unregister_single(con: ConnectionT, name: str) -> None:
|
|
| 141 |
+def unregister_single_module(con: ConnectionT, name: str) -> None:
|
|
| 114 | 142 |
if con.name not in _modules:
|
| 115 | 143 |
return
|
| 116 | 144 |
if name not in _modules[con.name]:
|
| ... | ... | @@ -130,6 +158,15 @@ def get(account: str, name: str) -> Any: |
| 130 | 158 |
return ModuleMock(name)
|
| 131 | 159 |
|
| 132 | 160 |
|
| 161 |
+def _load_module(name: str, con: ConnectionT, *args: Any, **kwargs: Any) -> Any:
|
|
| 162 |
+ if name not in MODULES:
|
|
| 163 |
+ raise ValueError('Module %s does not exist' % name)
|
|
| 164 |
+ module = sys.modules.get(name)
|
|
| 165 |
+ if module is None:
|
|
| 166 |
+ module = import_module('.%s' % name, package='gajim.common.modules')
|
|
| 167 |
+ return module.get_instance(con, *args, **kwargs) # type: ignore
|
|
| 168 |
+ |
|
| 169 |
+ |
|
| 133 | 170 |
def get_handlers(con: ConnectionT) -> List[Tuple[Any, ...]]:
|
| 134 | 171 |
handlers = [] # type: List[Tuple[Any, ...]]
|
| 135 | 172 |
for module in _modules[con.name].values():
|
| ... | ... | @@ -70,7 +70,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf): |
| 70 | 70 |
self.is_zeroconf = True
|
| 71 | 71 |
|
| 72 | 72 |
# Register all modules
|
| 73 |
- modules.register(self)
|
|
| 73 |
+ modules.register_modules(self)
|
|
| 74 | 74 |
|
| 75 | 75 |
app.ged.register_event_handler('message-outgoing', ged.OUT_CORE,
|
| 76 | 76 |
self._nec_message_outgoing)
|
| ... | ... | @@ -38,8 +38,6 @@ from gi.repository import Gtk |
| 38 | 38 |
from gi.repository import Gdk
|
| 39 | 39 |
from gi.repository import GLib
|
| 40 | 40 |
|
| 41 |
-from gajim import dataforms_widget
|
|
| 42 |
- |
|
| 43 | 41 |
from gajim.common import ged
|
| 44 | 42 |
from gajim.common.i18n import _
|
| 45 | 43 |
from gajim.common.const import ACTIVITIES
|
| ... | ... | @@ -48,7 +46,6 @@ from gajim.common.const import MOODS |
| 48 | 46 |
from gajim.common import app
|
| 49 | 47 |
from gajim.common import helpers
|
| 50 | 48 |
from gajim.common import i18n
|
| 51 |
-from gajim.common.modules import dataforms
|
|
| 52 | 49 |
from gajim.common.exceptions import GajimGeneralException
|
| 53 | 50 |
|
| 54 | 51 |
from gajim.gtk.dialogs import ErrorDialog
|
| ... | ... | @@ -57,7 +54,6 @@ from gajim.gtk.dialogs import InputDialog |
| 57 | 54 |
from gajim.gtk.dialogs import InformationDialog
|
| 58 | 55 |
from gajim.gtk.dialogs import AspellDictError
|
| 59 | 56 |
from gajim.gtk.util import get_icon_name
|
| 60 |
-from gajim.gtk.util import resize_window
|
|
| 61 | 57 |
from gajim.gtk.util import get_builder
|
| 62 | 58 |
from gajim.gtk.util import get_activity_icon_name
|
| 63 | 59 |
|
| ... | ... | @@ -1355,30 +1351,6 @@ class Dialog(Gtk.Dialog): |
| 1355 | 1351 |
self.destroy()
|
| 1356 | 1352 |
|
| 1357 | 1353 |
|
| 1358 |
-class DataFormWindow(Dialog):
|
|
| 1359 |
- def __init__(self, form, on_response_ok):
|
|
| 1360 |
- self.df_response_ok = on_response_ok
|
|
| 1361 |
- Dialog.__init__(self, None, 'test', [(Gtk.STOCK_CANCEL,
|
|
| 1362 |
- Gtk.ResponseType.CANCEL), (Gtk.STOCK_OK, Gtk.ResponseType.OK)],
|
|
| 1363 |
- on_response_ok=self.on_ok)
|
|
| 1364 |
- self.set_resizable(True)
|
|
| 1365 |
- resize_window(self, 600, 400)
|
|
| 1366 |
- self.dataform_widget = dataforms_widget.DataFormWidget()
|
|
| 1367 |
- self.dataform = dataforms.extend_form(node=form)
|
|
| 1368 |
- self.dataform_widget.set_sensitive(True)
|
|
| 1369 |
- self.dataform_widget.data_form = self.dataform
|
|
| 1370 |
- self.dataform_widget.show_all()
|
|
| 1371 |
- self.get_content_area().pack_start(self.dataform_widget, True, True, 0)
|
|
| 1372 |
- |
|
| 1373 |
- def on_ok(self):
|
|
| 1374 |
- form = self.dataform_widget.data_form
|
|
| 1375 |
- if isinstance(self.df_response_ok, tuple):
|
|
| 1376 |
- self.df_response_ok[0](form, *self.df_response_ok[1:])
|
|
| 1377 |
- else:
|
|
| 1378 |
- self.df_response_ok(form)
|
|
| 1379 |
- self.destroy()
|
|
| 1380 |
- |
|
| 1381 |
- |
|
| 1382 | 1354 |
class ResourceConflictDialog(TimeoutDialog, InputDialog):
|
| 1383 | 1355 |
def __init__(self, title, text, resource, ok_handler):
|
| 1384 | 1356 |
TimeoutDialog.__init__(self, 15)
|
| ... | ... | @@ -21,6 +21,7 @@ from gajim.gtkgui_helpers import scale_pixbuf_from_data |
| 21 | 21 |
|
| 22 | 22 |
from gajim.common import app
|
| 23 | 23 |
from gajim.common.i18n import _
|
| 24 |
+from gajim.common.modules.dataforms import extend_form
|
|
| 24 | 25 |
|
| 25 | 26 |
from gajim.gtk.util import MultiLineLabel
|
| 26 | 27 |
|
| ... | ... | @@ -551,3 +552,33 @@ class ImageMediaField(): |
| 551 | 552 |
|
| 552 | 553 |
def add(self, form_grid, row_number):
|
| 553 | 554 |
form_grid.attach(self._image, 1, row_number, 1, 1)
|
| 555 |
+ |
|
| 556 |
+ |
|
| 557 |
+class DataFormDialog(Gtk.Dialog):
|
|
| 558 |
+ def __init__(self, title, transient_for, form, node, submit_callback):
|
|
| 559 |
+ Gtk.Dialog.__init__(self,
|
|
| 560 |
+ title=title,
|
|
| 561 |
+ transient_for=transient_for,
|
|
| 562 |
+ modal=False)
|
|
| 563 |
+ self.set_default_size(600, 500)
|
|
| 564 |
+ |
|
| 565 |
+ self._submit_callback = submit_callback
|
|
| 566 |
+ self._form = DataFormWidget(extend_form(node=form))
|
|
| 567 |
+ self._node = node
|
|
| 568 |
+ |
|
| 569 |
+ self.get_content_area().get_style_context().add_class('dialog-margin')
|
|
| 570 |
+ self.get_content_area().add(self._form)
|
|
| 571 |
+ |
|
| 572 |
+ self.add_button(_('Cancel'), Gtk.ResponseType.CANCEL)
|
|
| 573 |
+ |
|
| 574 |
+ submit_button = self.add_button(_('Submit'), Gtk.ResponseType.OK)
|
|
| 575 |
+ submit_button.get_style_context().add_class('suggested-action')
|
|
| 576 |
+ self.set_default_response(Gtk.ResponseType.OK)
|
|
| 577 |
+ |
|
| 578 |
+ self.connect('response', self._on_response)
|
|
| 579 |
+ self.show_all()
|
|
| 580 |
+ |
|
| 581 |
+ def _on_response(self, _dialog, response):
|
|
| 582 |
+ if response == Gtk.ResponseType.OK:
|
|
| 583 |
+ self._submit_callback(self._form.get_submit_form(), self._node)
|
|
| 584 |
+ self.destroy()
|
| ... | ... | @@ -20,6 +20,7 @@ from gajim.common.i18n import _ |
| 20 | 20 |
|
| 21 | 21 |
from gajim.gtk.dialogs import ErrorDialog
|
| 22 | 22 |
from gajim.gtk.dialogs import WarningDialog
|
| 23 |
+from gajim.gtk.dataform import DataFormDialog
|
|
| 23 | 24 |
from gajim.gtk.util import get_builder
|
| 24 | 25 |
|
| 25 | 26 |
|
| ... | ... | @@ -122,14 +123,14 @@ class ManagePEPServicesWindow: |
| 122 | 123 |
con = app.connections[self.account]
|
| 123 | 124 |
con.get_module('PubSub').request_pb_configuration(our_jid, node)
|
| 124 | 125 |
|
| 126 |
+ def _on_config_submit(self, form, node):
|
|
| 127 |
+ our_jid = app.get_jid_from_account(self.account)
|
|
| 128 |
+ con = app.connections[self.account]
|
|
| 129 |
+ con.get_module('PubSub').send_pb_configure(our_jid, node, form)
|
|
| 130 |
+ |
|
| 125 | 131 |
def _nec_pep_config_received(self, obj):
|
| 126 |
- def on_ok(form, node):
|
|
| 127 |
- form.type_ = 'submit'
|
|
| 128 |
- our_jid = app.get_jid_from_account(self.account)
|
|
| 129 |
- con = app.connections[self.account]
|
|
| 130 |
- con.get_module('PubSub').send_pb_configure(our_jid, node, form)
|
|
| 131 |
- from gajim.dialogs import DataFormWindow
|
|
| 132 |
- window = DataFormWindow(obj.form, (on_ok, obj.node))
|
|
| 133 |
- title = _('Configure %s') % obj.node
|
|
| 134 |
- window.set_title(title)
|
|
| 135 |
- window.show_all()
|
|
| 132 |
+ DataFormDialog(_('Configure %s') % obj.node,
|
|
| 133 |
+ self.window,
|
|
| 134 |
+ obj.form,
|
|
| 135 |
+ obj.node,
|
|
| 136 |
+ self._on_config_submit)
|
| ... | ... | @@ -408,7 +408,7 @@ class PluginManager(metaclass=Singleton): |
| 408 | 408 |
if not module.zeroconf and con.name == 'Local':
|
| 409 | 409 |
continue
|
| 410 | 410 |
instance, name = module.get_instance(con)
|
| 411 |
- modules.register_single(con, instance, name)
|
|
| 411 |
+ modules.register_single_module(con, instance, name)
|
|
| 412 | 412 |
|
| 413 | 413 |
# If handlers have been registered, register the
|
| 414 | 414 |
# plugin handlers. Otherwise this will be done
|
| ... | ... | @@ -424,7 +424,7 @@ class PluginManager(metaclass=Singleton): |
| 424 | 424 |
for con in app.connections.values():
|
| 425 | 425 |
for module in plugin.modules:
|
| 426 | 426 |
instance = con.get_module(module.name)
|
| 427 |
- modules.unregister_single(con, module.name)
|
|
| 427 |
+ modules.unregister_single_module(con, module.name)
|
|
| 428 | 428 |
|
| 429 | 429 |
# Account is still connected and handlers are registered
|
| 430 | 430 |
# So just unregister the plugin handlers
|
| ... | ... | @@ -562,7 +562,7 @@ class PluginManager(metaclass=Singleton): |
| 562 | 562 |
instance, name = module.get_instance(con)
|
| 563 | 563 |
if not module.zeroconf and con.name == 'Local':
|
| 564 | 564 |
continue
|
| 565 |
- modules.register_single(con, instance, name)
|
|
| 565 |
+ modules.register_single_module(con, instance, name)
|
|
| 566 | 566 |
|
| 567 | 567 |
def _plugin_is_active_in_global_config(self, plugin):
|
| 568 | 568 |
return app.config.get_per('plugins', plugin.short_name, 'active')
|