bot/models/user.py
2026-08-30 11:43:38 +00:00

104 lines
3.5 KiB
Python

import json
import os
from typing import Any, Iterator
from telebot.types import CallbackQuery, InlineQuery, Message
from models import logger
from .schedule import Schedule, ScheduleAPIError, get_group_schedule
class User:
def __init__(self, userID: int) -> None:
self.id: int = userID
try:
self.data: dict[str, Any] = json.load(
open(f"./users/{self.id}.json", "r", encoding="utf-8")
)
except FileNotFoundError:
self.data = {}
except (json.JSONDecodeError, OSError):
logger.error("Bot", f'INVALID "{userID}" SAVED DATA! RESET!')
self.data = {}
self.state: str | bool | None = self.data.get("state", None)
self.group: str | None = self.data.get("group", None)
self.notifications: list[str] = self.data.get("notifications", []) # type: ignore
self.valid: bool = self.data.get("valid", True)
saved_groups = self.data.get("saved_groups", [])
self.saved_groups = [
value for value in saved_groups if isinstance(value, str) and value.strip()
]
if self.group and self.group not in self.saved_groups:
self.saved_groups.append(self.group)
self.saved_groups = list(dict.fromkeys(self.saved_groups))
self.user: dict = self.data.get("user", {})
self.usage: dict = self.data.get(
"usage", {"count": -1, "date": None, "time": None}
)
self.flags: list[str] = self.data.get('flags', [])
if "notifyEvening" in self.data.keys():
if self.data["notifyEvening"] and "evening" not in self.notifications:
self.notifications.append("evening")
if self.data.get("notifyBeforeLesson") and "lesson" not in self.notifications:
self.notifications.append("lesson")
self.save()
def schedule(self) -> Schedule | None:
if not self.group:
self.valid = False
self.notifications = []
self.setState("broken")
return None
try:
return get_group_schedule(self.group)
except ValueError:
self.valid = False
self.notifications = []
self.setState("broken")
return None
except ScheduleAPIError as error:
logger.error("Schedule", f"[{self.id}] {error}")
return None
def setState(self, newState: str) -> None:
self.state = newState
self.save()
def save(self) -> None:
return json.dump(
{
"state": self.state,
"group": self.group,
"notifications": self.notifications,
"valid": self.valid,
"saved_groups": self.saved_groups,
"user": self.user,
"usage": self.usage,
"flags": self.flags,
},
open(f"./users/{self.id}.json", "w", encoding="utf-8"),
ensure_ascii=False,
indent=4,
)
def validate(ctx: Message | InlineQuery | CallbackQuery) -> User:
try:
return User(ctx.from_user.id) # type: ignore
except Exception as e:
logger.error("Bot", f'INVALID "{ctx.from_user.id}" VALIDATION! {e}')
return False # type: ignore
def getAllUsers() -> Iterator[User]:
for _, _, filenames in os.walk("./users"):
for userFile in filenames:
if not userFile.endswith(".json"):
continue
yield User(int(userFile.removesuffix(".json")))