Fix slow series scans + per-episode prompting; add tests, CI, and perf optimizations - #1
Merged
Merged
Conversation
Bug 1 (scans hang / take forever on series): episode metadata was
fetched one HTTP request per episode. For a full season/series this
meant dozens or hundreds of serial rate-limited calls, and the results
table only populated after ALL of them finished -- so the UI looked
frozen. Add TMDBClient.get_season_details() to fetch a whole season in
a single /tv/{id}/season/{n} request and reuse the per-episode cache so
repeat scans skip the network entirely.
Bug 2 (asks per episode instead of inferring the season): the batch
group key was derived from the raw filename and only stripped text from
the episode pattern onward. Inconsistent filenames (some with a year or
1080p tag before SxxExx, some without) produced different keys and split
one series into several groups -> multiple identity prompts. Group by the
parser's already-cleaned title_guess instead; movies keep their year so
remakes are not merged.
Implements the QA follow-up actions: - tests/: pytest suite (parser, formatter incl. filename-safety, cache, TMDB client with mocked network, detection state machine, the two scan bug fixes, and a headless GUI smoke test). 31 tests, network never hit. - .github/workflows/ci.yml: runs pytest with coverage on Python 3.10-3.12, Qt headless (offscreen) with a dummy key. - pyproject.toml: pytest + coverage configuration. - requirements-dev.txt: pytest / pytest-cov. Fixes BUG-03 (language-aware episode cache): the episode cache key did not include the language, so changing the episode-title language returned stale titles for already-cached episodes. The key is now namespaced by the effective language; legacy entries simply miss and re-fetch once. Adds MainWindow(skip_setup=...) so automated/headless runs can construct the window without the first-run setup wizard's blocking modal.
…aster dup hashing Five scan-performance improvements: 1. Progressive results: phases 2 and 3 are now interleaved per title group. Each group's files are formatted and emitted as soon as that group is identified, so the table fills in incrementally instead of staying empty until the whole folder is resolved. 2. Parallel episode prefetch: missing seasons are fetched concurrently (bounded thread pool) so their network latencies overlap. ~6x faster on a 6-season series in a latency-simulated benchmark. The TMDB client rate limiter and the cache are now thread-safe. 3. Lower rate-limit spacing (0.25s -> 0.05s). TMDB tolerates it and still returns 429 + Retry-After, which is already handled. 4. Batched cache writes: a whole scan now writes the cache file once (begin_batch/end_batch) instead of once per lookup. 5. Duplicate finder: name-matched groups use the cheap quick hash instead of reading entire files (the hash there is only informational), and hashing switched from MD5 to the faster BLAKE2b. Adds tests for batched cache writes, language-aware cache, progressive grouped emission, and the duplicate-hash behavior (35 tests total).
- app.spec: exclude 'cryptography' from the bundle. RNMR has no cryptography features (HTTPS to TMDB uses the stdlib ssl module), so it was only ever pulled in transitively; excluding it shrinks the bundle and avoids an unrelated dependency. Verified the spec builds and the frozen app launches (validated on Linux; the binary starts the Qt event loop without errors). - .github/workflows/build-windows.yml: build dist/RNMR.exe with PyInstaller on windows-latest and upload it as an artifact. PyInstaller cannot cross-compile, so the real Windows .exe must be produced on a Windows runner; this makes that reproducible on tags or manual dispatch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the two reported bugs (slow/"frozen" scans and per-episode prompting), adds the project's first automated test suite + CI, lands five scan-performance optimizations, and validates the PyInstaller packaging.
Bug fixes
TMDBClient.get_season_details()to fetch a whole season in a single/tv/{id}/season/{n}request, reusing the per-episode cache so repeat scans skip the network entirely.1080pbeforeSxxExx). Now groups by the parser's cleanedtitle_guess; movies keep their year so remakes are not merged.Performance
Testing & build
tests/: first pytest suite (35 tests) covering parser, formatter (incl. filename-safety / path-traversal), cache, TMDB client (mocked), detection state machine, the bug fixes, and a headless GUI smoke test. Network is never hit..github/workflows/ci.yml: pytest + coverage on Python 3.10–3.12, Qt headless..github/workflows/build-windows.yml: buildsdist/RNMR.exeonwindows-latestand uploads it as an artifact (PyInstaller cannot cross-compile).MainWindow(skip_setup=...)so headless runs don't block on the first-run wizard.app.spec: excludecryptography(unused by RNMR; shrinks the bundle). Packaging verified end-to-end.https://claude.ai/code/session_01C2HyuCwrqW2iK6D3AQDmBL
Generated by Claude Code