mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
don't run Eventlogging by default -- the tests instantiate it, though.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
from . import capi, const
|
from . import capi, const, hookspec
|
||||||
from .capi import ffi
|
from .capi import ffi
|
||||||
from .account import Account # noqa
|
from .account import Account # noqa
|
||||||
|
|
||||||
@@ -74,3 +74,8 @@ def get_dc_event_name(integer, _DC_EVENTNAME_MAP={}):
|
|||||||
if name.startswith("DC_EVENT_"):
|
if name.startswith("DC_EVENT_"):
|
||||||
_DC_EVENTNAME_MAP[val] = name
|
_DC_EVENTNAME_MAP[val] = name
|
||||||
return _DC_EVENTNAME_MAP[integer]
|
return _DC_EVENTNAME_MAP[integer]
|
||||||
|
|
||||||
|
|
||||||
|
def register_global_plugin(plugin):
|
||||||
|
gm = hookspect.Global._get_plugin_manager()
|
||||||
|
gm.register(plugin)
|
||||||
|
|||||||
@@ -14,29 +14,20 @@ from .cutil import as_dc_charpointer, from_dc_charpointer, iter_array, DCLot
|
|||||||
from .chat import Chat
|
from .chat import Chat
|
||||||
from .message import Message
|
from .message import Message
|
||||||
from .contact import Contact
|
from .contact import Contact
|
||||||
from . import eventlogger
|
|
||||||
from .tracker import ImexTracker
|
from .tracker import ImexTracker
|
||||||
from . import hookspec
|
from . import hookspec
|
||||||
|
|
||||||
|
|
||||||
hookspec.Global._get_plugin_manager().register(eventlogger)
|
|
||||||
|
|
||||||
|
|
||||||
class Account(object):
|
class Account(object):
|
||||||
""" Each account is tied to a sqlite database file which is fully managed
|
""" Each account is tied to a sqlite database file which is fully managed
|
||||||
by the underlying deltachat core library. All public Account methods are
|
by the underlying deltachat core library. All public Account methods are
|
||||||
meant to be memory-safe and return memory-safe objects.
|
meant to be memory-safe and return memory-safe objects.
|
||||||
"""
|
"""
|
||||||
# to prevent garbled logging
|
def __init__(self, db_path, os_name=None):
|
||||||
_loglock = threading.RLock()
|
|
||||||
|
|
||||||
def __init__(self, db_path, logid=None, os_name=None):
|
|
||||||
""" initialize account object.
|
""" initialize account object.
|
||||||
|
|
||||||
:param db_path: a path to the account database. The database
|
:param db_path: a path to the account database. The database
|
||||||
will be created if it doesn't exist.
|
will be created if it doesn't exist.
|
||||||
:param logid: an optional logging prefix that should be used with
|
|
||||||
the default internal logging.
|
|
||||||
:param os_name: this will be put to the X-Mailer header in outgoing messages
|
:param os_name: this will be put to the X-Mailer header in outgoing messages
|
||||||
"""
|
"""
|
||||||
# initialize per-account plugin system
|
# initialize per-account plugin system
|
||||||
@@ -49,9 +40,9 @@ 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, logid=logid)
|
hook.at_account_init(account=self, db_path=db_path)
|
||||||
|
|
||||||
self._threads = IOThreads(self._dc_context)
|
self._threads = IOThreads(self)
|
||||||
|
|
||||||
# send all FFI events for this account to a plugin hook
|
# send all FFI events for this account to a plugin hook
|
||||||
def _ll_event(ctx, evt_name, data1, data2):
|
def _ll_event(ctx, evt_name, data1, data2):
|
||||||
@@ -86,13 +77,7 @@ class Account(object):
|
|||||||
# self.shutdown()
|
# self.shutdown()
|
||||||
|
|
||||||
def log_line(self, msg):
|
def log_line(self, msg):
|
||||||
t = threading.currentThread()
|
self._pm.hook.log_line(message=msg)
|
||||||
tname = getattr(t, "name", t)
|
|
||||||
if tname == "MainThread":
|
|
||||||
tname = "MAIN"
|
|
||||||
with self._loglock:
|
|
||||||
print("{:2.2f} [{}-{}] {}".format(time.time() - self._evlogger.init_time,
|
|
||||||
tname, self._evlogger.logid, msg))
|
|
||||||
|
|
||||||
def _check_config_key(self, name):
|
def _check_config_key(self, name):
|
||||||
if name not in self._configkeys:
|
if name not in self._configkeys:
|
||||||
@@ -537,7 +522,6 @@ class Account(object):
|
|||||||
deltachat.clear_context_callback(self._dc_context)
|
deltachat.clear_context_callback(self._dc_context)
|
||||||
del self._dc_context
|
del self._dc_context
|
||||||
atexit.unregister(self.shutdown)
|
atexit.unregister(self.shutdown)
|
||||||
self._pm.unregister(self._evlogger)
|
|
||||||
|
|
||||||
def set_location(self, latitude=0.0, longitude=0.0, accuracy=0.0):
|
def set_location(self, latitude=0.0, longitude=0.0, accuracy=0.0):
|
||||||
"""set a new location. It effects all chats where we currently
|
"""set a new location. It effects all chats where we currently
|
||||||
@@ -562,11 +546,11 @@ class Account(object):
|
|||||||
|
|
||||||
|
|
||||||
class IOThreads:
|
class IOThreads:
|
||||||
def __init__(self, dc_context, log_event=lambda *args: None):
|
def __init__(self, account):
|
||||||
self._dc_context = dc_context
|
self.account = account
|
||||||
|
self._dc_context = account._dc_context
|
||||||
self._thread_quitflag = False
|
self._thread_quitflag = False
|
||||||
self._name2thread = {}
|
self._name2thread = {}
|
||||||
self._log_event = log_event
|
|
||||||
|
|
||||||
def is_started(self):
|
def is_started(self):
|
||||||
return len(self._name2thread) > 0
|
return len(self._name2thread) > 0
|
||||||
@@ -587,6 +571,12 @@ class IOThreads:
|
|||||||
t.setDaemon(1)
|
t.setDaemon(1)
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def log_execution(self, message):
|
||||||
|
self.account.log_line(message + " START")
|
||||||
|
yield
|
||||||
|
self.account.log_line(message + " FINISHED")
|
||||||
|
|
||||||
def stop(self, wait=False):
|
def stop(self, wait=False):
|
||||||
self._thread_quitflag = True
|
self._thread_quitflag = True
|
||||||
|
|
||||||
@@ -603,42 +593,38 @@ class IOThreads:
|
|||||||
thread.join()
|
thread.join()
|
||||||
|
|
||||||
def imap_thread_run(self):
|
def imap_thread_run(self):
|
||||||
self._log_event("py-bindings-info", 0, "INBOX THREAD START")
|
with self.log_execution("INBOX THREAD START"):
|
||||||
while not self._thread_quitflag:
|
while not self._thread_quitflag:
|
||||||
lib.dc_perform_imap_jobs(self._dc_context)
|
lib.dc_perform_imap_jobs(self._dc_context)
|
||||||
if not self._thread_quitflag:
|
if not self._thread_quitflag:
|
||||||
lib.dc_perform_imap_fetch(self._dc_context)
|
lib.dc_perform_imap_fetch(self._dc_context)
|
||||||
if not self._thread_quitflag:
|
if not self._thread_quitflag:
|
||||||
lib.dc_perform_imap_idle(self._dc_context)
|
lib.dc_perform_imap_idle(self._dc_context)
|
||||||
self._log_event("py-bindings-info", 0, "INBOX THREAD FINISHED")
|
|
||||||
|
|
||||||
def mvbox_thread_run(self):
|
def mvbox_thread_run(self):
|
||||||
self._log_event("py-bindings-info", 0, "MVBOX THREAD START")
|
with self.log_execution("MVBOX THREAD"):
|
||||||
while not self._thread_quitflag:
|
while not self._thread_quitflag:
|
||||||
lib.dc_perform_mvbox_jobs(self._dc_context)
|
lib.dc_perform_mvbox_jobs(self._dc_context)
|
||||||
if not self._thread_quitflag:
|
if not self._thread_quitflag:
|
||||||
lib.dc_perform_mvbox_fetch(self._dc_context)
|
lib.dc_perform_mvbox_fetch(self._dc_context)
|
||||||
if not self._thread_quitflag:
|
if not self._thread_quitflag:
|
||||||
lib.dc_perform_mvbox_idle(self._dc_context)
|
lib.dc_perform_mvbox_idle(self._dc_context)
|
||||||
self._log_event("py-bindings-info", 0, "MVBOX THREAD FINISHED")
|
|
||||||
|
|
||||||
def sentbox_thread_run(self):
|
def sentbox_thread_run(self):
|
||||||
self._log_event("py-bindings-info", 0, "SENTBOX THREAD START")
|
with self.log_execution("SENTBOX THREAD"):
|
||||||
while not self._thread_quitflag:
|
while not self._thread_quitflag:
|
||||||
lib.dc_perform_sentbox_jobs(self._dc_context)
|
lib.dc_perform_sentbox_jobs(self._dc_context)
|
||||||
if not self._thread_quitflag:
|
if not self._thread_quitflag:
|
||||||
lib.dc_perform_sentbox_fetch(self._dc_context)
|
lib.dc_perform_sentbox_fetch(self._dc_context)
|
||||||
if not self._thread_quitflag:
|
if not self._thread_quitflag:
|
||||||
lib.dc_perform_sentbox_idle(self._dc_context)
|
lib.dc_perform_sentbox_idle(self._dc_context)
|
||||||
self._log_event("py-bindings-info", 0, "SENTBOX THREAD FINISHED")
|
|
||||||
|
|
||||||
def smtp_thread_run(self):
|
def smtp_thread_run(self):
|
||||||
self._log_event("py-bindings-info", 0, "SMTP THREAD START")
|
with self.log_execution("SMTP THREAD"):
|
||||||
while not self._thread_quitflag:
|
while not self._thread_quitflag:
|
||||||
lib.dc_perform_smtp_jobs(self._dc_context)
|
lib.dc_perform_smtp_jobs(self._dc_context)
|
||||||
if not self._thread_quitflag:
|
if not self._thread_quitflag:
|
||||||
lib.dc_perform_smtp_idle(self._dc_context)
|
lib.dc_perform_smtp_idle(self._dc_context)
|
||||||
self._log_event("py-bindings-info", 0, "SMTP THREAD FINISHED")
|
|
||||||
|
|
||||||
|
|
||||||
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):
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
from .hookspec import account_hookimpl, global_hookimpl
|
from .hookspec import account_hookimpl, global_hookimpl
|
||||||
|
|
||||||
|
|
||||||
@global_hookimpl
|
class FFIEventLogger:
|
||||||
def at_account_init(account, logid):
|
""" If you register an instance of this logger with an Account
|
||||||
account._evlogger = account.add_account_plugin(EventLogger(account, logid=logid))
|
you'll get all ffi-events printed.
|
||||||
|
"""
|
||||||
|
# to prevent garbled logging
|
||||||
|
_loglock = threading.RLock()
|
||||||
|
|
||||||
|
def __init__(self, account, logid):
|
||||||
class EventLogger:
|
"""
|
||||||
def __init__(self, account, logid=None):
|
:param logid: an optional logging prefix that should be used with
|
||||||
|
the default internal logging.
|
||||||
|
"""
|
||||||
self.account = account
|
self.account = account
|
||||||
if logid is None:
|
|
||||||
logid = str(self.account._dc_context).strip(">").split()[-1]
|
|
||||||
self.logid = logid
|
self.logid = logid
|
||||||
self.init_time = time.time()
|
self.init_time = time.time()
|
||||||
|
|
||||||
@@ -25,3 +29,16 @@ class EventLogger:
|
|||||||
return
|
return
|
||||||
evpart = "{}({!r},{!r})".format(evt_name, data1, data2)
|
evpart = "{}({!r},{!r})".format(evt_name, data1, data2)
|
||||||
self.account.log_line(evpart)
|
self.account.log_line(evpart)
|
||||||
|
|
||||||
|
@account_hookimpl
|
||||||
|
def log_line(self, message):
|
||||||
|
t = threading.currentThread()
|
||||||
|
tname = getattr(t, "name", t)
|
||||||
|
if tname == "MainThread":
|
||||||
|
tname = "MAIN"
|
||||||
|
with self._loglock:
|
||||||
|
print("{:2.2f} [{}-{}] {}".format(
|
||||||
|
time.time() - self.init_time,
|
||||||
|
tname,
|
||||||
|
self.logid,
|
||||||
|
message))
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ class PerAccount:
|
|||||||
def process_low_level_event(self, event_name, data1, data2):
|
def process_low_level_event(self, event_name, data1, data2):
|
||||||
""" process a CFFI low level events for a given account. """
|
""" process a CFFI low level events for a given account. """
|
||||||
|
|
||||||
|
@account_hookspec
|
||||||
|
def log_line(self, message):
|
||||||
|
""" log a message related to the account. """
|
||||||
|
|
||||||
@account_hookspec
|
@account_hookspec
|
||||||
def configure_completed(self, success):
|
def configure_completed(self, success):
|
||||||
""" Called when a configure process completed. """
|
""" Called when a configure process completed. """
|
||||||
@@ -47,5 +51,5 @@ class Global:
|
|||||||
return cls._plugin_manager
|
return cls._plugin_manager
|
||||||
|
|
||||||
@global_hookspec
|
@global_hookspec
|
||||||
def at_account_init(self, account, logid):
|
def at_account_init(self, account):
|
||||||
""" called when `Account::__init__()` function starts executing. """
|
""" called when `Account::__init__()` function starts executing. """
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from deltachat import Account
|
|||||||
from deltachat.tracker import ConfigureTracker
|
from deltachat.tracker import ConfigureTracker
|
||||||
from deltachat import const
|
from deltachat import const
|
||||||
from deltachat.capi import lib
|
from deltachat.capi import lib
|
||||||
|
from deltachat.eventlogger import FFIEventLogger
|
||||||
from _pytest.monkeypatch import MonkeyPatch
|
from _pytest.monkeypatch import MonkeyPatch
|
||||||
from ffi_event import FFIEventTracker
|
from ffi_event import FFIEventTracker
|
||||||
import tempfile
|
import tempfile
|
||||||
@@ -164,9 +165,10 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig, datadir):
|
|||||||
fin()
|
fin()
|
||||||
|
|
||||||
def make_account(self, path, logid):
|
def make_account(self, path, logid):
|
||||||
ac = Account(path, logid=logid)
|
ac = Account(path)
|
||||||
ac._evtracker = ac.add_account_plugin(FFIEventTracker(ac))
|
ac._evtracker = ac.add_account_plugin(FFIEventTracker(ac))
|
||||||
ac._configtracker = ac.add_account_plugin(ConfigureTracker())
|
ac._configtracker = ac.add_account_plugin(ConfigureTracker())
|
||||||
|
ac.add_account_plugin(FFIEventLogger(ac, logid=logid))
|
||||||
self._finalizers.append(ac.shutdown)
|
self._finalizers.append(ac.shutdown)
|
||||||
return ac
|
return ac
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user