import asyncio from contextlib import suppress from typing import Callable from app.automation.store import AutomationService from app.db import AutomationORM, session_scope from app.orchestrator import WiseClawOrchestrator from app.telegram.bot import TelegramBotService class AutomationScheduler: def __init__(self, orchestrator_factory: Callable[[], object], telegram_bot: TelegramBotService) -> None: self.orchestrator_factory = orchestrator_factory self.telegram_bot = telegram_bot self._task: asyncio.Task[None] | None = None self._running = False async def start(self) -> None: if self._task is not None: return self._running = True self._task = asyncio.create_task(self._loop()) async def stop(self) -> None: self._running = False if self._task is not None: self._task.cancel() with suppress(asyncio.CancelledError): await self._task self._task = None async def _loop(self) -> None: while self._running: try: await self._tick() except Exception: pass await asyncio.sleep(30) async def _tick(self) -> None: with session_scope() as session: service = AutomationService(session) due_items = service.due_automations() due_ids = [item.id for item in due_items] for automation_id in due_ids: await self._run_automation(automation_id) async def _run_automation(self, automation_id: int) -> None: with session_scope() as session: service = AutomationService(session) item = session.get(AutomationORM, automation_id) if item is None or item.status != "active": return prompt = item.prompt user_id = item.telegram_user_id try: with self.orchestrator_factory() as session: orchestrator = WiseClawOrchestrator(session) result = await orchestrator.handle_text_message(user_id, prompt) await self.telegram_bot.send_message(user_id, f"⏰ Otomasyon sonucu: {result}") with session_scope() as session: service = AutomationService(session) item = session.get(AutomationORM, automation_id) if item is not None: service.mark_run_result(item, result) except Exception as exc: with session_scope() as session: service = AutomationService(session) item = session.get(AutomationORM, automation_id) if item is not None: service.mark_run_error(item, str(exc))