4848GUILD_CATEGORY_TYPE = 4
4949EMOJI_REGEX = re .compile (r"<:(\w+):(\d+)>" )
5050
51+ MINIMUM_FLAGS : int = (
52+ 1 << 15 # guild_members_limited
53+ | 1 << 19 # message_content_limited
54+ )
55+
5156if GuildConstants .id == type (GuildConstants ).model_fields ["id" ].default :
5257 msg = (
5358 "Couldn't find the `GUILD_ID` environment variable. "
5762 sys .exit (1 )
5863
5964
60- class SilencedDict (dict [str , Any ]):
65+ class SilencedDict [ T ] (dict [str , T ]):
6166 """A dictionary that silences KeyError exceptions upon subscription to non existent items."""
6267
6368 def __init__ (self , name : str ):
@@ -93,9 +98,9 @@ def __init__(self, *, guild_id: int | str, bot_token: str):
9398 event_hooks = {"response" : [self ._raise_for_status ]},
9499 )
95100 self .guild_id : int | str = guild_id
96- self ._app_info : dict [str , Any ] | None = None
97- self ._guild_info : dict [str , Any ] | None = None
98- self ._guild_channels : list [dict [str , Any ]] | None = None
101+ self ._app_info : dict [str , object ] | None = None
102+ self ._guild_info : dict [str , object ] | None = None
103+ self ._guild_channels : list [dict [str , object ]] | None = None
99104
100105 @staticmethod
101106 def _raise_for_status (response : Response ) -> None :
@@ -105,17 +110,17 @@ def get_guild_info(self) -> dict[str, Any]:
105110 """Fetches the guild's information."""
106111 if self ._guild_info is None :
107112 response = self .get (f"/guilds/{ self .guild_id } " )
108- self ._guild_info = cast ("dict[str, Any ]" , response .json ())
113+ self ._guild_info = cast ("dict[str, object ]" , response .json ())
109114 return self ._guild_info
110115
111116 def get_guild_channels (self ) -> list [dict [str , Any ]]:
112117 """Fetches the guild's channels."""
113118 if self ._guild_channels is None :
114119 response = self .get (f"/guilds/{ self .guild_id } /channels" )
115- self ._guild_channels = cast ("list[dict[str, Any ]]" , response .json ())
120+ self ._guild_channels = cast ("list[dict[str, object ]]" , response .json ())
116121 return self ._guild_channels
117122
118- def get_channel (self , id_ : int | str ) -> dict [str , Any ]:
123+ def get_channel (self , id_ : int | str ) -> dict [str , object ]:
119124 """Fetches a channel by its ID."""
120125 for channel in self .get_guild_channels ():
121126 if channel ["id" ] == str (id_ ):
@@ -126,7 +131,7 @@ def get_app_info(self) -> dict[str, Any]:
126131 """Fetches the application's information."""
127132 if self ._app_info is None :
128133 response = self .get ("/applications/@me" )
129- self ._app_info = cast ("dict[str, Any ]" , response .json ())
134+ self ._app_info = cast ("dict[str, object ]" , response .json ())
130135 return self ._app_info
131136
132137 def upgrade_application_flags_if_necessary (self ) -> bool :
@@ -137,11 +142,11 @@ def upgrade_application_flags_if_necessary(self) -> bool:
137142 """
138143 # Fetch first to modify, not overwrite
139144 current_flags = self .get_app_info ().get ("flags" , 0 )
140- new_flags = current_flags | 1 << 15 | 1 << 19
145+ new_flags = current_flags | MINIMUM_FLAGS
141146
142147 if new_flags != current_flags :
143148 resp = self .patch ("/applications/@me" , json = {"flags" : new_flags })
144- self ._app_info = cast ("dict[str, Any ]" , resp .json ())
149+ self ._app_info = cast ("dict[str, object ]" , resp .json ())
145150 return True
146151
147152 return False
@@ -176,7 +181,7 @@ def upgrade_server_to_community_if_necessary(
176181
177182 def get_all_roles (self ) -> dict [str , int ]:
178183 """Fetches all the roles in a guild."""
179- result = SilencedDict (name = "Roles dictionary" )
184+ result = SilencedDict [ int ] (name = "Roles dictionary" )
180185
181186 roles = self .get_guild_info ()["roles" ]
182187
@@ -190,8 +195,8 @@ def get_all_channels_and_categories(self) -> tuple[dict[str, str], dict[str, str
190195 """Fetches all the text channels & categories in a guild."""
191196 off_topic_channel_name_regex = r"ot\d{1}(_.*)+"
192197 off_topic_count = 0
193- channels = SilencedDict (name = "Channels dictionary" )
194- categories = SilencedDict (name = "Categories dictionary" )
198+ channels = SilencedDict [ str ] (name = "Channels dictionary" )
199+ categories = SilencedDict [ str ] (name = "Categories dictionary" )
195200
196201 for channel in self .get_guild_channels ():
197202 channel_type = channel ["type" ]
@@ -246,7 +251,7 @@ def clone_emoji(self, *, new_name: str, original_emoji_id: str | int) -> str:
246251
247252 payload = {
248253 "name" : new_name ,
249- "image" : f"data:image/png ;base64,{ image_data } " ,
254+ "image" : f"data:image/webp ;base64,{ image_data } " ,
250255 }
251256
252257 response = self .post (
@@ -346,7 +351,7 @@ def get_channels(self) -> dict[str, Any]:
346351
347352 return data
348353
349- def get_categories (self ) -> dict [str , Any ]:
354+ def get_categories (self ) -> dict [str , str ]:
350355 """Get a config map of all of the categories in guild."""
351356 log .debug ("Syncing categories with bot configuration." )
352357 _channels , all_categories = self .client .get_all_channels_and_categories ()
@@ -363,13 +368,13 @@ def get_categories(self) -> dict[str, Any]:
363368 data [category_name ] = category_id
364369 return data
365370
366- def sync_webhooks (self ) -> dict [str , Any ]:
371+ def sync_webhooks (self ) -> dict [str , object ]:
367372 """Get webhook config. Will create all webhooks that cannot be found."""
368373 log .debug ("Syncing webhooks with bot configuration." )
369374
370375 all_channels , _categories = self .client .get_all_channels_and_categories ()
371376
372- data : dict [str , Any ] = {}
377+ data : dict [str , object ] = {}
373378
374379 existing_webhooks = self .client .get_all_guild_webhooks ()
375380 for webhook_name , configured_webhook in Webhooks .model_dump ().items ():
@@ -394,7 +399,7 @@ def sync_webhooks(self) -> dict[str, Any]:
394399
395400 return data
396401
397- def sync_emojis (self ) -> dict [str , Any ]:
402+ def sync_emojis (self ) -> dict [str , str ]:
398403 """Get emoji config. Will create all emojis that cannot be found."""
399404 existing_emojis = self .client .list_emojis ()
400405 log .debug ("Syncing emojis with bot configuration." )
@@ -417,7 +422,7 @@ def sync_emojis(self) -> dict[str, Any]:
417422
418423 return data
419424
420- def write_config_env (self , config : dict [str , dict [str , Any ]]) -> bool :
425+ def write_config_env (self , config : dict [str , dict [str , object ]]) -> bool :
421426 """Write the configuration to the specified env_file."""
422427 if not self .env_file .exists ():
423428 self .env_file .touch ()
@@ -444,7 +449,7 @@ def run(self) -> bool:
444449 """Runs the botstrap process."""
445450 # Track if any changes were made and exit with an error code if so.
446451 changes : bool = False
447- config : dict [str , dict [str , object ]] = {}
452+ config : dict [str , dict [str , object | Any ]] = {}
448453 changes |= self .upgrade_client ()
449454 self .check_guild_membership ()
450455
@@ -474,8 +479,9 @@ def run(self) -> bool:
474479 botstrap = BotStrapper (guild_id = GuildConstants .id , env_file = ENV_FILE , bot_token = BotConstants .token )
475480 with botstrap :
476481 changes_made = botstrap .run ()
482+
477483 if changes_made :
478484 log .info ("Botstrap completed successfully. Updated configuration has been written to %s" , ENV_FILE )
479485 else :
480486 log .info ("Botstrap completed successfully. No changes were necessary." )
481- sys .exit (changes_made )
487+ sys .exit (0 )
0 commit comments