Skip to content

Commit e44631a

Browse files
fix: only use one request for pulls
1 parent e99138b commit e44631a

File tree

1 file changed

+36
-33
lines changed

1 file changed

+36
-33
lines changed

bot/exts/utilities/githubinfo.py

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import re
33
from dataclasses import dataclass
44
from datetime import UTC, datetime
5+
from typing import Any
56
from urllib.parse import quote
67

78
import discord
@@ -22,7 +23,6 @@
2223

2324
REPOSITORY_ENDPOINT = "https://api.github.com/orgs/{org}/repos?per_page=100&type=public"
2425
ISSUE_ENDPOINT = "https://api.github.com/repos/{user}/{repository}/issues/{number}"
25-
PR_ENDPOINT = "https://api.github.com/repos/{user}/{repository}/pulls/{number}"
2626

2727
if Tokens.github:
2828
REQUEST_HEADERS["Authorization"] = f"token {Tokens.github.get_secret_value()}"
@@ -83,19 +83,13 @@ def remove_codeblocks(message: str) -> str:
8383
"""Remove any codeblock in a message."""
8484
return CODE_BLOCK_RE.sub("", message)
8585

86-
async def fetch_issue(
87-
self,
88-
number: int,
89-
repository: str,
90-
user: str
91-
) -> IssueState | FetchError:
86+
async def fetch_issue(self, number: int, repository: str, user: str) -> IssueState | FetchError:
9287
"""
9388
Retrieve an issue from a GitHub repository.
9489
9590
Returns IssueState on success, FetchError on failure.
9691
"""
9792
url = ISSUE_ENDPOINT.format(user=user, repository=repository, number=number)
98-
pulls_url = PR_ENDPOINT.format(user=user, repository=repository, number=number)
9993

10094
json_data, r = await self.fetch_data(url)
10195

@@ -109,35 +103,44 @@ async def fetch_issue(
109103
if r.status != 200:
110104
return FetchError(r.status, "Error while fetching issue.")
111105

112-
# The initial API request is made to the issues API endpoint, which will return information
113-
# if the issue or PR is present. However, the scope of information returned for PRs differs
114-
# from issues: if the 'issues' key is present in the response then we can pull the data we
115-
# need from the initial API call.
116-
if "issues" in json_data["html_url"]:
117-
emoji = Emojis.issue_open
118-
if json_data.get("state") == "closed":
119-
emoji = Emojis.issue_completed
120-
if json_data.get("state_reason") == "not_planned":
121-
emoji = Emojis.issue_not_planned
122-
123-
# If the 'issues' key is not contained in the API response and there is no error code, then
124-
# we know that a PR has been requested and a call to the pulls API endpoint is necessary
125-
# to get the desired information for the PR.
126-
else:
127-
pull_data, _ = await self.fetch_data(pulls_url)
128-
if pull_data["draft"]:
106+
# its important to note that the issues endpoint only provides issues and pull requests
107+
# discussions are not supported, but may still be provided
108+
# this method doesn't check for discussions, it just silently ignores them
109+
log.trace("Fetched issue/PR data: %r", json_data)
110+
if pull_data := json_data.get("pull_request"):
111+
if pull_data.get("merged_at"):
112+
emoji = Emojis.pull_request_merged
113+
elif json_data.get("draft") is True:
129114
emoji = Emojis.pull_request_draft
130-
elif pull_data["state"] == "open":
115+
elif json_data.get("state") == "open":
131116
emoji = Emojis.pull_request_open
132-
# When 'merged_at' is not None, this means that the state of the PR is merged
133-
elif pull_data["merged_at"] is not None:
134-
emoji = Emojis.pull_request_merged
135-
else:
117+
elif json_data.get("state") == "closed":
136118
emoji = Emojis.pull_request_closed
119+
else:
120+
# unknown state, GitHub added a new state and the emoji should be added
121+
log.error("Unknown PR state: %s for %s", json_data.get("state"), url)
122+
# fall the emoji back to a state
123+
emoji = Emojis.pull_request_open
124+
else:
125+
if json_data.get("state") == "closed":
126+
if json_data.get("state_reason") == "not_planned":
127+
emoji = Emojis.issue_not_planned
128+
else:
129+
emoji = Emojis.issue_completed
130+
elif json_data.get("draft") is True:
131+
# not currently used by GitHub, but future planning
132+
emoji = Emojis.issue_draft
133+
elif json_data.get("state") == "open":
134+
emoji = Emojis.issue_open
135+
else:
136+
# unknown state, GitHub added a new state and the emoji should be added
137+
log.error("Unknown issue state: %s for %s", json_data.get("state"), url)
138+
# fall the emoji back to a state
139+
emoji = Emojis.issue_open
137140

138-
issue_url = json_data.get("html_url")
141+
html_url = json_data["html_url"]
139142

140-
return IssueState(repository, number, issue_url, json_data.get("title", ""), emoji)
143+
return IssueState(repository, number, html_url, json_data.get("title", ""), emoji)
141144

142145
@staticmethod
143146
def format_embed(
@@ -217,7 +220,7 @@ async def on_message(self, message: discord.Message) -> None:
217220
resp = self.format_embed(links)
218221
await message.channel.send(embed=resp)
219222

220-
async def fetch_data(self, url: str) -> tuple[dict[str], ClientResponse]:
223+
async def fetch_data(self, url: str) -> tuple[dict[str, Any], ClientResponse]:
221224
"""Retrieve data as a dictionary and the response in a tuple."""
222225
log.trace(f"Querying GH issues API: {url}")
223226
async with self.bot.http_session.get(url, headers=REQUEST_HEADERS) as r:

0 commit comments

Comments
 (0)