I add command /prasp

It's version 0.2.2
This commit is contained in:
Niken
2025-10-05 22:29:49 +03:00
parent c5f6da31ba
commit 3ef1327b67
4 changed files with 89 additions and 14 deletions
+61 -2
View File
@@ -1,8 +1,11 @@
import hashlib
from datetime import datetime, timedelta
from typing import Optional, Tuple
from playwright.async_api import async_playwright, ViewportSize, FloatRect
import logging
import aiohttp
from bs4 import BeautifulSoup
import ssl
import certifi
logger = logging.getLogger(__name__)
@@ -23,7 +26,63 @@ class ScheduleService:
else:
return self.base_url.format(day=int(day), mouth=d.month), int(day), int(d.month)
async def get_schedule(self, group: str, day_offset: int = 0) -> Tuple[Optional[bytes], str, int, int]:
async def get_schedule(
self, group: str, day_offset: int = 0
) -> Tuple[str, str, int, int]:
"""Получение текста расписания (аналог Rust parse_schedule)"""
url, day, month = self._make_url(day_offset)
ssl_context = ssl.create_default_context(cafile=certifi.where())
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
connector = aiohttp.TCPConnector(ssl=ssl_context)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36'
}
# тут можно использовать aiohttp + chardet/charset_normalizer
async with aiohttp.ClientSession(connector=connector, headers=headers) as session:
async with session.get(url) as resp:
raw_bytes = await resp.read()
decoded = raw_bytes.decode("cp1251", errors="ignore")
document = BeautifulSoup(decoded, "html.parser")
# ищем <p class="MsoPlainText"><b>...</b>
elements = document.select("p.MsoPlainText b")
found_group = False
schedule_lines = []
for el in elements:
text = el.get_text(strip=True)
if not found_group:
if group in text:
found_group = True
schedule_lines.append(text)
else:
if "-----" in text or "+----" in text:
break
schedule_lines.append(text)
if not schedule_lines:
result = f"Расписание для группы {group} на {day} число не найдено"
else:
result = f"📅 Расписание для {day} числа:\n```\n"
for line in schedule_lines:
formatted = (
line.replace("¦", "")
.replace(" ", " ")
.strip()
)
if formatted:
result += f"{formatted}\n"
result += "```"
return result, url, day, month
async def get_pschedule(self, group: str, day_offset: int = 0) -> Tuple[Optional[bytes], str, int, int]:
"""Получение скриншота расписания"""
url, day, month = self._make_url(day_offset)
+9 -10
View File
@@ -2,7 +2,6 @@ import asyncio
from datetime import datetime, timedelta
from random import randint
from aiogram import Bot
from aiogram.types import BufferedInputFile
from models.state import BotState
from config import Config
from services.schedule_service import ScheduleService
@@ -74,21 +73,21 @@ class WatcherService:
async def _check_group_schedule(self, group: str, chat_id: int, day: int):
"""Проверка расписания для конкретной группы"""
clip_png, url, data_day, data_mouth = await self.schedule_service.get_schedule(group, day)
if clip_png:
msg = await self.bot.send_photo(
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,
BufferedInputFile(clip_png, filename=f"{group}.png"),
caption=f"Авто-расписание для {group} на {data_day:02d}.{data_mouth:02d}"
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=True)
else:
logger.warning(f"Не удалось получить расписание для {group}, {data_day}, {data_mouth}, {url}")
logger.warning(
f"Не удалось получить расписание для {group}, {data_day}, {data_month}, {url}"
)
return
#clip_hash = hashlib.md5(clip_png).hexdigest()
# Логика проверки изменений и отправки сообщений