util.py 2.7 KB

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