Files
XStats/scripts/publish_api.py
T

69 lines
2.2 KiB
Python

#!/usr/bin/env python3
# Copyright (C) 2026 ysicing
# SPDX-License-Identifier: AGPL-3.0-or-later
"""把发布清单提交给 XStats API。"""
import json
import os
import sys
import urllib.request
from collections.abc import Mapping
from pathlib import Path
DEFAULT_ENDPOINTS = (
"https://xstats-apps.12306.work/api/v1/releases/current",
"https://x-stats.china.12306.work/api/v1/releases/current",
)
def publish(appcast: Path, endpoints: list[str], token: str) -> None:
if not token:
raise ValueError("XSTATS_RELEASE_TOKEN 不能为空")
if not endpoints:
raise ValueError("至少需要一个版本发布接口")
body = appcast.read_bytes()
manifest = json.loads(body)
if not isinstance(manifest, dict) or not manifest.get("version"):
raise ValueError(f"{appcast} 不是有效的版本清单")
for endpoint in endpoints:
request = urllib.request.Request(
endpoint,
data=body,
method="PUT",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"User-Agent": "XStats-Release",
},
)
with urllib.request.urlopen(request, timeout=30) as response:
if response.status != 204:
raise RuntimeError(f"{endpoint} 返回 {response.status}")
print(f"✅ 版本清单已发布到 {endpoint}")
def configured_endpoints(environment: Mapping[str, str]) -> list[str]:
configured = environment.get("XSTATS_API_URLS", "")
if configured:
return [item.strip() for item in configured.split(",") if item.strip()]
if endpoint := environment.get("XSTATS_API_URL"):
return [endpoint]
return list(DEFAULT_ENDPOINTS)
def main() -> None:
if len(sys.argv) != 2:
raise SystemExit(f"用法:{sys.argv[0]} <appcast.json>")
endpoints = configured_endpoints(os.environ)
token = os.environ.get("XSTATS_RELEASE_TOKEN", "")
try:
publish(Path(sys.argv[1]), endpoints, token)
except Exception as error:
raise SystemExit(f"发布版本到 API 失败:{error}") from error
if __name__ == "__main__":
main()