Cleanups and bugfixes for (#2 and #8)

This commit is contained in:
2025-04-24 00:16:53 +02:00
parent 57c4ff3bf9
commit c1d8620478
11 changed files with 222 additions and 72 deletions

View File

@@ -1,12 +1,11 @@
from dataclasses import dataclass
from logging import Logger
from typing import Any, Dict, Optional
from typing import Any, Dict, List, Optional
from bson import ObjectId
from libbot.cache.classes import Cache
from pymongo.results import InsertOneResult
from classes.abstract.cacheable import Cacheable
from classes.errors.pycord_user import UserNotFoundError
from modules.database import col_users
from modules.utils import get_logger, restore_from_cache
@@ -15,10 +14,20 @@ logger: Logger = get_logger(__name__)
@dataclass
class PycordUser(Cacheable):
class PycordUser:
"""Dataclass of DB entry of a user"""
__slots__ = ("_id", "id", "guild_id", "channel_id", "current_event_id", "current_stage_id")
__slots__ = (
"_id",
"id",
"guild_id",
"channel_id",
"is_jailed",
"current_event_id",
"current_stage_id",
"registered_event_ids",
"completed_event_ids",
)
__short_name__ = "user"
__collection__ = col_users
@@ -26,8 +35,11 @@ class PycordUser(Cacheable):
id: int
guild_id: int
channel_id: int | None
is_jailed: bool
current_event_id: ObjectId | None
current_stage_id: ObjectId | None
registered_event_ids: List[ObjectId]
completed_event_ids: List[ObjectId]
@classmethod
async def from_id(
@@ -82,20 +94,31 @@ class PycordUser(Cacheable):
"id": self.id,
"guild_id": self.guild_id,
"channel_id": self.channel_id,
"is_jailed": self.is_jailed,
"current_event_id": (
self.current_event_id if not json_compatible else str(self.current_event_id)
),
"current_stage_id": (
self.current_stage_id if not json_compatible else str(self.current_stage_id)
),
"registered_event_ids": (
self.registered_event_ids
if not json_compatible
else [str(event_id) for event_id in self.registered_event_ids]
),
"completed_event_ids": (
self.completed_event_ids
if not json_compatible
else [str(event_id) for event_id in self.completed_event_ids]
),
}
async def _set(self, cache: Optional[Cache] = None, **kwargs) -> None:
async def _set(self, cache: Optional[Cache] = None, **kwargs: Any) -> None:
"""Set attribute data and save it into the database.
Args:
cache (:obj:`Cache`, optional): Cache engine to write the update into
**kwargs (str): Mapping of attribute names and respective values to be set
**kwargs (Any): Mapping of attribute names and respective values to be set
"""
for key, value in kwargs.items():
if not hasattr(self, key):
@@ -160,8 +183,11 @@ class PycordUser(Cacheable):
"id": user_id,
"guild_id": guild_id,
"channel_id": None,
"is_jailed": False,
"current_event_id": None,
"current_stage_id": None,
"registered_event_ids": [],
"completed_event_ids": [],
}
@staticmethod
@@ -179,3 +205,45 @@ class PycordUser(Cacheable):
"""
await self.__collection__.delete_one({"_id": self._id})
self._delete_cache(cache)
# TODO Add documentation
async def event_register(self, event_id: str | ObjectId, cache: Optional[Cache] = None) -> None:
event_id: ObjectId = ObjectId(event_id) if isinstance(event_id, str) else event_id
if event_id in self.registered_event_ids:
raise RuntimeError(f"User is already registered for event {event_id}")
# TODO Add a unique exception
# raise UserAlreadyRegisteredForEventError(event_name)
self.registered_event_ids.append(event_id)
await self._set(cache, registered_event_ids=self.registered_event_ids)
# TODO Add documentation
async def event_unregister(self, event_id: str | ObjectId, cache: Optional[Cache] = None) -> None:
event_id: ObjectId = ObjectId(event_id) if isinstance(event_id, str) else event_id
if event_id not in self.registered_event_ids:
raise RuntimeError(f"User is not registered for event {event_id}")
# TODO Add a unique exception
# raise UserNotRegisteredForEventError(event_name)
self.registered_event_ids.remove(event_id)
await self._set(cache, registered_event_ids=self.registered_event_ids)
# TODO Add documentation
async def event_complete(self, event_id: str | ObjectId, cache: Optional[Cache] = None) -> None:
event_id: ObjectId = ObjectId(event_id) if isinstance(event_id, str) else event_id
if event_id in self.completed_event_ids:
raise RuntimeError(f"User has already completed event {event_id}")
# TODO Add a unique exception
# raise UserAlreadyCompletedEventError(event_name)
self.completed_event_ids.append(event_id)
await self._set(cache, completed_event_ids=self.completed_event_ids)