add Client.run_until()

This commit is contained in:
adbenitez
2022-12-11 03:31:29 -05:00
parent be63e18ebf
commit 2ebd3f54e6
3 changed files with 111 additions and 36 deletions

View File

@@ -1,6 +1,17 @@
"""Event loop implementations offering high level event handling/hooking."""
import inspect
import logging
from typing import Callable, Dict, Iterable, Optional, Set, Tuple, Type, Union
from typing import (
Callable,
Coroutine,
Dict,
Iterable,
Optional,
Set,
Tuple,
Type,
Union,
)
from deltachat_rpc_client.account import Account
@@ -56,6 +67,18 @@ class Client:
self.logger.debug("Account configured")
async def run_forever(self) -> None:
"""Process events forever."""
await self.run_until(lambda _: False)
async def run_until(
self, func: Callable[[AttrDict], Union[bool, Coroutine]]
) -> AttrDict:
"""Process events until the given callable evaluates to True.
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...")
if await self.is_configured():
await self.account.start_io()
@@ -68,6 +91,12 @@ class Client:
if event.type == EventType.INCOMING_MSG:
await self._process_messages()
stop = func(event)
if inspect.isawaitable(stop):
stop = await stop
if stop:
return event
async def _on_event(
self, event: AttrDict, filter_type: Type[EventFilter] = RawEvent
) -> None:

View File

@@ -1,13 +1,11 @@
import json
import os
from typing import AsyncGenerator, List
from typing import AsyncGenerator, List, Optional
import aiohttp
import pytest_asyncio
from .account import Account
from .client import Bot
from .deltachat import DeltaChat
from . import Account, AttrDict, Bot, Client, DeltaChat, EventType, Message
from .rpc import Rpc
@@ -51,6 +49,46 @@ class ACFactory:
await account.start_io()
return accounts
async def send_message(
self,
to_account: Account,
from_account: Optional[Account] = None,
text: Optional[str] = None,
file: Optional[str] = None,
group: Optional[str] = None,
) -> Message:
if not from_account:
from_account = (await self.get_online_accounts(1))[0]
to_contact = await from_account.create_contact(
await to_account.get_config("addr")
)
if group:
to_chat = await from_account.create_group(group)
await to_chat.add_contact(to_contact)
else:
to_chat = await to_contact.create_chat()
return await to_chat.send_message(text=text, file=file)
async def process_message(
self,
to_client: Client,
from_account: Optional[Account] = None,
text: Optional[str] = None,
file: Optional[str] = None,
group: Optional[str] = None,
) -> AttrDict:
await self.send_message(
to_account=to_client.account,
from_account=from_account,
text=text,
file=file,
group=group,
)
event = await to_client.run_until(lambda e: e.type == EventType.INCOMING_MSG)
msg = await to_client.account.get_message_by_id(event.msg_id)
return await msg.get_snapshot()
@pytest_asyncio.fixture
async def rpc(tmp_path) -> AsyncGenerator: