mirror of
https://github.com/chatmail/core.git
synced 2026-05-07 08:56:30 +03:00
make eventlogger module a global plugin
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
from . import capi, const, hookspec
|
from . import capi, const, hookspec
|
||||||
from .capi import ffi
|
from .capi import ffi
|
||||||
from .account import Account # noqa
|
from .account import Account # noqa
|
||||||
|
from . import eventlogger
|
||||||
|
|
||||||
from pkg_resources import get_distribution, DistributionNotFound
|
from pkg_resources import get_distribution, DistributionNotFound
|
||||||
try:
|
try:
|
||||||
@@ -79,3 +80,7 @@ def get_dc_event_name(integer, _DC_EVENTNAME_MAP={}):
|
|||||||
def register_global_plugin(plugin):
|
def register_global_plugin(plugin):
|
||||||
gm = hookspec.Global._get_plugin_manager()
|
gm = hookspec.Global._get_plugin_manager()
|
||||||
gm.register(plugin)
|
gm.register(plugin)
|
||||||
|
gm.check_pending()
|
||||||
|
|
||||||
|
|
||||||
|
register_global_plugin(eventlogger)
|
||||||
|
|||||||
@@ -45,20 +45,10 @@ class Account(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
hook = hookspec.Global._get_plugin_manager().hook
|
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)
|
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
|
# open database
|
||||||
if hasattr(db_path, "encode"):
|
if hasattr(db_path, "encode"):
|
||||||
db_path = db_path.encode("utf8")
|
db_path = db_path.encode("utf8")
|
||||||
@@ -66,6 +56,8 @@ class Account(object):
|
|||||||
raise ValueError("Could not dc_open: {}".format(db_path))
|
raise ValueError("Could not dc_open: {}".format(db_path))
|
||||||
self._configkeys = self.get_config("sys.config_keys").split()
|
self._configkeys = self.get_config("sys.config_keys").split()
|
||||||
atexit.register(self.shutdown)
|
atexit.register(self.shutdown)
|
||||||
|
self._shutdown_event = Event()
|
||||||
|
|
||||||
|
|
||||||
@hookspec.account_hookimpl
|
@hookspec.account_hookimpl
|
||||||
def process_ffi_event(self, ffi_event):
|
def process_ffi_event(self, ffi_event):
|
||||||
@@ -549,20 +541,19 @@ class Account(object):
|
|||||||
If this account is not configured, an internal configuration
|
If this account is not configured, an internal configuration
|
||||||
job will be scheduled if config values are sufficiently specified.
|
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.
|
:raises MissingCredentials: if `addr` and `mail_pw` values are not set.
|
||||||
|
|
||||||
:returns: None
|
:returns: None
|
||||||
"""
|
"""
|
||||||
if not self.is_configured():
|
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")
|
raise MissingCredentials("addr or mail_pwd not set in config")
|
||||||
lib.dc_configure(self._dc_context)
|
lib.dc_configure(self._dc_context)
|
||||||
self._threads.start()
|
self._threads.start()
|
||||||
|
|
||||||
@hookspec.account_hookimpl
|
|
||||||
def after_shutdown(self):
|
|
||||||
self._shutdown_event.set()
|
|
||||||
|
|
||||||
def wait_shutdown(self):
|
def wait_shutdown(self):
|
||||||
""" wait until shutdown of this account has completed. """
|
""" wait until shutdown of this account has completed. """
|
||||||
self._shutdown_event.wait()
|
self._shutdown_event.wait()
|
||||||
@@ -570,16 +561,20 @@ class Account(object):
|
|||||||
def shutdown(self, wait=True):
|
def shutdown(self, wait=True):
|
||||||
""" shutdown account, stop threads and close and remove
|
""" shutdown account, stop threads and close and remove
|
||||||
underlying dc_context and callbacks. """
|
underlying dc_context and callbacks. """
|
||||||
if hasattr(self, "_dc_context") and hasattr(self, "_threads"):
|
dc_context = self._dc_context
|
||||||
if self._threads.is_started():
|
if dc_context is None:
|
||||||
self.stop_ongoing()
|
return
|
||||||
self._threads.stop(wait=False)
|
|
||||||
lib.dc_close(self._dc_context)
|
if self._threads.is_started():
|
||||||
self._threads.stop(wait=wait) # to wait for threads
|
self.stop_ongoing()
|
||||||
deltachat.clear_context_callback(self._dc_context)
|
self._threads.stop(wait=False)
|
||||||
del self._dc_context
|
lib.dc_close(dc_context)
|
||||||
atexit.unregister(self.shutdown)
|
self._threads.stop(wait=wait) # to wait for threads
|
||||||
self._pm.hook.after_shutdown()
|
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):
|
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
|
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:
|
class ScannedQRCode:
|
||||||
def __init__(self, dc_lot):
|
def __init__(self, dc_lot):
|
||||||
self._dc_lot = dc_lot
|
self._dc_lot = dc_lot
|
||||||
|
|||||||
@@ -1,6 +1,34 @@
|
|||||||
|
import deltachat
|
||||||
import threading
|
import threading
|
||||||
import time
|
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:
|
class FFIEventLogger:
|
||||||
|
|||||||
@@ -47,10 +47,6 @@ class PerAccount:
|
|||||||
def process_message_delivered(self, message):
|
def process_message_delivered(self, message):
|
||||||
""" Called when an outgoing message has been delivered to SMTP. """
|
""" 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:
|
class Global:
|
||||||
""" global hook specifications using a per-process singleton plugin manager instance.
|
""" global hook specifications using a per-process singleton plugin manager instance.
|
||||||
@@ -66,5 +62,10 @@ class Global:
|
|||||||
return cls._plugin_manager
|
return cls._plugin_manager
|
||||||
|
|
||||||
@global_hookspec
|
@global_hookspec
|
||||||
def at_account_init(self, account):
|
def account_init(self, account):
|
||||||
""" called when `Account::__init__()` function starts executing. """
|
""" called when `Account::__init__()` function starts executing. """
|
||||||
|
|
||||||
|
@global_hookspec
|
||||||
|
def account_after_shutdown(self, account, dc_context):
|
||||||
|
""" Called after the account has been shutdown. """
|
||||||
|
|
||||||
|
|||||||
@@ -230,8 +230,8 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig, datadir):
|
|||||||
configdict.update(config)
|
configdict.update(config)
|
||||||
configdict["mvbox_watch"] = str(int(mvbox))
|
configdict["mvbox_watch"] = str(int(mvbox))
|
||||||
configdict["mvbox_move"] = "1"
|
configdict["mvbox_move"] = "1"
|
||||||
ac.configure(**configdict)
|
ac.update_config(configdict)
|
||||||
ac.start_threads()
|
ac.start()
|
||||||
return ac
|
return ac
|
||||||
|
|
||||||
def get_one_online_account(self, pre_generated_key=True):
|
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"))
|
self._preconfigure_key(ac, account.get_config("addr"))
|
||||||
ac._evtracker.init_time = self.init_time
|
ac._evtracker.init_time = self.init_time
|
||||||
ac._evtracker.set_timeout(30)
|
ac._evtracker.set_timeout(30)
|
||||||
ac.configure(
|
ac.update_config(dict(
|
||||||
addr=account.get_config("addr"),
|
addr=account.get_config("addr"),
|
||||||
mail_pw=account.get_config("mail_pw"),
|
mail_pw=account.get_config("mail_pw"),
|
||||||
mvbox_watch=account.get_config("mvbox_watch"),
|
mvbox_watch=account.get_config("mvbox_watch"),
|
||||||
mvbox_move=account.get_config("mvbox_move"),
|
mvbox_move=account.get_config("mvbox_move"),
|
||||||
sentbox_watch=account.get_config("sentbox_watch"),
|
sentbox_watch=account.get_config("sentbox_watch"),
|
||||||
)
|
))
|
||||||
ac.start_threads()
|
ac.start()
|
||||||
return ac
|
return ac
|
||||||
|
|
||||||
am = AccountMaker()
|
am = AccountMaker()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from deltachat import capi, cutil, const, set_context_callback, clear_context_callback
|
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 ffi
|
||||||
from deltachat.capi import lib
|
from deltachat.capi import lib
|
||||||
|
|
||||||
@@ -24,14 +25,14 @@ def test_dc_close_events(tmpdir, acfactory):
|
|||||||
shutdowns = []
|
shutdowns = []
|
||||||
|
|
||||||
class ShutdownPlugin:
|
class ShutdownPlugin:
|
||||||
@account_hookimpl
|
@global_hookimpl
|
||||||
def after_shutdown(self):
|
def account_after_shutdown(self, account):
|
||||||
assert not hasattr(ac1, "_dc_context")
|
assert account._dc_context is None
|
||||||
shutdowns.append(1)
|
shutdowns.append(account)
|
||||||
ac1.add_account_plugin(ShutdownPlugin())
|
register_global_plugin(ShutdownPlugin())
|
||||||
assert hasattr(ac1, "_dc_context")
|
assert hasattr(ac1, "_dc_context")
|
||||||
ac1.shutdown()
|
ac1.shutdown()
|
||||||
assert shutdowns == [1]
|
assert shutdowns == [ac1]
|
||||||
|
|
||||||
def find(info_string):
|
def find(info_string):
|
||||||
evlog = ac1._evtracker
|
evlog = ac1._evtracker
|
||||||
|
|||||||
Reference in New Issue
Block a user