make eventlogger module a global plugin

This commit is contained in:
holger krekel
2020-02-23 17:43:29 +01:00
parent 0d4b6f5627
commit 79f5e736b0
6 changed files with 74 additions and 54 deletions

View File

@@ -1,6 +1,7 @@
from . import capi, const, hookspec
from .capi import ffi
from .account import Account # noqa
from . import eventlogger
from pkg_resources import get_distribution, DistributionNotFound
try:
@@ -79,3 +80,7 @@ def get_dc_event_name(integer, _DC_EVENTNAME_MAP={}):
def register_global_plugin(plugin):
gm = hookspec.Global._get_plugin_manager()
gm.register(plugin)
gm.check_pending()
register_global_plugin(eventlogger)

View File

@@ -45,20 +45,10 @@ class Account(object):
)
hook = hookspec.Global._get_plugin_manager().hook
hook.at_account_init(account=self, db_path=db_path)
hook.account_init(account=self, db_path=db_path)
self._shutdown_event = Event()
self._threads = iothreads.IOThreads(self)
# send all FFI events for this account to a plugin hook
def _ll_event(ctx, evt_name, data1, data2):
assert ctx == self._dc_context
ffi_event = FFIEvent(name=evt_name, data1=data1, data2=data2)
self._pm.hook.process_ffi_event(
account=self, ffi_event=ffi_event
)
deltachat.set_context_callback(self._dc_context, _ll_event)
# open database
if hasattr(db_path, "encode"):
db_path = db_path.encode("utf8")
@@ -66,6 +56,8 @@ class Account(object):
raise ValueError("Could not dc_open: {}".format(db_path))
self._configkeys = self.get_config("sys.config_keys").split()
atexit.register(self.shutdown)
self._shutdown_event = Event()
@hookspec.account_hookimpl
def process_ffi_event(self, ffi_event):
@@ -549,20 +541,19 @@ class Account(object):
If this account is not configured, an internal configuration
job will be scheduled if config values are sufficiently specified.
You may call :method:`wait_shutdown` or `shutdown` after the
account is in started mode.
:raises MissingCredentials: if `addr` and `mail_pw` values are not set.
:returns: None
"""
if not self.is_configured():
if not self.get_config("addr") or not self.get_config("mail_pwd"):
if not self.get_config("addr") or not self.get_config("mail_pw"):
raise MissingCredentials("addr or mail_pwd not set in config")
lib.dc_configure(self._dc_context)
self._threads.start()
@hookspec.account_hookimpl
def after_shutdown(self):
self._shutdown_event.set()
def wait_shutdown(self):
""" wait until shutdown of this account has completed. """
self._shutdown_event.wait()
@@ -570,16 +561,20 @@ class Account(object):
def shutdown(self, wait=True):
""" shutdown account, stop threads and close and remove
underlying dc_context and callbacks. """
if hasattr(self, "_dc_context") and hasattr(self, "_threads"):
if self._threads.is_started():
self.stop_ongoing()
self._threads.stop(wait=False)
lib.dc_close(self._dc_context)
self._threads.stop(wait=wait) # to wait for threads
deltachat.clear_context_callback(self._dc_context)
del self._dc_context
atexit.unregister(self.shutdown)
self._pm.hook.after_shutdown()
dc_context = self._dc_context
if dc_context is None:
return
if self._threads.is_started():
self.stop_ongoing()
self._threads.stop(wait=False)
lib.dc_close(dc_context)
self._threads.stop(wait=wait) # to wait for threads
self._dc_context = None
atexit.unregister(self.shutdown)
hook = hookspec.Global._get_plugin_manager().hook
hook.account_after_shutdown(account=self, dc_context=dc_context)
self._shutdown_event.set()
def _destroy_dc_context(dc_context, dc_context_unref=lib.dc_context_unref):
@@ -593,16 +588,6 @@ def _destroy_dc_context(dc_context, dc_context_unref=lib.dc_context_unref):
pass
class FFIEvent:
def __init__(self, name, data1, data2):
self.name = name
self.data1 = data1
self.data2 = data2
def __str__(self):
return "{name} data1={data1} data2={data2}".format(**self.__dict__)
class ScannedQRCode:
def __init__(self, dc_lot):
self._dc_lot = dc_lot

View File

@@ -1,6 +1,34 @@
import deltachat
import threading
import time
from .hookspec import account_hookimpl
from .hookspec import account_hookimpl, global_hookimpl
@global_hookimpl
def account_init(account):
# send all FFI events for this account to a plugin hook
def _ll_event(ctx, evt_name, data1, data2):
assert ctx == account._dc_context
ffi_event = FFIEvent(name=evt_name, data1=data1, data2=data2)
account._pm.hook.process_ffi_event(
account=account, ffi_event=ffi_event
)
deltachat.set_context_callback(account._dc_context, _ll_event)
@global_hookimpl
def account_after_shutdown(dc_context):
deltachat.clear_context_callback(dc_context)
class FFIEvent:
def __init__(self, name, data1, data2):
self.name = name
self.data1 = data1
self.data2 = data2
def __str__(self):
return "{name} data1={data1} data2={data2}".format(**self.__dict__)
class FFIEventLogger:

View File

@@ -47,10 +47,6 @@ class PerAccount:
def process_message_delivered(self, message):
""" Called when an outgoing message has been delivered to SMTP. """
@account_hookspec
def after_shutdown(self):
""" Called after the account has been shutdown. """
class Global:
""" global hook specifications using a per-process singleton plugin manager instance.
@@ -66,5 +62,10 @@ class Global:
return cls._plugin_manager
@global_hookspec
def at_account_init(self, account):
def account_init(self, account):
""" called when `Account::__init__()` function starts executing. """
@global_hookspec
def account_after_shutdown(self, account, dc_context):
""" Called after the account has been shutdown. """

View File

@@ -230,8 +230,8 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig, datadir):
configdict.update(config)
configdict["mvbox_watch"] = str(int(mvbox))
configdict["mvbox_move"] = "1"
ac.configure(**configdict)
ac.start_threads()
ac.update_config(configdict)
ac.start()
return ac
def get_one_online_account(self, pre_generated_key=True):
@@ -257,14 +257,14 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig, datadir):
self._preconfigure_key(ac, account.get_config("addr"))
ac._evtracker.init_time = self.init_time
ac._evtracker.set_timeout(30)
ac.configure(
ac.update_config(dict(
addr=account.get_config("addr"),
mail_pw=account.get_config("mail_pw"),
mvbox_watch=account.get_config("mvbox_watch"),
mvbox_move=account.get_config("mvbox_move"),
sentbox_watch=account.get_config("sentbox_watch"),
)
ac.start_threads()
))
ac.start()
return ac
am = AccountMaker()

View File

@@ -1,6 +1,7 @@
from __future__ import print_function
from deltachat import capi, cutil, const, set_context_callback, clear_context_callback
from deltachat.hookspec import account_hookimpl
from deltachat import register_global_plugin
from deltachat.hookspec import account_hookimpl, global_hookimpl
from deltachat.capi import ffi
from deltachat.capi import lib
@@ -24,14 +25,14 @@ def test_dc_close_events(tmpdir, acfactory):
shutdowns = []
class ShutdownPlugin:
@account_hookimpl
def after_shutdown(self):
assert not hasattr(ac1, "_dc_context")
shutdowns.append(1)
ac1.add_account_plugin(ShutdownPlugin())
@global_hookimpl
def account_after_shutdown(self, account):
assert account._dc_context is None
shutdowns.append(account)
register_global_plugin(ShutdownPlugin())
assert hasattr(ac1, "_dc_context")
ac1.shutdown()
assert shutdowns == [1]
assert shutdowns == [ac1]
def find(info_string):
evlog = ac1._evtracker