Files
gitlab-instance-0a899031_sh/d2ypp2/tools/render_tampermonkey_provisioning.py
root e1d7251545 s
2026-05-19 02:25:21 +00:00

92 lines
3.0 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
import argparse
import hashlib
import json
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parent.parent
DEFAULT_SCRIPT = ROOT / "services" / "neko" / "provisioning" / "youtube-studio-auto-dismiss.user.js"
DEFAULT_OUTPUT = ROOT / "services" / "neko" / "provisioning" / "tampermonkey-provisioning.json"
GREASYFORK_URL = "https://greasyfork.org/scripts/557378-youtube-studio-auto-dismiss/code/YouTube%20Studio%20Auto%20Dismiss.user.js"
def tm_sha256(text: str) -> str:
return hashlib.sha256(text.encode("utf-8")).hexdigest()
def tm_hash(value: Any, seen: list[int] | None = None) -> str:
if seen is None:
seen = []
if value is None:
return tm_sha256("object:null")
if isinstance(value, dict):
ident = id(value)
if ident in seen:
raise ValueError("Found circular structure")
seen.append(ident)
try:
parts = [tm_hash(value[key], seen) for key in sorted(value)]
finally:
seen.pop()
return tm_sha256("".join(parts))
if isinstance(value, list):
ident = id(value)
if ident in seen:
raise ValueError("Found circular structure")
seen.append(ident)
try:
parts = [tm_hash(item, seen) for item in value]
finally:
seen.pop()
return tm_sha256("".join(parts))
if isinstance(value, bool):
return tm_sha256(f"boolean:{str(value).lower()}")
if isinstance(value, (int, float)) and not isinstance(value, bool):
return tm_sha256(f"number:{value}")
if isinstance(value, str):
return tm_sha256(f"string:{value}")
raise TypeError(f"Unsupported provisioning value: {type(value)!r}")
def build_payload(script_text: str) -> dict[str, Any]:
return {
"version": "1",
"scripts": [
{
"name": "YouTube Studio Auto Dismiss",
"file_url": GREASYFORK_URL,
"source": script_text,
"enabled": True,
"position": 1,
}
],
"settings": {
"runtime_content_mode": "content",
},
}
def main() -> int:
parser = argparse.ArgumentParser(description="Render Tampermonkey provisioning JSON and hash.")
parser.add_argument("--script", type=Path, default=DEFAULT_SCRIPT)
parser.add_argument("--output", type=Path, default=DEFAULT_OUTPUT)
parser.add_argument("--write", action="store_true", help="Write the rendered JSON to --output.")
args = parser.parse_args()
script_text = args.script.read_text(encoding="utf-8").strip() + "\n"
payload = build_payload(script_text)
rendered = json.dumps(payload, ensure_ascii=False, indent=2) + "\n"
if args.write:
args.output.write_text(rendered, encoding="utf-8")
print(rendered, end="")
print(f"hash=1:{tm_hash(payload)}")
return 0
if __name__ == "__main__":
raise SystemExit(main())