diff --git a/python/src/deltachat/__init__.py b/python/src/deltachat/__init__.py index 4a8f21bf9..780f9e462 100644 --- a/python/src/deltachat/__init__.py +++ b/python/src/deltachat/__init__.py @@ -1,6 +1,6 @@ -from deltachat import capi, const -from deltachat.capi import ffi -from deltachat.account import Account # noqa +from . import capi, const +from .capi import ffi +from .account import Account # noqa from pkg_resources import get_distribution, DistributionNotFound try: diff --git a/python/src/deltachat/account.py b/python/src/deltachat/account.py index 045dd4de3..a4e53ed10 100644 --- a/python/src/deltachat/account.py +++ b/python/src/deltachat/account.py @@ -14,9 +14,12 @@ from .cutil import as_dc_charpointer, from_dc_charpointer, iter_array, DCLot from .chat import Chat from .message import Message from .contact import Contact -from .eventlogger import EventLogger +from . import eventlogger from .tracker import ImexTracker -from .hookspec import AccountHookSpecs, account_hookimpl +from . import hookspec + + +hookspec.Global._get_plugin_manager().register(eventlogger) class Account(object): @@ -36,17 +39,19 @@ class Account(object): the default internal logging. :param os_name: this will be put to the X-Mailer header in outgoing messages """ + # initialize per-account plugin system + self._pm = hookspec.PerAccount._make_plugin_manager() + self.add_account_plugin(self) + self._dc_context = ffi.gc( lib.dc_context_new(lib.py_dc_callback, ffi.NULL, as_dc_charpointer(os_name)), _destroy_dc_context, ) - self._evlogger = EventLogger(self, logid) - self._threads = IOThreads(self._dc_context, self._evlogger._log_event) - # initialize per-account plugin system - self._pm = AccountHookSpecs._make_plugin_manager() - self.add_account_plugin(self) - self.add_account_plugin(self._evlogger) + hook = hookspec.Global._get_plugin_manager().hook + hook.at_account_init(account=self, db_path=db_path, logid=logid) + + self._threads = IOThreads(self._dc_context) # send all FFI events for this account to a plugin hook def _ll_event(ctx, evt_name, data1, data2): @@ -64,7 +69,7 @@ class Account(object): self._configkeys = self.get_config("sys.config_keys").split() atexit.register(self.shutdown) - @account_hookimpl + @hookspec.account_hookimpl def process_low_level_event(self, event_name, data1, data2): if event_name == "DC_EVENT_CONFIGURE_PROGRESS": if data1 == 0 or data1 == 1000: diff --git a/python/src/deltachat/eventlogger.py b/python/src/deltachat/eventlogger.py index 95831088e..899777e8c 100644 --- a/python/src/deltachat/eventlogger.py +++ b/python/src/deltachat/eventlogger.py @@ -1,5 +1,10 @@ import time -from .hookspec import account_hookimpl +from .hookspec import account_hookimpl, global_hookimpl + + +@global_hookimpl +def at_account_init(account, logid): + account._evlogger = account.add_account_plugin(EventLogger(account, logid=logid)) class EventLogger: diff --git a/python/src/deltachat/hookspec.py b/python/src/deltachat/hookspec.py index c960b4a82..58dc850ef 100644 --- a/python/src/deltachat/hookspec.py +++ b/python/src/deltachat/hookspec.py @@ -2,14 +2,17 @@ import pluggy -__all__ = ["account_hookspec", "account_hookimpl", "AccountHookSpecs"] _account_name = "deltachat-account" account_hookspec = pluggy.HookspecMarker(_account_name) account_hookimpl = pluggy.HookimplMarker(_account_name) +_global_name = "deltachat-global" +global_hookspec = pluggy.HookspecMarker(_global_name) +global_hookimpl = pluggy.HookimplMarker(_global_name) -class AccountHookSpecs: + +class PerAccount: """ per-Account-instance hook specifications. Account hook implementations need to be registered with an Account instance. @@ -27,3 +30,22 @@ class AccountHookSpecs: @account_hookspec def configure_completed(self, success): """ Called when a configure process completed. """ + + + +class Global: + """ global hook specifications using a per-process singleton plugin manager instance. + + """ + _plugin_manager = None + + @classmethod + def _get_plugin_manager(cls): + if cls._plugin_manager is None: + cls._plugin_manager = pm = pluggy.PluginManager(_global_name) + pm.add_hookspecs(cls) + return cls._plugin_manager + + @global_hookspec + def at_account_init(self, account, logid): + """ called when `Account::__init__()` function starts executing. """