# -*- coding: utf-8 -*- """一次性脚本:把前端 CDN 资源下载到 public/vendor/,实现完全本地化。""" import os, re, sys, urllib.request, urllib.parse ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) VENDOR = os.path.join(ROOT, "public", "vendor") os.makedirs(VENDOR, exist_ok=True) UA = {"User-Agent": "Mozilla/5.0"} def download(url, dest): req = urllib.request.Request(url, headers=UA) with urllib.request.urlopen(req, timeout=30) as r: data = r.read() with open(dest, "wb") as f: f.write(data) print(f" {os.path.relpath(dest, ROOT)} ({len(data)} B)") return data def main(): print("下载 Bootstrap CSS...") download( "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css", os.path.join(VENDOR, "bootstrap.min.css"), ) print("下载 Bootstrap Icons CSS...") css = download( "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css", os.path.join(VENDOR, "bootstrap-icons.css"), ).decode("utf-8", "ignore") # 找出字体 url 并本地化 CSS_URL = "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" urls = re.findall(r'url\(["\']?([^"\')]+)["\']?\)', css) for u in set(urls): if u.startswith("data:"): continue full = urllib.parse.urljoin(CSS_URL, u) fname = os.path.basename(full.split("?")[0]) print(f"下载字体 {fname}...") download(full, os.path.join(VENDOR, fname)) css = css.replace(u, "./" + fname) with open(os.path.join(VENDOR, "bootstrap-icons.css"), "w", encoding="utf-8") as f: f.write(css) print(" 已重写 bootstrap-icons.css 字体路径") print("下载 SortableJS...") download( "https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js", os.path.join(VENDOR, "Sortable.min.js"), ) print("\n完成。vendor 目录:") for f in sorted(os.listdir(VENDOR)): print(" ", f) if __name__ == "__main__": main()