Implemented #7
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from logging import Logger
|
from logging import Logger
|
||||||
|
from pathlib import Path
|
||||||
from typing import Any, override, List, Dict
|
from typing import Any, override, List, Dict
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
from discord import Guild, User, TextChannel
|
from discord import Guild, User, TextChannel, Attachment, File
|
||||||
from libbot.cache.classes import CacheMemcached, CacheRedis
|
from libbot.cache.classes import CacheMemcached, CacheRedis
|
||||||
from libbot.cache.manager import create_cache_client
|
from libbot.cache.manager import create_cache_client
|
||||||
from libbot.pycord.classes import PycordBot as LibPycordBot
|
from libbot.pycord.classes import PycordBot as LibPycordBot
|
||||||
@@ -59,7 +60,6 @@ class PycordBot(LibPycordBot):
|
|||||||
async def _execute_event_controller(self) -> None:
|
async def _execute_event_controller(self) -> None:
|
||||||
await self._process_events_start()
|
await self._process_events_start()
|
||||||
await self._process_events_end()
|
await self._process_events_end()
|
||||||
# await self._process_events_post_end()
|
|
||||||
|
|
||||||
async def _process_events_start(self) -> None:
|
async def _process_events_start(self) -> None:
|
||||||
# Get events to start
|
# Get events to start
|
||||||
@@ -69,22 +69,45 @@ class PycordBot(LibPycordBot):
|
|||||||
|
|
||||||
# Process each event
|
# Process each event
|
||||||
for event in events:
|
for event in events:
|
||||||
|
if len(event.stage_ids) == 0:
|
||||||
|
# TODO Make a nice message for management
|
||||||
|
logger.error("Could not start the event %s: no event stages are defined.", event._id)
|
||||||
|
continue
|
||||||
|
|
||||||
guild: Guild = self.get_guild(event.guild_id)
|
guild: Guild = self.get_guild(event.guild_id)
|
||||||
pycord_guild: PycordGuild = await self.find_guild(guild)
|
pycord_guild: PycordGuild = await self.find_guild(guild)
|
||||||
|
first_stage: PycordEventStage = await self.find_event_stage(event.stage_ids[0])
|
||||||
|
|
||||||
# Get list of participants
|
# Get list of participants
|
||||||
users: List[PycordUser] = await self._get_event_participants(event._id)
|
users: List[PycordUser] = await self._get_event_participants(event._id)
|
||||||
|
|
||||||
for user in users:
|
for user in users:
|
||||||
|
await user._set(self.cache, current_event_id=event._id, current_stage_id=first_stage._id)
|
||||||
|
|
||||||
# Create a channel for each participant
|
# Create a channel for each participant
|
||||||
await user.setup_event_channel(self, guild, pycord_guild, event, cache=self.cache)
|
await user.setup_event_channel(self, guild, pycord_guild, event, cache=self.cache)
|
||||||
|
|
||||||
# Send a notification about event start
|
# Send a notification about event start
|
||||||
user_channel: TextChannel = guild.get_channel(user.event_channels[str(event._id)])
|
user_channel: TextChannel = guild.get_channel(user.event_channels[str(event._id)])
|
||||||
|
|
||||||
|
thumbnail: File | None = (
|
||||||
|
None
|
||||||
|
if event.thumbnail is None
|
||||||
|
else File(Path(f"data/{event.thumbnail['id']}"), event.thumbnail["filename"])
|
||||||
|
)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
# TODO Also send a thumbnail, event info and short explanation on how to play
|
# TODO Also send a thumbnail, event info and short explanation on how to play
|
||||||
await user_channel.send(f"Event **{event.name}** is starting!")
|
await user_channel.send(
|
||||||
|
f"Event **{event.name}** is starting!\n\nUse slash command `/guess` to suggest your answers to each event stage.",
|
||||||
|
file=thumbnail,
|
||||||
|
)
|
||||||
|
|
||||||
|
first_stage_files: List[File] | None = first_stage.get_media_files()
|
||||||
|
|
||||||
|
await user_channel.send(
|
||||||
|
f"First stage...\n\n{first_stage.question}", files=first_stage_files
|
||||||
|
)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await self._notify_admins(
|
await self._notify_admins(
|
||||||
@@ -103,6 +126,13 @@ class PycordBot(LibPycordBot):
|
|||||||
for event in events:
|
for event in events:
|
||||||
guild: Guild = self.get_guild(event.guild_id)
|
guild: Guild = self.get_guild(event.guild_id)
|
||||||
pycord_guild: PycordGuild = await self.find_guild(guild)
|
pycord_guild: PycordGuild = await self.find_guild(guild)
|
||||||
|
stages: List[PycordEventStage] = await self._get_event_stages(event)
|
||||||
|
|
||||||
|
# TODO Make a nice message
|
||||||
|
stages_string: str = "\n\n".join(
|
||||||
|
f"**Stage {stage.sequence+1}**\nQuestion: {stage.question}\nAnswer: ||{stage.answer}||"
|
||||||
|
for stage in stages
|
||||||
|
)
|
||||||
|
|
||||||
# Get list of participants
|
# Get list of participants
|
||||||
users: List[PycordUser] = await self._get_event_participants(event._id)
|
users: List[PycordUser] = await self._get_event_participants(event._id)
|
||||||
@@ -112,8 +142,9 @@ class PycordBot(LibPycordBot):
|
|||||||
user_channel: TextChannel = guild.get_channel(user.event_channels[str(event._id)])
|
user_channel: TextChannel = guild.get_channel(user.event_channels[str(event._id)])
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
# TODO Reveal answers to stages
|
await user_channel.send(
|
||||||
await user_channel.send(f"Event **{event.name}** has ended!")
|
f"Event **{event.name}** has ended! Stages and respective answers are listed below.\n\n{stages_string}"
|
||||||
|
)
|
||||||
|
|
||||||
# Lock each participant out
|
# Lock each participant out
|
||||||
await user.lock_event_channel(guild, event._id, channel=user_channel)
|
await user.lock_event_channel(guild, event._id, channel=user_channel)
|
||||||
@@ -125,37 +156,6 @@ class PycordBot(LibPycordBot):
|
|||||||
f"Event **{event.name}** has ended! Users can no longer submit their answers.",
|
f"Event **{event.name}** has ended! Users can no longer submit their answers.",
|
||||||
)
|
)
|
||||||
|
|
||||||
# async def _process_events_post_end(self) -> None:
|
|
||||||
# # Get events that ended an hour ago
|
|
||||||
# # TODO Replace with 1 hour after testing!
|
|
||||||
# events: List[PycordEvent] = await self._get_events(
|
|
||||||
# {
|
|
||||||
# "ends": datetime.now(tz=ZoneInfo("UTC")).replace(second=0, microsecond=0)
|
|
||||||
# - timedelta(minutes=1)
|
|
||||||
# }
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# # Process each event
|
|
||||||
# for event in events:
|
|
||||||
# guild: Guild = self.get_guild(event.guild_id)
|
|
||||||
# pycord_guild: PycordGuild = await self.find_guild(guild)
|
|
||||||
#
|
|
||||||
# # Get list of participants
|
|
||||||
# users: List[PycordUser] = await self._get_event_participants(event._id)
|
|
||||||
#
|
|
||||||
# for user in users:
|
|
||||||
# # Send a notification about event start
|
|
||||||
# user_channel: TextChannel = guild.get_channel(user.event_channels[str(event._id)])
|
|
||||||
#
|
|
||||||
# # Remove their view permissions
|
|
||||||
# await user.lock_event_channel(guild, event._id, completely=True, channel=user_channel)
|
|
||||||
#
|
|
||||||
# await self._notify_admins(
|
|
||||||
# guild,
|
|
||||||
# pycord_guild,
|
|
||||||
# f"Access has been updated, users can no longer access their channels for the event **{event.name}**.",
|
|
||||||
# )
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def _get_events(query: Dict[str, Any]) -> List[PycordEvent]:
|
async def _get_events(query: Dict[str, Any]) -> List[PycordEvent]:
|
||||||
events: List[PycordEvent] = []
|
events: List[PycordEvent] = []
|
||||||
@@ -174,6 +174,9 @@ class PycordBot(LibPycordBot):
|
|||||||
|
|
||||||
return users
|
return users
|
||||||
|
|
||||||
|
async def _get_event_stages(self, event: PycordEvent) -> List[PycordEventStage]:
|
||||||
|
return [(await self.find_event_stage(stage_id)) for stage_id in event.stage_ids]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def _notify_admins(guild: Guild, pycord_guild: PycordGuild, message: str) -> None:
|
async def _notify_admins(guild: Guild, pycord_guild: PycordGuild, message: str) -> None:
|
||||||
management_channel: TextChannel | None = guild.get_channel(pycord_guild.channel_id)
|
management_channel: TextChannel | None = guild.get_channel(pycord_guild.channel_id)
|
||||||
@@ -264,3 +267,13 @@ class PycordBot(LibPycordBot):
|
|||||||
# TODO Document this method
|
# TODO Document this method
|
||||||
async def find_event_stage(self, stage_id: str | ObjectId) -> PycordEventStage:
|
async def find_event_stage(self, stage_id: str | ObjectId) -> PycordEventStage:
|
||||||
return await PycordEventStage.from_id(stage_id, cache=self.cache)
|
return await PycordEventStage.from_id(stage_id, cache=self.cache)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def process_attachments(attachments: List[Attachment]) -> List[Dict[str, Any]]:
|
||||||
|
processed_attachments: List[Dict[str, Any]] = []
|
||||||
|
|
||||||
|
for attachment in attachments:
|
||||||
|
await attachment.save(Path(f"data/{attachment.id}"))
|
||||||
|
processed_attachments.append({"id": attachment.id, "filename": attachment.filename})
|
||||||
|
|
||||||
|
return processed_attachments
|
||||||
|
@@ -27,7 +27,7 @@ class PycordEvent:
|
|||||||
"creator_id",
|
"creator_id",
|
||||||
"starts",
|
"starts",
|
||||||
"ends",
|
"ends",
|
||||||
"thumbnail_id",
|
"thumbnail",
|
||||||
"stage_ids",
|
"stage_ids",
|
||||||
)
|
)
|
||||||
__short_name__ = "event"
|
__short_name__ = "event"
|
||||||
@@ -42,7 +42,7 @@ class PycordEvent:
|
|||||||
creator_id: int
|
creator_id: int
|
||||||
starts: datetime
|
starts: datetime
|
||||||
ends: datetime
|
ends: datetime
|
||||||
thumbnail_id: str | None
|
thumbnail: Dict[str, Any] | None
|
||||||
stage_ids: List[ObjectId]
|
stage_ids: List[ObjectId]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -105,7 +105,7 @@ class PycordEvent:
|
|||||||
creator_id: int,
|
creator_id: int,
|
||||||
starts: datetime,
|
starts: datetime,
|
||||||
ends: datetime,
|
ends: datetime,
|
||||||
thumbnail_id: str | None,
|
thumbnail: Dict[str, Any] | None,
|
||||||
cache: Optional[Cache] = None,
|
cache: Optional[Cache] = None,
|
||||||
) -> "PycordEvent":
|
) -> "PycordEvent":
|
||||||
db_entry: Dict[str, Any] = {
|
db_entry: Dict[str, Any] = {
|
||||||
@@ -117,7 +117,7 @@ class PycordEvent:
|
|||||||
"creator_id": creator_id,
|
"creator_id": creator_id,
|
||||||
"starts": starts,
|
"starts": starts,
|
||||||
"ends": ends,
|
"ends": ends,
|
||||||
"thumbnail_id": thumbnail_id,
|
"thumbnail": thumbnail,
|
||||||
"stage_ids": [],
|
"stage_ids": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ class PycordEvent:
|
|||||||
"creator_id": self.creator_id,
|
"creator_id": self.creator_id,
|
||||||
"starts": self.starts,
|
"starts": self.starts,
|
||||||
"ends": self.ends,
|
"ends": self.ends,
|
||||||
"thumbnail_id": self.thumbnail_id,
|
"thumbnail": self.thumbnail,
|
||||||
"stage_ids": self.stage_ids,
|
"stage_ids": self.stage_ids,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ class PycordEvent:
|
|||||||
"creator_id": None,
|
"creator_id": None,
|
||||||
"starts": None,
|
"starts": None,
|
||||||
"ends": None,
|
"ends": None,
|
||||||
"thumbnail_id": None,
|
"thumbnail": None,
|
||||||
"stage_ids": [],
|
"stage_ids": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from logging import Logger
|
from logging import Logger
|
||||||
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, Optional
|
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 File
|
||||||
from libbot.cache.classes import Cache
|
from libbot.cache.classes import Cache
|
||||||
from pymongo.results import InsertOneResult
|
from pymongo.results import InsertOneResult
|
||||||
|
|
||||||
@@ -38,7 +40,7 @@ class PycordEventStage:
|
|||||||
creator_id: int
|
creator_id: int
|
||||||
question: str
|
question: str
|
||||||
answer: str
|
answer: str
|
||||||
media: List[int]
|
media: List[Dict[str, Any]]
|
||||||
|
|
||||||
@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":
|
||||||
@@ -235,3 +237,11 @@ class PycordEventStage:
|
|||||||
"""
|
"""
|
||||||
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
|
||||||
|
def get_media_files(self) -> List[File] | None:
|
||||||
|
return (
|
||||||
|
None
|
||||||
|
if len(self.media) == 0
|
||||||
|
else [File(Path(f"data/{media['id']}"), media["filename"]) for media in self.media]
|
||||||
|
)
|
||||||
|
@@ -361,3 +361,9 @@ class PycordUser:
|
|||||||
self.event_channels[event_id if isinstance(event_id, str) else str(event_id)] = channel_id
|
self.event_channels[event_id if isinstance(event_id, str) else str(event_id)] = channel_id
|
||||||
|
|
||||||
await self._set(cache, event_channels=self.event_channels)
|
await self._set(cache, event_channels=self.event_channels)
|
||||||
|
|
||||||
|
# TODO Add documentation
|
||||||
|
async def set_event_stage(self, stage_id: str | ObjectId | None, cache: Optional[Cache] = None) -> None:
|
||||||
|
await self._set(
|
||||||
|
cache, current_stage_id=stage_id if isinstance(stage_id, str) else ObjectId(stage_id)
|
||||||
|
)
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Dict, List, Any
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from bson.errors import InvalidId
|
from bson.errors import InvalidId
|
||||||
@@ -64,13 +65,17 @@ class Event(Cog):
|
|||||||
|
|
||||||
await validate_event_validity(ctx, name, start_date, end_date, guild_timezone)
|
await validate_event_validity(ctx, name, start_date, end_date, guild_timezone)
|
||||||
|
|
||||||
|
processed_media: List[Dict[str, Any]] = (
|
||||||
|
[] if thumbnail is None else await self.bot.process_attachments([thumbnail])
|
||||||
|
)
|
||||||
|
|
||||||
event: PycordEvent = await self.bot.create_event(
|
event: PycordEvent = await self.bot.create_event(
|
||||||
name=name,
|
name=name,
|
||||||
guild_id=guild.id,
|
guild_id=guild.id,
|
||||||
creator_id=ctx.author.id,
|
creator_id=ctx.author.id,
|
||||||
starts=start_date.astimezone(ZoneInfo("UTC")),
|
starts=start_date.astimezone(ZoneInfo("UTC")),
|
||||||
ends=end_date.astimezone(ZoneInfo("UTC")),
|
ends=end_date.astimezone(ZoneInfo("UTC")),
|
||||||
thumbnail_id=thumbnail.id if thumbnail else None,
|
thumbnail=processed_media[0] if thumbnail else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
@@ -138,12 +143,16 @@ class Event(Cog):
|
|||||||
|
|
||||||
await validate_event_validity(ctx, name, start_date, end_date, guild_timezone)
|
await validate_event_validity(ctx, name, start_date, end_date, guild_timezone)
|
||||||
|
|
||||||
|
processed_media: List[Dict[str, Any]] = (
|
||||||
|
[] if thumbnail is None else await self.bot.process_attachments([thumbnail])
|
||||||
|
)
|
||||||
|
|
||||||
await pycord_event.update(
|
await pycord_event.update(
|
||||||
self.bot.cache,
|
self.bot.cache,
|
||||||
starts=start_date,
|
starts=start_date,
|
||||||
ends=end_date,
|
ends=end_date,
|
||||||
name=pycord_event.name if name is None else name,
|
name=pycord_event.name if name is None else name,
|
||||||
thumbnail_id=pycord_event.thumbnail_id if thumbnail is None else thumbnail.id,
|
thumbnail=pycord_event.thumbnail if thumbnail is None else processed_media[0],
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
|
@@ -1,5 +1,10 @@
|
|||||||
from discord import ApplicationContext, Cog, option, slash_command
|
from typing import List
|
||||||
|
|
||||||
|
from bson import ObjectId
|
||||||
|
from bson.errors import InvalidId
|
||||||
|
from discord import ApplicationContext, Cog, option, slash_command, File
|
||||||
|
|
||||||
|
from classes import PycordEvent, PycordUser, PycordGuild, PycordEventStage
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
|
|
||||||
|
|
||||||
@@ -16,7 +21,64 @@ class Guess(Cog):
|
|||||||
)
|
)
|
||||||
@option("answer", description="An answer to the current stage")
|
@option("answer", description="An answer to the current stage")
|
||||||
async def command_guess(self, ctx: ApplicationContext, answer: str) -> None:
|
async def command_guess(self, ctx: ApplicationContext, answer: str) -> None:
|
||||||
await ctx.respond("Not implemented.")
|
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
|
||||||
|
|
||||||
|
user: PycordUser = await self.bot.find_user(ctx.author)
|
||||||
|
|
||||||
|
if user.current_event_id is None or user.current_stage_id is None:
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("You have no ongoing events.")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
event: PycordEvent = await self.bot.find_event(event_id=user.current_event_id)
|
||||||
|
stage: PycordEventStage = await self.bot.find_event_stage(user.current_stage_id)
|
||||||
|
except (InvalidId, RuntimeError):
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond(
|
||||||
|
"Your event could not be found. Please, report this issue to the event's management."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
if answer.lower() != stage.answer.lower():
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("Provided answer is wrong.")
|
||||||
|
return
|
||||||
|
|
||||||
|
next_stage_index = stage.sequence + 1
|
||||||
|
next_stage_id: ObjectId | None = (
|
||||||
|
None if len(event.stage_ids) < next_stage_index + 1 else event.stage_ids[next_stage_index]
|
||||||
|
)
|
||||||
|
|
||||||
|
if next_stage_id is None:
|
||||||
|
# TODO Make a nice message
|
||||||
|
user.completed_event_ids.append(event._id)
|
||||||
|
|
||||||
|
await user._set(
|
||||||
|
self.bot.cache,
|
||||||
|
current_event_id=None,
|
||||||
|
current_stage_id=None,
|
||||||
|
completed_event_ids=user.completed_event_ids,
|
||||||
|
)
|
||||||
|
|
||||||
|
await ctx.respond("Event is completed.")
|
||||||
|
return
|
||||||
|
|
||||||
|
next_stage: PycordEventStage = await self.bot.find_event_stage(next_stage_id)
|
||||||
|
|
||||||
|
files: List[File] | None = next_stage.get_media_files()
|
||||||
|
|
||||||
|
await ctx.respond(
|
||||||
|
f"Provided answer is correct! Next stage...\n\n{next_stage.question}",
|
||||||
|
files=files,
|
||||||
|
)
|
||||||
|
|
||||||
|
await user.set_event_stage(next_stage._id, cache=self.bot.cache)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: PycordBot) -> None:
|
def setup(bot: PycordBot) -> None:
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from bson.errors import InvalidId
|
from bson.errors import InvalidId
|
||||||
from discord import ApplicationContext, Cog, option, slash_command
|
from discord import ApplicationContext, Cog, option, slash_command
|
||||||
from discord.utils import basic_autocomplete
|
from discord.utils import basic_autocomplete
|
||||||
@@ -47,9 +49,10 @@ class Register(Cog):
|
|||||||
|
|
||||||
await user.event_register(pycord_event._id, cache=self.bot.cache)
|
await user.event_register(pycord_event._id, cache=self.bot.cache)
|
||||||
|
|
||||||
# TODO Text channel must be created and updated
|
# TODO Make a nice message
|
||||||
|
await ctx.respond(
|
||||||
await ctx.respond("Ok.")
|
f"You are now registered for the event **{pycord_event.name}**.\n\nNew channel will be created for you and further instructions will be provided as soon as the event starts <t:{int((pycord_event.starts.replace(tzinfo=ZoneInfo('UTC'))).timestamp())}:R>. Good luck!"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: PycordBot) -> None:
|
def setup(bot: PycordBot) -> None:
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import List, Dict, Any
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from bson.errors import InvalidId
|
from bson.errors import InvalidId
|
||||||
@@ -14,11 +15,11 @@ from modules.utils import autocomplete_active_events, autocomplete_event_stages
|
|||||||
async def validate_event_status(
|
async def validate_event_status(
|
||||||
ctx: ApplicationContext,
|
ctx: ApplicationContext,
|
||||||
event: PycordEvent,
|
event: PycordEvent,
|
||||||
) -> None:
|
) -> bool:
|
||||||
if event.is_cancelled:
|
if event.is_cancelled:
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await ctx.respond("This event was cancelled.")
|
await ctx.respond("This event was cancelled.")
|
||||||
return
|
return False
|
||||||
|
|
||||||
if (
|
if (
|
||||||
event.starts.replace(tzinfo=ZoneInfo("UTC"))
|
event.starts.replace(tzinfo=ZoneInfo("UTC"))
|
||||||
@@ -27,7 +28,9 @@ async def validate_event_status(
|
|||||||
):
|
):
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await ctx.respond("Ongoing events cannot be modified.")
|
await ctx.respond("Ongoing events cannot be modified.")
|
||||||
return
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Stage(Cog):
|
class Stage(Cog):
|
||||||
@@ -75,7 +78,12 @@ class Stage(Cog):
|
|||||||
await ctx.respond("Event was not found.")
|
await ctx.respond("Event was not found.")
|
||||||
return
|
return
|
||||||
|
|
||||||
await validate_event_status(ctx, pycord_event)
|
if not (await validate_event_status(ctx, pycord_event)):
|
||||||
|
return
|
||||||
|
|
||||||
|
processed_media: List[Dict[str, Any]] = (
|
||||||
|
[] if media is None else await self.bot.process_attachments([media])
|
||||||
|
)
|
||||||
|
|
||||||
event_stage: PycordEventStage = await self.bot.create_event_stage(
|
event_stage: PycordEventStage = await self.bot.create_event_stage(
|
||||||
event=pycord_event,
|
event=pycord_event,
|
||||||
@@ -85,7 +93,7 @@ class Stage(Cog):
|
|||||||
creator_id=ctx.author.id,
|
creator_id=ctx.author.id,
|
||||||
question=question,
|
question=question,
|
||||||
answer=answer,
|
answer=answer,
|
||||||
media=[] if media is None else [media.id],
|
media=[] if media is None else processed_media,
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
@@ -140,7 +148,8 @@ class Stage(Cog):
|
|||||||
await ctx.respond("Event was not found.")
|
await ctx.respond("Event was not found.")
|
||||||
return
|
return
|
||||||
|
|
||||||
await validate_event_status(ctx, pycord_event)
|
if not (await validate_event_status(ctx, pycord_event)):
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
event_stage: PycordEventStage = await self.bot.find_event_stage(stage)
|
event_stage: PycordEventStage = await self.bot.find_event_stage(stage)
|
||||||
@@ -154,11 +163,15 @@ class Stage(Cog):
|
|||||||
await ctx.respond("Stage sequence out of range.")
|
await ctx.respond("Stage sequence out of range.")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
processed_media: List[Dict[str, Any]] = (
|
||||||
|
[] if media is None else await self.bot.process_attachments([media])
|
||||||
|
)
|
||||||
|
|
||||||
if not (question is None and answer is None and media is None and remove_media is False):
|
if not (question is None and answer is None and media is None and remove_media is False):
|
||||||
await event_stage.update(
|
await event_stage.update(
|
||||||
question=event_stage.question if question is None else question,
|
question=event_stage.question if question is None else question,
|
||||||
answer=event_stage.answer if answer is None else answer,
|
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]),
|
media=([] if remove_media else (event_stage.media if media is None else processed_media)),
|
||||||
)
|
)
|
||||||
|
|
||||||
if order is not None and order - 1 != event_stage.sequence:
|
if order is not None and order - 1 != event_stage.sequence:
|
||||||
@@ -207,7 +220,8 @@ class Stage(Cog):
|
|||||||
await ctx.respond("Event was not found.")
|
await ctx.respond("Event was not found.")
|
||||||
return
|
return
|
||||||
|
|
||||||
await validate_event_status(ctx, pycord_event)
|
if not (await validate_event_status(ctx, pycord_event)):
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
event_stage: PycordEventStage = await self.bot.find_event_stage(stage)
|
event_stage: PycordEventStage = await self.bot.find_event_stage(stage)
|
||||||
|
0
data/.gitkeep
Normal file
0
data/.gitkeep
Normal file
Reference in New Issue
Block a user