104 lines
3.5 KiB
Python
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")))
|