Worked on #13 and #4. There are some caching issues left, though. Introduced abstract class Cacheable. Replaced async_pymongo with pymongo

This commit is contained in:
2025-05-06 02:54:30 +02:00
parent 9d562e2e9d
commit 86c75d06fa
22 changed files with 412 additions and 137 deletions

View File

@@ -7,7 +7,7 @@ from .autocomplete_utils import (
autocomplete_user_registered_events,
)
from .cache_utils import restore_from_cache
from .datetime_utils import get_unix_timestamp
from .datetime_utils import get_unix_timestamp, get_utc_now
from .event_utils import validate_event_validity
from .git_utils import get_current_commit
from .logging_utils import get_logger, get_logging_config

View File

@@ -49,31 +49,41 @@ async def autocomplete_user_available_events(ctx: AutocompleteContext) -> List[O
async def autocomplete_user_registered_events(ctx: AutocompleteContext) -> List[OptionChoice]:
"""Return list of active events user is registered in"""
utc_now: datetime = datetime.now(tz=ZoneInfo("UTC"))
pipeline: List[Dict[str, Any]] = [
{"$match": {"id": ctx.interaction.user.id}},
{
"$lookup": {
"from": "events",
"localField": "registered_event_ids",
"foreignField": "_id",
"let": {"event_ids": "$registered_event_ids"},
"pipeline": [
{
"$match": {
"$expr": {
"$and": [
{"$in": ["$_id", "$$event_ids"]},
{"$eq": ["$ended", None]},
{"$gt": ["$ends", utc_now]},
{"$gt": ["$starts", utc_now]},
{"$eq": ["$is_cancelled", False]},
]
}
}
}
],
"as": "registered_events",
}
},
{
"$match": {
"registered_events.ended": None,
"registered_events.ends": {"$gt": datetime.now(tz=ZoneInfo("UTC"))},
"registered_events.starts": {"$gt": datetime.now(tz=ZoneInfo("UTC"))},
"registered_events.is_cancelled": False,
}
},
{"$match": {"registered_events.0": {"$exists": True}}},
]
event_names: List[OptionChoice] = []
async for result in col_users.aggregate(pipeline):
for registered_event in result["registered_events"]:
event_names.append(OptionChoice(registered_event["name"], str(registered_event["_id"])))
async with await col_users.aggregate(pipeline) as cursor:
async for result in cursor:
for registered_event in result["registered_events"]:
event_names.append(OptionChoice(registered_event["name"], str(registered_event["_id"])))
return event_names

View File

@@ -5,3 +5,8 @@ from zoneinfo import ZoneInfo
# TODO Add documentation
def get_unix_timestamp(date: datetime, to_utc: bool = False) -> int:
return int((date if not to_utc else date.replace(tzinfo=ZoneInfo("UTC"))).timestamp())
# TODO Add documentation
def get_utc_now() -> datetime:
return datetime.now(tz=ZoneInfo("UTC"))

View File

@@ -23,15 +23,15 @@ async def validate_event_validity(
end_date_internal: datetime = end_date.astimezone(ZoneInfo("UTC")) if to_utc else end_date
if start_date_internal < datetime.now(tz=ZoneInfo("UTC")):
await ctx.respond(_("event_start_past", "messages", locale=ctx.locale))
await ctx.respond(_("event_start_past", "messages", locale=ctx.locale), ephemeral=True)
return False
if end_date_internal < datetime.now(tz=ZoneInfo("UTC")):
await ctx.respond(_("event_end_past", "messages", locale=ctx.locale))
await ctx.respond(_("event_end_past", "messages", locale=ctx.locale), ephemeral=True)
return False
if start_date_internal >= end_date_internal:
await ctx.respond(_("event_end_before_start", "messages", locale=ctx.locale))
await ctx.respond(_("event_end_before_start", "messages", locale=ctx.locale), ephemeral=True)
return False
# TODO Add validation for concurrent events.
@@ -47,7 +47,7 @@ async def validate_event_validity(
query["_id"] = {"$ne": event_id}
if (await col_events.find_one(query)) is not None:
await ctx.respond(_("event_name_duplicate", "messages", locale=ctx.locale))
await ctx.respond(_("event_name_duplicate", "messages", locale=ctx.locale), ephemeral=True)
return False
return True

View File

@@ -7,7 +7,7 @@ from libbot.i18n import _
async def is_operation_confirmed(ctx: ApplicationContext, confirm: bool) -> bool:
if confirm is None or not confirm:
await ctx.respond(ctx.bot._("operation_unconfirmed", "messages", locale=ctx.locale))
await ctx.respond(ctx.bot._("operation_unconfirmed", "messages", locale=ctx.locale), ephemeral=True)
return False
return True
@@ -18,7 +18,7 @@ async def is_event_status_valid(
event: "PycordEvent",
) -> bool:
if event.is_cancelled:
await ctx.respond(_("event_is_cancelled", "messages", locale=ctx.locale))
await ctx.respond(_("event_is_cancelled", "messages", locale=ctx.locale), ephemeral=True)
return False
if (
@@ -26,7 +26,7 @@ async def is_event_status_valid(
<= datetime.now(tz=ZoneInfo("UTC"))
<= event.ends.replace(tzinfo=ZoneInfo("UTC"))
):
await ctx.respond(_("event_ongoing_not_editable", "messages", locale=ctx.locale))
await ctx.respond(_("event_ongoing_not_editable", "messages", locale=ctx.locale), ephemeral=True)
return False
return True