good bye global plugin manager ... we only do per-account object plugin_management for now

This commit is contained in:
holger krekel
2020-02-22 17:43:00 +01:00
parent e9967c32e6
commit ec67b3975c
3 changed files with 40 additions and 44 deletions

View File

@@ -3,6 +3,7 @@
from __future__ import print_function
import atexit
import threading
from contextlib import contextmanager
import os
import time
from array import array
@@ -16,7 +17,7 @@ from .chat import Chat
from .message import Message
from .contact import Contact
from .eventlogger import EventLogger
from .hookspec import get_plugin_manager, hookimpl
from .hookspec import AccountHookSpecs, account_hookimpl
class Account(object):
@@ -41,15 +42,15 @@ class Account(object):
self._evlogger = EventLogger(self, logid, debug)
self._threads = IOThreads(self._dc_context, self._evlogger._log_event)
# register event call back and initialize plugin system
# register event call back and initialize per-account plugin system
def _ll_event(ctx, evt_name, data1, data2):
assert ctx == self._dc_context
self.pluggy.hook.process_low_level_event(
self.plugin_manager.hook.process_low_level_event(
account=self, event_name=evt_name, data1=data1, data2=data2
)
self.pluggy = get_plugin_manager()
self.pluggy.register(self._evlogger)
self.plugin_manager = AccountHookSpecs._make_plugin_manager()
self.plugin_manager.register(self._evlogger)
deltachat.set_context_callback(self._dc_context, _ll_event)
# open database
@@ -382,7 +383,7 @@ class Account(object):
return export_files[0]
def _export(self, path, imex_cmd):
with ImexTracker(self) as imex_tracker:
with temp_plugin(self.plugin_manager, ImexTracker()) as imex_tracker:
lib.dc_imex(self._dc_context, imex_cmd, as_dc_charpointer(path), ffi.NULL)
if not self._threads.is_started():
lib.dc_perform_imap_jobs(self._dc_context)
@@ -404,7 +405,7 @@ class Account(object):
self._import(path, imex_cmd=12)
def _import(self, path, imex_cmd):
with ImexTracker(self) as imex_tracker:
with temp_plugin(self.plugin_manager, ImexTracker()) as imex_tracker:
lib.dc_imex(self._dc_context, imex_cmd, as_dc_charpointer(path), ffi.NULL)
if not self._threads.is_started():
lib.dc_perform_imap_jobs(self._dc_context)
@@ -511,7 +512,7 @@ class Account(object):
deltachat.clear_context_callback(self._dc_context)
del self._dc_context
atexit.unregister(self.shutdown)
self.pluggy.unregister(self._evlogger)
self.plugin_manager.unregister(self._evlogger)
def set_location(self, latitude=0.0, longitude=0.0, accuracy=0.0):
"""set a new location. It effects all chats where we currently
@@ -528,23 +529,19 @@ class Account(object):
raise ValueError("no chat is streaming locations")
@contextmanager
def temp_plugin(plugin_manager, plugin):
plugin_manager.register(plugin)
yield plugin
plugin_manager.unregister(plugin)
class ImexTracker:
def __init__(self, account):
def __init__(self):
self._imex_events = Queue()
self.account = account
def __enter__(self):
self.account.pluggy.register(self)
return self
def __exit__(self, *args):
self.account.pluggy.unregister(self)
@hookimpl
def process_low_level_event(self, account, event_name, data1, data2):
# there could be multiple accounts instantiated
if self.account is not account:
return
@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":

View File

@@ -2,7 +2,7 @@ import threading
import re
import time
from queue import Queue, Empty
from .hookspec import hookimpl
from .hookspec import account_hookimpl
class EventLogger:
@@ -18,11 +18,10 @@ class EventLogger:
self._timeout = None
self.init_time = time.time()
@hookimpl
def process_low_level_event(self, account, event_name, data1, data2):
if self.account == account:
self._log_event(event_name, data1, data2)
self._event_queue.put((event_name, data1, data2))
@account_hookimpl
def process_low_level_event(self, event_name, data1, data2):
self._log_event(event_name, data1, data2)
self._event_queue.put((event_name, data1, data2))
def set_timeout(self, timeout):
self._timeout = timeout

View File

@@ -1,25 +1,25 @@
""" Hooks for python bindings """
""" Hooks for Python bindings to Delta Chat Core Rust CFFI"""
import pluggy
name = "deltachat"
__all__ = ["account_hookspec", "account_hookimpl", "AccountHookSpecs"]
hookspec = pluggy.HookspecMarker(name)
hookimpl = pluggy.HookimplMarker(name)
_plugin_manager = None
_account_name = "deltachat-account"
account_hookspec = pluggy.HookspecMarker(_account_name)
account_hookimpl = pluggy.HookimplMarker(_account_name)
def get_plugin_manager():
global _plugin_manager
if _plugin_manager is None:
_plugin_manager = pluggy.PluginManager(name)
_plugin_manager.add_hookspecs(DeltaChatHookSpecs)
return _plugin_manager
class AccountHookSpecs:
""" per-Account-instance hook specifications.
Account hook implementations need to be registered with an Account instance.
"""
@classmethod
def _make_plugin_manager(cls):
pm = pluggy.PluginManager(_account_name)
pm.add_hookspecs(cls)
return pm
class DeltaChatHookSpecs:
""" Plugin Hook specifications for Python bindings to Delta Chat CFFI. """
@hookspec
def process_low_level_event(self, account, event_name, data1, data2):
@account_hookspec
def process_low_level_event(self, event_name, data1, data2):
""" process a CFFI low level events for a given account. """