82 lines
2.2 KiB
Python
82 lines
2.2 KiB
Python
"""GitHub 请求共用:GITHUB_TOKEN、请求头、仓库 API。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
from typing import Any
|
||
|
||
import certifi
|
||
import httpx
|
||
|
||
from daily.config import env
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
DEFAULT_USER_AGENT = (
|
||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
||
"(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||
)
|
||
|
||
|
||
def github_token() -> str | None:
|
||
raw = (env("GITHUB_TOKEN") or "").strip()
|
||
return raw or None
|
||
|
||
|
||
def github_api_headers() -> dict[str, str]:
|
||
headers = {
|
||
"User-Agent": env("GITHUB_TRENDING_USER_AGENT", DEFAULT_USER_AGENT),
|
||
"Accept": "application/vnd.github+json",
|
||
"X-GitHub-Api-Version": "2022-11-28",
|
||
}
|
||
token = github_token()
|
||
if token:
|
||
headers["Authorization"] = f"Bearer {token}"
|
||
return headers
|
||
|
||
|
||
def github_html_headers() -> dict[str, str]:
|
||
headers = {
|
||
"User-Agent": env("GITHUB_TRENDING_USER_AGENT", DEFAULT_USER_AGENT),
|
||
"Accept": "text/html,application/xhtml+xml",
|
||
"Accept-Language": "en-US,en;q=0.9",
|
||
}
|
||
token = github_token()
|
||
if token:
|
||
headers["Authorization"] = f"Bearer {token}"
|
||
return headers
|
||
|
||
|
||
def fetch_repo_api(repo: str) -> dict[str, Any] | None:
|
||
url = f"https://api.github.com/repos/{repo}"
|
||
try:
|
||
with httpx.Client(
|
||
timeout=12.0,
|
||
verify=certifi.where(),
|
||
headers=github_api_headers(),
|
||
) as client:
|
||
resp = client.get(url)
|
||
if resp.status_code != 200:
|
||
return None
|
||
data = resp.json()
|
||
return {
|
||
"description": data.get("description") or "",
|
||
"language": data.get("language") or "",
|
||
"stars": data.get("stargazers_count", 0),
|
||
}
|
||
except Exception as exc:
|
||
logger.debug("GitHub API repo %s 失败: %s", repo, exc)
|
||
return None
|
||
|
||
|
||
def format_star_count(value: int | float | str) -> str:
|
||
try:
|
||
n = int(value)
|
||
except (TypeError, ValueError):
|
||
return str(value)
|
||
if n >= 1_000_000:
|
||
return f"{n / 1_000_000:.1f}M".replace(".0M", "M")
|
||
if n >= 1_000:
|
||
return f"{n / 1_000:.1f}K".replace(".0K", "K")
|
||
return f"{n:,}"
|