From a2f179ae3504e80b39f9a9e1ba951a15a3bd7006 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 00:21:26 -0400 Subject: [PATCH 01/24] Add private option to /book --- ext/libcal.py | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/ext/libcal.py b/ext/libcal.py index 6d9b8c2..97a6497 100644 --- a/ext/libcal.py +++ b/ext/libcal.py @@ -15,17 +15,19 @@ from lib.ocr import get_room_data, NoMatchException plugin = lightbulb.Plugin("LibCal") config = load_config() + def add_rooms_to_embed(room_list: list[Room], embed: hikari.Embed): for room in room_list: embed.add_field(room.get_time_str(), room.number) + class BookingConfirmationView(miru.View): - def __init__(self, *, timeout: Optional[float] = 120, autodefer: bool = True, room_list: list[Room] = [], image: Resource | None = None) -> None: + def __init__(self, *, timeout: Optional[float] = 120, autodefer: bool = True, + room_list: list[Room] = [], image: Resource | None = None, private: bool = False + ) -> None: self.room_list = room_list - if image is not None: - self.image = image - else: - self.image = None + self.image = image + self.private = private super().__init__(timeout=timeout, autodefer=autodefer) @miru.button(label="Yes", style=hikari.ButtonStyle.SUCCESS) @@ -33,25 +35,31 @@ class BookingConfirmationView(miru.View): gcal = GoogleCalendarAPI() for room in self.room_list: await gcal.create_event(room.number, room.start_time, room.end_time) - embed = hikari.Embed(title="Rooms Booked!") - add_rooms_to_embed(self.room_list, embed) - await ctx.edit_response(embed=embed, components=[]) + embed = hikari.Embed(title="Rooms Booked!") + add_rooms_to_embed(self.room_list, embed) + await ctx.edit_response(embed=embed, components=[]) - thread_embed = hikari.Embed(title="Rooms were booked!") - thread_embed.set_author(name=ctx.user.username, icon=ctx.user.avatar_url) + thread_embed = hikari.Embed(title="Rooms were booked!") + thread_embed.set_author( + name=ctx.user.username, icon=ctx.user.avatar_url) + if not self.private: thread_embed.set_image(self.image) - add_rooms_to_embed(self.room_list, thread_embed) - await ctx.app.rest.create_message(config.discord_study_room_thread, embed=thread_embed) + add_rooms_to_embed(self.room_list, thread_embed) + await ctx.app.rest.create_message(config.discord_study_room_thread, embed=thread_embed) self.stop() @miru.button(label="No", style=hikari.ButtonStyle.DANGER) async def cancel_button(self, button: miru.Button, ctx: miru.Context) -> None: embed = hikari.Embed(title="Aborted!") + add_rooms_to_embed(self.room_list, embed) + embed.set_image(self.image) await ctx.edit_response(embed=embed, components=[]) self.stop() + @plugin.command @lightbulb.option("img", "image to check for events", type=hikari.Attachment, required=True) +@lightbulb.option("private", "if private, the bot will not share confirmation e-mails.", type=bool, default=False) @lightbulb.command("book", "add room bookings to Google Calendar", ephemeral=True) @lightbulb.implements(lightbulb.SlashCommand) async def book(ctx: lightbulb.Context) -> None: @@ -70,7 +78,8 @@ async def book(ctx: lightbulb.Context) -> None: async def book_error_handler(event: lightbulb.CommandErrorEvent): print("ERROR TYPE:", type(event.exception)) if isinstance(event.exception.__cause__, NoMatchException): - embed = hikari.Embed(title="Huh, I can't read that", description="Could you try another picture?") + embed = hikari.Embed(title="Huh, I can't read that", + description="Could you try another picture?") await event.context.respond(embed=embed) else: embed = hikari.Embed( From 7307aafaff2b26f20e7fa9223ef5758b84c94166 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 00:41:06 -0400 Subject: [PATCH 02/24] Add branch command --- ext/system.py | 73 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/ext/system.py b/ext/system.py index 1723e58..ff6cc0e 100644 --- a/ext/system.py +++ b/ext/system.py @@ -9,32 +9,39 @@ config = load_config() plugin = lightbulb.Plugin("SystemPlugin") + async def create_subprocess(*args): proc = await asyncio.create_subprocess_exec(*args, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE - ) + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) stdout, _ = await proc.communicate() return stdout.decode("utf-8").strip() + async def get_git_latest_commit_id(): return await create_subprocess("git", "rev-parse", "--short", "HEAD") + async def get_git_branch(): return await create_subprocess("git", "rev-parse", "--abbrev-ref", "HEAD") + async def get_git_remote(): remote = await create_subprocess("git", "branch", "-vv") return remote.split("[")[1].split("]")[0] + async def get_git_head_diff_branch(branch: str) -> str: # diff HEAD to remote return await create_subprocess("git", "diff", "head", branch) + async def get_git_index_diff_branch(branch: str) -> str: # diff index to remote return await create_subprocess("git", "diff", branch) + async def get_git_commits_ahead_behind(branch: str, remote: str) -> tuple[int, int]: # commits ahead/behind remote output = await create_subprocess("git", "rev-list", "--left-right", "--count", branch+"..."+remote) @@ -42,24 +49,30 @@ async def get_git_commits_ahead_behind(branch: str, remote: str) -> tuple[int, i commits_behind = int(output.split()[1]) return commits_ahead, commits_behind + async def get_git_dev(remote: str, branch: str) -> bool: # dev environment tests - if await get_git_head_diff_branch(remote) != "": # difference between HEAD and remote + # difference between HEAD and remote + if await get_git_head_diff_branch(remote) != "": return True elif config.git_branch != branch: # branch has been changed return True - elif await get_git_index_diff_branch(remote) != "": # difference between index and remote + # difference between index and remote + elif await get_git_index_diff_branch(remote) != "": return True - elif (await get_git_commits_ahead_behind(branch, remote))[0] > 0: # ahead in commits + # ahead in commits + elif (await get_git_commits_ahead_behind(branch, remote))[0] > 0: return True return False + async def get_git_update(dev_status: bool, branch, remote) -> bool: commits_behind, _ = await get_git_commits_ahead_behind(branch, remote) if not dev_status and commits_behind > 0: return True return False + async def get_git_status() -> dict: output = {} output["commit_id"] = await get_git_latest_commit_id() @@ -69,15 +82,17 @@ async def get_git_status() -> dict: output['update'] = await get_git_update(output['dev'], output['branch'], output['remote']) return output + @plugin.command @lightbulb.command("ping", "pong!", ephemeral=True) @lightbulb.implements(lightbulb.SlashCommand) async def ping(ctx: lightbulb.Context) -> None: embed = hikari.Embed(title="Pong!", - description=f"latency: {round(ctx.bot.heartbeat_latency * 1000, ndigits=2)}ms" - ) + description=f"latency: {round(ctx.bot.heartbeat_latency * 1000, ndigits=2)}ms" + ) await ctx.respond(embed) + @plugin.command @lightbulb.add_checks(lightbulb.owner_only) @lightbulb.command("update", "update the bot!", ephemeral=True) @@ -86,11 +101,46 @@ async def update(ctx: lightbulb.Context) -> None: if (await get_git_status())['dev'] is False: await create_subprocess("git", "pull") embed = hikari.Embed(title="Restarting", - description="Restarting to load an update!" - ) + description="Restarting to load an update!" + ) await ctx.respond(embed) await ctx.bot.close() + +@plugin.command +@lightbulb.add_checks(lightbulb.owner_only) +@lightbulb.command("branch", "get or set the working branch the bot uses.", ephemeral=True) +@lightbulb.implements(lightbulb.SlashCommandGroup) +async def branch(ctx: lightbulb.Context) -> None: + output = await create_subprocess("git", "rev-parse", "--symbolic-full-name", "--abbrev-ref", "HEAD") + embed = hikari.Embed(title="Current Branch", + description=f"Currently on branch '{output}'") + await ctx.respond(embed=embed) + + +@branch.child +@lightbulb.option("name", "name of the branch", type=str, required=True) +@lightbulb.command("switch", "switch branches") +@lightbulb.implements(lightbulb.SlashCommand) +async def switch(ctx: lightbulb.Context) -> None: + embed = hikari.Embed(title="Restarting", + description="Restarting to switch branches!" + ) + output = await create_subprocess("git", "switch", ctx.options.branch) + if "invalid reference" in output: # parsing output allows us more specificity. + embed.title = "Branch does not exist." + embed.description = "Please check your spelling." + await ctx.respond(embed) + return + elif "Already on" in output: + embed.title = f"Already on branch '{ctx.options.branch}'" + embed.description = "Just double checking, I presume?" + await ctx.respond(embed) + return + await ctx.respond(embed) + await ctx.bot.close() + + @plugin.command @lightbulb.command("info", "get bot information such as the version, and repository link.", ephemeral=True) @lightbulb.implements(lightbulb.SlashCommand) @@ -101,12 +151,13 @@ async def info(ctx: lightbulb.Context) -> None: embed.add_field("Version", git_status['commit_id'], inline=True) embed.add_field("Branch", git_status['branch'], inline=True) embed.add_field("Remote", git_status['remote'], inline=True) - embed.add_field("In Dev-Env?", git_status['dev']) embed.add_field("Needs Update?", git_status['update']) await ctx.respond(embed) + def load(bot: lightbulb.BotApp): bot.add_plugin(plugin) + def unload(bot: lightbulb.BotApp): bot.remove_plugin(plugin) From e31f066fd26d4eb7921f71222b5fc4d115ac61ad Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 00:51:31 -0400 Subject: [PATCH 03/24] fix branch subgroup --- ext/system.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/system.py b/ext/system.py index ff6cc0e..5932f6c 100644 --- a/ext/system.py +++ b/ext/system.py @@ -121,7 +121,7 @@ async def branch(ctx: lightbulb.Context) -> None: @branch.child @lightbulb.option("name", "name of the branch", type=str, required=True) @lightbulb.command("switch", "switch branches") -@lightbulb.implements(lightbulb.SlashCommand) +@lightbulb.implements(lightbulb.SlashSubGroup) async def switch(ctx: lightbulb.Context) -> None: embed = hikari.Embed(title="Restarting", description="Restarting to switch branches!" From 05424d7949091e340ab2374e1556a4b269599745 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 00:57:18 -0400 Subject: [PATCH 04/24] fix subcommand --- ext/system.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ext/system.py b/ext/system.py index 5932f6c..5fd354b 100644 --- a/ext/system.py +++ b/ext/system.py @@ -112,6 +112,13 @@ async def update(ctx: lightbulb.Context) -> None: @lightbulb.command("branch", "get or set the working branch the bot uses.", ephemeral=True) @lightbulb.implements(lightbulb.SlashCommandGroup) async def branch(ctx: lightbulb.Context) -> None: + pass + + +@branch.child +@lightbulb.command("get", "get the current branch") +@lightbulb.implements(lightbulb.SlashSubCommand) +async def branch_get(ctx: lightbulb.Context) -> None: output = await create_subprocess("git", "rev-parse", "--symbolic-full-name", "--abbrev-ref", "HEAD") embed = hikari.Embed(title="Current Branch", description=f"Currently on branch '{output}'") @@ -121,8 +128,8 @@ async def branch(ctx: lightbulb.Context) -> None: @branch.child @lightbulb.option("name", "name of the branch", type=str, required=True) @lightbulb.command("switch", "switch branches") -@lightbulb.implements(lightbulb.SlashSubGroup) -async def switch(ctx: lightbulb.Context) -> None: +@lightbulb.implements(lightbulb.SlashSubCommand) +async def branch_switch(ctx: lightbulb.Context) -> None: embed = hikari.Embed(title="Restarting", description="Restarting to switch branches!" ) From 33a1103f94cd6fbcee3ceed2e6014a844f83be1f Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 01:00:11 -0400 Subject: [PATCH 05/24] make branch commands ephemeral --- ext/system.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ext/system.py b/ext/system.py index 5fd354b..98f3325 100644 --- a/ext/system.py +++ b/ext/system.py @@ -109,14 +109,15 @@ async def update(ctx: lightbulb.Context) -> None: @plugin.command @lightbulb.add_checks(lightbulb.owner_only) -@lightbulb.command("branch", "get or set the working branch the bot uses.", ephemeral=True) +@lightbulb.command("branch", "get or set the working branch the bot uses.") @lightbulb.implements(lightbulb.SlashCommandGroup) async def branch(ctx: lightbulb.Context) -> None: - pass + pass # SlashCommandGroup body code isn't run @branch.child -@lightbulb.command("get", "get the current branch") +@lightbulb.add_checks(lightbulb.owner_only) +@lightbulb.command("get", "get the current branch", ephemeral=True) @lightbulb.implements(lightbulb.SlashSubCommand) async def branch_get(ctx: lightbulb.Context) -> None: output = await create_subprocess("git", "rev-parse", "--symbolic-full-name", "--abbrev-ref", "HEAD") @@ -126,8 +127,9 @@ async def branch_get(ctx: lightbulb.Context) -> None: @branch.child +@lightbulb.add_checks(lightbulb.owner_only) @lightbulb.option("name", "name of the branch", type=str, required=True) -@lightbulb.command("switch", "switch branches") +@lightbulb.command("switch", "switch branches", ephemeral=True) @lightbulb.implements(lightbulb.SlashSubCommand) async def branch_switch(ctx: lightbulb.Context) -> None: embed = hikari.Embed(title="Restarting", From f8a064565abf36bf9a80fa682eb6e39580e3504b Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 01:04:19 -0400 Subject: [PATCH 06/24] remove git_dev checks --- ext/system.py | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/ext/system.py b/ext/system.py index 98f3325..594e8a0 100644 --- a/ext/system.py +++ b/ext/system.py @@ -50,22 +50,6 @@ async def get_git_commits_ahead_behind(branch: str, remote: str) -> tuple[int, i return commits_ahead, commits_behind -async def get_git_dev(remote: str, branch: str) -> bool: - # dev environment tests - # difference between HEAD and remote - if await get_git_head_diff_branch(remote) != "": - return True - elif config.git_branch != branch: # branch has been changed - return True - # difference between index and remote - elif await get_git_index_diff_branch(remote) != "": - return True - # ahead in commits - elif (await get_git_commits_ahead_behind(branch, remote))[0] > 0: - return True - return False - - async def get_git_update(dev_status: bool, branch, remote) -> bool: commits_behind, _ = await get_git_commits_ahead_behind(branch, remote) if not dev_status and commits_behind > 0: @@ -78,7 +62,6 @@ async def get_git_status() -> dict: output["commit_id"] = await get_git_latest_commit_id() output["branch"] = await get_git_branch() output["remote"] = await get_git_remote() - output["dev"] = await get_git_dev(output['remote'], output['branch']) output['update'] = await get_git_update(output['dev'], output['branch'], output['remote']) return output @@ -98,8 +81,7 @@ async def ping(ctx: lightbulb.Context) -> None: @lightbulb.command("update", "update the bot!", ephemeral=True) @lightbulb.implements(lightbulb.SlashCommand) async def update(ctx: lightbulb.Context) -> None: - if (await get_git_status())['dev'] is False: - await create_subprocess("git", "pull") + await create_subprocess("git", "pull") embed = hikari.Embed(title="Restarting", description="Restarting to load an update!" ) From ca5866037697972b74143644c1fa76cc3ecba899 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 01:06:48 -0400 Subject: [PATCH 07/24] remove git dev --- ext/system.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/system.py b/ext/system.py index 594e8a0..8b50711 100644 --- a/ext/system.py +++ b/ext/system.py @@ -50,9 +50,9 @@ async def get_git_commits_ahead_behind(branch: str, remote: str) -> tuple[int, i return commits_ahead, commits_behind -async def get_git_update(dev_status: bool, branch, remote) -> bool: +async def get_git_update(branch, remote) -> bool: commits_behind, _ = await get_git_commits_ahead_behind(branch, remote) - if not dev_status and commits_behind > 0: + if commits_behind > 0: return True return False @@ -62,7 +62,7 @@ async def get_git_status() -> dict: output["commit_id"] = await get_git_latest_commit_id() output["branch"] = await get_git_branch() output["remote"] = await get_git_remote() - output['update'] = await get_git_update(output['dev'], output['branch'], output['remote']) + output['update'] = await get_git_update(output['branch'], output['remote']) return output From ebd90927882b4e05fc9d5c12ed1027b0a647df73 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 01:09:56 -0400 Subject: [PATCH 08/24] fix get_git_remote with multiple branches --- ext/system.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/system.py b/ext/system.py index 8b50711..7c28030 100644 --- a/ext/system.py +++ b/ext/system.py @@ -29,7 +29,9 @@ async def get_git_branch(): async def get_git_remote(): remote = await create_subprocess("git", "branch", "-vv") - return remote.split("[")[1].split("]")[0] + for line in remote.split("\n"): + if "*" in line: + return line.split("[")[1].split("]")[0] async def get_git_head_diff_branch(branch: str) -> str: From abd583401e2548c646fe2a26667b62966af28fb7 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 01:13:28 -0400 Subject: [PATCH 09/24] fix branch_switch --- ext/system.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/system.py b/ext/system.py index 7c28030..8541f13 100644 --- a/ext/system.py +++ b/ext/system.py @@ -95,11 +95,11 @@ async def update(ctx: lightbulb.Context) -> None: @lightbulb.add_checks(lightbulb.owner_only) @lightbulb.command("branch", "get or set the working branch the bot uses.") @lightbulb.implements(lightbulb.SlashCommandGroup) -async def branch(ctx: lightbulb.Context) -> None: +async def branch_group(ctx: lightbulb.Context) -> None: pass # SlashCommandGroup body code isn't run -@branch.child +@branch_group.child @lightbulb.add_checks(lightbulb.owner_only) @lightbulb.command("get", "get the current branch", ephemeral=True) @lightbulb.implements(lightbulb.SlashSubCommand) @@ -110,7 +110,7 @@ async def branch_get(ctx: lightbulb.Context) -> None: await ctx.respond(embed=embed) -@branch.child +@branch_group.child @lightbulb.add_checks(lightbulb.owner_only) @lightbulb.option("name", "name of the branch", type=str, required=True) @lightbulb.command("switch", "switch branches", ephemeral=True) @@ -119,7 +119,7 @@ async def branch_switch(ctx: lightbulb.Context) -> None: embed = hikari.Embed(title="Restarting", description="Restarting to switch branches!" ) - output = await create_subprocess("git", "switch", ctx.options.branch) + output = await create_subprocess("git", "switch", ctx.options.name) if "invalid reference" in output: # parsing output allows us more specificity. embed.title = "Branch does not exist." embed.description = "Please check your spelling." From 1bd6e3709c0483302b25fcc020dfef2bc2ace2bb Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 01:20:01 -0400 Subject: [PATCH 10/24] add image to LibCal confirmation dialog --- ext/libcal.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/libcal.py b/ext/libcal.py index 97a6497..b1ad9d0 100644 --- a/ext/libcal.py +++ b/ext/libcal.py @@ -69,6 +69,7 @@ async def book(ctx: lightbulb.Context) -> None: add_rooms_to_embed(room_list, response) response.title = "Room Bookings" response.description = "Are the booking(s) correct?" + response.set_image(ctx.options.img) view = BookingConfirmationView(room_list=room_list, image=ctx.options.img) resp = await ctx.respond(response, components=view.build()) view.start(await resp.message()) From 05acd6e4b09656c6f9d26fe3f9dae3fc23c4e74a Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 01:22:42 -0400 Subject: [PATCH 11/24] add git fetch before info is gathered --- ext/system.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/system.py b/ext/system.py index 8541f13..5e14498 100644 --- a/ext/system.py +++ b/ext/system.py @@ -138,6 +138,7 @@ async def branch_switch(ctx: lightbulb.Context) -> None: @lightbulb.command("info", "get bot information such as the version, and repository link.", ephemeral=True) @lightbulb.implements(lightbulb.SlashCommand) async def info(ctx: lightbulb.Context) -> None: + await create_subprocess("git", "fetch") # updates with remote git_status = await get_git_status() embed = hikari.Embed(title="About Me!") embed.add_field("Git Repository", config.git_url) From 6f3ebbd45d841dbcb8b128901963a93e25b2e305 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sat, 20 Aug 2022 01:28:51 -0400 Subject: [PATCH 12/24] pass private Option from /book command to View --- ext/libcal.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/libcal.py b/ext/libcal.py index b1ad9d0..141e53d 100644 --- a/ext/libcal.py +++ b/ext/libcal.py @@ -37,6 +37,7 @@ class BookingConfirmationView(miru.View): await gcal.create_event(room.number, room.start_time, room.end_time) embed = hikari.Embed(title="Rooms Booked!") add_rooms_to_embed(self.room_list, embed) + embed.set_image(self.image) await ctx.edit_response(embed=embed, components=[]) thread_embed = hikari.Embed(title="Rooms were booked!") @@ -70,7 +71,8 @@ async def book(ctx: lightbulb.Context) -> None: response.title = "Room Bookings" response.description = "Are the booking(s) correct?" response.set_image(ctx.options.img) - view = BookingConfirmationView(room_list=room_list, image=ctx.options.img) + view = BookingConfirmationView( + room_list=room_list, image=ctx.options.img, private=ctx.options.private) resp = await ctx.respond(response, components=view.build()) view.start(await resp.message()) From 18f82347350f170bb6aab7cae083e10d0d14edc5 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sun, 21 Aug 2022 18:02:53 -0400 Subject: [PATCH 13/24] Add Profile Plugin add /avatar command to set bot's avatar. --- ext/profile.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 ext/profile.py diff --git a/ext/profile.py b/ext/profile.py new file mode 100644 index 0000000..3fc56a3 --- /dev/null +++ b/ext/profile.py @@ -0,0 +1,24 @@ +import hikari +import lightbulb + +plugin = lightbulb.Plugin("ProfilePlugin") + + +@plugin.command +@lightbulb.option("img", "image to set as new avatar", type=hikari.Attachment, required=True) +@lightbulb.add_checks(lightbulb.owner_only) +@lightbulb.command("avatar", "set the bot avatar.", ephemeral=True) +@lightbulb.implements(lightbulb.SlashCommand) +async def set_avatar(ctx: lightbulb.Context) -> None: + await ctx.bot.rest.edit_my_user(avatar=ctx.options.img) + embed = hikari.Embed(title="New avatar set!") + embed.set_image(ctx.options.img) + await ctx.respond(embed) + + +def load(bot: lightbulb.BotApp): + bot.add_plugin(plugin) + + +def unload(bot: lightbulb.BotApp): + bot.remove_plugin(plugin) From 8fa30420eff4c6c42bc638cf6ea590600ae863e8 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sun, 21 Aug 2022 18:34:13 -0400 Subject: [PATCH 14/24] add /status command --- ext/profile.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ext/profile.py b/ext/profile.py index 3fc56a3..601471b 100644 --- a/ext/profile.py +++ b/ext/profile.py @@ -16,6 +16,17 @@ async def set_avatar(ctx: lightbulb.Context) -> None: await ctx.respond(embed) +@plugin.command +@lightbulb.option("text", "text to set as custom status", type=hikari.Attachment, required=True) +@lightbulb.add_checks(lightbulb.owner_only) +@lightbulb.command("status", "set the bot status.", ephemeral=True) +@lightbulb.implements(lightbulb.SlashCommand) +async def set_status(ctx: lightbulb.Context) -> None: + await ctx.bot.update_presence(activity=hikari.Activity(name=ctx.options.text, type=hikari.ActivityType.CUSTOM)) + embed = hikari.Embed(title="New status set!", description=f"New Status: {ctx.options.text}") + await ctx.respond(embed) + + def load(bot: lightbulb.BotApp): bot.add_plugin(plugin) From 3c8a9add741cd50468d231b6353b502e2694af24 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Sun, 21 Aug 2022 18:37:02 -0400 Subject: [PATCH 15/24] fix type for text option on /status command --- ext/profile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/profile.py b/ext/profile.py index 601471b..e16e8f9 100644 --- a/ext/profile.py +++ b/ext/profile.py @@ -17,7 +17,7 @@ async def set_avatar(ctx: lightbulb.Context) -> None: @plugin.command -@lightbulb.option("text", "text to set as custom status", type=hikari.Attachment, required=True) +@lightbulb.option("text", "text to set as custom status", type=str, required=True) @lightbulb.add_checks(lightbulb.owner_only) @lightbulb.command("status", "set the bot status.", ephemeral=True) @lightbulb.implements(lightbulb.SlashCommand) From cf73726614c8760bea3ac0f65f184f90caa88eda Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Mon, 22 Aug 2022 00:35:08 -0400 Subject: [PATCH 16/24] bots can't have custom statuses, sad. :( --- ext/profile.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ext/profile.py b/ext/profile.py index e16e8f9..03e5051 100644 --- a/ext/profile.py +++ b/ext/profile.py @@ -18,12 +18,16 @@ async def set_avatar(ctx: lightbulb.Context) -> None: @plugin.command @lightbulb.option("text", "text to set as custom status", type=str, required=True) +@lightbulb.option("type", "type of status, 0 is Playing, 1 is Watching, 2 is Streaming, 3 is Listening, 4 is Competing", type=int, default=0) @lightbulb.add_checks(lightbulb.owner_only) @lightbulb.command("status", "set the bot status.", ephemeral=True) @lightbulb.implements(lightbulb.SlashCommand) async def set_status(ctx: lightbulb.Context) -> None: - await ctx.bot.update_presence(activity=hikari.Activity(name=ctx.options.text, type=hikari.ActivityType.CUSTOM)) - embed = hikari.Embed(title="New status set!", description=f"New Status: {ctx.options.text}") + choices = [hikari.ActivityType.PLAYING, hikari.ActivityType.WATCHING, + hikari.ActivityType.STREAMING, hikari.ActivityType.LISTENING, hikari.ActivityType.COMPETING] + await ctx.bot.update_presence(activity=hikari.Activity(name=ctx.options.text, type=choices[ctx.options.type])) + embed = hikari.Embed(title="New status set!", + description=f"New Status: {ctx.options.text}") await ctx.respond(embed) From b16ff88a79ede312139cdb692e6e3daafa67d4c1 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Mon, 22 Aug 2022 14:35:13 -0400 Subject: [PATCH 17/24] Added reporting for a failed OCR match --- ext/libcal.py | 11 +++++++++-- lib/ocr.py | 5 ++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ext/libcal.py b/ext/libcal.py index 141e53d..eec9da5 100644 --- a/ext/libcal.py +++ b/ext/libcal.py @@ -10,7 +10,7 @@ from typing import Optional from lib.config import load_config from lib.gcal import GoogleCalendarAPI from lib.room import Room -from lib.ocr import get_room_data, NoMatchException +from lib.ocr import get_room_data, NoMatchException, get_image_string plugin = lightbulb.Plugin("LibCal") config = load_config() @@ -82,8 +82,15 @@ async def book_error_handler(event: lightbulb.CommandErrorEvent): print("ERROR TYPE:", type(event.exception)) if isinstance(event.exception.__cause__, NoMatchException): embed = hikari.Embed(title="Huh, I can't read that", - description="Could you try another picture?") + description="Could you try another picture?\nI'll send a notice to the bot's maintainer. :)") await event.context.respond(embed=embed) + embed.title = "Image match failed!" + embed.description = f"I failed to find any bookings in the attached image." + embed.add_field("Image text", get_image_string(event.context.options.img)) + embed.set_image(event.context.options.img) + owners = event.context.bot.fetch_owner_ids() + for user_id in owners: + await event.context.bot.rest.fetch_user(user_id).send(embed) else: embed = hikari.Embed( title="Booking Error", description="Whelp, better luck next time I guess... the images used are attached.") diff --git a/lib/ocr.py b/lib/ocr.py index 343f66e..8d1ed65 100644 --- a/lib/ocr.py +++ b/lib/ocr.py @@ -67,7 +67,7 @@ def get_room_data(img: bytes) -> list[Room]: rooms: list[Room] = [] start_time: datetime | None = None end_time: datetime | None = None - img_string = image_to_string(Image.open(BytesIO(img))) + img_string = get_image_string(img) img_string = correct_newlines(img_string) img_string = correct_commas(img_string) matches = re.finditer(RE_STRING, img_string) @@ -85,3 +85,6 @@ def get_room_data(img: bytes) -> list[Room]: if len(rooms) == 0: raise NoMatchException return rooms + +def get_image_string(img: bytes) -> str: + return image_to_string(Image.open(BytesIO(img))) \ No newline at end of file From 64c0977eb061dadc3be1d6c0d2ad36c8be5a5c26 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Mon, 22 Aug 2022 14:42:51 -0400 Subject: [PATCH 18/24] fix issue with book_error_handler --- ext/libcal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/libcal.py b/ext/libcal.py index eec9da5..aa903ce 100644 --- a/ext/libcal.py +++ b/ext/libcal.py @@ -86,7 +86,7 @@ async def book_error_handler(event: lightbulb.CommandErrorEvent): await event.context.respond(embed=embed) embed.title = "Image match failed!" embed.description = f"I failed to find any bookings in the attached image." - embed.add_field("Image text", get_image_string(event.context.options.img)) + embed.add_field("Image text", get_image_string(event.context.options.img.read())) embed.set_image(event.context.options.img) owners = event.context.bot.fetch_owner_ids() for user_id in owners: From 1daacbc18c2a10c94c1844a86ac500d24e7cde72 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Mon, 22 Aug 2022 14:44:29 -0400 Subject: [PATCH 19/24] lol forgot an await --- ext/libcal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/libcal.py b/ext/libcal.py index aa903ce..fb63c11 100644 --- a/ext/libcal.py +++ b/ext/libcal.py @@ -86,7 +86,7 @@ async def book_error_handler(event: lightbulb.CommandErrorEvent): await event.context.respond(embed=embed) embed.title = "Image match failed!" embed.description = f"I failed to find any bookings in the attached image." - embed.add_field("Image text", get_image_string(event.context.options.img.read())) + embed.add_field("Image text", get_image_string(await event.context.options.img.read())) embed.set_image(event.context.options.img) owners = event.context.bot.fetch_owner_ids() for user_id in owners: From dfd2b0195ec53c56aa42d9877619385614639198 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Mon, 22 Aug 2022 14:55:10 -0400 Subject: [PATCH 20/24] dangit my linter is not being helpful right now --- ext/libcal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/libcal.py b/ext/libcal.py index fb63c11..768c50b 100644 --- a/ext/libcal.py +++ b/ext/libcal.py @@ -88,7 +88,7 @@ async def book_error_handler(event: lightbulb.CommandErrorEvent): embed.description = f"I failed to find any bookings in the attached image." embed.add_field("Image text", get_image_string(await event.context.options.img.read())) embed.set_image(event.context.options.img) - owners = event.context.bot.fetch_owner_ids() + owners = await event.context.bot.fetch_owner_ids() for user_id in owners: await event.context.bot.rest.fetch_user(user_id).send(embed) else: From 54bb479e393ff8e418339a5a725c73ffa451d62d Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Mon, 22 Aug 2022 14:56:46 -0400 Subject: [PATCH 21/24] omaigod --- ext/libcal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/libcal.py b/ext/libcal.py index 768c50b..6f13c5b 100644 --- a/ext/libcal.py +++ b/ext/libcal.py @@ -90,7 +90,7 @@ async def book_error_handler(event: lightbulb.CommandErrorEvent): embed.set_image(event.context.options.img) owners = await event.context.bot.fetch_owner_ids() for user_id in owners: - await event.context.bot.rest.fetch_user(user_id).send(embed) + await (await event.context.bot.rest.fetch_user(user_id)).send(embed) else: embed = hikari.Embed( title="Booking Error", description="Whelp, better luck next time I guess... the images used are attached.") From 1004769e80088021ba9aeee1feee3e9f748e93fd Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Mon, 22 Aug 2022 15:00:25 -0400 Subject: [PATCH 22/24] change get_image_string to include check processes --- lib/ocr.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/ocr.py b/lib/ocr.py index 8d1ed65..a6269f4 100644 --- a/lib/ocr.py +++ b/lib/ocr.py @@ -87,4 +87,7 @@ def get_room_data(img: bytes) -> list[Room]: return rooms def get_image_string(img: bytes) -> str: - return image_to_string(Image.open(BytesIO(img))) \ No newline at end of file + img_string = image_to_string(Image.open(BytesIO(img))) + img_string = correct_newlines(img_string) + img_string = correct_commas(img_string) + return img_string \ No newline at end of file From 4ebfa4495038bda830312faac219e968cb8288bf Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Mon, 22 Aug 2022 15:08:59 -0400 Subject: [PATCH 23/24] fix regex --- lib/ocr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ocr.py b/lib/ocr.py index a6269f4..781e1d0 100644 --- a/lib/ocr.py +++ b/lib/ocr.py @@ -17,7 +17,7 @@ config = load_config() RE_STRING = re.compile( # https://regex101.com/r/ELsqrO/1 r"(L-[0-9]{4}): " # room number (group 1) # time-slot (group 2,3,4 - group 5,6,7) - r"([1-12]{1,2}):([0,3]{2})(am|pm) - ([1-12]{1,2}):([0,3]{2})(am|pm), " + r"([1-9]{1,2}):([0,3]{2})(am|pm) - ([1-9]{1,2}):([0,3]{2})(am|pm), " # weekday (group 8) r"(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), " # month (group 9) From d1a2d57e425485d9888456e61a64720b739764c0 Mon Sep 17 00:00:00 2001 From: Riley Housden Date: Mon, 22 Aug 2022 15:10:17 -0400 Subject: [PATCH 24/24] update regex link --- lib/ocr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ocr.py b/lib/ocr.py index 781e1d0..9bcaa85 100644 --- a/lib/ocr.py +++ b/lib/ocr.py @@ -14,7 +14,7 @@ __all__ = ["get_room_data"] config = load_config() -RE_STRING = re.compile( # https://regex101.com/r/ELsqrO/1 +RE_STRING = re.compile( # https://regex101.com/r/OkWfkC/1 r"(L-[0-9]{4}): " # room number (group 1) # time-slot (group 2,3,4 - group 5,6,7) r"([1-9]{1,2}):([0,3]{2})(am|pm) - ([1-9]{1,2}):([0,3]{2})(am|pm), "