10
10
Any ,
11
11
AsyncIterator ,
12
12
Literal ,
13
- NamedTuple ,
14
13
Optional ,
15
14
Union ,
16
15
overload ,
49
48
)
50
49
OPTIONS_FILE = Path (__file__ ).parents [1 ] / "locale" / "options.json"
51
50
51
+ ### Enums
52
52
53
- class BlocklistTicket (NamedTuple ):
53
+
54
+ class ConfigType (Enum ):
55
+ TOGGLE = 0
56
+ SET = 1
57
+
58
+
59
+ ### Structs
60
+
61
+
62
+ class BlocklistTicket (msgspec .Struct , frozen = True ):
54
63
cog : Tickets
55
64
thread : discord .Thread
56
65
57
66
67
+ class ConfigHelpEntry (msgspec .Struct , frozen = True ):
68
+ key : str
69
+ default : str
70
+ description : str
71
+ examples : list [str ]
72
+ notes : list [str ]
73
+
74
+
58
75
class BlocklistEntity (msgspec .Struct , frozen = True ):
59
76
bot : Rodhaj
60
77
guild_id : int
@@ -66,63 +83,6 @@ def format(self) -> str:
66
83
return f"{ name } (ID: { self .entity_id } )"
67
84
68
85
69
- class BlocklistPages (SimplePages ):
70
- def __init__ (self , entries : list [BlocklistEntity ], * , ctx : GuildContext ):
71
- converted = [entry .format () for entry in entries ]
72
- super ().__init__ (converted , ctx = ctx )
73
-
74
-
75
- class Blocklist :
76
- def __init__ (self , bot : Rodhaj ):
77
- self .bot = bot
78
- self ._blocklist : dict [int , BlocklistEntity ] = {}
79
-
80
- async def _load (self , connection : Union [asyncpg .Connection , asyncpg .Pool ]):
81
- query = """
82
- SELECT guild_id, entity_id
83
- FROM blocklist;
84
- """
85
- rows = await connection .fetch (query )
86
- return {
87
- row ["entity_id" ]: BlocklistEntity (bot = self .bot , ** dict (row )) for row in rows
88
- }
89
-
90
- async def load (self , connection : Optional [asyncpg .Connection ] = None ):
91
- try :
92
- self ._blocklist = await self ._load (connection or self .bot .pool )
93
- except Exception :
94
- self ._blocklist = {}
95
-
96
- @overload
97
- def get (self , key : int ) -> Optional [BlocklistEntity ]: ...
98
-
99
- @overload
100
- def get (self , key : int ) -> BlocklistEntity : ...
101
-
102
- def get (self , key : int , default : Any = None ) -> Optional [BlocklistEntity ]:
103
- return self ._blocklist .get (key , default )
104
-
105
- def __contains__ (self , item : int ) -> bool :
106
- return item in self ._blocklist
107
-
108
- def __getitem__ (self , item : int ) -> BlocklistEntity :
109
- return self ._blocklist [item ]
110
-
111
- def __len__ (self ) -> int :
112
- return len (self ._blocklist )
113
-
114
- def all (self ) -> dict [int , BlocklistEntity ]:
115
- return self ._blocklist
116
-
117
- def replace (self , blocklist : dict [int , BlocklistEntity ]) -> None :
118
- self ._blocklist = blocklist
119
-
120
-
121
- class ConfigType (Enum ):
122
- TOGGLE = 0
123
- SET = 1
124
-
125
-
126
86
# Msgspec Structs are usually extremely fast compared to slotted classes
127
87
class GuildConfig (msgspec .Struct ):
128
88
bot : Rodhaj
@@ -196,6 +156,55 @@ def ticket_channel(self) -> Optional[discord.ForumChannel]:
196
156
return guild and guild .get_channel (self .ticket_channel_id ) # type: ignore
197
157
198
158
159
+ ### Core classes
160
+
161
+
162
+ class Blocklist :
163
+ def __init__ (self , bot : Rodhaj ):
164
+ self .bot = bot
165
+ self ._blocklist : dict [int , BlocklistEntity ] = {}
166
+
167
+ async def _load (self , connection : Union [asyncpg .Connection , asyncpg .Pool ]):
168
+ query = """
169
+ SELECT guild_id, entity_id
170
+ FROM blocklist;
171
+ """
172
+ rows = await connection .fetch (query )
173
+ return {
174
+ row ["entity_id" ]: BlocklistEntity (bot = self .bot , ** dict (row )) for row in rows
175
+ }
176
+
177
+ async def load (self , connection : Optional [asyncpg .Connection ] = None ):
178
+ try :
179
+ self ._blocklist = await self ._load (connection or self .bot .pool )
180
+ except Exception :
181
+ self ._blocklist = {}
182
+
183
+ @overload
184
+ def get (self , key : int ) -> Optional [BlocklistEntity ]: ...
185
+
186
+ @overload
187
+ def get (self , key : int ) -> BlocklistEntity : ...
188
+
189
+ def get (self , key : int , default : Any = None ) -> Optional [BlocklistEntity ]:
190
+ return self ._blocklist .get (key , default )
191
+
192
+ def __contains__ (self , item : int ) -> bool :
193
+ return item in self ._blocklist
194
+
195
+ def __getitem__ (self , item : int ) -> BlocklistEntity :
196
+ return self ._blocklist [item ]
197
+
198
+ def __len__ (self ) -> int :
199
+ return len (self ._blocklist )
200
+
201
+ def all (self ) -> dict [int , BlocklistEntity ]:
202
+ return self ._blocklist
203
+
204
+ def replace (self , blocklist : dict [int , BlocklistEntity ]) -> None :
205
+ self ._blocklist = blocklist
206
+
207
+
199
208
class GuildWebhookDispatcher :
200
209
def __init__ (self , bot : Rodhaj , guild_id : int ):
201
210
self .bot = bot
@@ -234,12 +243,7 @@ async def get_config(self) -> Optional[GuildWebhook]:
234
243
return GuildWebhook (bot = self .bot , ** dict (rows ))
235
244
236
245
237
- class ConfigHelpEntry (msgspec .Struct , frozen = True ):
238
- key : str
239
- default : str
240
- description : str
241
- examples : list [str ]
242
- notes : list [str ]
246
+ ### Embeds
243
247
244
248
245
249
class ConfigEntryEmbed (Embed ):
@@ -256,6 +260,15 @@ def __init__(self, entry: ConfigHelpEntry, **kwargs):
256
260
)
257
261
258
262
263
+ ### UI elements (Sources and Pages)
264
+
265
+
266
+ class BlocklistPages (SimplePages ):
267
+ def __init__ (self , entries : list [BlocklistEntity ], * , ctx : GuildContext ):
268
+ converted = [entry .format () for entry in entries ]
269
+ super ().__init__ (converted , ctx = ctx )
270
+
271
+
259
272
class ConfigHelpPageSource (menus .ListPageSource ):
260
273
async def format_page (self , menu : ConfigHelpPages , entry : ConfigHelpEntry ):
261
274
embed = ConfigEntryEmbed (entry = entry )
@@ -309,6 +322,9 @@ def __init__(
309
322
self .embed = discord .Embed (colour = discord .Colour .from_rgb (200 , 168 , 255 ))
310
323
311
324
325
+ ### Flags and Converters
326
+
327
+
312
328
class ConfigOptionFlags (commands .FlagConverter ):
313
329
active : Optional [bool ] = commands .flag (
314
330
name = "active" ,
@@ -377,6 +393,9 @@ async def convert(self, ctx: GuildContext, argument: str):
377
393
return argument
378
394
379
395
396
+ ### Command cog
397
+
398
+
380
399
class Config (commands .Cog ):
381
400
"""Config and setup commands for Rodhaj"""
382
401
@@ -511,6 +530,7 @@ def clean_prefixes(self, prefixes: Union[str, list[str]]) -> str:
511
530
return ", " .join (f"`{ prefix } `" for prefix in prefixes [2 :])
512
531
513
532
### Misc Utilities
533
+
514
534
async def _handle_error (
515
535
self , error : commands .CommandError , * , ctx : GuildContext
516
536
) -> None :
@@ -520,6 +540,8 @@ async def _handle_error(
520
540
elif isinstance (error , commands .BadArgument ):
521
541
await ctx .send (str (error ))
522
542
543
+ ### Commands
544
+
523
545
@is_manager ()
524
546
@bot_check_permissions (manage_channels = True , manage_webhooks = True )
525
547
@commands .guild_only ()
0 commit comments