@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Проверка: UI-статика не тянет ресурсы с CDN (fonts.gstatic, jsdelivr и т.д.)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
STATIC = ROOT / "static"
|
||||
TEMPLATES = ROOT / "templates"
|
||||
|
||||
CDN_IN_CSS = re.compile(r"url\s*\(\s*['\"]?https?://", re.I)
|
||||
CDN_IN_HTML = re.compile(
|
||||
r"""(?:src|href)\s*=\s*['"]https?://""",
|
||||
re.I,
|
||||
)
|
||||
|
||||
REQUIRED_FILES = [
|
||||
"js/chart.umd.min.js",
|
||||
"js/wesp-zootech-icons.js",
|
||||
"icons/route-location.svg",
|
||||
"icons/cow.svg",
|
||||
"css/inter-fonts.css",
|
||||
"css/roboto-fonts.css",
|
||||
"css/font-awesome.min.css",
|
||||
"fonts/inter/inter-400.ttf",
|
||||
"fonts/inter/inter-700.ttf",
|
||||
"fonts/roboto/roboto-400.ttf",
|
||||
"webfonts/fa-solid-900.woff2",
|
||||
"webfonts/fa-solid-900.ttf",
|
||||
]
|
||||
|
||||
|
||||
def _scan_css(path: Path) -> list[str]:
|
||||
text = path.read_text(encoding="utf-8", errors="replace")
|
||||
issues: list[str] = []
|
||||
for i, line in enumerate(text.splitlines(), 1):
|
||||
if CDN_IN_CSS.search(line):
|
||||
issues.append(f"{path.relative_to(ROOT)}:{i}: external url() in CSS")
|
||||
return issues
|
||||
|
||||
|
||||
def _scan_html(path: Path) -> list[str]:
|
||||
text = path.read_text(encoding="utf-8", errors="replace")
|
||||
issues: list[str] = []
|
||||
for i, line in enumerate(text.splitlines(), 1):
|
||||
if CDN_IN_HTML.search(line):
|
||||
issues.append(f"{path.relative_to(ROOT)}:{i}: external src/href in HTML")
|
||||
return issues
|
||||
|
||||
|
||||
def main() -> int:
|
||||
issues: list[str] = []
|
||||
|
||||
for rel in REQUIRED_FILES:
|
||||
if not (STATIC / rel).is_file():
|
||||
issues.append(f"missing required static file: static/{rel}")
|
||||
|
||||
css_dirs = [STATIC / "css", STATIC / "vendor"]
|
||||
for css_dir in css_dirs:
|
||||
if not css_dir.is_dir():
|
||||
continue
|
||||
for path in sorted(css_dir.rglob("*.css")):
|
||||
issues.extend(_scan_css(path))
|
||||
|
||||
for html_root in (STATIC, TEMPLATES):
|
||||
if not html_root.is_dir():
|
||||
continue
|
||||
for path in sorted(html_root.rglob("*.html")):
|
||||
issues.extend(_scan_html(path))
|
||||
|
||||
if issues:
|
||||
print("verify_static_offline_assets: FAILED", file=sys.stderr)
|
||||
for item in issues:
|
||||
print(f" - {item}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
print("verify_static_offline_assets: OK")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user