Files
wiseclaw/backend/app/automation/scheduler.py

74 lines
2.7 KiB
Python

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))