From f1f8bf1a85132290b1afd05465a826abeeab965b Mon Sep 17 00:00:00 2001 From: dnns01 <git@dnns01.de> Date: Mon, 16 Sep 2024 23:47:34 +0200 Subject: [PATCH] Improvements to appointments No appointments in the past, no appointments with negative reminder or recurring and if an appointment was due, but no reminder has been sent yet, the reminder is skipped and the final notification is sent instead. --- extensions/appointments.py | 24 ++++++++++++++++++------ models.py | 21 +++++++++++++++------ views/appointment_view.py | 4 ++-- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/extensions/appointments.py b/extensions/appointments.py index c3d5824..1b6bcae 100644 --- a/extensions/appointments.py +++ b/extensions/appointments.py @@ -31,11 +31,8 @@ class Appointments(commands.GroupCog, name="appointments", description="Handle A async def timer(self): for appointment in Appointment.select().order_by(Appointment.channel): now = datetime.now() - date_time = appointment.date_time - remind_at = date_time - timedelta( - minutes=appointment.reminder) if not appointment.reminder_sent else date_time - if now >= remind_at: + if now >= appointment.remind_at(): try: channel = await self.bot.fetch_channel(appointment.channel) message = await channel.fetch_message(appointment.message) @@ -71,14 +68,29 @@ class Appointments(commands.GroupCog, name="appointments", description="Handle A description="Detailliertere Beschreibung, was gemacht werden soll.", recurring="In welchem Intervall (in Tagen) soll der Termin wiederholt werden?") async def cmd_add_appointment(self, interaction: Interaction, date: str, time: str, reminder: int, title: str, - description: str = "", recurring: int = 0): + description: str = "", recurring: int = 0) -> None: """ Add an appointment to a channel """ channel = interaction.channel author_id = interaction.user.id try: date_time = datetime.strptime(f"{date} {time}", self.bot.dt_format()) + if date_time <= datetime.now(): + await interaction.response.send_message("Fehler! Der Termin muss in der Zukunft liegen.", + ephemeral=True) + return + elif reminder < 0: + await interaction.response.send_message("Fehler! Du kannst keinen negativen Wert für die Benachrichtigung angeben.", + ephemeral=True) + return + elif recurring < 0: + await interaction.response.send_message("Fehler! Du kannst keinen negativen Wert für die Wiederholung deines Termins angeben.", + ephemeral=True) + return + except ValueError: - await interaction.response.send_message("Fehler! Ungültiges Datum und/oder Zeit.\nBitte gib ein gültiges Datum im Format TT.MM.JJJJ und eine gültige Uhrzeit im Format HH:MM an.", ephemeral=True) + await interaction.response.send_message( + "Fehler! Ungültiges Datum und/oder Zeit.\nBitte gib ein gültiges Datum im Format TT.MM.JJJJ und eine gültige Uhrzeit im Format HH:MM an.", + ephemeral=True) return appointment = Appointment.create(channel=channel.id, message=0, date_time=date_time, reminder=reminder, diff --git a/models.py b/models.py index 13649db..7e4ec05 100644 --- a/models.py +++ b/models.py @@ -1,6 +1,6 @@ -import datetime import io import uuid +from datetime import timedelta, datetime import discord from discord import Colour @@ -131,11 +131,10 @@ class Appointment(BaseModel): def get_embed(self, state: int) -> discord.Embed: attendees = self.attendees - description = (f"Wenn du eine Benachrichtigung zum Beginn des Termins" - f"{f', sowie {self.reminder} Minuten vorher, ' if self.reminder > 0 else f' '}" - f"erhalten möchtest, verwende den \"Zusagen\" Button unter dieser Nachricht. " - f"Hast du bereits zugesagt und möchtest aber doch keine Benachrichtigung erhalten, " - f"kannst du den \"Absagen\" Button benutzen.") if state != 2 else "" + description = (f"- Durch Klicken auf Anmelden erhältst du eine Benachrichtigung zum Beginn des Termins" + f"{f', sowie {self.reminder} Minuten vorher' if self.reminder > 0 else f''}.\n" + f"- Durch Klicken auf Abmelden nimmst du deine vorherige Abmeldung wieder zurück und wirst " + f"nicht benachrichtigt.") if state != 2 else "" emoji = "📅" if state == 0 else ("📣" if state == 1 else "✅") embed = discord.Embed(title=f"{emoji} {self.title} {'findet jetzt statt.' if state == 2 else ''}", description=description) @@ -156,6 +155,16 @@ class Appointment(BaseModel): return embed + def remind_at(self) -> datetime: + if self.reminder_sent: + return self.date_time + elif datetime.now() >= self.date_time: + Appointment.update(reminder_sent=True).where(Appointment.id == self.id).execute() + self.reminder_sent = True + return self.date_time + else: + return self.date_time - timedelta(minutes=self.reminder) + def get_start_time(self, state) -> str: if state == 0: return f"<t:{int(self.date_time.timestamp())}:F>" diff --git a/views/appointment_view.py b/views/appointment_view.py index f571359..e1a1a0f 100644 --- a/views/appointment_view.py +++ b/views/appointment_view.py @@ -8,7 +8,7 @@ class AppointmentView(discord.ui.View): def __init__(self): super().__init__(timeout=None) - @discord.ui.button(label='Zusagen', style=discord.ButtonStyle.green, custom_id='appointment_view:accept', emoji="👍") + @discord.ui.button(label='Anmelden', style=discord.ButtonStyle.green, custom_id='appointment_view:accept', emoji="👍") async def accept(self, interaction: discord.Interaction, button: discord.ui.Button): if appointment := Appointment.get_or_none(Appointment.message == interaction.message.id): attendee = appointment.attendees.filter(member_id=interaction.user.id) @@ -22,7 +22,7 @@ class AppointmentView(discord.ui.View): await interaction.response.defer(thinking=False) - @discord.ui.button(label='Absagen', style=discord.ButtonStyle.red, custom_id='appointment_view:decline', emoji="👎") + @discord.ui.button(label='Abmelden', style=discord.ButtonStyle.red, custom_id='appointment_view:decline', emoji="👎") async def decline(self, interaction: discord.Interaction, button: discord.ui.Button): if appointment := Appointment.get_or_none(Appointment.message == interaction.message.id): attendee = appointment.attendees.filter(member_id=interaction.user.id) -- GitLab