Propagate .mvlog-id into worker state and exclude from fingerprints
This commit is contained in:
parent
765daa150c
commit
2ae7c75f91
1 changed files with 34 additions and 3 deletions
|
|
@ -12,6 +12,7 @@ import logging
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -28,6 +29,7 @@ LOCK_NAME = ".movmaker-lock"
|
||||||
ENABLED_NAME = ".movmaker-enabled"
|
ENABLED_NAME = ".movmaker-enabled"
|
||||||
PREVIEW_NAME = ".movmaker-preview"
|
PREVIEW_NAME = ".movmaker-preview"
|
||||||
HIDDEN_NAME = ".mvlog-hidden"
|
HIDDEN_NAME = ".mvlog-hidden"
|
||||||
|
ARTICLE_ID_NAME = ".mvlog-id"
|
||||||
INTRO_LOGO_ALPHA = "0.5"
|
INTRO_LOGO_ALPHA = "0.5"
|
||||||
MVLOG_WORKER_RECOMMENDED_INTERVAL_MINUTES = 5
|
MVLOG_WORKER_RECOMMENDED_INTERVAL_MINUTES = 5
|
||||||
|
|
||||||
|
|
@ -60,6 +62,23 @@ def remote_file_exists(host: str | None, path: str) -> bool:
|
||||||
return ssh(host, f"test -f {remote_q(path)}", check=False).returncode == 0
|
return ssh(host, f"test -f {remote_q(path)}", check=False).returncode == 0
|
||||||
|
|
||||||
|
|
||||||
|
def read_remote_text(host: str | None, path: str) -> str:
|
||||||
|
if host is None:
|
||||||
|
try:
|
||||||
|
return Path(path).read_text(encoding="utf-8")
|
||||||
|
except Exception:
|
||||||
|
return ""
|
||||||
|
res = ssh(host, f"cat {remote_q(path)} 2>/dev/null", check=False)
|
||||||
|
return res.stdout if res.returncode == 0 else ""
|
||||||
|
|
||||||
|
|
||||||
|
def read_article_id(host: str | None, job_dir: str) -> str | None:
|
||||||
|
raw = read_remote_text(host, f"{job_dir}/{ARTICLE_ID_NAME}").strip().lower()
|
||||||
|
if re.fullmatch(r"\d{14}[a-f0-9]{16}", raw):
|
||||||
|
return raw
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def acquire_lock(host: str, job_dir: str) -> bool:
|
def acquire_lock(host: str, job_dir: str) -> bool:
|
||||||
lock = f"{job_dir}/{LOCK_NAME}"
|
lock = f"{job_dir}/{LOCK_NAME}"
|
||||||
cmd = f"mkdir {remote_q(lock)} 2>/dev/null && date -Iseconds > {remote_q(lock + '/started_at')}"
|
cmd = f"mkdir {remote_q(lock)} 2>/dev/null && date -Iseconds > {remote_q(lock + '/started_at')}"
|
||||||
|
|
@ -78,7 +97,7 @@ entries = []
|
||||||
for dirpath, dirnames, filenames in os.walk(root):
|
for dirpath, dirnames, filenames in os.walk(root):
|
||||||
dirnames[:] = [d for d in dirnames if d != '.movmaker-lock']
|
dirnames[:] = [d for d in dirnames if d != '.movmaker-lock']
|
||||||
for name in filenames:
|
for name in filenames:
|
||||||
if name in {'.movmaker-state.json', '.movmaker-enabled', '.movmaker-preview', '.mvlog-hidden'}:
|
if name in {'.movmaker-state.json', '.movmaker-enabled', '.movmaker-preview', '.mvlog-hidden', '.mvlog-id'}:
|
||||||
continue
|
continue
|
||||||
path = os.path.join(dirpath, name)
|
path = os.path.join(dirpath, name)
|
||||||
rel = os.path.relpath(path, root)
|
rel = os.path.relpath(path, root)
|
||||||
|
|
@ -253,6 +272,7 @@ def render_job(local_input: Path, local_out: Path, extra_args: list[str]) -> Pat
|
||||||
|
|
||||||
def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_args: list[str], force: bool) -> None:
|
def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_args: list[str], force: bool) -> None:
|
||||||
job_dir = f"{remote_root}/in-dir/{job}"
|
job_dir = f"{remote_root}/in-dir/{job}"
|
||||||
|
article_id = read_article_id(host, job_dir)
|
||||||
state = read_state(host, job_dir)
|
state = read_state(host, job_dir)
|
||||||
full_requested = remote_file_exists(host, f"{job_dir}/{ENABLED_NAME}")
|
full_requested = remote_file_exists(host, f"{job_dir}/{ENABLED_NAME}")
|
||||||
preview_requested = remote_file_exists(host, f"{job_dir}/{PREVIEW_NAME}")
|
preview_requested = remote_file_exists(host, f"{job_dir}/{PREVIEW_NAME}")
|
||||||
|
|
@ -284,6 +304,8 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
|
||||||
"mode": "preview" if preview_mode else "full",
|
"mode": "preview" if preview_mode else "full",
|
||||||
"started_at": now(),
|
"started_at": now(),
|
||||||
})
|
})
|
||||||
|
if article_id:
|
||||||
|
processing_state["article_id"] = article_id
|
||||||
if preview_mode:
|
if preview_mode:
|
||||||
processing_state["preview_fingerprint"] = fingerprint_before
|
processing_state["preview_fingerprint"] = fingerprint_before
|
||||||
else:
|
else:
|
||||||
|
|
@ -313,6 +335,8 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
|
||||||
"updated_at": now(),
|
"updated_at": now(),
|
||||||
"message": "Input changed during render; will regenerate on next run.",
|
"message": "Input changed during render; will regenerate on next run.",
|
||||||
})
|
})
|
||||||
|
if article_id:
|
||||||
|
stale_state["article_id"] = article_id
|
||||||
if preview_mode:
|
if preview_mode:
|
||||||
stale_state["preview_fingerprint"] = fingerprint_after
|
stale_state["preview_fingerprint"] = fingerprint_after
|
||||||
stale_state["previous_preview_fingerprint"] = fingerprint_before
|
stale_state["previous_preview_fingerprint"] = fingerprint_before
|
||||||
|
|
@ -341,6 +365,8 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
|
||||||
"preview_output": preview_output,
|
"preview_output": preview_output,
|
||||||
"preview_generated_at": now(),
|
"preview_generated_at": now(),
|
||||||
})
|
})
|
||||||
|
if article_id:
|
||||||
|
new_state["article_id"] = article_id
|
||||||
write_state(host, job_dir, new_state)
|
write_state(host, job_dir, new_state)
|
||||||
print(f"published preview: {job} -> {preview_output}")
|
print(f"published preview: {job} -> {preview_output}")
|
||||||
|
|
||||||
|
|
@ -365,6 +391,8 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
|
||||||
"output": output,
|
"output": output,
|
||||||
"generated_at": now(),
|
"generated_at": now(),
|
||||||
})
|
})
|
||||||
|
if article_id:
|
||||||
|
new_state["article_id"] = article_id
|
||||||
write_state(host, job_dir, new_state)
|
write_state(host, job_dir, new_state)
|
||||||
print(f"published: {job} -> {output}")
|
print(f"published: {job} -> {output}")
|
||||||
|
|
||||||
|
|
@ -376,11 +404,14 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
|
||||||
return
|
return
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
try:
|
try:
|
||||||
write_state(host, job_dir, {
|
error_state = {
|
||||||
"status": "error",
|
"status": "error",
|
||||||
"updated_at": now(),
|
"updated_at": now(),
|
||||||
"message": str(exc),
|
"message": str(exc),
|
||||||
})
|
}
|
||||||
|
if article_id:
|
||||||
|
error_state["article_id"] = article_id
|
||||||
|
write_state(host, job_dir, error_state)
|
||||||
finally:
|
finally:
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue