From e2959c27ad6a84170100462f640fbfcba7e0b694 Mon Sep 17 00:00:00 2001 From: stijndcl Date: Sat, 13 Aug 2022 00:41:47 +0200 Subject: [PATCH] Adding new deadlines --- database/crud/deadlines.py | 13 ++++++-- didier/cogs/owner.py | 21 ++++++++++--- didier/data/embeds/deadlines.py | 1 + didier/views/modals/__init__.py | 3 +- didier/views/modals/custom_commands.py | 2 +- didier/views/modals/deadlines.py | 43 ++++++++++++++++++++++++++ 6 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 didier/views/modals/deadlines.py diff --git a/database/crud/deadlines.py b/database/crud/deadlines.py index 338a4c3..8a7ad66 100644 --- a/database/crud/deadlines.py +++ b/database/crud/deadlines.py @@ -1,3 +1,4 @@ +from typing import Optional from zoneinfo import ZoneInfo from dateutil.parser import parse @@ -5,7 +6,7 @@ from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload -from database.schemas.relational import Deadline +from database.schemas.relational import Deadline, UforaCourse __all__ = ["add_deadline", "get_deadlines"] @@ -14,6 +15,7 @@ async def add_deadline(session: AsyncSession, course_id: int, name: str, date_st """Add a new deadline""" date_dt = parse(date_str).replace(tzinfo=ZoneInfo("Europe/Brussels")) + # If we only have a day, assume it's the end of the day if date_dt.hour == date_dt.minute == date_dt.second == 0: date_dt.replace(hour=23, minute=59, second=59) @@ -22,10 +24,15 @@ async def add_deadline(session: AsyncSession, course_id: int, name: str, date_st await session.commit() -async def get_deadlines(session: AsyncSession) -> list[Deadline]: +async def get_deadlines(session: AsyncSession, *, course: Optional[UforaCourse] = None) -> list[Deadline]: """Get a list of all deadlines that are currently known This includes deadlines that have passed already """ - statement = select(Deadline).options(selectinload(Deadline.course)) + statement = select(Deadline) + + if course is not None: + statement = statement.where(Deadline.course_id == course.course_id) + + statement = statement.options(selectinload(Deadline.course)) return (await session.execute(statement)).scalars().all() diff --git a/didier/cogs/owner.py b/didier/cogs/owner.py index badd0c2..69560ca 100644 --- a/didier/cogs/owner.py +++ b/didier/cogs/owner.py @@ -5,13 +5,14 @@ from discord import app_commands from discord.ext import commands import settings -from database.crud import custom_commands, links +from database.crud import custom_commands, links, ufora_courses from database.exceptions.constraints import DuplicateInsertException from database.exceptions.not_found import NoResultFoundException from didier import Didier from didier.utils.discord.flags.owner import EditCustomFlags, SyncOptionFlags from didier.views.modals import ( AddDadJoke, + AddDeadline, AddLink, CreateCustomCommand, EditCustomCommand, @@ -137,6 +138,18 @@ class Owner(commands.Cog): modal = AddDadJoke(self.client) await interaction.response.send_modal(modal) + @add_slash.command(name="deadline", description="Add a deadline") + async def add_deadline_slash(self, interaction: discord.Interaction, course: str): + """Slash command to add a deadline""" + async with self.client.postgres_session as session: + course_instance = await ufora_courses.get_course_by_name(session, course) + + if course_instance is None: + return await interaction.response.send_message(f"No course found matching `{course}`.", ephemeral=True) + + modal = AddDeadline(self.client, course_instance) + await interaction.response.send_modal(modal) + @add_slash.command(name="link", description="Add a new link") async def add_link_slash(self, interaction: discord.Interaction): """Slash command to add new links""" @@ -166,15 +179,13 @@ class Owner(commands.Cog): async def edit_custom_slash(self, interaction: discord.Interaction, command: str): """Slash command to edit a custom command""" if not await self.client.is_owner(interaction.user): - return interaction.response.send_message( - "Je hebt geen toestemming om dit commando uit te voeren.", ephemeral=True - ) + return interaction.response.send_message("You don't have permission to run this command.", ephemeral=True) async with self.client.postgres_session as session: _command = await custom_commands.get_command(session, command) if _command is None: return await interaction.response.send_message( - f"Geen commando gevonden voor ``{command}``.", ephemeral=True + f"No command found matching `{command}`.", ephemeral=True ) modal = EditCustomCommand(self.client, _command.name, _command.response) diff --git a/didier/data/embeds/deadlines.py b/didier/data/embeds/deadlines.py index 0c07c40..244d811 100644 --- a/didier/data/embeds/deadlines.py +++ b/didier/data/embeds/deadlines.py @@ -46,6 +46,7 @@ class Deadlines(EmbedBaseModel): # Strike through deadlines that aren't active anymore deadlines_grouped[year].append(deadline_str if not passed else f"~~{deadline_str}~~") + # Send an easter egg when there are no deadlines if not has_active_deadlines: embed.description = "There are currently no upcoming deadlines." embed.set_image(url="https://c.tenor.com/RUzJ3lDGQUsAAAAC/iron-man-you-can-rest-now.gif") diff --git a/didier/views/modals/__init__.py b/didier/views/modals/__init__.py index 8a64d4d..42c2ce8 100644 --- a/didier/views/modals/__init__.py +++ b/didier/views/modals/__init__.py @@ -1,5 +1,6 @@ from .custom_commands import CreateCustomCommand, EditCustomCommand from .dad_jokes import AddDadJoke +from .deadlines import AddDeadline from .links import AddLink -__all__ = ["AddDadJoke", "CreateCustomCommand", "EditCustomCommand", "AddLink"] +__all__ = ["AddDadJoke", "AddDeadline", "CreateCustomCommand", "EditCustomCommand", "AddLink"] diff --git a/didier/views/modals/custom_commands.py b/didier/views/modals/custom_commands.py index 2116bd9..738e74a 100644 --- a/didier/views/modals/custom_commands.py +++ b/didier/views/modals/custom_commands.py @@ -71,7 +71,7 @@ class EditCustomCommand(discord.ui.Modal, title="Edit Custom Command"): async with self.client.postgres_session as session: await edit_command(session, self.original_name, name_field.value, response_field.value) - await interaction.response.send_message(f"Successfully edited ``{self.original_name}``.", ephemeral=True) + await interaction.response.send_message(f"Successfully edited `{self.original_name}`.", ephemeral=True) @overrides async def on_error(self, interaction: discord.Interaction, error: Exception): # type: ignore diff --git a/didier/views/modals/deadlines.py b/didier/views/modals/deadlines.py new file mode 100644 index 0000000..bd8882b --- /dev/null +++ b/didier/views/modals/deadlines.py @@ -0,0 +1,43 @@ +import traceback + +import discord.ui +from discord import Interaction +from overrides import overrides + +from database.crud.deadlines import add_deadline +from database.schemas.relational import UforaCourse + +__all__ = ["AddDeadline"] + +from didier import Didier + + +class AddDeadline(discord.ui.Modal, title="Add Deadline"): + """Modal to add a new deadline""" + + client: Didier + ufora_course: UforaCourse + + name: discord.ui.TextInput = discord.ui.TextInput( + label="Name", placeholder="Project 9001", required=True, style=discord.TextStyle.short + ) + deadline: discord.ui.TextInput = discord.ui.TextInput( + label="Deadline", placeholder="DD/MM/YYYY HH:MM:SS*", required=True, style=discord.TextStyle.short + ) + + def __init__(self, client: Didier, ufora_course: UforaCourse, *args, **kwargs): + super().__init__(*args, **kwargs) + self.client = client + self.ufora_course = ufora_course + + @overrides + async def on_submit(self, interaction: Interaction): + async with self.client.postgres_session as session: + await add_deadline(session, self.ufora_course.course_id, self.name.value, self.deadline.value) + + await interaction.response.send_message("Successfully added new deadline.", ephemeral=True) + + @overrides + async def on_error(self, interaction: Interaction, error: Exception): # type: ignore + await interaction.response.send_message("Something went wrong.", ephemeral=True) + traceback.print_tb(error.__traceback__)