96 lines
2.7 KiB
Python
96 lines
2.7 KiB
Python
"""
|
||
根据 manifest 批量导入贴纸到 assets/stickers_builtin,并生成 index.json。
|
||
|
||
用法:
|
||
python3 scripts/import_stickers_manifest.py --manifest stickers_manifest.json
|
||
|
||
manifest 示例:
|
||
{
|
||
"pack": {
|
||
"id": "fluent-emoji-subset",
|
||
"name": "Fluent Emoji 子集(抖音常用)",
|
||
"license": "MIT (CHECK BEFORE PROD)",
|
||
"attribution": "Microsoft Fluent UI Emoji"
|
||
},
|
||
"categories": [
|
||
{
|
||
"id": "douyin-basic",
|
||
"name": "抖音常用",
|
||
"items": [
|
||
{"id": "fire", "name": "火", "url": "https://.../fire.png", "tags": ["火","爆款"]},
|
||
{"id": "heart", "name": "爱心", "url": "https://.../heart.png", "tags": ["点赞","互动"]}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import argparse
|
||
import json
|
||
import os
|
||
from pathlib import Path
|
||
from urllib.request import urlopen, Request
|
||
|
||
|
||
def _safe_name(s: str) -> str:
|
||
return "".join(ch if ch.isalnum() or ch in ("-", "_") else "_" for ch in (s or ""))[:80] or "item"
|
||
|
||
|
||
def download(url: str, out: Path) -> None:
|
||
out.parent.mkdir(parents=True, exist_ok=True)
|
||
req = Request(url, headers={"User-Agent": "video-flow-stickers/1.0"})
|
||
with urlopen(req, timeout=60) as r:
|
||
out.write_bytes(r.read())
|
||
|
||
|
||
def main() -> int:
|
||
ap = argparse.ArgumentParser()
|
||
ap.add_argument("--manifest", required=True, help="manifest json path")
|
||
ap.add_argument("--out-dir", default="assets/stickers_builtin", help="output directory")
|
||
args = ap.parse_args()
|
||
|
||
manifest_path = Path(args.manifest)
|
||
data = json.loads(manifest_path.read_text(encoding="utf-8"))
|
||
|
||
out_dir = Path(args.out_dir)
|
||
out_dir.mkdir(parents=True, exist_ok=True)
|
||
|
||
pack = data.get("pack") or {}
|
||
categories = data.get("categories") or []
|
||
|
||
# 下载并重写 file 字段(落地为本地文件)
|
||
for cat in categories:
|
||
for it in (cat.get("items") or []):
|
||
url = str(it.get("url") or "")
|
||
if not url:
|
||
continue
|
||
ext = Path(url.split("?")[0]).suffix.lower()
|
||
if ext not in [".png", ".svg", ".webp"]:
|
||
ext = ".png"
|
||
fid = _safe_name(str(it.get("id") or it.get("name") or "item"))
|
||
fname = f"{fid}{ext}"
|
||
target = out_dir / fname
|
||
if not target.exists():
|
||
print(f"download: {url} -> {target}")
|
||
download(url, target)
|
||
it["file"] = fname
|
||
it.pop("url", None)
|
||
|
||
# 输出 index.json
|
||
out_index = out_dir / "index.json"
|
||
out_index.write_text(
|
||
json.dumps({"pack": pack, "categories": categories}, ensure_ascii=False, indent=2),
|
||
encoding="utf-8",
|
||
)
|
||
print(f"written: {out_index}")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
raise SystemExit(main())
|
||
|
||
|
||
|