Files
myfirstprogram/services/watcher_service.py
T

124 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()
# Логика проверки изменений и отправки сообщений
# ... (ваша существующая логика)