Feat: Add file logging to mvlog_worker.py

This commit is contained in:
hbrain 2026-05-27 06:35:56 +00:00
parent 6ba59cbfa7
commit e1f7c7b019

View file

@ -26,6 +26,7 @@ PUSH_CONFIG = Path.home() / ".config" / "mvlog" / "push.json"
STATE_NAME = ".movmaker-state.json"
LOCK_NAME = ".movmaker-lock"
ENABLED_NAME = ".movmaker-enabled"
PREVIEW_NAME = ".movmaker-preview"
HIDDEN_NAME = ".mvlog-hidden"
NOTIFIED_CACHE = "cache/push_notifications.json"
@ -74,7 +75,7 @@ entries = []
for dirpath, dirnames, filenames in os.walk(root):
dirnames[:] = [d for d in dirnames if d != '.movmaker-lock']
for name in filenames:
if name in {'.movmaker-state.json', '.movmaker-enabled', '.mvlog-hidden'}:
if name in {'.movmaker-state.json', '.movmaker-enabled', '.movmaker-preview', '.mvlog-hidden'}:
continue
path = os.path.join(dirpath, name)
rel = os.path.relpath(path, root)
@ -214,9 +215,12 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
job_dir = f"{remote_root}/in-dir/{job}"
state = read_state(host, job_dir)
maybe_send_first_show_notification(host, remote_root, job_dir, job, state)
if not 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}")
if not full_requested and not preview_requested:
print(f"disabled: {job}")
return
preview_mode = preview_requested and not full_requested
if not acquire_lock(host, job_dir):
print(f"skip locked: {job}")
return
@ -224,17 +228,29 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
fingerprint_before = remote_fingerprint(host, job_dir)
state = read_state(host, job_dir)
old_output = state.get("output") if isinstance(state.get("output"), str) else None
if not force and state.get("status") == "done" and state.get("fingerprint") == fingerprint_before and old_output:
old_preview_output = state.get("preview_output") if isinstance(state.get("preview_output"), str) else None
if preview_mode:
if not force and state.get("preview_fingerprint") == fingerprint_before and old_preview_output:
if remote_file_exists(host, f"{remote_root}/out-dir/{old_preview_output}"):
print(f"preview up to date: {job} -> {old_preview_output}")
return
elif not force and state.get("status") == "done" and state.get("fingerprint") == fingerprint_before and old_output:
if remote_file_exists(host, f"{remote_root}/out-dir/{old_output}"):
print(f"up to date: {job} -> {old_output}")
return
write_state(host, job_dir, {
processing_state = dict(state)
processing_state.update({
"status": "processing",
"fingerprint": fingerprint_before,
"mode": "preview" if preview_mode else "full",
"started_at": now(),
"output": old_output,
})
if preview_mode:
processing_state["preview_fingerprint"] = fingerprint_before
else:
processing_state["fingerprint"] = fingerprint_before
processing_state["output"] = old_output
write_state(host, job_dir, processing_state)
local_job = work_dir / job
if local_job.exists():
@ -242,29 +258,56 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
local_input = local_job / "input"
local_out = local_job / "out"
copy_job_from_remote(host, job_dir, local_input)
print(f"rendering: {job}")
local_mp4 = render_job(local_input, local_out, extra_args)
render_args = [*extra_args, "--preview"] if preview_mode else extra_args
print(f"rendering {'preview: ' if preview_mode else ''}{job}")
local_mp4 = render_job(local_input, local_out, render_args)
if preview_mode:
preview_mp4 = local_mp4.with_name(f"{local_mp4.stem}_preview{local_mp4.suffix}")
local_mp4.rename(preview_mp4)
local_mp4 = preview_mp4
fingerprint_after = remote_fingerprint(host, job_dir)
if fingerprint_after != fingerprint_before:
write_state(host, job_dir, {
stale_state = dict(state)
stale_state.update({
"status": "stale",
"fingerprint": fingerprint_after,
"previous_fingerprint": fingerprint_before,
"updated_at": now(),
"message": "Input changed during render; will regenerate on next run.",
"output": old_output,
})
if preview_mode:
stale_state["preview_fingerprint"] = fingerprint_after
stale_state["previous_preview_fingerprint"] = fingerprint_before
else:
stale_state["fingerprint"] = fingerprint_after
stale_state["previous_fingerprint"] = fingerprint_before
stale_state["output"] = old_output
write_state(host, job_dir, stale_state)
print(f"stale during render, not publishing: {job}")
return
output = publish_output(host, remote_root, local_mp4, old_output)
new_state = {
if preview_mode:
preview_output = publish_output(host, remote_root, local_mp4, old_preview_output)
new_state = dict(state)
new_state.update({
"status": "done",
"mode": "preview",
"preview_fingerprint": fingerprint_after,
"preview_output": preview_output,
"preview_generated_at": now(),
})
write_state(host, job_dir, new_state)
print(f"published preview: {job} -> {preview_output}")
return
output = publish_output(host, remote_root, local_mp4, old_output)
new_state = dict(state)
new_state.update({
"status": "done",
"mode": "full",
"fingerprint": fingerprint_after,
"output": output,
"generated_at": now(),
}
})
maybe_send_first_show_notification(host, remote_root, job_dir, job, new_state)
write_state(host, job_dir, new_state)
print(f"published: {job} -> {output}")