Skip to content

Commit b600dbb

Browse files
refactor: cache guild info and guild channels
this lowers the amount of requests we make and reduces the chance of ratelimiting
1 parent 00c0f13 commit b600dbb

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed

botstrap.py

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,36 @@ def __init__(self, guild_id: int | str):
8484
)
8585
self.guild_id = guild_id
8686
self._app_info: dict[str, Any] | None = None
87+
self._guild_info: dict[str, Any] | None = None
88+
self._guild_channels: list[dict[str, Any]] | None = None
8789

8890
@staticmethod
8991
def _raise_for_status(response: Response) -> None:
9092
response.raise_for_status()
9193

9294
@property
95+
def guild_info(self) -> dict[str, Any]:
96+
"""Fetches the guild's information."""
97+
if self._guild_info is None:
98+
response = self.get(f"/guilds/{self.guild_id}")
99+
self._guild_info = cast("dict[str, Any]", response.json())
100+
return self._guild_info
101+
102+
@property
103+
def guild_channels(self) -> list[dict[str, Any]]:
104+
"""Fetches the guild's channels."""
105+
if self._guild_channels is None:
106+
response = self.get(f"/guilds/{self.guild_id}/channels")
107+
self._guild_channels = cast("list[dict[str, Any]]", response.json())
108+
return self._guild_channels
109+
110+
def get_channel(self, id: int | str) -> dict[str, Any]:
111+
"""Fetches a channel by its ID."""
112+
for channel in self.guild_channels:
113+
if channel["id"] == str(id):
114+
return channel
115+
raise KeyError(f"Channel with ID {id} not found.")
116+
@property
93117
def app_info(self) -> dict[str, Any]:
94118
"""Fetches the application's information."""
95119
if self._app_info is None:
@@ -117,26 +141,25 @@ def upgrade_application_flags_if_necessary(self) -> bool:
117141
def check_if_in_guild(self) -> bool:
118142
"""Check if the bot is a member of the guild."""
119143
try:
120-
response = self.get(f"/guilds/{self.guild_id}")
144+
_ = self.guild_info
121145
except HTTPStatusError:
122146
return False
123-
return response.status_code == 200
147+
return True
124148

125149
def upgrade_server_to_community_if_necessary(
126150
self,
127151
rules_channel_id_: int | str,
128152
announcements_channel_id_: int | str,
129153
) -> None:
130154
"""Fetches server info & upgrades to COMMUNITY if necessary."""
131-
response = self.get(f"/guilds/{self.guild_id}")
132-
payload = response.json()
155+
payload = self.guild_info
133156

134157
if COMMUNITY_FEATURE not in payload["features"]:
135158
log.info("This server is currently not a community, upgrading.")
136159
payload["features"].append(COMMUNITY_FEATURE)
137160
payload["rules_channel_id"] = rules_channel_id_
138161
payload["public_updates_channel_id"] = announcements_channel_id_
139-
self.patch(f"/guilds/{self.guild_id}", json=payload)
162+
self._guild_info = self.patch(f"/guilds/{self.guild_id}", json=payload).json()
140163
log.info(f"Server {self.guild_id} has been successfully updated to a community.")
141164

142165
def create_forum_channel(self, channel_name_: str, category_id_: int | str | None = None) -> str:
@@ -150,22 +173,20 @@ def create_forum_channel(self, channel_name_: str, category_id_: int | str | Non
150173
log.info(f"New forum channel: {channel_name_} has been successfully created.")
151174
return forum_channel_id
152175

153-
def is_forum_channel(self, channel_id_: str) -> bool:
176+
def is_forum_channel(self, channel_id: str) -> bool:
154177
"""A boolean that indicates if a channel is of type GUILD_FORUM."""
155-
response = self.get(f"/channels/{channel_id_}")
156-
return response.json()["type"] == GUILD_FORUM_TYPE
178+
return self.get_channel(channel_id)["type"] == GUILD_FORUM_TYPE
157179

158-
def delete_channel(self, channel_id_: str | int) -> None:
180+
def delete_channel(self, channel_id: str | int) -> None:
159181
"""Delete a channel."""
160-
log.info(f"Channel python-help: {channel_id_} is not a forum channel and will be replaced with one.")
161-
self.delete(f"/channels/{channel_id_}")
182+
log.info("Channel python-help: %s is not a forum channel and will be replaced with one.", channel_id)
183+
self.delete(f"/channels/{channel_id}")
162184

163185
def get_all_roles(self) -> dict[str, int]:
164186
"""Fetches all the roles in a guild."""
165187
result = SilencedDict(name="Roles dictionary")
166188

167-
response = self.get(f"guilds/{self.guild_id}/roles")
168-
roles = response.json()
189+
roles = self.guild_info["roles"]
169190

170191
for role in roles:
171192
name = "_".join(part.lower() for part in role["name"].split(" ")).replace("-", "_")
@@ -180,8 +201,7 @@ def get_all_channels_and_categories(self) -> tuple[dict[str, str], dict[str, str
180201
channels = SilencedDict(name="Channels dictionary")
181202
categories = SilencedDict(name="Categories dictionary")
182203

183-
response = self.get(f"guilds/{self.guild_id}/channels")
184-
server_channels = response.json()
204+
server_channels = self.guild_channels
185205

186206
for channel in server_channels:
187207
channel_type = channel["type"]

0 commit comments

Comments
 (0)