Skip to content

Commit 2163904

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 b488508 commit 2163904

File tree

1 file changed

+35
-16
lines changed

1 file changed

+35
-16
lines changed

botstrap.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +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

94+
@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+
92117
@property
93118
def app_info(self) -> dict[str, Any]:
94119
"""Fetches the application's information."""
@@ -117,7 +142,7 @@ def upgrade_application_flags_if_necessary(self) -> bool:
117142
def check_if_in_guild(self) -> bool:
118143
"""Check if the bot is a member of the guild."""
119144
try:
120-
_ = self.get(f"/guilds/{self.guild_id}")
145+
_ = self.guild_info
121146
except HTTPStatusError as e:
122147
if e.response.status_code == 403 or e.response.status_code == 404:
123148
return False
@@ -130,15 +155,14 @@ def upgrade_server_to_community_if_necessary(
130155
announcements_channel_id_: int | str,
131156
) -> None:
132157
"""Fetches server info & upgrades to COMMUNITY if necessary."""
133-
response = self.get(f"/guilds/{self.guild_id}")
134-
payload = response.json()
158+
payload = self.guild_info
135159

136160
if COMMUNITY_FEATURE not in payload["features"]:
137161
log.info("This server is currently not a community, upgrading.")
138162
payload["features"].append(COMMUNITY_FEATURE)
139163
payload["rules_channel_id"] = rules_channel_id_
140164
payload["public_updates_channel_id"] = announcements_channel_id_
141-
self.patch(f"/guilds/{self.guild_id}", json=payload)
165+
self._guild_info = self.patch(f"/guilds/{self.guild_id}", json=payload).json()
142166
log.info(f"Server {self.guild_id} has been successfully updated to a community.")
143167

144168
def create_forum_channel(self, channel_name_: str, category_id_: int | str | None = None) -> str:
@@ -152,22 +176,20 @@ def create_forum_channel(self, channel_name_: str, category_id_: int | str | Non
152176
log.info(f"New forum channel: {channel_name_} has been successfully created.")
153177
return forum_channel_id
154178

155-
def is_forum_channel(self, channel_id_: str) -> bool:
179+
def is_forum_channel(self, channel_id: str) -> bool:
156180
"""A boolean that indicates if a channel is of type GUILD_FORUM."""
157-
response = self.get(f"/channels/{channel_id_}")
158-
return response.json()["type"] == GUILD_FORUM_TYPE
181+
return self.get_channel(channel_id)["type"] == GUILD_FORUM_TYPE
159182

160-
def delete_channel(self, channel_id_: str | int) -> None:
183+
def delete_channel(self, channel_id: str | int) -> None:
161184
"""Delete a channel."""
162-
log.info(f"Channel python-help: {channel_id_} is not a forum channel and will be replaced with one.")
163-
self.delete(f"/channels/{channel_id_}")
185+
log.info("Channel python-help: %s is not a forum channel and will be replaced with one.", channel_id)
186+
self.delete(f"/channels/{channel_id}")
164187

165188
def get_all_roles(self) -> dict[str, int]:
166189
"""Fetches all the roles in a guild."""
167190
result = SilencedDict(name="Roles dictionary")
168191

169-
response = self.get(f"guilds/{self.guild_id}/roles")
170-
roles = response.json()
192+
roles = self.guild_info["roles"]
171193

172194
for role in roles:
173195
name = "_".join(part.lower() for part in role["name"].split(" ")).replace("-", "_")
@@ -182,10 +204,7 @@ def get_all_channels_and_categories(self) -> tuple[dict[str, str], dict[str, str
182204
channels = SilencedDict(name="Channels dictionary")
183205
categories = SilencedDict(name="Categories dictionary")
184206

185-
response = self.get(f"guilds/{self.guild_id}/channels")
186-
server_channels = response.json()
187-
188-
for channel in server_channels:
207+
for channel in self.guild_channels:
189208
channel_type = channel["type"]
190209
name = "_".join(part.lower() for part in channel["name"].split(" ")).replace("-", "_")
191210
if re.match(off_topic_channel_name_regex, name):

0 commit comments

Comments
 (0)