commit 8782aff9309305c22058f6222bc9fd972273cdbb
parent 7105732a28f5708f9a5860b68ff95984ea40522f
Author: Chris Roberts <chris.roberts@learningunix.net>
Date: Sun, 19 Jul 2026 15:56:06 -0500
Update TODO: confirm PIN direction, scope the encode-only feature
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat:
| M | TODO.md | | | 27 | +++++++++++++++++++++++++++ |
1 file changed, 27 insertions(+), 0 deletions(-)
diff --git a/TODO.md b/TODO.md
@@ -41,3 +41,30 @@ Fixed: `rip_index()` now checks `app.config["JOB"]["running"]` first and skips
`query_disc()`/`find_existing_rip()` entirely when a job is already active, just rendering the
"a rip is already in progress" branch without ever touching the drive. Covered by
`test_rip_index_skips_disc_query_while_job_running` in `tests/test_app.py`.
+
+## Feature: pick files from a directory and just run the encode step
+
+For files that already exist on disk (ripped some other way, or re-encoding with different
+settings) -- skip the whole rip pipeline and just run `encode.py` against chosen files directly.
+
+Scoped, not yet built: select **multiple** files from a directory listing, encode them **one at
+a time in sequence** (not concurrently -- shared hardware, and avoids fighting the existing rip
+pipeline's own encode step for CPU/GPU).
+
+Comparatively small lift, smaller than the original rebuild, similar in size to the `/setup`
+page work -- `encode.py`'s `encode()` is already a fully standalone, fully tested function with
+zero dependency on MakeMKV or the disc. New pieces needed:
+
+- `GET /encode` -- list `.mkv` files in `settings.output_dir` (filter out ones already ending
+ `_x265.mkv`, same convention `.scripts/rip` already uses), render as a multi-select pick-list.
+- Path-traversal validation on whatever file(s) get submitted -- `Path.resolve()` + containment
+ check against the allowed directory, not trusted as-is from the form.
+- A new orchestration function (probably alongside `pipeline.run()`) that loops over the
+ selected files, calling `encode_module.encode()` on each in turn, updating the shared
+ `app.config["JOB"]` status per file as it works through the queue. Reusing the *same* status
+ dict/background-thread pattern as the rip pipeline also means an encode-only job can't start
+ while a rip is using the hardware, and vice versa, for free.
+- A small new template; `status.html` likely needs no changes since it already just reflects
+ whatever's in the shared status dict regardless of which job populated it.
+- Tests: file listing, path-traversal rejection, the "already running" guard -- similar scope to
+ the `/setup` tests.