3
3
import asyncio
4
4
import pathlib
5
5
import random
6
- from typing import TYPE_CHECKING , TypeVar
7
6
from collections .abc import Sequence
7
+ from typing import TYPE_CHECKING , TypeVar
8
8
9
9
import arrow
10
+ from rapidfuzz import fuzz , process
11
+
10
12
import discord
11
13
from core import Cog
12
14
from discord .ext import commands
13
15
from utilities .exceptions import ParrotCheckFailure
14
16
15
- from rapidfuzz import fuzz , process
16
-
17
17
if TYPE_CHECKING :
18
18
from core import Context , Parrot
19
19
@@ -59,21 +59,17 @@ async def on_command(self, ctx: Context):
59
59
"""This event will be triggered when the command is being completed; triggered by [discord.User]!."""
60
60
if ctx .author .bot :
61
61
return
62
- await ctx .database_command_update (
63
- success = not ctx .command_failed ,
64
- )
62
+ await ctx .database_command_update (success = not ctx .command_failed )
65
63
66
- def _get_object_by_fuzzy (self , * , argument : str , objects : Sequence [T ]) -> tuple [T | None , str | None , int | None ] | None :
64
+ def _get_object_by_fuzzy (self , * , argument : str , objects : Sequence [T ]) -> tuple [T , str , int ] | None :
67
65
"""Get an object from a list of objects by fuzzy matching."""
68
66
if not argument :
69
67
return None
70
68
CUT_OFF = 90
71
69
names = [o .name for o in objects ]
72
- algorithms = [fuzz .ratio , fuzz .partial_ratio , fuzz .token_sort_ratio , fuzz .token_set_ratio , fuzz .WRatio ]
73
- for algo in algorithms :
74
- if data := process .extractOne (argument , names , scorer = algo , score_cutoff = CUT_OFF ):
75
- result , score , position = data
76
- return objects [position ], result , int (score )
70
+ if data := process .extractOne (argument , names , scorer = fuzz .WRatio , score_cutoff = CUT_OFF ):
71
+ result , score , position = data
72
+ return objects [position ], result , int (score )
77
73
78
74
@Cog .listener ()
79
75
async def on_command_error (self , ctx : Context , error : commands .CommandError ): # noqa: PLR0912, PLR0915, C901
@@ -84,7 +80,7 @@ async def on_command_error(self, ctx: Context, error: commands.CommandError): #
84
80
85
81
# get the original exception
86
82
error = getattr (error , "original" , error )
87
- TO_RAISE_ERROR , DELETE_AFTER = False , None
83
+ TO_RAISE_ERROR , DELETE_AFTER , RESET_COOLDOWN = False , None , False
88
84
ignore = (
89
85
commands .CommandNotFound ,
90
86
discord .NotFound ,
@@ -105,6 +101,7 @@ async def on_command_error(self, ctx: Context, error: commands.CommandError): #
105
101
fmt = " and " .join (missing )
106
102
ERROR_EMBED .description = f"Please provide the following permission(s) to the bot.```\n { fmt } ```"
107
103
ERROR_EMBED .set_author (name = (f"{ QUESTION_MARK } Bot Missing permissions { QUESTION_MARK } " ))
104
+ RESET_COOLDOWN = True
108
105
109
106
elif isinstance (error , commands .CommandOnCooldown ):
110
107
now = arrow .utcnow ().shift (seconds = error .retry_after ).datetime
@@ -126,7 +123,7 @@ async def on_command_error(self, ctx: Context, error: commands.CommandError): #
126
123
127
124
ERROR_EMBED .description = f"You need the following permission(s) to the run the command.```\n { fmt } ```"
128
125
ERROR_EMBED .set_author (name = f"{ QUESTION_MARK } Missing permissions { QUESTION_MARK } " )
129
- ctx . command . reset_cooldown ( ctx )
126
+ RESET_COOLDOWN = True
130
127
131
128
elif isinstance (error , commands .MissingRole ):
132
129
missing = [error .missing_role ]
@@ -136,7 +133,7 @@ async def on_command_error(self, ctx: Context, error: commands.CommandError): #
136
133
fmt = " and " .join (missing ) # type: ignore
137
134
ERROR_EMBED .description = f"You need the the following role(s) to use the command```\n { fmt } ```"
138
135
ERROR_EMBED .set_author (name = f"{ QUESTION_MARK } Missing Role { QUESTION_MARK } " )
139
- ctx . command . reset_cooldown ( ctx )
136
+ RESET_COOLDOWN = True
140
137
141
138
elif isinstance (error , commands .MissingAnyRole ):
142
139
missing = list (error .missing_roles )
@@ -146,16 +143,16 @@ async def on_command_error(self, ctx: Context, error: commands.CommandError): #
146
143
fmt = " and " .join (missing ) # type: ignore
147
144
ERROR_EMBED .description = f"You need the the following role(s) to use the command```\n { fmt } ```"
148
145
ERROR_EMBED .set_author (name = f"{ QUESTION_MARK } Missing Role { QUESTION_MARK } " )
149
- ctx . command . reset_cooldown ( ctx )
146
+ RESET_COOLDOWN = True
150
147
151
148
elif isinstance (error , commands .NSFWChannelRequired ):
152
149
ERROR_EMBED .description = "This command will only run in NSFW marked channel. https://i.imgur.com/oe4iK5i.gif"
153
150
ERROR_EMBED .set_author (name = f"{ QUESTION_MARK } NSFW Channel Required { QUESTION_MARK } " )
154
151
ERROR_EMBED .set_image (url = "https://i.imgur.com/oe4iK5i.gif" )
155
- ctx . command . reset_cooldown ( ctx )
152
+ RESET_COOLDOWN = True
156
153
157
154
elif isinstance (error , commands .BadArgument ):
158
- ctx . command . reset_cooldown ( ctx )
155
+ RESET_COOLDOWN = True
159
156
objects = []
160
157
if isinstance (error , commands .MessageNotFound ):
161
158
ERROR_EMBED .description = "Message ID/Link you provied is either invalid or deleted"
@@ -189,7 +186,7 @@ async def on_command_error(self, ctx: Context, error: commands.CommandError): #
189
186
ERROR_EMBED .set_author (name = f"{ QUESTION_MARK } Bad Argument { QUESTION_MARK } " )
190
187
191
188
if objects :
192
- if ( obj := self ._get_object_by_fuzzy (argument = error .argument , objects = objects ) ): # type: ignore
189
+ if obj := self ._get_object_by_fuzzy (argument = error .argument , objects = objects ): # type: ignore
193
190
_ , result , score = obj
194
191
ERROR_EMBED .description += f"\n \n Did you mean `{ result } `?"
195
192
ERROR_EMBED .set_footer (text = f"Confidence: { score } %" )
@@ -199,7 +196,7 @@ async def on_command_error(self, ctx: Context, error: commands.CommandError): #
199
196
commands .MissingRequiredArgument | commands .BadUnionArgument | commands .TooManyArguments ,
200
197
):
201
198
command = ctx .command
202
- ctx . command . reset_cooldown ( ctx )
199
+ RESET_COOLDOWN = True
203
200
ERROR_EMBED .description = f"Please use proper syntax.```\n { ctx .clean_prefix } { command .qualified_name } { '|' if command .aliases else '' } { '|' .join (command .aliases or '' )} { command .signature } ```"
204
201
205
202
ERROR_EMBED .set_author (name = f"{ QUESTION_MARK } Invalid Syntax { QUESTION_MARK } " )
@@ -218,17 +215,17 @@ async def on_command_error(self, ctx: Context, error: commands.CommandError): #
218
215
ERROR_EMBED .set_author (name = (f"{ QUESTION_MARK } Max Concurrenry Reached { QUESTION_MARK } " ))
219
216
220
217
elif isinstance (error , ParrotCheckFailure ):
221
- ctx . command . reset_cooldown ( ctx )
218
+ RESET_COOLDOWN = True
222
219
ERROR_EMBED .description = f"{ error .__str__ ().format (ctx = ctx )} "
223
220
ERROR_EMBED .set_author (name = f"{ QUESTION_MARK } Unexpected Error { QUESTION_MARK } " )
224
221
225
222
elif isinstance (error , commands .CheckAnyFailure ):
226
- ctx . command . reset_cooldown ( ctx )
223
+ RESET_COOLDOWN = True
227
224
ERROR_EMBED .description = " or\n " .join ([error .__str__ ().format (ctx = ctx ) for error in error .errors ])
228
225
ERROR_EMBED .set_author (name = f"{ QUESTION_MARK } Unexpected Error { QUESTION_MARK } " )
229
226
230
227
elif isinstance (error , commands .CheckFailure ):
231
- ctx . command . reset_cooldown ( ctx )
228
+ RESET_COOLDOWN = True
232
229
ERROR_EMBED .set_author (name = f"{ QUESTION_MARK } Unexpected Error { QUESTION_MARK } " )
233
230
ERROR_EMBED .description = "You don't have the required permissions to use this command."
234
231
@@ -257,6 +254,9 @@ async def on_command_error(self, ctx: Context, error: commands.CommandError): #
257
254
258
255
ERROR_EMBED .timestamp = discord .utils .utcnow ()
259
256
257
+ if RESET_COOLDOWN :
258
+ ctx .command .reset_cooldown (ctx )
259
+
260
260
msg : discord .Message | None = await ctx .reply (random .choice (quote ), embed = ERROR_EMBED )
261
261
262
262
try :
0 commit comments