139 lines
5.2 KiB
Python
139 lines
5.2 KiB
Python
import datetime
|
|
|
|
import requests
|
|
from bs4 import BeautifulSoup
|
|
|
|
from DB import UseDB
|
|
|
|
|
|
def fetch_timetable_data(group_id: int) -> BeautifulSoup | None:
|
|
"""
|
|
Функция для парсинга сайта по id группы пользователя
|
|
|
|
:param group_id: int - id группы пользователя
|
|
|
|
:return: BeautifulSoup | None - объект парсиного сайта или ничего если сайт не доступен
|
|
"""
|
|
base_url = "https://timetable.pallada.sibsau.ru/timetable/group/"
|
|
response = requests.get(f"{base_url}{group_id}")
|
|
if response.status_code == 200:
|
|
soup = BeautifulSoup(response.text, "html.parser")
|
|
return soup
|
|
return None
|
|
|
|
|
|
def extract_week_data(soup: BeautifulSoup, shift: int) -> dict:
|
|
"""
|
|
Функция для получения нужной недели из сайта
|
|
|
|
:param soup: BeautifulSoup - объект парсиного сайта
|
|
:param shift: int - на сколько дней вперёд пытается пользователь получить расписание
|
|
|
|
:return: dict - готовый текст дня
|
|
"""
|
|
current_week_number = int(datetime.datetime.utcnow().isocalendar()[1])
|
|
current_day_of_week = datetime.datetime.now().weekday()
|
|
if current_day_of_week + shift > 6:
|
|
current_week_number += 1
|
|
current_week_number += 1
|
|
week_tab_id = "week_1_tab" if current_week_number % 2 else "week_2_tab"
|
|
week_data: BeautifulSoup = soup.find('div', {"id": week_tab_id})
|
|
day_name = (
|
|
datetime.datetime.now() + datetime.timedelta(days=shift)
|
|
).strftime('%A').lower()
|
|
return parse_day_data(week_data.find('div', {"class": day_name}))
|
|
|
|
|
|
def parse_day_data(day_data: BeautifulSoup) -> dict:
|
|
"""
|
|
Функция для получения данных из объекта дня
|
|
|
|
:param day_data: BeautifulSoup - объект дня для получения данных
|
|
|
|
:return: dict - готовый текст дня
|
|
"""
|
|
schedule = {}
|
|
lines = day_data.find_all('div', {"class": "line"})
|
|
for line in lines:
|
|
time_slot = line.find('div', {"class": "hidden-xs"}).text.strip().replace("\n", "")
|
|
schedule[time_slot] = [
|
|
format_lesson_details(li.text)
|
|
for li in line.find_all('li')
|
|
]
|
|
return schedule
|
|
|
|
|
|
def format_lesson_details(lesson_text: str) -> str:
|
|
"""
|
|
Функция для удобного преобразования урока
|
|
|
|
:param lesson_text: str - текст урока
|
|
|
|
:return: str - готовый текст урока
|
|
"""
|
|
if "1 подгруппа" in lesson_text or "* подгруппа" in lesson_text:
|
|
lesson_text = f"⭐ {lesson_text} ⭐"
|
|
elif "2 подгруппа" in lesson_text:
|
|
lesson_text = f"☾ {lesson_text} ☾"
|
|
return lesson_text
|
|
|
|
|
|
def get_timetable_for_day(group_id: int, shift: int = 0) -> list[str]:
|
|
"""
|
|
Функция для получения всех предметов в виде строк
|
|
|
|
:param group_id: int - id группы пользователя
|
|
:param shift: int - на сколько дней вперёд пытается пользователь получить расписание
|
|
|
|
:return: list[str] - готовый объект со строками уроков дня
|
|
"""
|
|
try:
|
|
soup = fetch_timetable_data(group_id)
|
|
if soup:
|
|
schedule = extract_week_data(soup, shift)
|
|
else:
|
|
schedule = get_data_in_database(group_id, shift)
|
|
formatted_schedule = []
|
|
for time_slot, lessons in schedule.items():
|
|
lessons_text = '\n'.join(lessons)
|
|
formatted_schedule.append(f"Время: {time_slot}\n{lessons_text}")
|
|
return formatted_schedule
|
|
except AttributeError:
|
|
return ["Похоже в этот день мы не учимся"]
|
|
|
|
|
|
def get_data_in_database(group_id: int, shift: int = 0) -> dict:
|
|
"""
|
|
Функция для получения данных из базы данных
|
|
|
|
:param group_id: int - id группы пользователя
|
|
:param shift: int - на сколько дней вперёд пытается пользователь получить расписание
|
|
|
|
:return: dict - готовый текст дня
|
|
"""
|
|
current_week_number = int(datetime.datetime.utcnow().isocalendar()[1])
|
|
current_day_of_week = datetime.datetime.now().weekday()
|
|
if current_day_of_week + shift > 6:
|
|
current_week_number += 1
|
|
current_week_number += 1
|
|
week_tab_id = "week_1_tab" if current_week_number % 2 else "week_2_tab"
|
|
day_name = (
|
|
datetime.datetime.now() + datetime.timedelta(days=shift)
|
|
).strftime('%A').lower()
|
|
db = UseDB("saved_data")
|
|
response_data = db.find_document(
|
|
{
|
|
"group_id": group_id,
|
|
"week_tab_id": week_tab_id,
|
|
"day_name": day_name
|
|
}
|
|
)
|
|
response = {}
|
|
for i in response_data:
|
|
response[i["lesson_time"]] = [
|
|
i["lesson_name"],
|
|
i["lesson_author"],
|
|
i["lesson_nav"]
|
|
]
|
|
return response
|