This commit is contained in:
2025-05-06 20:16:44 +02:00
parent d1498f38e9
commit 96c1314234
5 changed files with 33 additions and 199 deletions

View File

@@ -2,6 +2,7 @@ from abc import ABC
from logging import Logger from logging import Logger
from typing import Optional, Any, Dict from typing import Optional, Any, Dict
from bson import ObjectId
from libbot.cache.classes import Cache from libbot.cache.classes import Cache
from classes.abstract import Cacheable from classes.abstract import Cacheable
@@ -13,6 +14,8 @@ logger: Logger = get_logger(__name__)
class BaseCacheable(Cacheable, ABC): class BaseCacheable(Cacheable, ABC):
"""Base implementation of Cacheable used by all cachable classes.""" """Base implementation of Cacheable used by all cachable classes."""
_id: ObjectId
async def _set(self, cache: Optional[Cache] = None, **kwargs: Any) -> None: async def _set(self, cache: Optional[Cache] = None, **kwargs: Any) -> None:
for key, value in kwargs.items(): for key, value in kwargs.items():
if not hasattr(self, key): if not hasattr(self, key):

View File

@@ -10,7 +10,7 @@ from discord import File
from libbot.cache.classes import Cache from libbot.cache.classes import Cache
from pymongo.results import InsertOneResult from pymongo.results import InsertOneResult
from classes.abstract import Cacheable from classes.base.base_cacheable import BaseCacheable
from classes.errors import EventStageNotFoundError from classes.errors import EventStageNotFoundError
from modules.database import col_stages from modules.database import col_stages
from modules.utils import get_logger, restore_from_cache from modules.utils import get_logger, restore_from_cache
@@ -19,7 +19,7 @@ logger: Logger = get_logger(__name__)
@dataclass @dataclass
class PycordEventStage(Cacheable): class PycordEventStage(BaseCacheable):
__slots__ = ( __slots__ = (
"_id", "_id",
"event_id", "event_id",
@@ -110,68 +110,19 @@ class PycordEventStage(Cacheable):
return cls(**db_entry) return cls(**db_entry)
async def _set(self, cache: Optional[Cache] = None, **kwargs: Any) -> None: async def _set(self, cache: Optional[Cache] = None, **kwargs: Any) -> None:
"""Set attribute data and save it into the database. await super()._set(cache, **kwargs)
Args:
cache (:obj:`Cache`, optional): Cache engine to write the update into
**kwargs (Any): Mapping of attribute names and respective values to be set
"""
for key, value in kwargs.items():
if not hasattr(self, key):
raise AttributeError()
setattr(self, key, value)
await self.__collection__.update_one({"_id": self._id}, {"$set": kwargs})
self._update_cache(cache)
logger.info("Set attributes of event stage %s to %s", self._id, kwargs)
async def _remove(self, *args: str, cache: Optional[Cache] = None) -> None: async def _remove(self, *args: str, cache: Optional[Cache] = None) -> None:
"""Remove attribute data and save it into the database. await super()._remove(*args, cache=cache)
Args:
cache (:obj:`Cache`, optional): Cache engine to write the update into
*args (str): List of attributes to remove
"""
attributes: Dict[str, Any] = {}
for key in args:
if not hasattr(self, key):
raise AttributeError()
default_value: Any = self.get_default_value(key)
setattr(self, key, default_value)
attributes[key] = default_value
await self.__collection__.update_one({"_id": self._id}, {"$set": attributes})
self._update_cache(cache)
logger.info("Reset attributes %s of event stage %s to default values", args, self._id)
def _get_cache_key(self) -> str: def _get_cache_key(self) -> str:
return f"{self.__short_name__}_{self._id}" return f"{self.__short_name__}_{self._id}"
def _update_cache(self, cache: Optional[Cache] = None) -> None: def _update_cache(self, cache: Optional[Cache] = None) -> None:
if cache is None: super()._update_cache(cache)
return
object_dict: Dict[str, Any] = self.to_dict(json_compatible=True)
if object_dict is not None:
cache.set_json(self._get_cache_key(), object_dict)
else:
self._delete_cache(cache)
def _delete_cache(self, cache: Optional[Cache] = None) -> None: def _delete_cache(self, cache: Optional[Cache] = None) -> None:
if cache is None: super()._delete_cache(cache)
return
cache.delete(self._get_cache_key())
@staticmethod @staticmethod
def _entry_to_cache(db_entry: Dict[str, Any]) -> Dict[str, Any]: def _entry_to_cache(db_entry: Dict[str, Any]) -> Dict[str, Any]:
@@ -255,41 +206,17 @@ class PycordEventStage(Cacheable):
cache: Optional[Cache] = None, cache: Optional[Cache] = None,
**kwargs: Any, **kwargs: Any,
) -> None: ) -> None:
"""Update attribute(s) on the object and save the updated entry into the database. await super().update(cache=cache, **kwargs)
Args:
cache (:obj:`Cache`, optional): Cache engine that will be used to update the cache.
**kwargs (Any): Mapping of attributes in format `attribute_name=attribute_value` to update.
Raises:
AttributeError: Provided attribute does not exist in the class.
"""
await self._set(cache=cache, **kwargs)
async def reset( async def reset(
self, self,
*args: str, *args: str,
cache: Optional[Cache] = None, cache: Optional[Cache] = None,
) -> None: ) -> None:
"""Remove attribute(s) on the object, replace them with a default value and save the updated entry into the database. await super().reset(*args, cache=cache)
Args:
*args (str): List of attributes to remove.
cache (:obj:`Cache`, optional): Cache engine that will be used to update the cache.
Raises:
AttributeError: Provided attribute does not exist in the class.
"""
await self._remove(*args, cache=cache)
async def purge(self, cache: Optional[Cache] = None) -> None: async def purge(self, cache: Optional[Cache] = None) -> None:
"""Completely remove event stage data from database. Currently only removes the event stage record from events collection. await super().purge(cache)
Args:
cache (:obj:`Cache`, optional): Cache engine to write the update into
"""
await self.__collection__.delete_one({"_id": self._id})
self._delete_cache(cache)
# TODO Add documentation # TODO Add documentation
def get_media_files(self) -> List[File] | None: def get_media_files(self) -> List[File] | None:

