|
9 | 9 | from typing import Final |
10 | 10 | from urllib.parse import urlparse |
11 | 11 |
|
| 12 | +from starlette.status import ( |
| 13 | + HTTP_200_OK, |
| 14 | + HTTP_301_MOVED_PERMANENTLY, |
| 15 | + HTTP_302_FOUND, |
| 16 | + HTTP_401_UNAUTHORIZED, |
| 17 | + HTTP_403_FORBIDDEN, |
| 18 | + HTTP_404_NOT_FOUND, |
| 19 | +) |
| 20 | + |
12 | 21 | from gitingest.utils.exceptions import InvalidGitHubTokenError |
13 | 22 |
|
14 | 23 | # GitHub Personal-Access tokens (classic + fine-grained). |
15 | 24 | # - ghp_ / gho_ / ghu_ / ghs_ / ghr_ → 36 alphanumerics |
16 | 25 | # - github_pat_ → 22 alphanumerics + "_" + 59 alphanumerics |
17 | 26 | _GITHUB_PAT_PATTERN: Final[str] = r"^(?:gh[pousr]_[A-Za-z0-9]{36}|github_pat_[A-Za-z0-9]{22}_[A-Za-z0-9]{59})$" |
18 | 27 |
|
19 | | -_OK: Final[set[str]] = {"200", "301"} # reachable / canonical redirect |
20 | | -_MISSING: Final[set[str]] = {"404", "302"} # not found / redirect |
21 | | -_NEEDS_AUTH: Final[set[str]] = {"401", "403"} # login or forbidden |
22 | | - |
23 | 28 |
|
24 | 29 | def is_github_host(url: str) -> bool: |
25 | 30 | """Check if a URL is from a GitHub host (github.com or GitHub Enterprise). |
@@ -109,6 +114,7 @@ async def check_repo_exists(url: str, token: str | None = None) -> bool: |
109 | 114 | If the host returns an unrecognised status code. |
110 | 115 |
|
111 | 116 | """ |
| 117 | + # TODO: use `requests` instead of `curl` |
112 | 118 | cmd: list[str] = [ |
113 | 119 | "curl", |
114 | 120 | "--silent", |
@@ -139,14 +145,15 @@ async def check_repo_exists(url: str, token: str | None = None) -> bool: |
139 | 145 | if proc.returncode != 0: |
140 | 146 | return False |
141 | 147 |
|
142 | | - status = stdout.decode().strip() |
143 | | - if status in _OK: |
| 148 | + status = int(stdout.decode().strip()) |
| 149 | + if status in {HTTP_200_OK, HTTP_301_MOVED_PERMANENTLY}: |
144 | 150 | return True |
145 | | - if status in _MISSING: |
| 151 | + # TODO: handle 302 redirects |
| 152 | + if status in {HTTP_404_NOT_FOUND, HTTP_302_FOUND}: |
146 | 153 | return False |
147 | | - if status in _NEEDS_AUTH: |
| 154 | + if status in {HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN}: |
148 | 155 | return False |
149 | | - msg = f"Unexpected HTTP status {status!r} for {url}" |
| 156 | + msg = f"Unexpected HTTP status {status} for {url}" |
150 | 157 | raise RuntimeError(msg) |
151 | 158 |
|
152 | 159 |
|
@@ -294,4 +301,4 @@ def validate_github_token(token: str) -> None: |
294 | 301 |
|
295 | 302 | """ |
296 | 303 | if not re.fullmatch(_GITHUB_PAT_PATTERN, token): |
297 | | - raise InvalidGitHubTokenError(token) |
| 304 | + raise InvalidGitHubTokenError |
0 commit comments