"""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:,}"