View File

@@ -79,59 +79,18 @@ class PycordGuild(BaseCacheable):
async def _set(self, cache: Optional[Cache] = None, **kwargs: Any) -> None: async def _set(self, cache: Optional[Cache] = None, **kwargs: Any) -> None:
await super()._set(cache, **kwargs) await super()._set(cache, **kwargs)
# for key, value in kwargs.items():
# if not hasattr(self, key):
# raise AttributeError()
#
# setattr(self, key, value)
#
# await self.__collection__.update_one({"_id": self._id}, {"$set": kwargs})
#
# self._update_cache(cache)
#
# logger.info("Set attributes of guild %s to %s", self.id, kwargs)
async def _remove(self, *args: str, cache: Optional[Cache] = None) -> None: async def _remove(self, *args: str, cache: Optional[Cache] = None) -> None:
await super()._remove(*args, cache=cache) await super()._remove(*args, cache=cache)
# attributes: Dict[str, Any] = {}
#
# for key in args:
# if not hasattr(self, key):
# raise AttributeError()
#
# default_value: Any = self.get_default_value(key)
#
# setattr(self, key, default_value)
#
# attributes[key] = default_value
#
# await self.__collection__.update_one({"_id": self._id}, {"$set": attributes})
#
# self._update_cache(cache)
#
# logger.info("Reset attributes %s of guild %s to default values", args, self.id)
def _get_cache_key(self) -> str: def _get_cache_key(self) -> str:
return f"{self.__short_name__}_{self.id}" return f"{self.__short_name__}_{self.id}"
def _update_cache(self, cache: Optional[Cache] = None) -> None: def _update_cache(self, cache: Optional[Cache] = None) -> None:
super()._update_cache(cache) super()._update_cache(cache)
# if cache is None:
# return
#
# object_dict: Dict[str, Any] = self.to_dict(json_compatible=True)
#
# if object_dict is not None:
# cache.set_json(self._get_cache_key(), object_dict)
# else:
# self._delete_cache(cache)
def _delete_cache(self, cache: Optional[Cache] = None) -> None: def _delete_cache(self, cache: Optional[Cache] = None) -> None:
super()._delete_cache(cache) super()._delete_cache(cache)
# if cache is None:
# return
#
# cache.delete(self._get_cache_key())
@staticmethod @staticmethod
def _entry_to_cache(db_entry: Dict[str, Any]) -> Dict[str, Any]: def _entry_to_cache(db_entry: Dict[str, Any]) -> Dict[str, Any]:
@@ -217,11 +176,6 @@ class PycordGuild(BaseCacheable):
await super().reset(*args, cache=cache) await super().reset(*args, cache=cache)
async def purge(self, cache: Optional[Cache] = None) -> None: async def purge(self, cache: Optional[Cache] = None) -> None:
"""Completely remove guild data from database. Currently only removes the guild record from guilds collection.
Args:
cache (:obj:`Cache`, optional): Cache engine to write the update into
"""
await super().purge(cache) await super().purge(cache)
def is_configured(self) -> bool: def is_configured(self) -> bool:

View File

