Ну насрал, ну уебан, короче jsonchik запилил, и сделал супер безопасный парсер этого json, хотя лучше энивей потом перейти на бд
This commit is contained in:
parent
11ad1c43c9
commit
e0a46cf551
2 changed files with 119 additions and 52 deletions
43
Schedule.json
Normal file
43
Schedule.json
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"0": [
|
||||
[9, 50, 10, 35, 5],
|
||||
[10, 40, 11, 25, 30],
|
||||
[11, 55, 12, 40, 5],
|
||||
[12, 45, 13, 30, 15],
|
||||
[13, 45, 14, 30, 5],
|
||||
[14, 35, 15, 20, 30],
|
||||
[15, 50, 16, 35, 5],
|
||||
[16, 40, 17, 25, null]
|
||||
],
|
||||
"1": [
|
||||
[9, 50, 10, 35, 5],
|
||||
[10, 40, 11, 25, 30],
|
||||
[11, 55, 12, 40, 5],
|
||||
[12, 45, 13, 30, 15],
|
||||
[13, 45, 14, 30, 5],
|
||||
[14, 35, 15, 20, null]
|
||||
],
|
||||
"2": [],
|
||||
"3": [
|
||||
[8, 0, 8, 45, 5],
|
||||
[8, 50, 9, 35, 15],
|
||||
[9, 50, 10, 35, 5],
|
||||
[10, 40, 11, 25, 30],
|
||||
[11, 55, 12, 40, 5],
|
||||
[12, 45, 13, 30, 15],
|
||||
[13, 45, 14, 30, 5],
|
||||
[14, 35, 15, 20, 30],
|
||||
[15, 50, 16, 35, 5],
|
||||
[16, 40, 17, 25, null]
|
||||
],
|
||||
"4": [
|
||||
[9, 50, 10, 35, 5],
|
||||
[10, 40, 11, 25, 30],
|
||||
[11, 55, 12, 40, 5],
|
||||
[12, 45, 13, 30, 15],
|
||||
[13, 45, 14, 30, 5],
|
||||
[14, 35, 15, 20, null]
|
||||
],
|
||||
"5": [],
|
||||
"6": []
|
||||
}
|
||||
128
main.py
128
main.py
|
|
@ -1,11 +1,12 @@
|
|||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from textwrap import wrap
|
||||
import random
|
||||
from typing import Any
|
||||
|
||||
from aiogram import Bot, Dispatcher, F, types
|
||||
from aiogram.enums import ParseMode
|
||||
|
|
@ -40,54 +41,80 @@ def templates_list_text() -> str:
|
|||
|
||||
# ---- Schedule & breaks ----
|
||||
|
||||
def make_time(h: int, m: int) -> time:
|
||||
return time(hour=h, minute=m)
|
||||
def _ensure_int(value: Any, field_name: str, day: int, lesson_idx: int) -> int:
|
||||
if isinstance(value, bool) or not isinstance(value, int):
|
||||
raise ValueError(
|
||||
f"Invalid {field_name} in day {day}, lesson #{lesson_idx + 1}: expected integer, got {value!r}"
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
# Schedule format: list of (lesson_start, lesson_end, break_minutes_after)
|
||||
SCHEDULE: dict[int, list[tuple[time, time, int | None]]] = {
|
||||
0: [ # Monday
|
||||
(make_time(9, 50), make_time(10, 35), 5),
|
||||
(make_time(10, 40), make_time(11, 25), 30),
|
||||
(make_time(11, 55), make_time(12, 40), 5),
|
||||
(make_time(12, 45), make_time(13, 30), 15),
|
||||
(make_time(13, 45), make_time(14, 30), 5),
|
||||
(make_time(14, 35), make_time(15, 20), 30),
|
||||
(make_time(15, 50), make_time(16, 35), 5),
|
||||
(make_time(16, 40), make_time(17, 25), None),
|
||||
],
|
||||
1: [ # Tuesday
|
||||
(make_time(9, 50), make_time(10, 35), 5),
|
||||
(make_time(10, 40), make_time(11, 25), 30),
|
||||
(make_time(11, 55), make_time(12, 40), 5),
|
||||
(make_time(12, 45), make_time(13, 30), 15),
|
||||
(make_time(13, 45), make_time(14, 30), 5),
|
||||
(make_time(14, 35), make_time(15, 20), None),
|
||||
],
|
||||
2: [], # Wednesday — кайфуем дома
|
||||
3: [ # Thursday
|
||||
(make_time(8, 0), make_time(8, 45), 5),
|
||||
(make_time(8, 50), make_time(9, 35), 15),
|
||||
(make_time(9, 50), make_time(10, 35), 5),
|
||||
(make_time(10, 40), make_time(11, 25), 30),
|
||||
(make_time(11, 55), make_time(12, 40), 5),
|
||||
(make_time(12, 45), make_time(13, 30), 15),
|
||||
(make_time(13, 45), make_time(14, 30), 5),
|
||||
(make_time(14, 35), make_time(15, 20), 30),
|
||||
(make_time(15, 50), make_time(16, 35), 5),
|
||||
(make_time(16, 40), make_time(17, 25), None),
|
||||
],
|
||||
4: [ # Friday
|
||||
(make_time(9, 50), make_time(10, 35), 5),
|
||||
(make_time(10, 40), make_time(11, 25), 30),
|
||||
(make_time(11, 55), make_time(12, 40), 5),
|
||||
(make_time(12, 45), make_time(13, 30), 15),
|
||||
(make_time(13, 45), make_time(14, 30), 5),
|
||||
(make_time(14, 35), make_time(15, 20), None),
|
||||
],
|
||||
5: [], # Saturday — выходной
|
||||
6: [], # Sunday — выходной
|
||||
}
|
||||
def load_schedule_from_json(file_path: str | Path = BASE_DIR / "Schedule.json") -> dict[int, list[tuple[time, time, int | None]]]:
|
||||
path = Path(file_path)
|
||||
if not path.is_absolute():
|
||||
path = BASE_DIR / path
|
||||
|
||||
with path.open("r", encoding="utf-8") as f:
|
||||
try:
|
||||
raw_data = json.load(f)
|
||||
except json.JSONDecodeError as exc:
|
||||
raise ValueError(f"Invalid JSON in schedule file {path}: {exc}") from exc
|
||||
|
||||
if not isinstance(raw_data, dict):
|
||||
raise ValueError(f"Schedule JSON root must be an object, got: {type(raw_data).__name__}")
|
||||
|
||||
formatted_schedule: dict[int, list[tuple[time, time, int | None]]] = {day: [] for day in range(7)}
|
||||
|
||||
for day_key, lessons in raw_data.items():
|
||||
try:
|
||||
day = int(day_key)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError(f"Day key must be an integer from 0 to 6, got: {day_key!r}") from exc
|
||||
|
||||
if day < 0 or day > 6:
|
||||
raise ValueError(f"Day key must be in range 0..6, got: {day}")
|
||||
|
||||
if not isinstance(lessons, list):
|
||||
raise ValueError(f"Lessons for day {day} must be a list, got: {type(lessons).__name__}")
|
||||
|
||||
parsed_lessons: list[tuple[time, time, int | None]] = []
|
||||
for idx, lesson in enumerate(lessons):
|
||||
if not isinstance(lesson, list) or len(lesson) != 5:
|
||||
raise ValueError(
|
||||
f"Day {day}, lesson #{idx + 1} must be [start_h, start_m, end_h, end_m, break_minutes]"
|
||||
)
|
||||
|
||||
start_h = _ensure_int(lesson[0], "start_h", day, idx)
|
||||
start_m = _ensure_int(lesson[1], "start_m", day, idx)
|
||||
end_h = _ensure_int(lesson[2], "end_h", day, idx)
|
||||
end_m = _ensure_int(lesson[3], "end_m", day, idx)
|
||||
|
||||
break_minutes_raw = lesson[4]
|
||||
if break_minutes_raw is None:
|
||||
break_minutes = None
|
||||
else:
|
||||
break_minutes = _ensure_int(break_minutes_raw, "break_minutes", day, idx)
|
||||
if break_minutes < 0:
|
||||
raise ValueError(f"Day {day}, lesson #{idx + 1}: break_minutes must be >= 0")
|
||||
|
||||
try:
|
||||
start_t = time(start_h, start_m)
|
||||
end_t = time(end_h, end_m)
|
||||
except ValueError as exc:
|
||||
raise ValueError(f"Day {day}, lesson #{idx + 1}: invalid lesson time") from exc
|
||||
|
||||
if (end_h, end_m) <= (start_h, start_m):
|
||||
raise ValueError(f"Day {day}, lesson #{idx + 1}: end time must be after start time")
|
||||
|
||||
parsed_lessons.append((start_t, end_t, break_minutes))
|
||||
|
||||
parsed_lessons.sort(key=lambda item: (item[0].hour, item[0].minute))
|
||||
formatted_schedule[day] = parsed_lessons
|
||||
|
||||
return formatted_schedule
|
||||
|
||||
# Теперь заменяем глобальный словарь SCHEDULE:
|
||||
SCHEDULE = load_schedule_from_json()
|
||||
|
||||
|
||||
def minutes_until_break(now: datetime | None = None) -> str:
|
||||
|
|
@ -364,7 +391,6 @@ async def handle_gen_mem(message: Message, bot: Bot):
|
|||
|
||||
await message.reply_photo(BufferedInputFile(output.getvalue(), filename="meme.jpg"))
|
||||
|
||||
<<<<<<< HEAD
|
||||
async def handle_size(message: Message):
|
||||
size = round(random.uniform(0.1, 35.0), 1)
|
||||
|
||||
|
|
@ -385,8 +411,7 @@ async def handle_size(message: Message):
|
|||
f"📏 Твой хуек: {size} см\n"
|
||||
f"Ты: {status}"
|
||||
)
|
||||
=======
|
||||
KEYWORDS = {'крип', 'радиохэд', 'creep', 'radiohead'}
|
||||
KEYWORDS_CREEP = {'крип', 'радиохэд', 'creep', 'radiohead'}
|
||||
# I'M CREEP
|
||||
async def handle_keywords(message: types.Message):
|
||||
|
||||
|
|
@ -395,7 +420,7 @@ async def handle_keywords(message: types.Message):
|
|||
|
||||
text = message.text.lower()
|
||||
|
||||
if any(re.search(rf'\b{word}\b', text) for word in KEYWORDS):
|
||||
if any(re.search(rf'\b{word}\b', text) for word in KEYWORDS_CREEP):
|
||||
audio_path = BASE_DIR / "maket" / "Radiohead - Creep.mp3"
|
||||
|
||||
if audio_path.exists():
|
||||
|
|
@ -405,7 +430,6 @@ async def handle_keywords(message: types.Message):
|
|||
)
|
||||
else:
|
||||
logger.warning(f"Файл не найден по пути: {audio_path}")
|
||||
>>>>>>> SUDOZOVCHIK-CREEP-FUNCTION
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
|||
Loading…
Reference in a new issue