@@ -870,6 +870,127 @@ async def strike(self, ctx: "TeXBotApplicationContext", str_strike_member_id: st
870870
871871 await self ._command_perform_strike (ctx , strike_member )
872872
873+ @discord .slash_command ( # type: ignore[misc, no-untyped-call]
874+ name = "get-strikes" ,
875+ description = "Get the number of strikes a user has." ,
876+ )
877+ @discord .option ( # type: ignore[misc, no-untyped-call]
878+ name = "user" ,
879+ description = "The user to check the number of strikes for." ,
880+ input_type = str ,
881+ autocomplete = discord .utils .basic_autocomplete (autocomplete_get_members ), # type: ignore[arg-type]
882+ required = True ,
883+ parameter_name = "str_strike_member_id" ,
884+ )
885+ @CommandChecks .check_interaction_user_has_committee_role
886+ @CommandChecks .check_interaction_user_in_main_guild
887+ async def get_strikes ( # type: ignore[misc]
888+ self , ctx : "TeXBotApplicationContext" , str_strike_member_id : str
889+ ) -> None :
890+ """
891+ Define method and callback response of of the "get-strikes" command.
892+
893+ Responds with the number of strikes a user has.
894+ """
895+ try :
896+ strike_member : discord .Member = await self .bot .get_member_from_str_id (
897+ str_member_id = str_strike_member_id
898+ )
899+ except ValueError as member_id_not_integer_error :
900+ await self .command_send_error (ctx , message = member_id_not_integer_error .args [0 ])
901+ return
902+
903+ strikes_count : int = 0
904+ try :
905+ strikes_count = (
906+ await DiscordMemberStrikes .objects .aget (discord_id = strike_member .id )
907+ ).strikes
908+ except DiscordMemberStrikes .DoesNotExist :
909+ logger .debug ("No strikes found for user %s" , strike_member )
910+
911+ await ctx .respond (
912+ content = (f"User { strike_member .mention } has { strikes_count } strikes." ),
913+ ephemeral = True ,
914+ )
915+
916+ @discord .slash_command ( # type: ignore[misc, no-untyped-call]
917+ name = "decrement-strikes" ,
918+ description = "Remove a single strike from a user." ,
919+ )
920+ @discord .option ( # type: ignore[misc, no-untyped-call]
921+ name = "user" ,
922+ description = "The user to remove a strike from." ,
923+ input_type = str ,
924+ autocomplete = discord .utils .basic_autocomplete (autocomplete_get_members ), # type: ignore[arg-type]
925+ required = True ,
926+ parameter_name = "str_strike_member_id" ,
927+ )
928+ async def decrement_strikes ( # type: ignore[misc]
929+ self , ctx : "TeXBotApplicationContext" , str_strike_member_id : str
930+ ) -> None :
931+ """
932+ Definition & callback response of the "decrement-strikes" command.
933+
934+ The "decrement-strikes" command removes a strike from the given member.
935+ If the member only has one strike, the corresponding `DiscordMemberStrikes`
936+ object will be deleted from the database.
937+ """
938+ try :
939+ strike_member : discord .Member = await self .bot .get_member_from_str_id (
940+ str_member_id = str_strike_member_id ,
941+ )
942+ except ValueError as member_id_not_integer_error :
943+ await self .command_send_error (ctx , message = member_id_not_integer_error .args [0 ])
944+ return
945+
946+ try :
947+ discord_member_strikes : DiscordMemberStrikes = (
948+ await DiscordMemberStrikes .objects .aget (discord_id = strike_member .id )
949+ )
950+ except DiscordMemberStrikes .DoesNotExist :
951+ await ctx .respond (
952+ content = (
953+ ":information_source: No action taken. "
954+ f"User { strike_member .mention } does not have any strikes to remove!"
955+ ),
956+ ephemeral = True ,
957+ )
958+ logger .info (
959+ "%s attempted to remove a strike from user %s, but they had none" ,
960+ ctx .user ,
961+ strike_member ,
962+ )
963+ return
964+
965+ if discord_member_strikes .strikes <= 1 :
966+ await discord_member_strikes .adelete ()
967+ await ctx .respond (
968+ content = f"Successfully removed all strikes from { strike_member .mention } ." ,
969+ ephemeral = True ,
970+ )
971+ logger .info (
972+ "%s removed all strikes from user %s" ,
973+ ctx .user ,
974+ strike_member ,
975+ )
976+ return
977+
978+ discord_member_strikes .strikes -= 1
979+ await discord_member_strikes .asave ()
980+ await ctx .respond (
981+ content = (
982+ f"Successfully removed a strike from { strike_member .mention } . "
983+ f"User now has { discord_member_strikes .strikes } strikes."
984+ ),
985+ ephemeral = True ,
986+ )
987+ logger .info (
988+ "%s removed 1 strike from user %s, they now have %s" ,
989+ ctx .user ,
990+ strike_member ,
991+ discord_member_strikes .strikes ,
992+ )
993+
873994
874995class StrikeContextCommandsCog (BaseStrikeCog ):
875996 """Cog class that defines the context menu strike command and its call-back method."""
0 commit comments