Implemented /event edit and /edit cancel

This commit is contained in:
2025-04-21 22:49:23 +02:00
parent b72f930c94
commit 08d1ca4d33
5 changed files with 286 additions and 120 deletions

View File

@@ -87,9 +87,6 @@ class PycordBot(LibPycordBot):
await super().start(*args, **kwargs)
async def close(self, **kwargs) -> None:
if self.scheduler is not None:
self.scheduler.shutdown()
await super().close(**kwargs)
async def find_event(self, event_id: str | ObjectId | None = None, event_name: str | None = None):
@@ -97,6 +94,6 @@ class PycordBot(LibPycordBot):
raise AttributeError("Either event's ID or name must be provided!")
if event_id is not None:
await PycordEvent.from_id(event_id, cache=self.cache)
return await PycordEvent.from_id(event_id, cache=self.cache)
else:
await PycordEvent.from_name(event_name, cache=self.cache)
return await PycordEvent.from_name(event_name, cache=self.cache)

View File

@@ -1,7 +1,8 @@
from dataclasses import dataclass
from datetime import datetime, timezone
from datetime import datetime
from logging import Logger
from typing import Any, Dict, List, Optional
from zoneinfo import ZoneInfo
from bson import ObjectId
from libbot.cache.classes import Cache
@@ -21,6 +22,7 @@ class PycordEvent:
"guild_id",
"created",
"ended",
"cancelled",
"creator_id",
"starts",
"ends",
@@ -35,6 +37,7 @@ class PycordEvent:
guild_id: int
created: datetime
ended: datetime | None
cancelled: bool
creator_id: int
starts: datetime
ends: datetime
@@ -85,28 +88,31 @@ class PycordEvent:
if db_entry is None:
raise RuntimeError(f"Event with name {event_name} not found")
# TODO Add a unique exception
# raise EventNotFoundError(event_name)
if cache is not None:
cache.set_json(f"{cls.__short_name__}_{db_entry['_id']}", db_entry)
return cls(**db_entry)
# TODO Implement this method
@classmethod
async def create(
cls,
name: str,
guild_id: int,
creator_id: int,
starts: datetime,
ends: datetime,
thumbnail_id: str | None,
cache: Optional[Cache] = None,
cls,
name: str,
guild_id: int,
creator_id: int,
starts: datetime,
ends: datetime,
thumbnail_id: str | None,
cache: Optional[Cache] = None,
) -> "PycordEvent":
db_entry: Dict[str, Any] = {
"name": name,
"guild_id": guild_id,
"created": datetime.now(tz=timezone.utc),
"created": datetime.now(tz=ZoneInfo("UTC")),
"ended": None,
"cancelled": False,
"creator_id": creator_id,
"starts": starts,
"ends": ends,
@@ -123,7 +129,8 @@ class PycordEvent:
return cls(**db_entry)
async def _set(self, key: str, value: Any, cache: Optional[Cache] = None) -> None:
# TODO Update the docstring
async def _set(self, cache: Optional[Cache] = None, **kwargs) -> None:
"""Set attribute data and save it into the database.
Args:
@@ -131,36 +138,43 @@ class PycordEvent:
value (Any): Value to set
cache (:obj:`Cache`, optional): Cache engine to write the update into
"""
if not hasattr(self, key):
raise AttributeError()
for key, value in kwargs.items():
if not hasattr(self, key):
raise AttributeError()
setattr(self, key, value)
setattr(self, key, value)
await self.__collection__.update_one({"_id": self._id}, {"$set": {key: value}}, upsert=True)
await self.__collection__.update_one({"_id": self._id}, {"$set": kwargs}, upsert=True)
self._update_cache(cache)
logger.info("Set attribute '%s' of event %s to '%s'", key, self._id, value)
logger.info("Set attributes of event %s to %s", self._id, kwargs)
async def _remove(self, key: str, cache: Optional[Cache] = None) -> None:
# TODO Update the docstring
async def _remove(self, cache: Optional[Cache] = None, *args: str) -> None:
"""Remove attribute data and save it into the database.
Args:
key (str): Attribute to remove
cache (:obj:`Cache`, optional): Cache engine to write the update into
"""
if not hasattr(self, key):
raise AttributeError()
attributes: Dict[str, Any] = {}
default_value: Any = PycordEvent.get_default_value(key)
for key in args:
if not hasattr(self, key):
raise AttributeError()
setattr(self, key, default_value)
default_value: Any = self.get_default_value(key)
await self.__collection__.update_one({"_id": self._id}, {"$set": {key: default_value}}, upsert=True)
setattr(self, key, default_value)
attributes[key] = default_value
await self.__collection__.update_one({"_id": self._id}, {"$set": attributes}, upsert=True)
self._update_cache(cache)
logger.info("Removed attribute '%s' of event %s", key, self._id)
logger.info("Reset attributes %s of event %s to default values", args, self._id)
def _get_cache_key(self) -> str:
return f"{self.__short_name__}_{self._id}"
@@ -197,6 +211,7 @@ class PycordEvent:
"guild_id": self.guild_id,
"created": self.created,
"ended": self.ended,
"cancelled": self.cancelled,
"creator_id": self.creator_id,
"starts": self.starts,
"ends": self.ends,
@@ -211,6 +226,7 @@ class PycordEvent:
"guild_id": None,
"created": None,
"ended": None,
"cancelled": False,
"creator_id": None,
"starts": None,
"ends": None,
@@ -225,6 +241,22 @@ class PycordEvent:
return PycordEvent.get_defaults()[key]
# TODO Add documentation
async def update(
self,
cache: Optional[Cache] = None,
**kwargs,
):
await self._set(cache=cache, **kwargs)
# TODO Add documentation
async def reset(
self,
cache: Optional[Cache] = None,
*args,
):
await self._remove(cache, *args)
async def purge(self, cache: Optional[Cache] = None) -> None:
"""Completely remove event data from database. Currently only removes the event record from events collection.
@@ -233,3 +265,6 @@ class PycordEvent:
"""
await self.__collection__.delete_one({"_id": self._id})
self._delete_cache(cache)
async def cancel(self, cache: Optional[Cache] = None):
await self._set(cache, cancelled=True)

View File

@@ -17,15 +17,16 @@ logger: Logger = get_logger(__name__)
class PycordGuild:
"""Dataclass of DB entry of a guild"""
__slots__ = ("_id", "id", "channel_id", "category_id", "timezone")
__slots__ = ("_id", "id", "channel_id", "category_id", "timezone", "language")
__short_name__ = "guild"
__collection__ = col_guilds
_id: ObjectId
id: int
channel_id: Optional[int]
category_id: Optional[int]
channel_id: int | None
category_id: int | None
timezone: str
language: str | None
@classmethod
async def from_id(
@@ -67,7 +68,8 @@ class PycordGuild:
return cls(**db_entry)
async def _set(self, key: str, value: Any, cache: Optional[Cache] = None) -> None:
# TODO Update the docstring
async def _set(self, cache: Optional[Cache] = None, **kwargs) -> None:
"""Set attribute data and save it into the database.
Args:
@@ -75,36 +77,43 @@ class PycordGuild:
value (Any): Value to set
cache (:obj:`Cache`, optional): Cache engine to write the update into
"""
if not hasattr(self, key):
raise AttributeError()
for key, value in kwargs.items():
if not hasattr(self, key):
raise AttributeError()
setattr(self, key, value)
setattr(self, key, value)
await self.__collection__.update_one({"_id": self._id}, {"$set": {key: value}}, upsert=True)
await self.__collection__.update_one({"_id": self._id}, {"$set": kwargs}, upsert=True)
self._update_cache(cache)
logger.info("Set attribute '%s' of guild %s to '%s'", key, self.id, value)
logger.info("Set attributes of guild %s to %s", self.id, kwargs)
async def _remove(self, key: str, cache: Optional[Cache] = None) -> None:
# TODO Update the docstring
async def _remove(self, cache: Optional[Cache] = None, *args: str) -> None:
"""Remove attribute data and save it into the database.
Args:
key (str): Attribute to remove
cache (:obj:`Cache`, optional): Cache engine to write the update into
"""
if not hasattr(self, key):
raise AttributeError()
attributes: Dict[str, Any] = {}
default_value: Any = PycordGuild.get_default_value(key)
for key in args:
if not hasattr(self, key):
raise AttributeError()
setattr(self, key, default_value)
default_value: Any = self.get_default_value(key)
await self.__collection__.update_one({"_id": self._id}, {"$set": {key: default_value}}, upsert=True)
setattr(self, key, default_value)
attributes[key] = default_value
await self.__collection__.update_one({"_id": self._id}, {"$set": attributes}, upsert=True)
self._update_cache(cache)
logger.info("Removed attribute '%s' of guild %s", key, self.id)
logger.info("Reset attributes %s of guild %s to default values", args, self.id)
def _get_cache_key(self) -> str:
return f"{self.__short_name__}_{self.id}"
@@ -141,11 +150,18 @@ class PycordGuild:
"channel_id": self.channel_id,
"category_id": self.category_id,
"timezone": self.timezone,
"language": self.language,
}
@staticmethod
def get_defaults(guild_id: Optional[int] = None) -> Dict[str, Any]:
return {"id": guild_id, "channel_id": None, "category_id": None, "timezone": "UTC"}
return {
"id": guild_id,
"channel_id": None,
"category_id": None,
"timezone": "UTC",
"language": None,
}
@staticmethod
def get_default_value(key: str) -> Any:
@@ -154,6 +170,22 @@ class PycordGuild:
return PycordGuild.get_defaults()[key]
# TODO Add documentation
async def update(
self,
cache: Optional[Cache] = None,
**kwargs,
):
await self._set(cache=cache, **kwargs)
# TODO Add documentation
async def reset(
self,
cache: Optional[Cache] = None,
*args,
):
await self._remove(cache, *args)
async def purge(self, cache: Optional[Cache] = None) -> None:
"""Completely remove guild data from database. Currently only removes the guild record from guilds collection.
@@ -161,8 +193,11 @@ class PycordGuild:
cache (:obj:`Cache`, optional): Cache engine to write the update into
"""
await self.__collection__.delete_one({"_id": self._id})
self._delete_cache(cache)
logger.info("Purged guild %s (%s) from the database", self.id, self._id)
# TODO Add documentation
def is_configured(self) -> bool:
return (
@@ -174,24 +209,32 @@ class PycordGuild:
# TODO Add documentation
async def set_channel(self, channel_id: Optional[int] = None, cache: Optional[Cache] = None) -> None:
await self._set("channel_id", channel_id, cache)
await self._set(cache, channel_id=channel_id)
# TODO Add documentation
async def reset_channel(self, cache: Optional[Cache] = None) -> None:
await self._remove("channel_id", cache)
await self._remove(cache, "channel_id")
# TODO Add documentation
async def set_category(self, category_id: Optional[int] = None, cache: Optional[Cache] = None) -> None:
await self._set("category_id", category_id, cache)
await self._set(cache, category_id=category_id)
# TODO Add documentation
async def reset_category(self, cache: Optional[Cache] = None) -> None:
await self._remove("category_id", cache)
await self._remove(cache, "category_id")
# TODO Add documentation
async def set_timezone(self, timezone: str, cache: Optional[Cache] = None) -> None:
await self._set("timezone", timezone, cache)
await self._set(cache, timezone=timezone)
# TODO Add documentation
async def reset_timezone(self, cache: Optional[Cache] = None) -> None:
await self._remove("timezone", cache)
await self._remove(cache, "timezone")
# TODO Add documentation
async def set_language(self, language: str, cache: Optional[Cache] = None) -> None:
await self._set(cache, language=language)
# TODO Add documentation
async def reset_language(self, cache: Optional[Cache] = None) -> None:
await self._remove(cache, "language")