Fix intro title fade toggle

This commit is contained in:
hbrain 2026-05-28 17:45:02 +00:00
parent 4a61a3100b
commit 37dccfb28c
2 changed files with 50 additions and 12 deletions

View file

@ -57,7 +57,9 @@ def list_jobs(host: str, remote_root: str) -> list[str]:
return [line.strip() for line in out.splitlines() if line.strip()]
def remote_file_exists(host: str, path: str) -> bool:
def remote_file_exists(host: str | None, path: str) -> bool:
if host is None:
return Path(path).is_file()
return ssh(host, f"test -f {remote_q(path)}", check=False).returncode == 0
@ -92,7 +94,13 @@ print(hashlib.sha256(json.dumps(entries, ensure_ascii=False, separators=(',', ':
return ssh(host, cmd).stdout.strip()
def read_remote_json(host: str, path: str) -> dict:
def read_remote_json(host: str | None, path: str) -> dict:
if host is None:
try:
data = json.loads(Path(path).read_text(encoding="utf-8"))
return data if isinstance(data, dict) else {}
except Exception:
return {}
res = ssh(host, f"cat {remote_q(path)} 2>/dev/null", check=False)
if res.returncode != 0 or not res.stdout.strip():
return {}
@ -115,11 +123,24 @@ def write_remote_json(host: str, path: str, data: dict) -> None:
ssh(host, cmd, input_text=payload)
def read_state(host: str, job_dir: str) -> dict:
def read_state(host: str | None, job_dir: str) -> dict:
if host is None:
path = Path(job_dir) / STATE_NAME
if not path.exists():
return {}
try:
return json.loads(path.read_text(encoding="utf-8"))
except Exception:
return {}
return read_remote_json(host, f"{job_dir}/{STATE_NAME}")
def write_state(host: str, job_dir: str, state: dict) -> None:
def write_state(host: str | None, job_dir: str, state: dict) -> None:
if host is None:
path = Path(job_dir) / STATE_NAME
path.write_text(json.dumps(state, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
path.chmod(0o664)
return
path = f"{job_dir}/{STATE_NAME}"
tmp_path = f"{path}.tmp.$$"
data = json.dumps(state, ensure_ascii=False, indent=2) + "\n"
@ -129,7 +150,7 @@ def write_state(host: str, job_dir: str, state: dict) -> None:
f"mv {remote_q(tmp_path)} {remote_q(path)}"
)
ssh(host, cmd, input_text=data)
def copy_job_from_remote(host: str, job_dir: str, local_input: Path) -> None:
local_input.mkdir(parents=True, exist_ok=True)
@ -215,7 +236,23 @@ def render_job(local_input: Path, local_out: Path, extra_args: list[str]) -> Pat
"--intro-logo-alpha", INTRO_LOGO_ALPHA,
]
cmd = [sys.executable, str(MOVMAKER), str(local_input), "--out-dir", str(local_out), *intro_args, *extra_args]
subprocess.run(cmd, check=True)
log_dir = local_input / ".logs"
log_dir.mkdir(parents=True, exist_ok=True)
log_path = log_dir / f"mvlog_worker_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
except subprocess.CalledProcessError as exc:
log_path.write_text(
"Command failed:\n" + " ".join(cmd) + "\n\nSTDOUT:\n" + (exc.stdout or "") + "\n\nSTDERR:\n" + (exc.stderr or ""),
encoding="utf-8",
)
raise RuntimeError(f"movmaker failed; see {log_path}") from exc
else:
if result.stdout or result.stderr:
log_path.write_text(
"Command:\n" + " ".join(cmd) + "\n\nSTDOUT:\n" + (result.stdout or "") + "\n\nSTDERR:\n" + (result.stderr or ""),
encoding="utf-8",
)
outputs = sorted(local_out.glob("*.mp4"), key=lambda p: p.stat().st_mtime, reverse=True)
if not outputs:
raise RuntimeError("movmaker finished but no MP4 was produced")
@ -338,6 +375,7 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
def main() -> int:
parser = argparse.ArgumentParser(description="Render changed MVLog input dirs from a remote web server.")
parser.add_argument("--local", action="store_true", help="Treat remote paths as local; skip SSH")
parser.add_argument("--host", default="192.168.0.204", help="SSH host for the web server")
parser.add_argument("--remote-root", default="/var/www/html/mvlog", help="Remote MVLog web root")
parser.add_argument("--work-dir", default=str(Path.home() / ".cache" / "mvlog-worker"), help="Local work directory")
@ -348,9 +386,9 @@ def main() -> int:
work_dir = Path(args.work_dir)
work_dir.mkdir(parents=True, exist_ok=True)
jobs = args.job or list_jobs(args.host, args.remote_root)
jobs = args.job or list_jobs(None if args.local else args.host, args.remote_root)
for job in jobs:
process_job(args.host, args.remote_root, job, work_dir, args.movmaker_arg, args.force)
process_job(None if args.local else args.host, args.remote_root, job, work_dir, args.movmaker_arg, args.force)
return 0