From d6b9b7ac2c0ab832e97431cbd74c23e0ac31c3b7 Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Sun, 16 Oct 2022 18:56:27 -0600 Subject: [PATCH] Add LTX commands, more to come --- jarvis/cogs/ltx.py | 263 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 jarvis/cogs/ltx.py diff --git a/jarvis/cogs/ltx.py b/jarvis/cogs/ltx.py new file mode 100644 index 0000000..4d5548a --- /dev/null +++ b/jarvis/cogs/ltx.py @@ -0,0 +1,263 @@ +"""JARVIS LTX commands for dbrand dishpits.""" +from typing import Dict, List + +from dateparser import parse +from dateparser_data.settings import default_parsers +from jarvis_core.db import q +from jarvis_core.db.models import Event +from naff import Client, Extension, InteractionContext +from naff.models.discord.embed import EmbedField +from naff.models.discord.user import Member +from naff.models.naff.application_commands import ( + OptionTypes, + SlashCommand, + slash_option, +) + +from jarvis.utils import build_embed + +dipshit_id = 552574845078994967 + + +class EventCog(Extension): + def __init__(self, bot: Client): + self.bot = bot + self.cache: Dict[int, List[str]] = {} + self.add_ext_check(self.is_dipshit) + + async def is_dipshit(self, ctx: InteractionContext) -> bool: + """Checks if author is bot owner.""" + return dipshit_id in ctx.author._role_ids + + ltx = SlashCommand(name="ltx", description="LTX Meetup management", scopes=[520021794380447745]) + + @ltx.subcommand(sub_cmd_name="register", sub_cmd_description="Register for LTX") + @slash_option(name="going", description="Are you going?", opt_type=OptionTypes.BOOLEAN) + async def _ltx_register(self, ctx: InteractionContext, going: bool) -> None: + event = await Event.find_one(q(user=ctx.author.id, event="ltx")) + if not event: + event = Event(user=ctx.author.id, going=going) + event.going = going + msg = "going" if going else "not going" + await ctx.send(f"Registration updated! You are now {msg}", ephemeral=True) + + @ltx.subcommand(sub_cmd_name="show", sub_cmd_description="Show registration info") + @slash_option( + name="user", description="User to show", opt_type=OptionTypes.USER, required=False + ) + async def _ltx_show(self, ctx: InteractionContext, user: Member) -> None: + user = user or ctx.author + event = await Event.find_one(q(user=user.id, event="ltx")) + if not event: + await ctx.send("That user hasn't registered", ephemeral=False) + return + + if not event.going: + await ctx.send("That user isn't going", ephemeral=False) + return + + fields = [] + + if event.travel_method == "flying": + before_flight = "N/A" + if event.before_flight: + dts = int(event.before_departure_time.timestamp()) + ats = int(event.before_arrival_time.timestamp()) + before_flight = f"🛫 {event.before_flight} 🛬\n -> " + + after_flight = "N/A" + if event.after_flight: + dts = int(event.after_departure_time.timestamp()) + ats = int(event.after_arrival_time.timestamp()) + after_flight = f"🛫 {event.after_flight} 🛬\n -> " + + fields += [ + EmbedField(name="Before LTX flight", value=before_flight), + EmbedField(name="After LTX flight", value=after_flight), + ] + + fields.append(EmbedField(name="Hotel", value=event.hotel or "N/A")) + + embed = build_embed(title="Your LTX Details", description=None, fields=fields) + embed.set_author(name=user.display_name, icon_url=user.display_avatar.url) + embed.set_footer(text="LTX Dates: July 29-30, 2023") + + await ctx.send(embeds=embed) + + @ltx.subcommand(sub_cmd_name="before_flight", sub_cmd_description="Update pre-LTX flight info") + @slash_option( + name="departure", description="Departure Time", opt_type=OptionTypes.STRING, required=True + ) + @slash_option( + name="arrival", description="Arrival Time", opt_type=OptionTypes.STRING, required=True + ) + @slash_option( + name="from_airport", + description="Departure Airport", + opt_type=OptionTypes.STRING, + required=True, + ) + @slash_option( + name="to_airport", description="Arrival Airport", opt_type=OptionTypes.STRING, required=True + ) + @slash_option( + name="flight", description="Flight Number", opt_type=OptionTypes.STRING, required=True + ) + async def _ltx_before_flight( + self, + ctx: InteractionContext, + departure: str, + arrival: str, + from_airport: str, + to_airport: str, + flight: str, + ) -> None: + event = await Event.find_one(q(user=ctx.author.id, event="ltx")) + if not event: + event = Event(user=ctx.author.id, event="ltx", going=True) + + base_settings = { + "PREFER_DATES_FROM": "future", + "TIMEZONE": "UTC", + "RETURN_AS_TIMEZONE_AWARE": True, + } + + rt_settings = base_settings.copy() + rt_settings["PARSERS"] = [ + x for x in default_parsers if x not in ["absolute-time", "timestamp"] + ] + + rt_depart_at = parse(departure, settings=rt_settings) + rt_arrive_at = parse(arrival, settings=rt_settings) + + at_settings = base_settings.copy() + at_settings["PARSERS"] = [x for x in default_parsers if x != "relative-time"] + + at_depart_at = parse(departure, settings=at_settings) + at_arrive_at = parse(arrival, settings=at_settings) + + if rt_depart_at: + departure = rt_depart_at + elif at_depart_at: + departure = at_depart_at + else: + await ctx.send("Invalid departure time", ephemeral=True) + return + + if rt_arrive_at: + arrival = rt_arrive_at + elif at_arrive_at: + arrival = at_arrive_at + else: + await ctx.send("Invalid arrival time", ephemeral=True) + return + + event.before_arrival_time = arrival + event.before_departure_time = departure + event.before_flight = f"{from_airport} -> {to_airport} {flight}" + + dts = int(departure.timestamp()) + ats = int(arrival.timestamp()) + + fields = ( + EmbedField(name="Departure", value=f" ()"), + EmbedField(name="Arrival", value=f" ()"), + ) + + embed = build_embed( + title="Your Pre-LTX Flight Information", + description=f"🛫 {from_airport} -> {to_airport} 🛬", + fields=fields, + ) + embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.display_avatar.url) + + await ctx.send(embeds=embed) + + @ltx.subcommand(sub_cmd_name="after_flight", sub_cmd_description="Update post-LTX flight info") + @slash_option( + name="departure", description="Departure Time", opt_type=OptionTypes.STRING, required=True + ) + @slash_option( + name="arrival", description="Arrival Time", opt_type=OptionTypes.STRING, required=True + ) + @slash_option( + name="from_airport", + description="Departure Airport", + opt_type=OptionTypes.STRING, + required=True, + ) + @slash_option( + name="to_airport", description="Arrival Airport", opt_type=OptionTypes.STRING, required=True + ) + @slash_option( + name="flight", description="Flight Number", opt_type=OptionTypes.STRING, required=True + ) + async def _ltx_after_flight( + self, + ctx: InteractionContext, + departure: str, + arrival: str, + from_airport: str, + to_airport: str, + flight: str, + ) -> None: + event = await Event.find_one(q(user=ctx.author.id, event="ltx")) + if not event: + event = Event(user=ctx.author.id, event="ltx", going=True) + + base_settings = { + "PREFER_DATES_FROM": "future", + "TIMEZONE": "UTC", + "RETURN_AS_TIMEZONE_AWARE": True, + } + + rt_settings = base_settings.copy() + rt_settings["PARSERS"] = [ + x for x in default_parsers if x not in ["absolute-time", "timestamp"] + ] + + rt_depart_at = parse(departure, settings=rt_settings) + rt_arrive_at = parse(arrival, settings=rt_settings) + + at_settings = base_settings.copy() + at_settings["PARSERS"] = [x for x in default_parsers if x != "relative-time"] + + at_depart_at = parse(departure, settings=at_settings) + at_arrive_at = parse(arrival, settings=at_settings) + + if rt_depart_at: + departure = rt_depart_at + elif at_depart_at: + departure = at_depart_at + else: + await ctx.send("Invalid departure time", ephemeral=True) + return + + if rt_arrive_at: + arrival = rt_arrive_at + elif at_arrive_at: + arrival = at_arrive_at + else: + await ctx.send("Invalid arrival time", ephemeral=True) + return + + event.after_arrival_time = arrival + event.after_departure_time = departure + event.after_flight = f"{from_airport} -> {to_airport} {flight}" + + dts = int(departure.timestamp()) + ats = int(arrival.timestamp()) + + fields = ( + EmbedField(name="Departure", value=f" ()"), + EmbedField(name="Arrival", value=f" ()"), + ) + + embed = build_embed( + title="Your Post-LTX Flight Information", + description=f"🛫 {from_airport} -> {to_airport} 🛬", + fields=fields, + ) + embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.display_avatar.url) + + await ctx.send(embeds=embed)