mirror of
https://github.com/chatmail/core.git
synced 2026-04-29 11:26:29 +03:00
api(jsonrpc): add run_until parameter for bots (#7688)
This commit also makes testing hooks easier, as it allows to process events and run hooks on them, until a certain event occurs. --------- Co-authored-by: iequidoo <117991069+iequidoo@users.noreply.github.com>
This commit is contained in:
@@ -44,8 +44,13 @@ class AttrDict(dict):
|
|||||||
super().__setattr__(attr, val)
|
super().__setattr__(attr, val)
|
||||||
|
|
||||||
|
|
||||||
|
def _forever(_event: AttrDict) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def run_client_cli(
|
def run_client_cli(
|
||||||
hooks: Optional[Iterable[Tuple[Callable, Union[type, "EventFilter"]]]] = None,
|
hooks: Optional[Iterable[Tuple[Callable, Union[type, "EventFilter"]]]] = None,
|
||||||
|
until: Callable[[AttrDict], bool] = _forever,
|
||||||
argv: Optional[list] = None,
|
argv: Optional[list] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -55,10 +60,11 @@ def run_client_cli(
|
|||||||
"""
|
"""
|
||||||
from .client import Client
|
from .client import Client
|
||||||
|
|
||||||
_run_cli(Client, hooks, argv, **kwargs)
|
_run_cli(Client, until, hooks, argv, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def run_bot_cli(
|
def run_bot_cli(
|
||||||
|
until: Callable[[AttrDict], bool] = _forever,
|
||||||
hooks: Optional[Iterable[Tuple[Callable, Union[type, "EventFilter"]]]] = None,
|
hooks: Optional[Iterable[Tuple[Callable, Union[type, "EventFilter"]]]] = None,
|
||||||
argv: Optional[list] = None,
|
argv: Optional[list] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
@@ -69,11 +75,12 @@ def run_bot_cli(
|
|||||||
"""
|
"""
|
||||||
from .client import Bot
|
from .client import Bot
|
||||||
|
|
||||||
_run_cli(Bot, hooks, argv, **kwargs)
|
_run_cli(Bot, until, hooks, argv, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def _run_cli(
|
def _run_cli(
|
||||||
client_type: Type["Client"],
|
client_type: Type["Client"],
|
||||||
|
until: Callable[[AttrDict], bool] = _forever,
|
||||||
hooks: Optional[Iterable[Tuple[Callable, Union[type, "EventFilter"]]]] = None,
|
hooks: Optional[Iterable[Tuple[Callable, Union[type, "EventFilter"]]]] = None,
|
||||||
argv: Optional[list] = None,
|
argv: Optional[list] = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
@@ -111,7 +118,7 @@ def _run_cli(
|
|||||||
kwargs={"email": args.email, "password": args.password},
|
kwargs={"email": args.email, "password": args.password},
|
||||||
)
|
)
|
||||||
configure_thread.start()
|
configure_thread.start()
|
||||||
client.run_forever()
|
client.run_until(until)
|
||||||
|
|
||||||
|
|
||||||
def extract_addr(text: str) -> str:
|
def extract_addr(text: str) -> str:
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from typing import (
|
|||||||
|
|
||||||
from ._utils import (
|
from ._utils import (
|
||||||
AttrDict,
|
AttrDict,
|
||||||
|
_forever,
|
||||||
parse_system_add_remove,
|
parse_system_add_remove,
|
||||||
parse_system_image_changed,
|
parse_system_image_changed,
|
||||||
parse_system_title_changed,
|
parse_system_title_changed,
|
||||||
@@ -91,19 +92,28 @@ class Client:
|
|||||||
|
|
||||||
def run_forever(self) -> None:
|
def run_forever(self) -> None:
|
||||||
"""Process events forever."""
|
"""Process events forever."""
|
||||||
self.run_until(lambda _: False)
|
self.run_until(_forever)
|
||||||
|
|
||||||
def run_until(self, func: Callable[[AttrDict], bool]) -> AttrDict:
|
def run_until(self, func: Callable[[AttrDict], bool]) -> AttrDict:
|
||||||
"""Process events until the given callable evaluates to True.
|
"""Start the event processing loop."""
|
||||||
|
|
||||||
The callable should accept an AttrDict object representing the
|
|
||||||
last processed event. The event is returned when the callable
|
|
||||||
evaluates to True.
|
|
||||||
"""
|
|
||||||
self.logger.debug("Listening to incoming events...")
|
self.logger.debug("Listening to incoming events...")
|
||||||
if self.is_configured():
|
if self.is_configured():
|
||||||
self.account.start_io()
|
self.account.start_io()
|
||||||
self._process_messages() # Process old messages.
|
self._process_messages() # Process old messages.
|
||||||
|
return self._process_events(until_func=func) # Loop over incoming events
|
||||||
|
|
||||||
|
def _process_events(
|
||||||
|
self,
|
||||||
|
until_func: Callable[[AttrDict], bool],
|
||||||
|
until_event: EventType = False,
|
||||||
|
) -> AttrDict:
|
||||||
|
"""Process events until the given callable evaluates to True,
|
||||||
|
or until a certain event happens.
|
||||||
|
|
||||||
|
The until_func callable should accept an AttrDict object representing
|
||||||
|
the last processed event. The event is returned when the callable
|
||||||
|
evaluates to True.
|
||||||
|
"""
|
||||||
while True:
|
while True:
|
||||||
event = self.account.wait_for_event()
|
event = self.account.wait_for_event()
|
||||||
event["kind"] = EventType(event.kind)
|
event["kind"] = EventType(event.kind)
|
||||||
@@ -112,10 +122,13 @@ class Client:
|
|||||||
if event.kind == EventType.INCOMING_MSG:
|
if event.kind == EventType.INCOMING_MSG:
|
||||||
self._process_messages()
|
self._process_messages()
|
||||||
|
|
||||||
stop = func(event)
|
stop = until_func(event)
|
||||||
if stop:
|
if stop:
|
||||||
return event
|
return event
|
||||||
|
|
||||||
|
if event.kind == until_event:
|
||||||
|
return event
|
||||||
|
|
||||||
def _on_event(self, event: AttrDict, filter_type: Type[EventFilter] = RawEvent) -> None:
|
def _on_event(self, event: AttrDict, filter_type: Type[EventFilter] = RawEvent) -> None:
|
||||||
for hook, evfilter in self._hooks.get(filter_type, []):
|
for hook, evfilter in self._hooks.get(filter_type, []):
|
||||||
if evfilter.filter(event):
|
if evfilter.filter(event):
|
||||||
|
|||||||
Reference in New Issue
Block a user