98 lines
3.0 KiB
Python
98 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
将 16 型 MBTI 占位 PNG 下载到 soul-api/static,供 Gin r.Static(\"/static\", \"./static\") 提供,
|
||
管理端与小程序访问 /static/mbti-avatars-png-male/{TYPE}.png 等路径时不再 404。
|
||
|
||
素材:DiceBear 9.x notionists/png(HTTPS API,可按 seed 复现)。
|
||
许可见 https://www.dicebear.com/licenses/ ,商用请以官网为准;可随后在管理端替换为自有 OSS URL。
|
||
|
||
用法(仓库根目录)::
|
||
python scripts/fetch_mbti_png_to_soul_api_static.py
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import ssl
|
||
import time
|
||
import urllib.error
|
||
import urllib.parse
|
||
import urllib.request
|
||
from pathlib import Path
|
||
|
||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||
OUT_BASE = REPO_ROOT / "soul-api" / "static"
|
||
|
||
MBTI = [
|
||
"INTJ",
|
||
"INTP",
|
||
"ENTJ",
|
||
"ENTP",
|
||
"INFJ",
|
||
"INFP",
|
||
"ENFJ",
|
||
"ENFP",
|
||
"ISTJ",
|
||
"ISFJ",
|
||
"ESTJ",
|
||
"ESFJ",
|
||
"ISTP",
|
||
"ISFP",
|
||
"ESTP",
|
||
"ESFP",
|
||
]
|
||
|
||
# DiceBear PNG 限流约 10/s,保守间隔
|
||
DELAY_SEC = 0.2
|
||
|
||
|
||
def fetch_one(url: str, dest: Path) -> None:
|
||
ctx = ssl.create_default_context()
|
||
req = urllib.request.Request(url, headers={"User-Agent": "SoulMbtiPngPrefetch/1.0 (+internal)"})
|
||
with urllib.request.urlopen(req, timeout=90, context=ctx) as resp:
|
||
data = resp.read()
|
||
if len(data) < 100:
|
||
raise RuntimeError(f"{url}: response too small ({len(data)} bytes)")
|
||
dest.write_bytes(data)
|
||
|
||
|
||
def main() -> None:
|
||
packs: list[tuple[str, str, str]] = [
|
||
("male", "mbti-avatars-png-male", "男版占位(DiceBear notionists)"),
|
||
("female", "mbti-avatars-png-female", "女版占位(DiceBear notionists,seed 区分)"),
|
||
]
|
||
base = "https://api.dicebear.com/9.x/notionists/png"
|
||
|
||
total = 0
|
||
for gender_key, dirname, subtitle in packs:
|
||
out_dir = OUT_BASE / dirname
|
||
out_dir.mkdir(parents=True, exist_ok=True)
|
||
readme = out_dir / "README.txt"
|
||
lines = [
|
||
"MBTI 默认头像 PNG(本目录文件名 = 四字母类型)",
|
||
subtitle,
|
||
"由脚本 scripts/fetch_mbti_png_to_soul_api_static.py 生成,可商用请自行核对 DiceBear 许可。",
|
||
"部署 soul-api 时须随二进制一同带上 static/,否则前端会显示占位缩写。",
|
||
"",
|
||
]
|
||
for code in MBTI:
|
||
seed = f"{code}-{gender_key}"
|
||
url = f"{base}?seed={urllib.parse.quote(seed)}&size=128"
|
||
dest = out_dir / f"{code}.png"
|
||
print(f"{dest.relative_to(REPO_ROOT)} ...")
|
||
try:
|
||
fetch_one(url, dest)
|
||
except urllib.error.HTTPError as e:
|
||
raise SystemExit(f"HTTP {e.code} {url}") from e
|
||
total += 1
|
||
lines.append(f"{code}.png <- {seed}")
|
||
time.sleep(DELAY_SEC)
|
||
readme.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||
print(f"ok {dirname} ({len(MBTI)} files)")
|
||
|
||
print(f"done: {total} png -> {OUT_BASE.relative_to(REPO_ROOT)}")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|