progress.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import asyncio
  2. import logging
  3. from aiogram import Bot, Dispatcher
  4. from aiogram.contrib.fsm_storage.memory import MemoryStorage
  5. from aiogram.dispatcher.filters.state import StatesGroup, State
  6. from aiogram.types import Message, CallbackQuery
  7. from aiogram_dialog import Dialog, DialogManager, Window, DialogRegistry, BaseDialogManager, \
  8. StartMode
  9. from aiogram_dialog.widgets.kbd import Button
  10. from aiogram_dialog.widgets.text import Const, Multi, Text
  11. from typing import Any
  12. from src.config import API_TOKEN
  13. class Processing(Text):
  14. def __init__(self, field: str, width: int = 10, filled="🟩", empty="⬜", when = None):
  15. super().__init__(when)
  16. self.field = field
  17. self.width = width
  18. self.filled = filled
  19. self.empty = empty
  20. async def _render_text(self, data: dict, manager: DialogManager) -> str:
  21. if manager.is_preview():
  22. percent = 15
  23. else:
  24. percent = data[self.field]
  25. rest = self.width - percent
  26. return f"processing: {self.filled * percent + self.empty * rest}"
  27. # name progress dialog
  28. class Bg(StatesGroup):
  29. progress = State()
  30. async def get_bg_data(dialog_manager: DialogManager, **kwargs):
  31. if context := dialog_manager.current_context():
  32. return {"progress": context.dialog_data.get("progress", 0)}
  33. else:
  34. return {"progress": "OOOOPS"}
  35. bg_dialog = Dialog(
  36. Window(
  37. Multi(
  38. Const("Summarizing is processing, please wait...\n"),
  39. Processing("progress", 10),
  40. ),
  41. state=Bg.progress,
  42. getter=get_bg_data,
  43. ),
  44. )
  45. # main dialog
  46. class MainSG(StatesGroup):
  47. main = State()
  48. async def start_bg(c: CallbackQuery, button: Button, manager: DialogManager):
  49. await manager.start(Bg.progress)
  50. asyncio.create_task(background(c, manager.bg()))
  51. async def background(c: CallbackQuery,
  52. manager: DialogManager | BaseDialogManager,
  53. cross_data: Any = None,
  54. context_id: str | None = None,
  55. time_out = 40):
  56. i = 0
  57. time = 0
  58. await asyncio.sleep(1)
  59. while True and time < time_out:
  60. i = i + 1 if i < 10 else 0
  61. time += 1
  62. await manager.update({"progress": i})
  63. await asyncio.sleep(1)
  64. if mess:=cross_data.intent_queue[context_id]:
  65. if mess == 'done':
  66. del cross_data.intent_queue[context_id]
  67. await manager.done()
  68. return
  69. await manager.done()
  70. main_menu = Dialog(
  71. Window(
  72. Const("Press button to start processing"),
  73. Button(Const("Start 👀"), id="start", on_click=start_bg),
  74. state=MainSG.main,
  75. getter=get_bg_data
  76. ),
  77. )
  78. async def start(m: Message, dialog_manager: DialogManager):
  79. await dialog_manager.start(MainSG.main, mode=StartMode.RESET_STACK)
  80. async def main():
  81. # real main
  82. logging.basicConfig(level=logging.INFO)
  83. logging.getLogger("aiogram_dialog").setLevel(logging.DEBUG)
  84. storage = MemoryStorage()
  85. bot = Bot(token=API_TOKEN) # type: ignore
  86. dp = Dispatcher(bot, storage=storage)
  87. registry = DialogRegistry(dp)
  88. registry.register(bg_dialog)
  89. registry.register(main_menu)
  90. dp.register_message_handler(start, text="/start", state="*")
  91. await dp.start_polling()
  92. if __name__ == '__main__':
  93. asyncio.run(main())