diff --git a/worldtimezone/__main__.py b/worldtimezone/__main__.py index 44473c5..10773ec 100644 --- a/worldtimezone/__main__.py +++ b/worldtimezone/__main__.py @@ -3,6 +3,7 @@ import hikari import lightbulb +import miru from hikari import Intents from lightbulb.ext import tasks @@ -19,6 +20,7 @@ banner=None, ) tasks.load(bot) +bot.d.miru = miru.Client(bot) @bot.listen(hikari.StartingEvent) diff --git a/worldtimezone/extensions/calendar.py b/worldtimezone/extensions/calendar.py index f18d2de..92acf7d 100644 --- a/worldtimezone/extensions/calendar.py +++ b/worldtimezone/extensions/calendar.py @@ -1,9 +1,11 @@ import datetime +from typing import override +import dateparser import lightbulb +import miru import pytz -from extensions import calendar_data -from extensions import world_clock_data +from extensions import calendar_data, world_clock_data plugin = lightbulb.Plugin("Calendar") @@ -50,7 +52,7 @@ "add_complex", description="create a new event (the hard way)", pass_options=True ) @lightbulb.implements(lightbulb.SlashCommand) -async def addIt( +async def add_complexIt( ctx: lightbulb.SlashContext, title: str, start_hour: int, @@ -174,7 +176,7 @@ async def addIt( _ = await ctx.respond(f"Event `{title}` created") -@addIt.autocomplete("timezone") +@add_complexIt.autocomplete("timezone") async def addIt_autocomplete_timezone( opt, # pyright: ignore[reportUnknownParameterType, reportMissingParameterType] inter, # pyright: ignore[reportUnknownParameterType, reportMissingParameterType, reportUnusedParameter] @@ -184,6 +186,143 @@ async def addIt_autocomplete_timezone( ) +class AddEventModal(miru.Modal, title="Add Event"): + e_title = miru.TextInput(label="Title", placeholder="Event Name", required=True) + e_start = miru.TextInput( + label="Start", placeholder="20 september, 10:00", required=True + ) + e_end = miru.TextInput(label="End", placeholder="2024-09-20 11:00", required=True) + e_reminder = miru.TextInput( + label="Reminder", placeholder="2024-09-20 09:50:00", required=False + ) + e_reminder_number = miru.TextInput( + label="Number of Reminder", value="1", required=True + ) + e_reminder_interval = miru.TextInput( + label="Minute(s) Interval between Reminders", value="5", required=True + ) + e_timezone = miru.TextInput( + label="Timezone", placeholder="(your timezone by default)", required=False + ) + + @override + async def callback(self, ctx: miru.ModalContext) -> None: + wcd = ( # pyright: ignore[reportUnknownVariableType, reportUnknownMemberType] + ctx.client.app.d.world_clock_data # pyright: ignore[reportAttributeAccessIssue, reportUnknownMemberType] + ) + assert isinstance(wcd, world_clock_data.WorldClockData) + assert ctx.guild_id is not None + user_info = wcd.get_member(ctx.guild_id, ctx.user.id) + if self.e_timezone.value is None and (user_info is None or user_info.tz == ""): + _ = await ctx.respond("Please set your timezone first") + return + now = datetime.datetime.now() + if self.e_timezone.value is None: + assert user_info is not None + now = pytz.timezone( + user_info.tz # pyright: ignore[reportArgumentType] + ).localize(now) + else: + now = pytz.timezone(self.e_timezone.value).localize(now) + + assert self.e_start.value is not None # Field Required + start_date = dateparser.parse(self.e_start.value) + if start_date is None: + _ = await ctx.respond(f"Can't parse {self.e_start.value} to a date") + return + if self.e_timezone.value is None: + assert user_info is not None + start_date = pytz.timezone( + user_info.tz # pyright: ignore[reportArgumentType] + ).localize(start_date) + else: + start_date = pytz.timezone(self.e_timezone.value).localize(start_date) + + assert self.e_end.value is not None # Field Required + end_date = dateparser.parse(self.e_end.value) + if end_date is None: + _ = await ctx.respond(f"Can't parse {self.e_end.value} to a date") + return + if self.e_timezone.value is None: + assert user_info is not None + end_date = pytz.timezone( + user_info.tz # pyright: ignore[reportArgumentType] + ).localize(end_date) + else: + end_date = pytz.timezone(self.e_timezone.value).localize(end_date) + + if self.e_reminder.value is None: + reminder_date = start_date - datetime.timedelta(hours=1) + else: + reminder_date = dateparser.parse(self.e_reminder.value) + if reminder_date is None: + _ = await ctx.respond(f"Can't parse {self.e_reminder.value} to a date") + return + if self.e_timezone.value is None: + assert user_info is not None + reminder_date = pytz.timezone( + user_info.tz # pyright: ignore[reportArgumentType] + ).localize(reminder_date) + else: + reminder_date = pytz.timezone(self.e_timezone.value).localize( + reminder_date + ) + + reminder_number = 0 + try: + assert self.e_reminder_number.value is not None # Field required + reminder_number = int(self.e_reminder_number.value) + except ValueError: + _ = await ctx.respond( + f"Can't parse {self.e_reminder_number.value} to number" + ) + return + if reminder_number == 0: + reminder_date = None + + reminder_interval = 0 + try: + assert self.e_reminder_interval.value is not None # Field required + reminder_interval = int(self.e_reminder_interval.value) + except ValueError: + _ = await ctx.respond( + f"Can't parse {self.e_reminder_interval.value} to number" + ) + return + + cd = ( # pyright: ignore [reportUnknownMemberType, reportUnknownVariableType] + ctx.client.app.d.calendar_data # pyright: ignore[reportAttributeAccessIssue, reportUnknownMemberType] + ) + assert isinstance(cd, calendar_data.CalendarData) + user = cd.get_user(ctx.user.id) + if user is None: + user = cd.create_user(ctx.user.id) + assert self.e_title.value is not None # Field required + cd.create_event( + user, + self.e_title.value, + start_date, + end_date, + reminder_date, + reminder_number, + reminder_interval, + ) + _ = await ctx.respond(f"Event `{self.e_title.value}` created") + + +@lightbulb.add_checks(lightbulb.human_only) +@plugin.command +@lightbulb.command("add", description="create an event with a nice UI") +@lightbulb.implements(lightbulb.SlashCommand) +async def addIt(ctx: lightbulb.SlashContext) -> None: + modal = AddEventModal() + miru_client = ctx.bot.d.miru # pyright: ignore[reportAny] + assert isinstance(miru_client, miru.Client) + builder = modal.build_response(miru_client) + await builder.create_modal_response(ctx.interaction) + miru_client.start_modal(modal) + + def load(bot: lightbulb.BotApp): bot.d.calendar_data = calendar_data.CalendarData() bot.load_extensions("extensions.calendar_tasks") diff --git a/worldtimezone/extensions/calendar_data.py b/worldtimezone/extensions/calendar_data.py index d9a78ef..6a8047a 100644 --- a/worldtimezone/extensions/calendar_data.py +++ b/worldtimezone/extensions/calendar_data.py @@ -10,7 +10,6 @@ class TimestampField(peewee.DateTimeField): - field_type = "TEXT" @override diff --git a/worldtimezone/extensions/calendar_tasks.py b/worldtimezone/extensions/calendar_tasks.py index 5912ca4..1c9f521 100644 --- a/worldtimezone/extensions/calendar_tasks.py +++ b/worldtimezone/extensions/calendar_tasks.py @@ -1,7 +1,7 @@ import hikari import lightbulb -from lightbulb.ext import tasks from extensions import calendar_data +from lightbulb.ext import tasks @tasks.task(m=1, auto_start=True, pass_app=True) diff --git a/worldtimezone/extensions/world_clock_tasks.py b/worldtimezone/extensions/world_clock_tasks.py index 5e529b0..0ddcf8e 100644 --- a/worldtimezone/extensions/world_clock_tasks.py +++ b/worldtimezone/extensions/world_clock_tasks.py @@ -3,9 +3,8 @@ import hikari import lightbulb import pytz -from lightbulb.ext import tasks - from extensions import world_clock_data +from lightbulb.ext import tasks @tasks.task(m=5, auto_start=True, pass_app=True)