Files
aero/get.py
T

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