util.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. from collections.abc import Callable, Coroutine
  2. from typing import TypeVar, Any
  3. from datetime import datetime
  4. from logging import Logger
  5. from aiohttp import ClientSession
  6. from ..types import Message, Context, Attachment, Command
  7. from .base import Injector, InjectorWithCleanup, Simple
  8. __all__ = [
  9. "MessageInjector",
  10. "ContextInjector",
  11. "Origin",
  12. "Channel",
  13. "Sender",
  14. "Timestamp",
  15. "OriginAdmin",
  16. "ChannelAdmin",
  17. "Text",
  18. "Attachments",
  19. "CommandInjector",
  20. "Request",
  21. "Respond",
  22. "LoggerInjector",
  23. "Config",
  24. "Lazy",
  25. ]
  26. MessageInjector = Simple[Message](lambda m, c: m)
  27. ContextInjector = Simple[Context](lambda m, c: c)
  28. Origin = Simple[str](lambda m, c: m.origin_id)
  29. Channel = Simple[str](lambda m, c: m.channel_id)
  30. Sender = Simple[str](lambda m, c: m.sender_id)
  31. Timestamp = Simple[datetime](lambda m, c: m.timestamp)
  32. OriginAdmin = Simple[bool](lambda m, c: m.origin_admin)
  33. ChannelAdmin = Simple[bool](lambda m, c: m.channel_admin)
  34. Text = Simple[str](lambda m, c: m.text)
  35. Attachments = Simple[list[Attachment]](lambda m, c: m.attachments)
  36. CommandInjector = Simple[Command](lambda m, c: m.command)
  37. Request = Simple[ClientSession](lambda m, c: c.request)
  38. Respond = Simple[Callable[[], Coroutine[None, None, None]]](lambda m, c: c.respond)
  39. LoggerInjector = Simple[Logger](lambda m, c: c.logger)
  40. class Config(Injector[Any]):
  41. def __init__(self, key: str):
  42. self.key = key
  43. async def inject(self, message: Message, context: Context) -> Any:
  44. return context.config(self.key)
  45. Dep = TypeVar("Dep")
  46. class Lazy(InjectorWithCleanup[Callable[[], Coroutine[None, None, Dep]]]):
  47. def __init__(self, deferred: Injector[Dep]):
  48. self.deferred = deferred
  49. async def inject(
  50. self, message: Message, context: Context
  51. ) -> Callable[[], Coroutine[None, None, Dep]]:
  52. class _Wrapper:
  53. def __init__(self, deferred):
  54. self._calculated = None
  55. async def call():
  56. if self._calculated is None:
  57. self._calculated = await deferred.inject(message, context)
  58. return self._calculated
  59. self._call = call
  60. def __call__(self):
  61. return self._call()
  62. return _Wrapper(self.deferred)
  63. async def cleanup(self, dep: Callable[[], Coroutine[None, None, Dep]]):
  64. if isinstance(self.deferred, InjectorWithCleanup) and dep._calculated is not None:
  65. await self.deferred.cleanup(dep._calculated)