import asyncio from datetime import datetime, timedelta from random import randint from aiogram import Bot, types from models.state import BotState from config import Config from services.schedule_service import ScheduleService from logging import getLogger logger = getLogger(__name__) class WatcherService: def __init__(self, state: BotState, bot: Bot): self.state = state self.bot = bot self.schedule_service = ScheduleService() async def start(self): """Запуск слежки""" if self.state.watcher_work: return self.state.watcher_work = True self.state.watcher_task = asyncio.create_task(self._watcher_loop()) logger.info("Watcher запущен") async def stop(self): """Остановка слежки""" if not self.state.watcher_work: return self.state.watcher_work = False if self.state.watcher_task: self.state.watcher_task.cancel() try: await self.state.watcher_task except asyncio.CancelledError: pass logger.info("Watcher остановлен") async def _watcher_loop(self): """Основной цикл слежки""" while self.state.watcher_work: try: find = await self._check_all_groups() if find: # ничего не нашли → ждём delay = randint( Config.WATCHER_BASE_DELAY, Config.WATCHER_BASE_DELAY + 30 ) logger.info(f"Следующая проверка через {delay}") await asyncio.sleep(delay) else: # нашли → останавливаемся logger.info("Расписание найдено, останавливаем watcher") self.state.watcher_work = False break except asyncio.CancelledError: break except Exception as e: logger.error(f"Ошибка в watcher_loop: {e}") await asyncio.sleep(60) @staticmethod def _get_target_day() -> datetime: """Получение целевого дня""" now = datetime.now() target = now + timedelta(days=1) if target.weekday() == 6: target += timedelta(days=1) return target async def _check_all_groups(self) -> bool: """ Возвращает True, если НИ в одной группе не найдено расписание. Возвращает False, если хотя бы в одной группе найдено расписание. """ day = self._get_target_day() found_any = False for group, chat_id in Config.GROUP_CHATS.items(): logger.info( f"Проверяем расписание для {group} на {day.strftime('%d.%m.%Y')}" ) found = await self._check_group_schedule(group, chat_id, day.day) if found: found_any = True return not found_any # <-- вот так правильно async def _check_group_schedule(self, group: str, chat_id: int, day: int) -> bool: text, url, data_day, data_month = await self.schedule_service.get_schedule( group, day ) if text and "не найдено" not in text.lower(): msg = await self.bot.send_message( chat_id, f"Авто-расписание для {group} на {data_day:02d}.{data_month:02d}\n\n{text}", parse_mode="Markdown", ) await self.bot.pin_chat_message( chat_id, msg.message_id, disable_notification=False ) return True else: png, url, data_day, data_month = await self.schedule_service.get_pschedule( group, day ) if png: await self.bot.send_photo( chat_id, types.BufferedInputFile(png, filename=f"{group}.png"), caption=f"АВАРИЙНЫЙ РЕЖИМ\n\nАвто-расписание для {group} на {data_day:02d}.{data_month:02d}\n\nНайдено с ошибкой", ) return True return False # clip_hash = hashlib.md5(clip_png).hexdigest() # Логика проверки изменений и отправки сообщений # ... (ваша существующая логика)