| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- """站点清单与地址解析。
- 四个线上地址共享同一个数据库和同一把 jwt 密钥,凭据完全通用;
- .org / .cc 是地区可达性,www / next 是代码版本(不是数据环境)。
- 开发机是另一个库、另一把密钥,故单独一桶,且永不作为自动 fallback 目标。
- """
- import urllib.parse
- from errors import WpError
- SITES = [
- {"key": "www", "url": "https://www.wikipali.org/api", "version": "稳定版", "domain": ".org"},
- {"key": "www.cc", "url": "https://www.wikipali.cc/api", "version": "稳定版", "domain": ".cc"},
- {"key": "next", "url": "https://next.wikipali.org/api", "version": "最新版", "domain": ".org"},
- {"key": "next.cc", "url": "https://next.wikipali.cc/api", "version": "最新版", "domain": ".cc"},
- {"key": "local", "url": "http://127.0.0.1:8000/api", "version": "开发机", "domain": "本机"},
- ]
- ONLINE_URLS = [s["url"] for s in SITES if s["key"] != "local"]
- LOCAL_URL = SITES[-1]["url"]
- DEFAULT_API_URL = SITES[0]["url"]
- def normalize_api_url(url):
- url = url.rstrip("/")
- parsed = urllib.parse.urlparse(url)
- if parsed.scheme not in ("http", "https"):
- raise WpError(f"API 地址必须以 http:// 或 https:// 开头:{url}")
- host = (parsed.hostname or "").lower()
- if parsed.scheme == "http" and host not in ("127.0.0.1", "localhost", "::1"):
- raise WpError(f"只有 127.0.0.1 / localhost 允许用 http://,其余必须 https://:{url}")
- return url
- def expand_site_alias(value):
- """把序号 / 简称展开成完整 url;已是 url 则原样返回。"""
- value = value.strip()
- if value.isdigit():
- idx = int(value) - 1
- if 0 <= idx < len(SITES):
- return SITES[idx]["url"]
- raise WpError(f"站点序号超出范围:{value}(可选 1-{len(SITES)})")
- for site in SITES:
- if value == site["key"]:
- return site["url"]
- if "://" in value:
- return value
- raise WpError(
- f"无法识别的站点:{value}。可用简称:" + " / ".join(s["key"] for s in SITES) + ",或直接给完整 url"
- )
- def site_label(api_url):
- for site in SITES:
- if site["url"] == api_url:
- return f"{site['version']} · {site['domain']}"
- return "自定义地址"
|