From 3c9e5c56ab1a1564f3359ce76befbb544ef24018 Mon Sep 17 00:00:00 2001 From: Raphael Sinai Date: Mon, 28 Apr 2025 17:18:57 +0100 Subject: [PATCH 1/6] added override status to whois --- registration/src/commands/whois_commands.py | 1 + 1 file changed, 1 insertion(+) diff --git a/registration/src/commands/whois_commands.py b/registration/src/commands/whois_commands.py index 13701c4..1d20094 100644 --- a/registration/src/commands/whois_commands.py +++ b/registration/src/commands/whois_commands.py @@ -71,6 +71,7 @@ async def whois(interaction: discord.Interaction, *, "Can Print: " + str(perms.get("print", "Not Found")) + "\n" + "Can Laser: " + str(perms.get("laser", "Not Found")) + "\n" + "Can Resin: " + str(perms.get("resin", "Not Found")) + "\n" + "Print Override: " + str(perms.get("printer_override", "Not Found")) + "\n" ), inline=False) From e809dff01ca13b3b734ef487e7f241f5c0214201 Mon Sep 17 00:00:00 2001 From: Raphael Sinai Date: Thu, 1 May 2025 19:51:01 +0100 Subject: [PATCH 2/6] fix missing + --- registration/src/commands/whois_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registration/src/commands/whois_commands.py b/registration/src/commands/whois_commands.py index 1d20094..83d4dfc 100644 --- a/registration/src/commands/whois_commands.py +++ b/registration/src/commands/whois_commands.py @@ -70,7 +70,7 @@ async def whois(interaction: discord.Interaction, *, "Inducted: " + str(perms.get("inducted", "Not Found")) + "\n" + "Can Print: " + str(perms.get("print", "Not Found")) + "\n" + "Can Laser: " + str(perms.get("laser", "Not Found")) + "\n" + - "Can Resin: " + str(perms.get("resin", "Not Found")) + "\n" + "Can Resin: " + str(perms.get("resin", "Not Found")) + "\n" + "Print Override: " + str(perms.get("printer_override", "Not Found")) + "\n" ), inline=False) From 94f5142aba0b00d71ff89da131f7352f17c29887 Mon Sep 17 00:00:00 2001 From: Raphael Sinai Date: Sun, 4 May 2025 17:19:53 +0100 Subject: [PATCH 3/6] added is_trained and individual mac_addr per person --- registration/src/commands/permissions.py | 15 ++++++++++++--- registration/src/commands/whois_commands.py | 13 ++++++++++++- registration/src/utils/api.py | 15 +++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/registration/src/commands/permissions.py b/registration/src/commands/permissions.py index 85a9add..a423b24 100644 --- a/registration/src/commands/permissions.py +++ b/registration/src/commands/permissions.py @@ -14,6 +14,7 @@ CAN_LASER = "Can Laser" CAN_RESIN = "Can Resin" PRINTER_OVERRIDE = "Printer Override" +IS_LAB_TRAINED = "Is Lab Trained" class PermissionSelect(discord.ui.Select): @@ -24,7 +25,7 @@ def __init__( **kwargs) -> None: super().__init__( min_values=0, - max_values=5, + max_values=6, **kwargs) self.shortcode = shortcode @@ -55,6 +56,11 @@ def __init__( value=PRINTER_OVERRIDE, default=permission_info.printer_override, ) + self.add_option( + label=IS_LAB_TRAINED, + value=IS_LAB_TRAINED, + default=permission_info.is_lab_trained, + ) async def callback(self, interaction: discord.Interaction): o = self.values @@ -64,15 +70,17 @@ async def callback(self, interaction: discord.Interaction): can_laser = CAN_LASER in o can_resin = CAN_RESIN in o printer_override = PRINTER_OVERRIDE in o + is_lab_trained = IS_LAB_TRAINED in o logging.info( - f"Selected {can_print} {inducted} {can_laser} {can_resin} {printer_override}") + f"Selected {can_print} {inducted} {can_laser} {can_resin} {printer_override} {is_lab_trained}") if (self.permissions.print == can_print and self.permissions.inducted == inducted and self.permissions.laser == can_laser and self.permissions.resin == can_resin and - self.permissions.printer_override == printer_override): + self.permissions.printer_override == printer_override and + self.permissions.is_lab_trained == is_lab_trained): return await interaction.response.edit_message( embed=discord.Embed( title="Successfully updated Permssions", @@ -91,6 +99,7 @@ async def callback(self, interaction: discord.Interaction): "laser": can_laser, "resin": can_resin, "printer_override": printer_override, + "is_lab_trained": is_lab_trained }, auth=BASIC_AUTH ) diff --git a/registration/src/commands/whois_commands.py b/registration/src/commands/whois_commands.py index 83d4dfc..f98c25c 100644 --- a/registration/src/commands/whois_commands.py +++ b/registration/src/commands/whois_commands.py @@ -71,7 +71,8 @@ async def whois(interaction: discord.Interaction, *, "Can Print: " + str(perms.get("print", "Not Found")) + "\n" + "Can Laser: " + str(perms.get("laser", "Not Found")) + "\n" + "Can Resin: " + str(perms.get("resin", "Not Found")) + "\n" + - "Print Override: " + str(perms.get("printer_override", "Not Found")) + "\n" + "Print Override: " + str(perms.get("printer_override", "Not Found")) + "\n" + + "Is Lab Trained: " + str(perms.get("is_lab_trained", "Not Found")) + "\n" ), inline=False) @@ -95,6 +96,16 @@ async def whois(interaction: discord.Interaction, *, f"Started At: {last_print.time_started}" ), inline=False) + + mac_addrs = utils.get_mac_addresses_from_shortcode(shortcode) + + if mac_addrs: + embed.add_field( + name="MAC Addresses", + value=( + "\n".join(mac_addrs) + ) + ) if discord_id: res = requests.get( utils.SERVER_IP + "/user/notes", diff --git a/registration/src/utils/api.py b/registration/src/utils/api.py index f0ca525..a4be5a6 100644 --- a/registration/src/utils/api.py +++ b/registration/src/utils/api.py @@ -16,6 +16,7 @@ "get_shortcode_from_discord", "get_perms_from_shortcode", "MemberPermissions", + "get_mac_addresses_from_shortcode" ] """ @@ -97,6 +98,7 @@ class MemberPermissions: card_id: str = "" resin: bool = False printer_override: bool = False + is_lab_trained: bool = False def get_perms_from_shortcode(shortcode: str) -> MemberPermissions: @@ -136,6 +138,19 @@ def get_stats_from_discord(discord_id: str): return Stats() +def get_mac_addresses_from_shortcode(shortcode: str): + res = requests.get( + SERVER_IP + "/member/mac_addresses", + params={ + "shortcode": shortcode + }, + auth=BASIC_AUTH + ) + + if res.status_code == 200: + return res.json() + + return None @dataclass class Print: From 53328aec46c1852f84d1e34ddeca913af5079620 Mon Sep 17 00:00:00 2001 From: Raphael Sinai Date: Sun, 4 May 2025 18:48:56 +0100 Subject: [PATCH 4/6] added add mac address command --- registration/src/bot_class.py | 13 ++++ registration/src/commands/__init__.py | 2 + registration/src/commands/mac_addresses.py | 78 ++++++++++++++++++++++ registration/src/utils/validation.py | 6 ++ 4 files changed, 99 insertions(+) create mode 100644 registration/src/commands/mac_addresses.py diff --git a/registration/src/bot_class.py b/registration/src/bot_class.py index b75405f..b1b2c75 100644 --- a/registration/src/bot_class.py +++ b/registration/src/bot_class.py @@ -28,6 +28,7 @@ card_office, who_is_printing, project_admin_dashboard, + add_mac_address, ) from src.utils import (deregister_discord_id, error_msg, committee_command, SERVER_IP, verified_member, @@ -350,6 +351,18 @@ async def permissions_( async def whois_printing_( interaction: discord.Interaction): return await who_is_printing(interaction) + + @self.tree.command( + name="add-mac-address", + description="**ADMIN ONLY**: Add a BLE mac address to trained committee" + ) + @committee_command + async def add_mac_address_( + interaction : discord.Interaction, + user : str, + mac_addr : str + ): + return await add_mac_address(interaction, user, mac_addr) async def on_message(self, message): # pylint: disable=arguments-differ """ diff --git a/registration/src/commands/__init__.py b/registration/src/commands/__init__.py index e503975..9ea85e8 100644 --- a/registration/src/commands/__init__.py +++ b/registration/src/commands/__init__.py @@ -16,6 +16,7 @@ from .project import * from .project_admin import * from .permissions import * +from .mac_addresses import * __all__ = [] __all__.extend(project.__all__) @@ -27,6 +28,7 @@ __all__.extend(printer_commands.__all__) __all__.extend(printer_status_commands.__all__) __all__.extend(induct.__all__) +__all__.extend(mac_addresses.__all__) __all__.extend(timelapse.__all__) __all__.extend(quote.__all__) diff --git a/registration/src/commands/mac_addresses.py b/registration/src/commands/mac_addresses.py new file mode 100644 index 0000000..b283970 --- /dev/null +++ b/registration/src/commands/mac_addresses.py @@ -0,0 +1,78 @@ +__all__ = [ + "add_mac_address" +] + +import logging +import discord +import requests + +from src.utils import SERVER_IP +import src.utils as utils + +async def add_mac_address( + interaction: discord.Interaction, + user: str | discord.User | discord.Member, + mac_address: str, +): + logging.info(f"Add MAC Address: {user}") + + if isinstance(user, str): + if not utils.is_shortcode(user): + logging.info(f"add MAC Address shortcode invalid: {user}") + return await interaction.response.send_message( + embed=utils.invalid_shortcode(), ephemeral=True + ) + + discord_id = utils.get_discord_from_shortcode(user) + shortcode = user + + else: + discord_id = str(user.id) + logging.info(f"add MAC address Discord ID: {discord_id}") + + shortcode = utils.get_shortcode_from_discord(discord_id) + + if not shortcode: + return await interaction.response.send_message( + embed=utils.error_msg( + f"Couldn't get short code for <@{discord_id}>", + "Add mac address Warning"), + ephemeral=True) + + if not utils.is_mac_address(mac_address): + logging.info("invalid mac address format") + return await interaction.response.send_message( + embed=utils.error_msg( + f"Invalid mac address {mac_address}", + "Mac address invalid warning" + ), + ephemeral=True + ) + + + + response = requests.post( + SERVER_IP + "/member/mac_addresses/add", + params={ + "shortcode": shortcode, + "mac_address": mac_address + } + ) + + if response.status_code == 200: + embed = discord.Embed( + title="Add mac address", + description=f"Successfully added {mac_address} to {shortcode}" + ) + return await interaction.response.send_message( + embed=embed, + ephemeral=True, + ) + + return await interaction.response.send_message( + embed=utils.error_msg( + "Failed to add to db", + "MAC Address not added" + ), + ephemeral=True, + ) \ No newline at end of file diff --git a/registration/src/utils/validation.py b/registration/src/utils/validation.py index 28c0cb7..45709ef 100644 --- a/registration/src/utils/validation.py +++ b/registration/src/utils/validation.py @@ -9,6 +9,7 @@ "validate_card_uid", "validate_shortcode", "verified_member", + "is_mac_address" ] @@ -25,6 +26,7 @@ SHORTCODE_REGEX = r'^[a-z]{2,3}\d{2,5}$' UID_REGEX = r'^[0-9A-F]{8,14}$' DISCORD_ID_REGEX = r'^<@[0-9]{18,19}>$' +MAC_ADDR_REGEX = r'^([0-9A-F]{2}:){5}[0-9A-F]{2}' def is_shortcode(message: str) -> bool: @@ -63,6 +65,10 @@ def is_not_committee(author: discord.User | discord.Member): def is_member(author: discord.User | discord.Member): return "verified member" in [y.name.lower() for y in author.roles] +def is_mac_address(mac_addr : str): + mac_addr = mac_addr.upper() + found = re.findall(MAC_ADDR_REGEX, mac_addr) + return any(found) def committee_command(function: Callable): @functools.wraps(function) From 51df84b627d0f1d2bbf4767a60e99c60629f85a6 Mon Sep 17 00:00:00 2001 From: Raphael Sinai Date: Sun, 4 May 2025 19:15:24 +0100 Subject: [PATCH 5/6] added trained_member present to commands --- registration/src/bot_class.py | 12 ++++++ registration/src/commands/mac_addresses.py | 47 +++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/registration/src/bot_class.py b/registration/src/bot_class.py index b1b2c75..4ad8236 100644 --- a/registration/src/bot_class.py +++ b/registration/src/bot_class.py @@ -29,6 +29,7 @@ who_is_printing, project_admin_dashboard, add_mac_address, + trained_member_present ) from src.utils import (deregister_discord_id, error_msg, committee_command, SERVER_IP, verified_member, @@ -363,6 +364,17 @@ async def add_mac_address_( mac_addr : str ): return await add_mac_address(interaction, user, mac_addr) + @self.tree.command( + name="trained-member-present", + description="**ADMIN ONLY**: Check if a lab trained member is present in a time interval" + ) + @committee_command + async def trained_member_present_( + interaction: discord.Interaction, + timestamp: str, + interval: int, + ): + return await trained_member_present(interaction, timestamp, interval) async def on_message(self, message): # pylint: disable=arguments-differ """ diff --git a/registration/src/commands/mac_addresses.py b/registration/src/commands/mac_addresses.py index b283970..c95926e 100644 --- a/registration/src/commands/mac_addresses.py +++ b/registration/src/commands/mac_addresses.py @@ -1,10 +1,12 @@ __all__ = [ - "add_mac_address" + "add_mac_address", + "trained_member_present" ] import logging import discord import requests +from datetime import datetime from src.utils import SERVER_IP import src.utils as utils @@ -75,4 +77,45 @@ async def add_mac_address( "MAC Address not added" ), ephemeral=True, - ) \ No newline at end of file + ) + +async def trained_member_present( + interaction: discord.Interaction, + timestamp: str, + interval: int +): + try: + timestamp = datetime.strptime(timestamp, "%Y-%m-%d %H:%M") + except: + return await interaction.response.send_message( + embed=utils.error_msg( + "Format should be YYYY-MM-DD HH:MM", + "Invalid timestamp format" + ), + ephemeral=True + ) + response = requests.get( + SERVER_IP + "/access/trained_member_present", + params= { + "timestamp": str(timestamp), + "interval": interval + } + ) + + if len(response.json()) > 0: + embed = discord.Embed( + title="Committee Present", + description="\n".join(response.json()) + ) + return await interaction.response.send_message( + embed=embed, + ephemeral=True + ) + else: + return await interaction.response.send_message( + embed=utils.error_msg( + "No trained members present in that time interval", + "NO TRAINED MEMBER" + ), + ephemeral=True + ) \ No newline at end of file From 112d78190a847dfef1ed773e77646d1524247738 Mon Sep 17 00:00:00 2001 From: Raphael Sinai Date: Sun, 4 May 2025 19:19:50 +0100 Subject: [PATCH 6/6] update versions --- registration/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registration/pyproject.toml b/registration/pyproject.toml index 6996d5e..081cc06 100644 --- a/registration/pyproject.toml +++ b/registration/pyproject.toml @@ -1,5 +1,5 @@ [project] name = "ICRS Discord Bot" -version = "1.0.6" +version = "1.0.7" description = "Main ICRS Discord Bot." requires-python = ">=3.8"