3
3
import os
4
4
from datetime import datetime
5
5
from http .client import HTTPException
6
+ import random
6
7
from typing import Any
7
8
8
9
import discord
9
10
import psutil
10
11
import tzlocal
11
12
from apscheduler .schedulers .asyncio import AsyncIOScheduler
12
- from discord import Interaction , Guild
13
+ from discord import Guild , app_commands , Interaction , VoiceChannel , TextChannel , Message
14
+ from discord .app_commands import errors , Command
13
15
from discord .embeds import Embed
14
16
from discord .errors import NotFound
15
- from discord .ext .commands import AutoShardedBot as BaseBot
17
+ from discord .ext .commands import AutoShardedBot , Context
18
+ from discord import AutoShardedClient
19
+ from discord .ext .commands ._types import BotT
16
20
from discord .ext .commands .errors import CommandNotFound , BadArgument , MissingRequiredArgument , CommandOnCooldown , \
17
21
MissingPermissions , BotMissingPermissions
18
22
19
23
from lib .config import Config
20
- from lib .context import CustomContext
21
24
from lib .db import DB
22
- from lib .progress import Progress
25
+ from lib .errors import BotNotReady
26
+ from lib .progress import Progress , Timer
23
27
from lib .urban import UrbanDictionary
24
28
25
29
COMMAND_ERROR_REGEX = r"Command raised an exception: (.*?(?=: )): (.*)"
26
30
IGNORE_EXCEPTIONS = (CommandNotFound , BadArgument , RuntimeError )
27
31
28
32
29
- class Bot (BaseBot ):
33
+ class Bot (AutoShardedBot ):
30
34
def __init__ (self , shards : list [int ], version : str ):
31
35
self .config : Config = Config ()
32
36
self .db : DB = DB ()
@@ -36,24 +40,26 @@ def __init__(self, shards: list[int], version: str):
36
40
self .shards_ready = False
37
41
self .ready = False
38
42
self .expected_shards = len (shards )
43
+ self .timer = Timer ()
39
44
self .shard_progress = Progress ('Shards Ready' , self .expected_shards )
40
45
self .urban : UrbanDictionary = UrbanDictionary ()
41
46
self .VERSION = version
42
47
super ().__init__ (
48
+ command_prefix = None ,
43
49
owner_id = "507214515641778187" ,
44
50
shards = shards ,
45
51
intents = discord .Intents .all (),
46
- debug_guilds = ["1064582321728143421" ],
47
52
description = "Misc Bot used for advanced moderation and guild customization" )
48
53
self .tasks .add_job (self .db .commit , trigger = 'interval' , minutes = 30 )
49
54
self .shard_progress .start ()
50
55
51
56
async def on_connect (self ):
52
- await self .sync_commands ()
57
+ await self .tree . sync ()
53
58
while not self .shards_ready :
54
59
await asyncio .sleep (.5 )
55
- print (f"Signed into { self .user .display_name } #{ self .user .discriminator } " )
56
60
self .register_guilds ()
61
+ print (f"Signed into { self .user .display_name } #{ self .user .discriminator } " )
62
+ # asyncio.ensure_future(self.timer.start())
57
63
58
64
async def on_shard_ready (self , shard_id ):
59
65
await self .change_presence (activity = discord .Activity (type = discord .ActivityType .watching ,
@@ -63,6 +69,34 @@ async def on_shard_ready(self, shard_id):
63
69
if shard_id + 1 == self .expected_shards :
64
70
self .shards_ready = True
65
71
72
+ async def on_interaction (self , ctx : Interaction ):
73
+ if isinstance (ctx .command , Command ):
74
+ name_list , options = self .get_name (ctx .data , [])
75
+ name = " " .join (name_list )
76
+ self .db .execute (f"""INSERT INTO commands VALUES (?,?,?,?,?)""" , name , ctx .guild_id ,
77
+ ctx .user .id , json .dumps (options ), datetime .now ().timestamp ())
78
+
79
+ @staticmethod
80
+ async def send (ctx : Interaction , * args , ** kwargs ):
81
+ if kwargs .get ('embed' ):
82
+ embed : Embed = kwargs ['embed' ]
83
+ if not isinstance (embed .colour , discord .Colour ):
84
+ color = int ("0x" + '' .join ([random .choice ('0123456789ABCDEF' ) for j in range (6 )]), 16 )
85
+ embed .colour = color
86
+ embed .set_footer (text = "Made by Gccody" )
87
+ embed .timestamp = datetime .now ()
88
+ # embed.set_thumbnail(url=self.logo_path)
89
+ kwargs ['embed' ] = embed
90
+ if ctx .is_expired ():
91
+ channel = ctx .channel
92
+ if not isinstance (channel , VoiceChannel ):
93
+ return await ctx .channel .send (* args , ** kwargs )
94
+ try :
95
+ await ctx .original_response ()
96
+ return await ctx .followup .send (* args , ** kwargs )
97
+ except NotFound :
98
+ return await ctx .response .send_message (* args , ** kwargs )
99
+
66
100
def register_guilds (self ):
67
101
progress = Progress ('Registering guilds' , len (self .guilds ))
68
102
for guild in self .guilds :
@@ -71,12 +105,6 @@ def register_guilds(self):
71
105
self .db .commit ()
72
106
self .ready = True
73
107
self .tasks .start ()
74
- print ('\n Everything is ready!' )
75
-
76
- async def get_application_context (
77
- self , interaction : Interaction , cls = CustomContext
78
- ):
79
- return await super ().get_application_context (interaction , cls = cls )
80
108
81
109
async def on_guild_join (self , guild : Guild ):
82
110
self .db .execute ("""INSERT OR IGNORE INTO guilds VALUES (?,?,?)""" , guild .id , None , None )
@@ -105,50 +133,6 @@ def get_name(self, data: Any, groups: list[str]):
105
133
else :
106
134
return self .get_name (data .get ('options' ), [* groups , data .get ('name' )])
107
135
108
- async def on_interaction (self , interaction : discord .Interaction ):
109
- if not self .ready : return
110
- if interaction .is_command ():
111
- name_list , options = self .get_name (interaction .data , [])
112
- name = " " .join (name_list )
113
- self .db .execute (f"""INSERT INTO commands VALUES (?,?,?,?,?)""" , name , interaction .guild_id ,
114
- interaction .user .id , json .dumps (options ), datetime .now ().timestamp ())
115
- return await super ().on_interaction (interaction = interaction )
116
-
117
- async def on_application_command_error (self , ctx : CustomContext , exc ) -> None :
118
- if any ([isinstance (exc , error ) for error in IGNORE_EXCEPTIONS ]):
119
- pass
120
- elif isinstance (exc , MissingRequiredArgument ):
121
- await ctx .respond ("One or more required arguments are missing." )
122
- elif isinstance (exc , CommandOnCooldown ):
123
- embed : Embed = Embed (title = 'Command on Cooldown' ,
124
- description = f"That command is on cooldown. Try again in { exc .retry_after :,.2f} seconds." ,
125
- colour = 0xff0000 )
126
- await ctx .respond (embed = embed )
127
- elif isinstance (exc , MissingPermissions ):
128
- embed : Embed = Embed (title = 'You are missing permissions' , description = f'>>> { exc } ' , colour = 0xff0000 )
129
- elif isinstance (exc , BotMissingPermissions ):
130
- embed : Embed = Embed (title = 'Bot Missing Permissions' , description = f">>> { exc } " , colour = 0xff0000 )
131
- await ctx .respond (embed = embed )
132
- elif isinstance (exc , HTTPException ):
133
- embed : Embed = Embed (title = "Http Error" , description = 'Message failed to send' , colour = 0xff0000 )
134
- await ctx .respond (embed = embed )
135
- elif isinstance (exc , NotFound ):
136
- await ctx .respond (embed = Embed (title = 'Not Found Error' , description = 'One or more items could not be found.' ,
137
- colour = 0xff0000 ))
138
- elif hasattr (exc , "original" ):
139
- if isinstance (exc .original , HTTPException ):
140
- embed : Embed = Embed (title = "Http Error" , description = 'Message failed to send' , colour = 0xff0000 )
141
- await ctx .respond (embed = embed )
142
- if isinstance (exc .original , discord .Forbidden ):
143
- await ctx .message .delete ()
144
- embed : Embed = Embed (title = 'Forbidden Error' , description = 'Insufficient Permissions' , colour = 0xff0000 )
145
- await ctx .respond (embed = embed )
146
- else :
147
- raise exc .original
148
-
149
- else :
150
- raise exc
151
-
152
136
@staticmethod
153
137
async def cpu_percent (interval = None , * args , ** kwargs ):
154
138
python_process = psutil .Process (os .getpid ())
0 commit comments