@@ -1 +1 @@
|
||||
from . import utils, database, migrator, scheduler
|
||||
from . import database, migrator, scheduler, utils
|
||||
|
@@ -3,6 +3,9 @@ from .autocomplete_utils import (
|
||||
autocomplete_event_stages,
|
||||
autocomplete_languages,
|
||||
autocomplete_timezones,
|
||||
autocomplete_user_available_events,
|
||||
autocomplete_user_registered_events,
|
||||
)
|
||||
from .cache_utils import restore_from_cache
|
||||
from .event_utils import validate_event_validity
|
||||
from .logging_utils import get_logger, get_logging_config
|
||||
|
@@ -6,7 +6,7 @@ from bson import ObjectId
|
||||
from discord import AutocompleteContext, OptionChoice
|
||||
from pymongo import ASCENDING
|
||||
|
||||
from modules.database import col_events, col_stages
|
||||
from modules.database import col_events, col_stages, col_users
|
||||
|
||||
|
||||
async def autocomplete_timezones(ctx: AutocompleteContext) -> List[str]:
|
||||
@@ -29,7 +29,7 @@ async def autocomplete_active_events(ctx: AutocompleteContext) -> List[OptionCho
|
||||
query: Dict[str, Any] = {
|
||||
"ended": None,
|
||||
"ends": {"$gt": datetime.now(tz=ZoneInfo("UTC"))},
|
||||
"cancelled": {"$ne": True},
|
||||
"is_cancelled": {"$ne": True},
|
||||
}
|
||||
|
||||
event_names: List[OptionChoice] = []
|
||||
@@ -40,6 +40,43 @@ async def autocomplete_active_events(ctx: AutocompleteContext) -> List[OptionCho
|
||||
return event_names
|
||||
|
||||
|
||||
async def autocomplete_user_available_events(ctx: AutocompleteContext) -> List[OptionChoice]:
|
||||
"""Return list of active events user can register in"""
|
||||
|
||||
return await autocomplete_active_events(ctx)
|
||||
|
||||
|
||||
async def autocomplete_user_registered_events(ctx: AutocompleteContext) -> List[OptionChoice]:
|
||||
"""Return list of active events user is registered in"""
|
||||
|
||||
pipeline: List[Dict[str, Any]] = [
|
||||
{
|
||||
"$lookup": {
|
||||
"from": "events",
|
||||
"localField": "registered_event_ids",
|
||||
"foreignField": "_id",
|
||||
"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": {"$ne": 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"])))
|
||||
|
||||
return event_names
|
||||
|
||||
|
||||
async def autocomplete_event_stages(ctx: AutocompleteContext) -> List[OptionChoice]:
|
||||
"""Return list of stages of the event"""
|
||||
|
||||
|
46
modules/utils/event_utils.py
Normal file
46
modules/utils/event_utils.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from bson import ObjectId
|
||||
from discord import (
|
||||
ApplicationContext,
|
||||
)
|
||||
|
||||
from modules.database import col_events
|
||||
|
||||
|
||||
async def validate_event_validity(
|
||||
ctx: ApplicationContext,
|
||||
name: str,
|
||||
start_date: datetime | None,
|
||||
finish_date: datetime | None,
|
||||
guild_timezone: ZoneInfo,
|
||||
event_id: ObjectId | None = None,
|
||||
) -> None:
|
||||
if start_date > finish_date:
|
||||
# TODO Make a nice message
|
||||
await ctx.respond("Start date must be before finish date")
|
||||
return
|
||||
|
||||
if start_date < datetime.now(tz=guild_timezone):
|
||||
# TODO Make a nice message
|
||||
await ctx.respond("Start date must not be in the past")
|
||||
return
|
||||
|
||||
# TODO Add validation for concurrent events.
|
||||
# Only one event can take place at the same time.
|
||||
query: Dict[str, Any] = {
|
||||
"name": name,
|
||||
"ended": None,
|
||||
"ends": {"$gt": datetime.now(tz=ZoneInfo("UTC"))},
|
||||
"is_cancelled": {"$ne": True},
|
||||
}
|
||||
|
||||
if event_id is not None:
|
||||
query["_id"] = {"$ne": event_id}
|
||||
|
||||
if (await col_events.find_one(query)) is not None:
|
||||
# TODO Make a nice message
|
||||
await ctx.respond("There can only be one active event with the same name")
|
||||
return
|
Reference in New Issue
Block a user