@@ -17,7 +17,7 @@ from discord.abc import GuildChannel
from libbot.cache.classes import Cache from libbot.cache.classes import Cache
from pymongo.results import InsertOneResult from pymongo.results import InsertOneResult
from classes.abstract import Cacheable from classes.base.base_cacheable import BaseCacheable
from classes.errors import ( from classes.errors import (
DiscordCategoryNotFoundError, DiscordCategoryNotFoundError,
DiscordChannelNotFoundError, DiscordChannelNotFoundError,
@@ -34,17 +34,9 @@ logger: Logger = get_logger(__name__)
@dataclass @dataclass
class PycordUser(Cacheable): class PycordUser(BaseCacheable):
"""Dataclass of DB entry of a user""" """Dataclass of DB entry of a user"""
# TODO Implement this
async def update(self, cache: Optional[Cache] = None, **kwargs: Any) -> None:
pass
# TODO Implement this
async def reset(self, *args: str, cache: Optional[Cache] = None) -> None:
pass
__slots__ = ( __slots__ = (
"_id", "_id",
"id", "id",
@@ -145,68 +137,19 @@ class PycordUser(Cacheable):
} }
async def _set(self, cache: Optional[Cache] = None, **kwargs: Any) -> None: async def _set(self, cache: Optional[Cache] = None, **kwargs: Any) -> None:
"""Set attribute data and save it into the database. await super()._set(cache, **kwargs)
Args:
cache (:obj:`Cache`, optional): Cache engine to write the update into
**kwargs (Any): Mapping of attribute names and respective values to be set
"""
for key, value in kwargs.items():
if not hasattr(self, key):
raise AttributeError()
setattr(self, key, value)
await self.__collection__.update_one({"_id": self._id}, {"$set": kwargs})
self._update_cache(cache)
logger.info("Set attributes of user %s to %s", self.id, kwargs)
async def _remove(self, *args: str, cache: Optional[Cache] = None) -> None: async def _remove(self, *args: str, cache: Optional[Cache] = None) -> None:
"""Remove attribute data and save it into the database. await super()._remove(*args, cache=cache)
Args:
cache (:obj:`Cache`, optional): Cache engine to write the update into
*args (str): List of attributes to remove
"""
attributes: Dict[str, Any] = {}
for key in args:
if not hasattr(self, key):
raise AttributeError()
default_value: Any = self.get_default_value(key)
setattr(self, key, default_value)
attributes[key] = default_value
await self.__collection__.update_one({"_id": self._id}, {"$set": attributes})
self._update_cache(cache)
logger.info("Reset attributes %s of user %s to default values", args, self.id)
def _get_cache_key(self) -> str: def _get_cache_key(self) -> str:
return f"{self.__short_name__}_{self.id}_{self.guild_id}" return f"{self.__short_name__}_{self.id}_{self.guild_id}"
def _update_cache(self, cache: Optional[Cache] = None) -> None: def _update_cache(self, cache: Optional[Cache] = None) -> None:
if cache is None: super()._update_cache(cache)
return
object_dict: Dict[str, Any] = self.to_dict(json_compatible=True)
if object_dict is not None:
cache.set_json(self._get_cache_key(), object_dict)
else:
self._delete_cache(cache)
def _delete_cache(self, cache: Optional[Cache] = None) -> None: def _delete_cache(self, cache: Optional[Cache] = None) -> None:
if cache is None: super()._delete_cache(cache)
return
cache.delete(self._get_cache_key())
@staticmethod @staticmethod
def _entry_to_cache(db_entry: Dict[str, Any]) -> Dict[str, Any]: def _entry_to_cache(db_entry: Dict[str, Any]) -> Dict[str, Any]:
@@ -270,14 +213,22 @@ class PycordUser(Cacheable):
return PycordUser.get_defaults()[key] return PycordUser.get_defaults()[key]
async def purge(self, cache: Optional[Cache] = None) -> None: async def update(
"""Completely remove user data from database. Currently only removes the user record from users collection. self,
cache: Optional[Cache] = None,
**kwargs: Any,
) -> None:
await super().update(cache=cache, **kwargs)
Args: async def reset(
cache (:obj:`Cache`, optional): Cache engine to write the update into self,
""" *args: str,
await self.__collection__.delete_one({"_id": self._id}) cache: Optional[Cache] = None,
self._delete_cache(cache) ) -> None:
await super().reset(*args, cache=cache)
async def purge(self, cache: Optional[Cache] = None) -> None:
await super().purge(cache)
# TODO Add documentation # TODO Add documentation
async def event_register(self, event_id: str | ObjectId, cache: Optional[Cache] = None) -> None: async def event_register(self, event_id: str | ObjectId, cache: Optional[Cache] = None) -> None:

View File

@@ -64,7 +64,6 @@ class CogUnregister(Cog):
await ctx.respond(self.bot._("jailed_error", "messages", locale=ctx.locale), ephemeral=True) await ctx.respond(self.bot._("jailed_error", "messages", locale=ctx.locale), ephemeral=True)
return return
# TODO Fix a bug where registered_event_ids is invalid because of caching
if pycord_event._id not in user.registered_event_ids: if pycord_event._id not in user.registered_event_ids:
await ctx.respond( await ctx.respond(
self.bot._("unregister_not_registered", "messages", locale=ctx.locale), ephemeral=True self.bot._("unregister_not_registered", "messages", locale=ctx.locale), ephemeral=True