Implemented /stage edit and /stage delete (#2)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
from logging import Logger
|
from logging import Logger
|
||||||
from typing import Any
|
from typing import Any, override
|
||||||
|
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
from discord import Guild, User
|
from discord import Guild, User
|
||||||
@@ -43,6 +43,14 @@ class PycordBot(LibPycordBot):
|
|||||||
if "cache" in self.config and self.config["cache"]["type"] is not None:
|
if "cache" in self.config and self.config["cache"]["type"] is not None:
|
||||||
self.cache = create_cache_client(self.config, self.config["cache"]["type"])
|
self.cache = create_cache_client(self.config, self.config["cache"]["type"])
|
||||||
|
|
||||||
|
@override
|
||||||
|
async def start(self, *args: Any, **kwargs: Any) -> None:
|
||||||
|
await super().start(*args, **kwargs)
|
||||||
|
|
||||||
|
@override
|
||||||
|
async def close(self, **kwargs) -> None:
|
||||||
|
await super().close(**kwargs)
|
||||||
|
|
||||||
async def find_user(self, user: int | User) -> PycordUser:
|
async def find_user(self, user: int | User) -> PycordUser:
|
||||||
"""Find User by its ID or User object.
|
"""Find User by its ID or User object.
|
||||||
|
|
||||||
@@ -100,16 +108,11 @@ class PycordBot(LibPycordBot):
|
|||||||
|
|
||||||
event_stage: PycordEventStage = await PycordEventStage.create(**kwargs, cache=self.cache)
|
event_stage: PycordEventStage = await PycordEventStage.create(**kwargs, cache=self.cache)
|
||||||
|
|
||||||
await event.insert_stage(event_stage._id, kwargs["sequence"], cache=self.cache)
|
await event.insert_stage(self, event_stage._id, kwargs["sequence"], cache=self.cache)
|
||||||
|
|
||||||
return event_stage
|
return event_stage
|
||||||
|
|
||||||
async def start(self, *args: Any, **kwargs: Any) -> None:
|
# TODO Document this method
|
||||||
await super().start(*args, **kwargs)
|
|
||||||
|
|
||||||
async def close(self, **kwargs) -> None:
|
|
||||||
await super().close(**kwargs)
|
|
||||||
|
|
||||||
async def find_event(self, event_id: str | ObjectId | None = None, event_name: str | None = None):
|
async def find_event(self, event_id: str | ObjectId | None = None, event_name: str | None = None):
|
||||||
if event_id is None and event_name is None:
|
if event_id is None and event_name is None:
|
||||||
raise AttributeError("Either event's ID or name must be provided!")
|
raise AttributeError("Either event's ID or name must be provided!")
|
||||||
@@ -118,3 +121,7 @@ class PycordBot(LibPycordBot):
|
|||||||
return await PycordEvent.from_id(event_id, cache=self.cache)
|
return await PycordEvent.from_id(event_id, cache=self.cache)
|
||||||
else:
|
else:
|
||||||
return await PycordEvent.from_name(event_name, cache=self.cache)
|
return await PycordEvent.from_name(event_name, cache=self.cache)
|
||||||
|
|
||||||
|
# TODO Document this method
|
||||||
|
async def find_event_stage(self, stage_id: str | ObjectId) -> PycordEventStage:
|
||||||
|
return await PycordEventStage.from_id(stage_id, cache=self.cache)
|
||||||
|
@@ -5,10 +5,11 @@ from typing import Any, Dict, List, Optional
|
|||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
|
from discord import Bot
|
||||||
from libbot.cache.classes import Cache
|
from libbot.cache.classes import Cache
|
||||||
from pymongo.results import InsertOneResult
|
from pymongo.results import InsertOneResult
|
||||||
|
|
||||||
from modules.database import col_events, col_stages
|
from modules.database import col_events
|
||||||
from modules.logging_utils import get_logger
|
from modules.logging_utils import get_logger
|
||||||
|
|
||||||
logger: Logger = get_logger(__name__)
|
logger: Logger = get_logger(__name__)
|
||||||
@@ -266,14 +267,62 @@ class PycordEvent:
|
|||||||
await self.__collection__.delete_one({"_id": self._id})
|
await self.__collection__.delete_one({"_id": self._id})
|
||||||
self._delete_cache(cache)
|
self._delete_cache(cache)
|
||||||
|
|
||||||
|
# TODO Add documentation
|
||||||
async def cancel(self, cache: Optional[Cache] = None):
|
async def cancel(self, cache: Optional[Cache] = None):
|
||||||
await self._set(cache, cancelled=True)
|
await self._set(cache, cancelled=True)
|
||||||
|
|
||||||
async def insert_stage(
|
async def _update_event_stage_order(
|
||||||
self, event_stage_id: ObjectId, sequence: int, cache: Optional[Cache] = None
|
self,
|
||||||
|
bot: Any,
|
||||||
|
old_stage_ids: List[ObjectId],
|
||||||
|
cache: Optional[Cache] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.stage_ids.insert(sequence, event_stage_id)
|
logger.info("Updating event stages order for %s...", self._id)
|
||||||
await self._set(cache, stage_ids=self.stage_ids)
|
|
||||||
|
|
||||||
# TODO Check if this works
|
logger.debug("Old stage IDs: %s", old_stage_ids)
|
||||||
await col_stages.update_many({"_id": {"$eq": self.stage_ids[sequence:]}}, {"$inc": {"sequence": 1}})
|
logger.debug("New stage IDs: %s", self.stage_ids)
|
||||||
|
|
||||||
|
for event_stage_id in self.stage_ids:
|
||||||
|
if event_stage_id not in old_stage_ids:
|
||||||
|
continue
|
||||||
|
|
||||||
|
stage_index: int = self.stage_ids.index(event_stage_id)
|
||||||
|
old_stage_index: int = old_stage_ids.index(event_stage_id)
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
"Indexes for %s: was %s and is now %s", event_stage_id, old_stage_index, stage_index
|
||||||
|
)
|
||||||
|
|
||||||
|
if stage_index != old_stage_index:
|
||||||
|
await (await bot.find_event_stage(event_stage_id)).update(cache, sequence=stage_index)
|
||||||
|
|
||||||
|
# TODO Add documentation
|
||||||
|
async def insert_stage(
|
||||||
|
self, bot: Bot, event_stage_id: ObjectId, index: int, cache: Optional[Cache] = None
|
||||||
|
) -> None:
|
||||||
|
old_stage_ids: List[ObjectId] = self.stage_ids.copy()
|
||||||
|
|
||||||
|
self.stage_ids.insert(index, event_stage_id)
|
||||||
|
|
||||||
|
await self._set(cache, stage_ids=self.stage_ids)
|
||||||
|
await self._update_event_stage_order(bot, old_stage_ids, cache=cache)
|
||||||
|
|
||||||
|
# TODO Add documentation
|
||||||
|
async def reorder_stage(
|
||||||
|
self, bot: Any, event_stage_id: ObjectId, index: int, cache: Optional[Cache] = None
|
||||||
|
) -> None:
|
||||||
|
old_stage_ids: List[ObjectId] = self.stage_ids.copy()
|
||||||
|
|
||||||
|
self.stage_ids.insert(index, self.stage_ids.pop(self.stage_ids.index(event_stage_id)))
|
||||||
|
|
||||||
|
await self._set(cache, stage_ids=self.stage_ids)
|
||||||
|
await self._update_event_stage_order(bot, old_stage_ids, cache=cache)
|
||||||
|
|
||||||
|
# TODO Add documentation
|
||||||
|
async def remove_stage(self, bot: Bot, event_stage_id: ObjectId, cache: Optional[Cache] = None) -> None:
|
||||||
|
old_stage_ids: List[ObjectId] = self.stage_ids.copy()
|
||||||
|
|
||||||
|
self.stage_ids.pop(self.stage_ids.index(event_stage_id))
|
||||||
|
|
||||||
|
await self._set(cache, stage_ids=self.stage_ids)
|
||||||
|
await self._update_event_stage_order(bot, old_stage_ids, cache=cache)
|
||||||
|
@@ -38,7 +38,7 @@ class PycordEventStage:
|
|||||||
creator_id: int
|
creator_id: int
|
||||||
question: str
|
question: str
|
||||||
answer: str
|
answer: str
|
||||||
media: List[str]
|
media: List[int]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def from_id(cls, stage_id: str | ObjectId, cache: Optional[Cache] = None) -> "PycordEventStage":
|
async def from_id(cls, stage_id: str | ObjectId, cache: Optional[Cache] = None) -> "PycordEventStage":
|
||||||
|
@@ -12,7 +12,7 @@ from discord.utils import basic_autocomplete
|
|||||||
|
|
||||||
from classes import PycordGuild
|
from classes import PycordGuild
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
from modules.utils import autofill_timezones, autofill_languages
|
from modules.utils import autocomplete_timezones, autocomplete_languages
|
||||||
|
|
||||||
|
|
||||||
class Config(Cog):
|
class Config(Cog):
|
||||||
@@ -34,13 +34,13 @@ class Config(Cog):
|
|||||||
@option(
|
@option(
|
||||||
"timezone",
|
"timezone",
|
||||||
description="Timezone in which events take place",
|
description="Timezone in which events take place",
|
||||||
autocomplete=basic_autocomplete(autofill_timezones),
|
autocomplete=basic_autocomplete(autocomplete_timezones),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
@option(
|
@option(
|
||||||
"language",
|
"language",
|
||||||
description="Language for bot's messages",
|
description="Language for bot's messages",
|
||||||
autocomplete=basic_autocomplete(autofill_languages),
|
autocomplete=basic_autocomplete(autocomplete_languages),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
async def command_config_set(
|
async def command_config_set(
|
||||||
@@ -97,6 +97,11 @@ class Config(Cog):
|
|||||||
async def command_config_show(self, ctx: ApplicationContext) -> None:
|
async def command_config_show(self, ctx: ApplicationContext) -> None:
|
||||||
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
|
|
||||||
|
if not guild.is_configured():
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("Guild is not configured.")
|
||||||
|
return
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
f"**Guild config**\n\nChannel: <#{guild.channel_id}>\nCategory: <#{guild.category_id}>\nTimezone: {guild.timezone}\nLanguage: {guild.language}"
|
f"**Guild config**\n\nChannel: <#{guild.channel_id}>\nCategory: <#{guild.category_id}>\nTimezone: {guild.timezone}\nLanguage: {guild.language}"
|
||||||
|
@@ -15,7 +15,7 @@ from discord.utils import basic_autocomplete
|
|||||||
from classes import PycordEvent, PycordGuild
|
from classes import PycordEvent, PycordGuild
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
from modules.database import col_events
|
from modules.database import col_events
|
||||||
from modules.utils import autofill_active_events
|
from modules.utils import autocomplete_active_events
|
||||||
|
|
||||||
|
|
||||||
# TODO Move to staticmethod or to a separate module
|
# TODO Move to staticmethod or to a separate module
|
||||||
@@ -120,7 +120,7 @@ class Event(Cog):
|
|||||||
@option(
|
@option(
|
||||||
"event",
|
"event",
|
||||||
description="Name of the event",
|
description="Name of the event",
|
||||||
autocomplete=basic_autocomplete(autofill_active_events),
|
autocomplete=basic_autocomplete(autocomplete_active_events),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
@option("name", description="New name of the event", required=False)
|
@option("name", description="New name of the event", required=False)
|
||||||
@@ -192,14 +192,21 @@ class Event(Cog):
|
|||||||
@option(
|
@option(
|
||||||
"event",
|
"event",
|
||||||
description="Name of the event",
|
description="Name of the event",
|
||||||
autocomplete=basic_autocomplete(autofill_active_events),
|
autocomplete=basic_autocomplete(autocomplete_active_events),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
|
@option("confirm", description="Confirmation of the operation", required=False)
|
||||||
async def command_event_cancel(
|
async def command_event_cancel(
|
||||||
self,
|
self,
|
||||||
ctx: ApplicationContext,
|
ctx: ApplicationContext,
|
||||||
event: str,
|
event: str,
|
||||||
|
confirm: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
if confirm is None or not confirm:
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("Operation not confirmed.")
|
||||||
|
return
|
||||||
|
|
||||||
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
pycord_event: PycordEvent = await self.bot.find_event(event_id=event)
|
pycord_event: PycordEvent = await self.bot.find_event(event_id=event)
|
||||||
|
|
||||||
@@ -239,7 +246,7 @@ class Event(Cog):
|
|||||||
@option(
|
@option(
|
||||||
"event",
|
"event",
|
||||||
description="Name of the event",
|
description="Name of the event",
|
||||||
autocomplete=basic_autocomplete(autofill_active_events),
|
autocomplete=basic_autocomplete(autocomplete_active_events),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
async def command_event_show(self, ctx: ApplicationContext, event: str) -> None:
|
async def command_event_show(self, ctx: ApplicationContext, event: str) -> None:
|
||||||
|
@@ -4,7 +4,7 @@ from discord.utils import basic_autocomplete
|
|||||||
|
|
||||||
from classes import PycordGuild, PycordEventStage, PycordEvent
|
from classes import PycordGuild, PycordEventStage, PycordEvent
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
from modules.utils import autofill_active_events
|
from modules.utils import autocomplete_active_events, autocomplete_event_stages
|
||||||
|
|
||||||
|
|
||||||
class Stage(Cog):
|
class Stage(Cog):
|
||||||
@@ -24,7 +24,7 @@ class Stage(Cog):
|
|||||||
@option(
|
@option(
|
||||||
"event",
|
"event",
|
||||||
description="Name of the event",
|
description="Name of the event",
|
||||||
autocomplete=basic_autocomplete(autofill_active_events),
|
autocomplete=basic_autocomplete(autocomplete_active_events),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
@option("question", description="Question to be answered", required=True)
|
@option("question", description="Question to be answered", required=True)
|
||||||
@@ -54,7 +54,7 @@ class Stage(Cog):
|
|||||||
creator_id=ctx.author.id,
|
creator_id=ctx.author.id,
|
||||||
question=question,
|
question=question,
|
||||||
answer=answer,
|
answer=answer,
|
||||||
media=None if media is None else media.id,
|
media=[] if media is None else [media.id],
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
@@ -69,14 +69,21 @@ class Stage(Cog):
|
|||||||
@option(
|
@option(
|
||||||
"event",
|
"event",
|
||||||
description="Name of the event",
|
description="Name of the event",
|
||||||
autocomplete=basic_autocomplete(autofill_active_events),
|
autocomplete=basic_autocomplete(autocomplete_active_events),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
@option("stage", description="Stage to edit", required=True)
|
# TODO Add autofill
|
||||||
@option("order", description="Number in the event stages' order", required=False)
|
@option(
|
||||||
|
"stage",
|
||||||
|
description="Stage to edit",
|
||||||
|
autocomplete=basic_autocomplete(autocomplete_event_stages),
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
@option("order", description="Number in the event stages' order", min_value=1, required=False)
|
||||||
@option("question", description="Question to be answered", required=False)
|
@option("question", description="Question to be answered", required=False)
|
||||||
@option("answer", description="Answer to the stage's question", required=False)
|
@option("answer", description="Answer to the stage's question", required=False)
|
||||||
@option("media", description="Media file to be attached", required=False)
|
@option("media", description="Media file to be attached", required=False)
|
||||||
|
@option("remove_media", description="Remove attached media", required=False)
|
||||||
async def command_stage_edit(
|
async def command_stage_edit(
|
||||||
self,
|
self,
|
||||||
ctx: ApplicationContext,
|
ctx: ApplicationContext,
|
||||||
@@ -86,8 +93,33 @@ class Stage(Cog):
|
|||||||
question: str,
|
question: str,
|
||||||
answer: str,
|
answer: str,
|
||||||
media: Attachment = None,
|
media: Attachment = None,
|
||||||
|
remove_media: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
await ctx.respond("Not implemented.")
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
|
pycord_event: PycordEvent = await self.bot.find_event(event)
|
||||||
|
event_stage: PycordEventStage = await self.bot.find_event_stage(stage)
|
||||||
|
|
||||||
|
if not guild.is_configured():
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("Guild is not configured.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if order is not None and order > len(pycord_event.stage_ids):
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("Stage sequence out of range.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not (question is None and answer is None and media is None and remove_media is False):
|
||||||
|
await event_stage.update(
|
||||||
|
question=event_stage.question if question is None else question,
|
||||||
|
answer=event_stage.answer if answer is None else answer,
|
||||||
|
media=[] if remove_media else (event_stage.media if media is None else [media.id]),
|
||||||
|
)
|
||||||
|
|
||||||
|
if order is not None and order - 1 != event_stage.sequence:
|
||||||
|
await pycord_event.reorder_stage(self.bot, event_stage._id, order - 1, cache=self.bot.cache)
|
||||||
|
|
||||||
|
await ctx.respond("Event stage has been updated.")
|
||||||
|
|
||||||
# TODO Implement the command
|
# TODO Implement the command
|
||||||
# /stage delete <event> <stage> <confirm>
|
# /stage delete <event> <stage> <confirm>
|
||||||
@@ -98,15 +130,38 @@ class Stage(Cog):
|
|||||||
@option(
|
@option(
|
||||||
"event",
|
"event",
|
||||||
description="Name of the event",
|
description="Name of the event",
|
||||||
autocomplete=basic_autocomplete(autofill_active_events),
|
autocomplete=basic_autocomplete(autocomplete_active_events),
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
@option(
|
||||||
|
"stage",
|
||||||
|
description="Stage to delete",
|
||||||
|
autocomplete=basic_autocomplete(autocomplete_event_stages),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
@option("stage", description="Stage to edit", required=True)
|
|
||||||
@option("confirm", description="Confirmation of the operation", required=False)
|
@option("confirm", description="Confirmation of the operation", required=False)
|
||||||
async def command_stage_delete(
|
async def command_stage_delete(
|
||||||
self, ctx: ApplicationContext, event: str, stage: str, confirm: bool = False
|
self, ctx: ApplicationContext, event: str, stage: str, confirm: bool = False
|
||||||
) -> None:
|
) -> None:
|
||||||
await ctx.respond("Not implemented.")
|
if confirm is None or not confirm:
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("Operation not confirmed.")
|
||||||
|
return
|
||||||
|
|
||||||
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
|
pycord_event: PycordEvent = await self.bot.find_event(event)
|
||||||
|
event_stage: PycordEventStage = await self.bot.find_event_stage(stage)
|
||||||
|
|
||||||
|
if not guild.is_configured():
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("Guild is not configured.")
|
||||||
|
return
|
||||||
|
|
||||||
|
await pycord_event.remove_stage(self.bot, event_stage._id, cache=self.bot.cache)
|
||||||
|
await event_stage.purge(cache=self.bot.cache)
|
||||||
|
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("Okay.")
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: PycordBot) -> None:
|
def setup(bot: PycordBot) -> None:
|
||||||
|
@@ -2,9 +2,11 @@ from datetime import datetime
|
|||||||
from typing import List, Dict, Any
|
from typing import List, Dict, Any
|
||||||
from zoneinfo import ZoneInfo, available_timezones
|
from zoneinfo import ZoneInfo, available_timezones
|
||||||
|
|
||||||
|
from bson import ObjectId
|
||||||
from discord import AutocompleteContext, OptionChoice
|
from discord import AutocompleteContext, OptionChoice
|
||||||
|
from pymongo import ASCENDING
|
||||||
|
|
||||||
from modules.database import col_events
|
from modules.database import col_events, col_stages
|
||||||
|
|
||||||
|
|
||||||
def hex_to_int(hex_color: str) -> int:
|
def hex_to_int(hex_color: str) -> int:
|
||||||
@@ -16,19 +18,19 @@ def int_to_hex(integer_color: int) -> str:
|
|||||||
|
|
||||||
|
|
||||||
# TODO Maybe move to a separate module
|
# TODO Maybe move to a separate module
|
||||||
async def autofill_timezones(ctx: AutocompleteContext) -> List[str]:
|
async def autocomplete_timezones(ctx: AutocompleteContext) -> List[str]:
|
||||||
return sorted(list(available_timezones()))
|
return sorted(list(available_timezones()))
|
||||||
|
|
||||||
|
|
||||||
# TODO Maybe move to a separate module
|
# TODO Maybe move to a separate module
|
||||||
async def autofill_languages(ctx: AutocompleteContext) -> List[str]:
|
async def autocomplete_languages(ctx: AutocompleteContext) -> List[str]:
|
||||||
# TODO Discord normally uses a different set of locales.
|
# TODO Discord normally uses a different set of locales.
|
||||||
# For example, "en" being "en-US", etc. This will require changes to locale handling later.
|
# For example, "en" being "en-US", etc. This will require changes to locale handling later.
|
||||||
return ctx.bot.locales.keys()
|
return ctx.bot.locales.keys()
|
||||||
|
|
||||||
|
|
||||||
# TODO Maybe move to a separate module
|
# TODO Maybe move to a separate module
|
||||||
async def autofill_active_events(ctx: AutocompleteContext) -> List[OptionChoice]:
|
async def autocomplete_active_events(ctx: AutocompleteContext) -> List[OptionChoice]:
|
||||||
query: Dict[str, Any] = {
|
query: Dict[str, Any] = {
|
||||||
"ended": None,
|
"ended": None,
|
||||||
"ends": {"$gt": datetime.now(tz=ZoneInfo("UTC"))},
|
"ends": {"$gt": datetime.now(tz=ZoneInfo("UTC"))},
|
||||||
@@ -41,3 +43,24 @@ async def autofill_active_events(ctx: AutocompleteContext) -> List[OptionChoice]
|
|||||||
event_names.append(OptionChoice(result["name"], str(result["_id"])))
|
event_names.append(OptionChoice(result["name"], str(result["_id"])))
|
||||||
|
|
||||||
return event_names
|
return event_names
|
||||||
|
|
||||||
|
|
||||||
|
# TODO Maybe move to a separate module
|
||||||
|
async def autocomplete_event_stages(ctx: AutocompleteContext) -> List[OptionChoice]:
|
||||||
|
event_id: str | None = ctx.options["event"]
|
||||||
|
|
||||||
|
if event_id is None:
|
||||||
|
return []
|
||||||
|
|
||||||
|
query: Dict[str, Any] = {
|
||||||
|
"event_id": ObjectId(event_id),
|
||||||
|
}
|
||||||
|
|
||||||
|
event_stages: List[OptionChoice] = []
|
||||||
|
|
||||||
|
async for result in col_stages.find(query).sort([("sequence", ASCENDING)]):
|
||||||
|
event_stages.append(
|
||||||
|
OptionChoice(f"{result['sequence']+1} ({result['question']})", str(result["_id"]))
|
||||||
|
)
|
||||||
|
|
||||||
|
return event_stages
|
||||||
|
Reference in New Issue
Block a user