aboutsummaryrefslogtreecommitdiffstats
path: root/slack/task.py
diff options
context:
space:
mode:
authorTrygve Aaberge <trygveaa@gmail.com>2022-10-24 21:08:02 +0200
committerTrygve Aaberge <trygveaa@gmail.com>2024-02-18 11:32:52 +0100
commite3bc88120e071eac8fabb5b02d7b509488d563e2 (patch)
treef4f7195d629e4beb2e146624575d5f9302e0ab2d /slack/task.py
parente6796bbf07a5c8ecdc3411f583814be28f163807 (diff)
downloadwee-slack-e3bc88120e071eac8fabb5b02d7b509488d563e2.tar.gz
Split into multiple files
Diffstat (limited to 'slack/task.py')
-rw-r--r--slack/task.py79
1 files changed, 79 insertions, 0 deletions
diff --git a/slack/task.py b/slack/task.py
new file mode 100644
index 0000000..e976866
--- /dev/null
+++ b/slack/task.py
@@ -0,0 +1,79 @@
+from __future__ import annotations
+
+from typing import Any, Awaitable, Coroutine, Generator, Tuple, TypeVar
+from uuid import uuid4
+
+import globals
+import weechat
+
+T = TypeVar("T")
+
+
+class Future(Awaitable[T]):
+ def __init__(self):
+ self.id = str(uuid4())
+
+ def __await__(self) -> Generator[Future[T], T, T]:
+ return (yield self)
+
+
+class FutureProcess(Future[Tuple[str, int, str, str]]):
+ pass
+
+
+class FutureTimer(Future[Tuple[int]]):
+ pass
+
+
+class Task(Future[T]):
+ def __init__(self, coroutine: Coroutine[Future[Any], Any, T], final: bool):
+ super().__init__()
+ self.coroutine = coroutine
+ self.final = final
+
+
+def weechat_task_cb(data: str, *args: Any) -> int:
+ task = globals.active_tasks.pop(data)
+ task_runner(task, args)
+ return weechat.WEECHAT_RC_OK
+
+
+def task_runner(task: Task[Any], response: Any):
+ while True:
+ try:
+ future = task.coroutine.send(response)
+ if future.id in globals.active_responses:
+ response = globals.active_responses.pop(future.id)
+ else:
+ if future.id in globals.active_tasks:
+ raise Exception(
+ f"future.id in active_tasks, {future.id}, {globals.active_tasks}"
+ )
+ globals.active_tasks[future.id] = task
+ break
+ except StopIteration as e:
+ if task.id in globals.active_tasks:
+ task = globals.active_tasks.pop(task.id)
+ response = e.value
+ else:
+ if task.id in globals.active_responses:
+ raise Exception( # pylint: disable=raise-missing-from
+ f"task.id in active_responses, {task.id}, {globals.active_responses}"
+ )
+ if not task.final:
+ globals.active_responses[task.id] = e.value
+ break
+
+
+def create_task(
+ coroutine: Coroutine[Future[Any], Any, T], final: bool = False
+) -> Task[T]:
+ task = Task(coroutine, final)
+ task_runner(task, None)
+ return task
+
+
+async def sleep(milliseconds: int):
+ future = FutureTimer()
+ weechat.hook_timer(milliseconds, 0, 1, weechat_task_cb.__name__, future.id)
+ return await future