mirror of
https://github.com/chatmail/core.git
synced 2026-05-19 06:46:32 +03:00
move event tracking to new tracker.py file
some api cleanups
This commit is contained in:
@@ -7,8 +7,6 @@ from contextlib import contextmanager
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from array import array
|
from array import array
|
||||||
from queue import Queue
|
|
||||||
|
|
||||||
import deltachat
|
import deltachat
|
||||||
from . import const
|
from . import const
|
||||||
from .capi import ffi, lib
|
from .capi import ffi, lib
|
||||||
@@ -17,6 +15,7 @@ from .chat import Chat
|
|||||||
from .message import Message
|
from .message import Message
|
||||||
from .contact import Contact
|
from .contact import Contact
|
||||||
from .eventlogger import EventLogger
|
from .eventlogger import EventLogger
|
||||||
|
from .tracker import ImexTracker
|
||||||
from .hookspec import AccountHookSpecs, account_hookimpl
|
from .hookspec import AccountHookSpecs, account_hookimpl
|
||||||
|
|
||||||
|
|
||||||
@@ -45,13 +44,14 @@ class Account(object):
|
|||||||
self._threads = IOThreads(self._dc_context, self._evlogger._log_event)
|
self._threads = IOThreads(self._dc_context, self._evlogger._log_event)
|
||||||
|
|
||||||
# initialize per-account plugin system
|
# initialize per-account plugin system
|
||||||
self.plugin_manager = AccountHookSpecs._make_plugin_manager()
|
self._pm = AccountHookSpecs._make_plugin_manager()
|
||||||
self.plugin_manager.register(self._evlogger)
|
self.add_account_plugin(self)
|
||||||
|
self.add_account_plugin(self._evlogger)
|
||||||
|
|
||||||
# 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):
|
||||||
assert ctx == self._dc_context
|
assert ctx == self._dc_context
|
||||||
self.plugin_manager.hook.process_low_level_event(
|
self._pm.hook.process_low_level_event(
|
||||||
account=self, event_name=evt_name, data1=data1, data2=data2
|
account=self, event_name=evt_name, data1=data1, data2=data2
|
||||||
)
|
)
|
||||||
deltachat.set_context_callback(self._dc_context, _ll_event)
|
deltachat.set_context_callback(self._dc_context, _ll_event)
|
||||||
@@ -64,6 +64,19 @@ class Account(object):
|
|||||||
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)
|
||||||
|
|
||||||
|
@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:
|
||||||
|
success = data1 == 1000
|
||||||
|
self._pm.hook.configure_completed(success=success)
|
||||||
|
|
||||||
|
def add_account_plugin(self, plugin):
|
||||||
|
""" add an account plugin whose hookimpls are called. """
|
||||||
|
self._pm.register(plugin)
|
||||||
|
self._pm.check_pending()
|
||||||
|
return plugin
|
||||||
|
|
||||||
# def __del__(self):
|
# def __del__(self):
|
||||||
# self.shutdown()
|
# self.shutdown()
|
||||||
|
|
||||||
@@ -519,7 +532,7 @@ 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.plugin_manager.unregister(self._evlogger)
|
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
|
||||||
@@ -538,33 +551,9 @@ class Account(object):
|
|||||||
@contextmanager
|
@contextmanager
|
||||||
def temp_plugin(self, plugin):
|
def temp_plugin(self, plugin):
|
||||||
""" run a code block with the given plugin temporarily registered. """
|
""" run a code block with the given plugin temporarily registered. """
|
||||||
self.plugin_manager.register(plugin)
|
self._pm.register(plugin)
|
||||||
yield plugin
|
yield plugin
|
||||||
self.plugin_manager.unregister(plugin)
|
self._pm.unregister(plugin)
|
||||||
|
|
||||||
|
|
||||||
class ImexTracker:
|
|
||||||
def __init__(self):
|
|
||||||
self._imex_events = Queue()
|
|
||||||
|
|
||||||
@account_hookimpl
|
|
||||||
def process_low_level_event(self, event_name, data1, data2):
|
|
||||||
if event_name == "DC_EVENT_IMEX_PROGRESS":
|
|
||||||
self._imex_events.put(data1)
|
|
||||||
elif event_name == "DC_EVENT_IMEX_FILE_WRITTEN":
|
|
||||||
self._imex_events.put(data1)
|
|
||||||
|
|
||||||
def wait_finish(self, progress_timeout=60):
|
|
||||||
""" Return list of written files, raise ValueError if ExportFailed. """
|
|
||||||
files_written = []
|
|
||||||
while True:
|
|
||||||
ev = self._imex_events.get(timeout=progress_timeout)
|
|
||||||
if isinstance(ev, str):
|
|
||||||
files_written.append(ev)
|
|
||||||
elif ev == 0:
|
|
||||||
raise ValueError("export failed, exp-files: {}".format(files_written))
|
|
||||||
elif ev == 1000:
|
|
||||||
return files_written
|
|
||||||
|
|
||||||
|
|
||||||
class IOThreads:
|
class IOThreads:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import threading
|
|
||||||
import time
|
import time
|
||||||
from .hookspec import account_hookimpl
|
from .hookspec import account_hookimpl
|
||||||
|
|
||||||
|
|||||||
@@ -23,3 +23,7 @@ class AccountHookSpecs:
|
|||||||
@account_hookspec
|
@account_hookspec
|
||||||
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 configure_completed(self, success):
|
||||||
|
""" Called when a configure process completed. """
|
||||||
|
|||||||
74
python/src/deltachat/tracker.py
Normal file
74
python/src/deltachat/tracker.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
|
||||||
|
from queue import Queue
|
||||||
|
from threading import Event
|
||||||
|
|
||||||
|
from .hookspec import account_hookimpl
|
||||||
|
|
||||||
|
|
||||||
|
class ImexFailed(RuntimeError):
|
||||||
|
""" Exception for signalling that import/export operations failed."""
|
||||||
|
|
||||||
|
|
||||||
|
class ImexTracker:
|
||||||
|
def __init__(self):
|
||||||
|
self._imex_events = Queue()
|
||||||
|
|
||||||
|
@account_hookimpl
|
||||||
|
def process_low_level_event(self, event_name, data1, data2):
|
||||||
|
if event_name == "DC_EVENT_IMEX_PROGRESS":
|
||||||
|
self._imex_events.put(data1)
|
||||||
|
elif event_name == "DC_EVENT_IMEX_FILE_WRITTEN":
|
||||||
|
self._imex_events.put(data1)
|
||||||
|
|
||||||
|
def wait_finish(self, progress_timeout=60):
|
||||||
|
""" Return list of written files, raise ValueError if ExportFailed. """
|
||||||
|
files_written = []
|
||||||
|
while True:
|
||||||
|
ev = self._imex_events.get(timeout=progress_timeout)
|
||||||
|
if isinstance(ev, str):
|
||||||
|
files_written.append(ev)
|
||||||
|
elif ev == 0:
|
||||||
|
raise ImexFailed("export failed, exp-files: {}".format(files_written))
|
||||||
|
elif ev == 1000:
|
||||||
|
return files_written
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigureFailed(RuntimeError):
|
||||||
|
""" Exception for signalling that configuration failed."""
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigureTracker:
|
||||||
|
def __init__(self):
|
||||||
|
self._configure_events = Queue()
|
||||||
|
self._smtp_finished = Event()
|
||||||
|
self._imap_finished = Event()
|
||||||
|
self._ffi_events = []
|
||||||
|
|
||||||
|
@account_hookimpl
|
||||||
|
def process_low_level_event(self, event_name, data1, data2):
|
||||||
|
self._ffi_events.append((event_name, data1, data2))
|
||||||
|
if event_name == "DC_EVENT_SMTP_CONNECTED":
|
||||||
|
self._smtp_finished.set()
|
||||||
|
elif event_name == "DC_EVENT_IMAP_CONNECTED":
|
||||||
|
self._imap_finished.set()
|
||||||
|
|
||||||
|
@account_hookimpl
|
||||||
|
def configure_completed(self, success):
|
||||||
|
self._configure_events.put(success)
|
||||||
|
|
||||||
|
def wait_smtp_connected(self):
|
||||||
|
""" wait until smtp is configured. """
|
||||||
|
self._smtp_finished.wait()
|
||||||
|
|
||||||
|
def wait_imap_connected(self):
|
||||||
|
""" wait until smtp is configured. """
|
||||||
|
self._imap_finished.wait()
|
||||||
|
|
||||||
|
def wait_finish(self):
|
||||||
|
""" wait until configure is completed.
|
||||||
|
|
||||||
|
Raise Exception if Configure failed
|
||||||
|
"""
|
||||||
|
if not self._configure_events.get():
|
||||||
|
content = "\n".join("{}: {} {}".format(*args) for args in self._ffi_events)
|
||||||
|
raise ConfigureFailed(content)
|
||||||
@@ -6,6 +6,7 @@ import pytest
|
|||||||
import requests
|
import requests
|
||||||
import time
|
import time
|
||||||
from deltachat import Account
|
from deltachat import Account
|
||||||
|
from deltachat.tracker import ConfigureTracker
|
||||||
from deltachat import const
|
from deltachat import const
|
||||||
from deltachat.capi import lib
|
from deltachat.capi import lib
|
||||||
from _pytest.monkeypatch import MonkeyPatch
|
from _pytest.monkeypatch import MonkeyPatch
|
||||||
@@ -164,8 +165,8 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig, datadir):
|
|||||||
|
|
||||||
def make_account(self, path, logid):
|
def make_account(self, path, logid):
|
||||||
ac = Account(path, logid=logid)
|
ac = Account(path, logid=logid)
|
||||||
ac._evtracker = FFIEventTracker(ac)
|
ac._evtracker = ac.add_account_plugin(FFIEventTracker(ac))
|
||||||
ac.plugin_manager.register(ac._evtracker)
|
ac._configtracker = ac.add_account_plugin(ConfigureTracker())
|
||||||
self._finalizers.append(ac.shutdown)
|
self._finalizers.append(ac.shutdown)
|
||||||
return ac
|
return ac
|
||||||
|
|
||||||
@@ -232,17 +233,16 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig, datadir):
|
|||||||
def get_one_online_account(self, pre_generated_key=True):
|
def get_one_online_account(self, pre_generated_key=True):
|
||||||
ac1 = self.get_online_configuring_account(
|
ac1 = self.get_online_configuring_account(
|
||||||
pre_generated_key=pre_generated_key)
|
pre_generated_key=pre_generated_key)
|
||||||
wait_successful_IMAP_SMTP_connection(ac1)
|
ac1._configtracker.wait_imap_connected()
|
||||||
wait_configuration_progress(ac1, 1000)
|
ac1._configtracker.wait_smtp_connected()
|
||||||
|
ac1._configtracker.wait_finish()
|
||||||
return ac1
|
return ac1
|
||||||
|
|
||||||
def get_two_online_accounts(self):
|
def get_two_online_accounts(self):
|
||||||
ac1 = self.get_online_configuring_account()
|
ac1 = self.get_online_configuring_account()
|
||||||
ac2 = self.get_online_configuring_account()
|
ac2 = self.get_online_configuring_account()
|
||||||
wait_successful_IMAP_SMTP_connection(ac1)
|
ac1._configtracker.wait_finish()
|
||||||
wait_configuration_progress(ac1, 1000)
|
ac2._configtracker.wait_finish()
|
||||||
wait_successful_IMAP_SMTP_connection(ac2)
|
|
||||||
wait_configuration_progress(ac2, 1000)
|
|
||||||
return ac1, ac2
|
return ac1, ac2
|
||||||
|
|
||||||
def clone_online_account(self, account, pre_generated_key=True):
|
def clone_online_account(self, account, pre_generated_key=True):
|
||||||
|
|||||||
Reference in New Issue
Block a user