@@ -100,7 +100,9 @@ def add_application_command(self, command: ApplicationCommand) -> None:
100
100
command .guild_ids = self .debug_guilds
101
101
self ._pending_application_commands .append (command )
102
102
103
- def remove_application_command (self , command : ApplicationCommand ) -> Optional [ApplicationCommand ]:
103
+ def remove_application_command (
104
+ self , command : ApplicationCommand
105
+ ) -> Optional [ApplicationCommand ]:
104
106
"""Remove a :class:`.ApplicationCommand` from the internal list
105
107
of commands.
106
108
@@ -155,7 +157,9 @@ async def register_commands(self) -> None:
155
157
global_permissions : List = []
156
158
157
159
registered_commands = await self .http .get_global_commands (self .user .id )
158
- for command in [cmd for cmd in self .pending_application_commands if cmd .guild_ids is None ]:
160
+ for command in [
161
+ cmd for cmd in self .pending_application_commands if cmd .guild_ids is None
162
+ ]:
159
163
as_dict = command .to_dict ()
160
164
if len (registered_commands ) > 0 :
161
165
matches = [
@@ -185,41 +189,64 @@ async def register_commands(self) -> None:
185
189
update_guild_commands = {}
186
190
async for guild in self .fetch_guilds (limit = None ):
187
191
update_guild_commands [guild .id ] = []
188
- for command in [cmd for cmd in self .pending_application_commands if cmd .guild_ids is not None ]:
192
+ for command in [
193
+ cmd
194
+ for cmd in self .pending_application_commands
195
+ if cmd .guild_ids is not None
196
+ ]:
189
197
as_dict = command .to_dict ()
190
198
for guild_id in command .guild_ids :
191
199
to_update = update_guild_commands [guild_id ]
192
200
update_guild_commands [guild_id ] = to_update + [as_dict ]
193
201
194
- for guild_id in update_guild_commands :
202
+ for guild_id , guild_data in update_guild_commands . items () :
195
203
try :
196
- cmds = await self .http .bulk_upsert_guild_commands (self .user .id , guild_id ,
197
- update_guild_commands [guild_id ])
204
+ cmds = await self .http .bulk_upsert_guild_commands (
205
+ self .user .id , guild_id , update_guild_commands [guild_id ]
206
+ )
198
207
199
208
# Permissions for this Guild
200
209
guild_permissions : List = []
201
210
except Forbidden :
202
- if not update_guild_commands [ guild_id ] :
211
+ if not guild_data :
203
212
continue
204
- else :
205
- print (f"Failed to add command to guild { guild_id } " , file = sys .stderr )
206
- raise
213
+ print (f"Failed to add command to guild { guild_id } " , file = sys .stderr )
214
+ raise
207
215
else :
208
216
for i in cmds :
209
- cmd = get (self .pending_application_commands , name = i ["name" ], description = i ["description" ],
210
- type = i ['type' ])
217
+ cmd = get (
218
+ self .pending_application_commands ,
219
+ name = i ["name" ],
220
+ description = i ["description" ],
221
+ type = i ["type" ],
222
+ )
211
223
self .application_commands [i ["id" ]] = cmd
212
224
213
225
# Permissions
214
- permissions = [perm .to_dict () for perm in cmd .permissions if perm .guild_id is None or (
215
- perm .guild_id == guild_id and perm .guild_id in cmd .guild_ids )]
216
- guild_permissions .append ({"id" : i ["id" ], "permissions" : permissions })
226
+ permissions = [
227
+ perm .to_dict ()
228
+ for perm in cmd .permissions
229
+ if perm .guild_id is None
230
+ or (
231
+ perm .guild_id == guild_id and perm .guild_id in cmd .guild_ids
232
+ )
233
+ ]
234
+ guild_permissions .append (
235
+ {"id" : i ["id" ], "permissions" : permissions }
236
+ )
217
237
218
238
for global_command in global_permissions :
219
- permissions = [perm .to_dict () for perm in global_command ['permissions' ] if
220
- perm .guild_id is None or (
221
- perm .guild_id == guild_id and perm .guild_id in cmd .guild_ids )]
222
- guild_permissions .append ({"id" : global_command ["id" ], "permissions" : permissions })
239
+ permissions = [
240
+ perm .to_dict ()
241
+ for perm in global_command ["permissions" ]
242
+ if perm .guild_id is None
243
+ or (
244
+ perm .guild_id == guild_id and perm .guild_id in cmd .guild_ids
245
+ )
246
+ ]
247
+ guild_permissions .append (
248
+ {"id" : global_command ["id" ], "permissions" : permissions }
249
+ )
223
250
224
251
# Collect & Upsert Permissions for Each Guild
225
252
# Command Permissions for this Guild
@@ -231,47 +258,78 @@ async def register_commands(self) -> None:
231
258
232
259
# Replace Role / Owner Names with IDs
233
260
for permission in item ["permissions" ]:
234
- if isinstance (permission ['id' ], str ):
261
+ if isinstance (permission ["id" ], str ):
235
262
# Replace Role Names
236
- if permission ['type' ] == 1 and isinstance (permission ['id' ], str ):
237
- role = get (self .get_guild (guild_id ).roles , name = permission ['id' ])
263
+ if permission ["type" ] == 1 :
264
+ role = get (
265
+ self .get_guild (guild_id ).roles ,
266
+ name = permission ["id" ],
267
+ )
238
268
239
269
# If not missing
240
- if not role is None :
270
+ if role is not None :
241
271
new_cmd_perm ["permissions" ].append (
242
- {"id" : role .id , "type" : 1 , "permission" : permission ['permission' ]})
272
+ {
273
+ "id" : role .id ,
274
+ "type" : 1 ,
275
+ "permission" : permission ["permission" ],
276
+ }
277
+ )
243
278
else :
244
- print ("No Role ID found in Guild ({guild_id}) for Role ({role})" .format (
245
- guild_id = guild_id , role = permission ['id' ]))
246
- # Add Owner IDs
247
- elif permission ['type' ] == 2 and permission ['id' ] == "owner" :
279
+ print (
280
+ "No Role ID found in Guild ({guild_id}) for Role ({role})" .format (
281
+ guild_id = guild_id , role = permission ["id" ]
282
+ )
283
+ )
284
+ # Add owner IDs
285
+ elif (
286
+ permission ["type" ] == 2 and permission ["id" ] == "owner"
287
+ ):
248
288
app = await self .application_info () # type: ignore
249
289
if app .team :
250
290
for m in app .team .members :
251
291
new_cmd_perm ["permissions" ].append (
252
- {"id" : m .id , "type" : 2 , "permission" : permission ['permission' ]})
292
+ {
293
+ "id" : m .id ,
294
+ "type" : 2 ,
295
+ "permission" : permission ["permission" ],
296
+ }
297
+ )
253
298
else :
254
299
new_cmd_perm ["permissions" ].append (
255
- {"id" : app .owner .id , "type" : 2 , "permission" : permission ['permission' ]})
256
- # Add the Rest
300
+ {
301
+ "id" : app .owner .id ,
302
+ "type" : 2 ,
303
+ "permission" : permission ["permission" ],
304
+ }
305
+ )
306
+ # Add the rest
257
307
else :
258
308
new_cmd_perm ["permissions" ].append (permission )
259
309
260
310
# Make sure we don't have over 10 overwrites
261
- if len (new_cmd_perm [' permissions' ]) > 10 :
311
+ if len (new_cmd_perm [" permissions" ]) > 10 :
262
312
print (
263
313
"Command '{name}' has more than 10 permission overrides in guild ({guild_id}).\n will only use the first 10 permission overrides." .format (
264
- name = self .application_commands [new_cmd_perm ['id' ]].name , guild_id = guild_id ))
265
- new_cmd_perm ['permissions' ] = new_cmd_perm ['permissions' ][:10 ]
314
+ name = self .application_commands [new_cmd_perm ["id" ]].name ,
315
+ guild_id = guild_id ,
316
+ )
317
+ )
318
+ new_cmd_perm ["permissions" ] = new_cmd_perm ["permissions" ][:10 ]
266
319
267
320
# Append to guild_cmd_perms
268
321
guild_cmd_perms .append (new_cmd_perm )
269
322
270
323
# Upsert
271
324
try :
272
- await self .http .bulk_upsert_command_permissions (self .user .id , guild_id , guild_cmd_perms )
325
+ await self .http .bulk_upsert_command_permissions (
326
+ self .user .id , guild_id , guild_cmd_perms
327
+ )
273
328
except Forbidden :
274
- print (f"Failed to add command permissions to guild { guild_id } " , file = sys .stderr )
329
+ print (
330
+ f"Failed to add command permissions to guild { guild_id } " ,
331
+ file = sys .stderr ,
332
+ )
275
333
raise
276
334
277
335
async def process_application_commands (self , interaction : Interaction ) -> None :
@@ -306,16 +364,16 @@ async def process_application_commands(self, interaction: Interaction) -> None:
306
364
else :
307
365
ctx = await self .get_application_context (interaction )
308
366
ctx .command = command
309
- self .dispatch (' application_command' , ctx )
367
+ self .dispatch (" application_command" , ctx )
310
368
try :
311
369
if await self .can_run (ctx , call_once = True ):
312
370
await ctx .command .invoke (ctx )
313
371
else :
314
- raise CheckFailure (' The global check once functions failed.' )
372
+ raise CheckFailure (" The global check once functions failed." )
315
373
except DiscordException as exc :
316
374
await ctx .command .dispatch_error (ctx , exc )
317
375
else :
318
- self .dispatch (' application_command_completion' , ctx )
376
+ self .dispatch (" application_command_completion" , ctx )
319
377
320
378
def slash_command (self , ** kwargs ):
321
379
"""A shortcut decorator that invokes :func:`.ApplicationCommandMixin.command` and adds it to
@@ -400,7 +458,9 @@ def command(self, **kwargs):
400
458
"""
401
459
return self .application_command (** kwargs )
402
460
403
- def command_group (self , name : str , description : str , guild_ids = None ) -> SlashCommandGroup :
461
+ def command_group (
462
+ self , name : str , description : str , guild_ids = None
463
+ ) -> SlashCommandGroup :
404
464
# TODO: Write documentation for this. I'm not familiar enough with what this function does to do it myself.
405
465
group = SlashCommandGroup (name , description , guild_ids )
406
466
self .add_application_command (group )
@@ -451,24 +511,30 @@ def __init__(self, description=None, *args, **options):
451
511
self ._check_once = []
452
512
self ._before_invoke = None
453
513
self ._after_invoke = None
454
- self .description = inspect .cleandoc (description ) if description else ''
455
- self .owner_id = options .get (' owner_id' )
456
- self .owner_ids = options .get (' owner_ids' , set ())
514
+ self .description = inspect .cleandoc (description ) if description else ""
515
+ self .owner_id = options .get (" owner_id" )
516
+ self .owner_ids = options .get (" owner_ids" , set ())
457
517
458
- self .debug_guild = options .pop ("debug_guild" , None ) # TODO: remove or reimplement
518
+ self .debug_guild = options .pop (
519
+ "debug_guild" , None
520
+ ) # TODO: remove or reimplement
459
521
self .debug_guilds = options .pop ("debug_guilds" , None )
460
522
461
523
if self .owner_id and self .owner_ids :
462
- raise TypeError (' Both owner_id and owner_ids are set.' )
524
+ raise TypeError (" Both owner_id and owner_ids are set." )
463
525
464
- if self .owner_ids and not isinstance (self .owner_ids , collections .abc .Collection ):
465
- raise TypeError (f'owner_ids must be a collection not { self .owner_ids .__class__ !r} ' )
526
+ if self .owner_ids and not isinstance (
527
+ self .owner_ids , collections .abc .Collection
528
+ ):
529
+ raise TypeError (
530
+ f"owner_ids must be a collection not { self .owner_ids .__class__ !r} "
531
+ )
466
532
467
533
if self .debug_guild :
468
534
if self .debug_guilds is None :
469
535
self .debug_guilds = [self .debug_guild ]
470
536
else :
471
- raise TypeError (' Both debug_guild and debug_guilds are set.' )
537
+ raise TypeError (" Both debug_guild and debug_guilds are set." )
472
538
473
539
self ._checks = []
474
540
self ._check_once = []
@@ -481,7 +547,9 @@ async def on_connect(self):
481
547
async def on_interaction (self , interaction ):
482
548
await self .process_application_commands (interaction )
483
549
484
- async def on_application_command_error (self , context : ApplicationContext , exception : DiscordException ) -> None :
550
+ async def on_application_command_error (
551
+ self , context : ApplicationContext , exception : DiscordException
552
+ ) -> None :
485
553
"""|coro|
486
554
487
555
The default command error handler provided by the bot.
@@ -504,8 +572,10 @@ async def on_application_command_error(self, context: ApplicationContext, except
504
572
# if cog and cog.has_error_handler():
505
573
# return
506
574
507
- print (f'Ignoring exception in command { context .command } :' , file = sys .stderr )
508
- traceback .print_exception (type (exception ), exception , exception .__traceback__ , file = sys .stderr )
575
+ print (f"Ignoring exception in command { context .command } :" , file = sys .stderr )
576
+ traceback .print_exception (
577
+ type (exception ), exception , exception .__traceback__ , file = sys .stderr
578
+ )
509
579
510
580
# global check registration
511
581
# TODO: Remove these from commands.Bot
@@ -611,7 +681,9 @@ def whitelist(ctx):
611
681
self .add_check (func , call_once = True )
612
682
return func
613
683
614
- async def can_run (self , ctx : ApplicationContext , * , call_once : bool = False ) -> bool :
684
+ async def can_run (
685
+ self , ctx : ApplicationContext , * , call_once : bool = False
686
+ ) -> bool :
615
687
data = self ._check_once if call_once else self ._checks
616
688
617
689
if len (data ) == 0 :
@@ -620,7 +692,6 @@ async def can_run(self, ctx: ApplicationContext, *, call_once: bool = False) ->
620
692
# type-checker doesn't distinguish between functions and methods
621
693
return await async_all (f (ctx ) for f in data ) # type: ignore
622
694
623
-
624
695
def before_invoke (self , coro ):
625
696
"""A decorator that registers a coroutine as a pre-invoke hook.
626
697
A pre-invoke hook is called directly before the command is
@@ -646,7 +717,7 @@ def before_invoke(self, coro):
646
717
The coroutine passed is not actually a coroutine.
647
718
"""
648
719
if not asyncio .iscoroutinefunction (coro ):
649
- raise TypeError (' The pre-invoke hook must be a coroutine.' )
720
+ raise TypeError (" The pre-invoke hook must be a coroutine." )
650
721
651
722
self ._before_invoke = coro
652
723
return coro
@@ -678,11 +749,12 @@ def after_invoke(self, coro):
678
749
679
750
"""
680
751
if not asyncio .iscoroutinefunction (coro ):
681
- raise TypeError (' The post-invoke hook must be a coroutine.' )
752
+ raise TypeError (" The post-invoke hook must be a coroutine." )
682
753
683
754
self ._after_invoke = coro
684
755
return coro
685
756
757
+
686
758
class Bot (BotBase , Client ):
687
759
"""Represents a discord bot.
688
760
0 commit comments