riplex 0.6.2__tar.gz → 0.6.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {riplex-0.6.2 → riplex-0.6.4}/.github/ISSUE_TEMPLATE/bug_report.yml +1 -1
- riplex-0.6.4/.github/ISSUE_TEMPLATE/crash_report.yml +82 -0
- {riplex-0.6.2 → riplex-0.6.4}/.github/copilot-instructions.md +38 -0
- {riplex-0.6.2 → riplex-0.6.4}/.github/workflows/release.yml +5 -0
- {riplex-0.6.2/src/riplex.egg-info → riplex-0.6.4}/PKG-INFO +2 -2
- {riplex-0.6.2 → riplex-0.6.4}/docs/changelog.md +17 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/troubleshooting.md +19 -0
- riplex-0.6.4/issues/debug-artifacts-consolidation.md +146 -0
- riplex-0.6.4/issues/planned-features.md +509 -0
- {riplex-0.6.2 → riplex-0.6.4}/pyproject.toml +1 -1
- riplex-0.6.4/src/riplex/__init__.py +8 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/disc/makemkv.py +130 -6
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/disc/provider.py +311 -14
- {riplex-0.6.2/src/riplex_app → riplex-0.6.4/src/riplex}/updater.py +56 -5
- {riplex-0.6.2 → riplex-0.6.4/src/riplex.egg-info}/PKG-INFO +2 -2
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex.egg-info/SOURCES.txt +6 -1
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex.egg-info/requires.txt +1 -1
- riplex-0.6.4/src/riplex_app/bug_report.py +145 -0
- riplex-0.6.4/src/riplex_app/crash_dump.py +116 -0
- riplex-0.6.4/src/riplex_app/keep_awake.py +88 -0
- riplex-0.6.4/src/riplex_app/main.py +331 -0
- riplex-0.6.4/src/riplex_app/screens/disc_detection.py +677 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/metadata.py +44 -1
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/organize_done.py +26 -9
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/organize_preview.py +30 -1
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/progress.py +5 -0
- riplex-0.6.4/src/riplex_app/screens/release.py +493 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/update.py +1 -1
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/welcome.py +47 -15
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_cli/main.py +25 -1
- riplex-0.6.4/tests/test_disc_detection_screen.py +46 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_disc_provider.py +92 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_makemkv.py +46 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_updater.py +100 -8
- riplex-0.6.2/issues/planned-features.md +0 -48
- riplex-0.6.2/src/riplex/__init__.py +0 -3
- riplex-0.6.2/src/riplex_app/bug_report.py +0 -76
- riplex-0.6.2/src/riplex_app/main.py +0 -130
- riplex-0.6.2/src/riplex_app/screens/disc_detection.py +0 -312
- riplex-0.6.2/src/riplex_app/screens/release.py +0 -233
- {riplex-0.6.2 → riplex-0.6.4}/.github/agents/riplex.agent.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/.github/workflows/publish.yml +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/.gitignore +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/.vscode/settings.json +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/CONTRIBUTORS.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/LICENSE +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/README.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/architecture.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/getting-started/configuration.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/getting-started/installation.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/guide/lookup.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/guide/orchestrate.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/guide/organize.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/guide/workflow.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/index.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/naming-rules.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/docs/reference/cli.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/issues/orchestrate-dvdcompare-fallback.md +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/mkdocs.yml +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/setup.cfg +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/cache.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/config.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/dedup.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/detect.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/disc/__init__.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/disc/analysis.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/formatter.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/lookup.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/manifest.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/matcher.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/metadata/__init__.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/metadata/planner.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/metadata/provider.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/metadata/sources/__init__.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/metadata/sources/tmdb.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/models.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/normalize.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/organizer.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/scanner.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/snapshot.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/splitter.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/tagger.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/title.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex/ui.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex.egg-info/dependency_links.txt +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex.egg-info/entry_points.txt +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex.egg-info/top_level.txt +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/__init__.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/__init__.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/disc_overview.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/disc_swap.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/done.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/folder_picker.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/orchestrate_done.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_app/screens/selection.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_cli/__init__.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_cli/commands/__init__.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_cli/commands/lookup.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_cli/commands/orchestrate.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_cli/commands/organize.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_cli/commands/rip.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_cli/commands/setup.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/src/riplex_cli/formatting.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/__init__.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/fixtures/chernobyl_disc1.json +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/fixtures/makemkvcon_frozen_planet_ii_d2.txt +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/fixtures/makemkvcon_list.txt +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/snapshots/Batman Begins.snapshot.json +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/snapshots/Blade Runner (Blu-ray 4k).snapshot.json +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/snapshots/Blade Runner The Final Cut.snapshot.json +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/snapshots/Seven Worlds One Planet.snapshot.json +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/snapshots/The Dark Knight Rises.snapshot.json +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/snapshots/The Dark Knight.snapshot.json +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/snapshots/Waterworld.snapshot.json +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_cache.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_cli_utils.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_config.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_dedup.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_detect.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_disc_analysis.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_disc_fixtures.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_formatter.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_matcher.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_normalize.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_organizer.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_planner.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_rip_guide.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_scanner.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_snapshot.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_splitter.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_tagger.py +0 -0
- {riplex-0.6.2 → riplex-0.6.4}/tests/test_ui.py +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
name: Crash Report
|
|
2
|
+
description: Report an unhandled exception / crash in riplex (auto-filed from the GUI's "Report Crash" button)
|
|
3
|
+
title: "[Crash] "
|
|
4
|
+
labels: ["bug", "crash"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for reporting a crash! Most fields below are pre-filled by the
|
|
10
|
+
GUI. Please review and add anything else that might help reproduce.
|
|
11
|
+
|
|
12
|
+
- type: input
|
|
13
|
+
id: version
|
|
14
|
+
attributes:
|
|
15
|
+
label: riplex version
|
|
16
|
+
placeholder: "e.g. 0.4.1"
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: input
|
|
21
|
+
id: platform
|
|
22
|
+
attributes:
|
|
23
|
+
label: Platform
|
|
24
|
+
placeholder: "e.g. Windows-11-10.0.26100-SP0"
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
|
|
28
|
+
- type: dropdown
|
|
29
|
+
id: frontend
|
|
30
|
+
attributes:
|
|
31
|
+
label: Frontend
|
|
32
|
+
options:
|
|
33
|
+
- CLI
|
|
34
|
+
- GUI
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
|
|
38
|
+
- type: input
|
|
39
|
+
id: exception-type
|
|
40
|
+
attributes:
|
|
41
|
+
label: Exception type
|
|
42
|
+
placeholder: "e.g. FileNotFoundError"
|
|
43
|
+
validations:
|
|
44
|
+
required: true
|
|
45
|
+
|
|
46
|
+
- type: input
|
|
47
|
+
id: exception-message
|
|
48
|
+
attributes:
|
|
49
|
+
label: Exception message
|
|
50
|
+
placeholder: "e.g. [WinError 2] The system cannot find the file specified"
|
|
51
|
+
|
|
52
|
+
- type: input
|
|
53
|
+
id: last-screen
|
|
54
|
+
attributes:
|
|
55
|
+
label: Last screen / action
|
|
56
|
+
description: Which screen were you on, or what did you click, when the crash happened?
|
|
57
|
+
placeholder: "e.g. organize_done — clicked Open Folder"
|
|
58
|
+
|
|
59
|
+
- type: textarea
|
|
60
|
+
id: traceback
|
|
61
|
+
attributes:
|
|
62
|
+
label: Traceback
|
|
63
|
+
description: Full Python traceback (auto-filled by the GUI).
|
|
64
|
+
render: text
|
|
65
|
+
validations:
|
|
66
|
+
required: true
|
|
67
|
+
|
|
68
|
+
- type: textarea
|
|
69
|
+
id: what-were-you-doing
|
|
70
|
+
attributes:
|
|
71
|
+
label: What were you doing?
|
|
72
|
+
description: Brief description of the steps leading up to the crash.
|
|
73
|
+
|
|
74
|
+
- type: textarea
|
|
75
|
+
id: debug-files
|
|
76
|
+
attributes:
|
|
77
|
+
label: Debug files
|
|
78
|
+
description: |
|
|
79
|
+
Please attach the crash dump file referenced above. It contains the
|
|
80
|
+
full traceback, app state, and recent logs needed to reproduce the
|
|
81
|
+
crash. If a `_riplex/` debug folder also exists at your output
|
|
82
|
+
directory, zip it and drag it here as well.
|
|
@@ -28,6 +28,20 @@ For the GUI, also include the gui extra:
|
|
|
28
28
|
pip install -e ".[dev,gui]"
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
### Editable-installing dvdcompare-scraper (optional)
|
|
32
|
+
|
|
33
|
+
By default `dvdcompare-scraper` is pulled from PyPI as a regular install, so
|
|
34
|
+
local edits to that sibling repo (typically at
|
|
35
|
+
`../dvdcompare-scraper/`) do not take effect until a new version is
|
|
36
|
+
published. To pick up scraper changes immediately without bumping the
|
|
37
|
+
version, editable-install it once:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
pip install -e ../dvdcompare-scraper
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
After this, `riplex-ui` and the CLI will use the local checkout directly.
|
|
44
|
+
|
|
31
45
|
### macOS extras (Homebrew Python only)
|
|
32
46
|
|
|
33
47
|
If you installed Python via Homebrew, two additional one-time steps are needed:
|
|
@@ -60,6 +74,30 @@ riplex-ui # Launch the Flet GUI
|
|
|
60
74
|
|
|
61
75
|
Do NOT use `python -m riplex` (that errors — riplex is a library package, not runnable). Do NOT use `python -m riplex_cli.main` when the entry point works.
|
|
62
76
|
|
|
77
|
+
Because `riplex` is editable-installed (`pip install -e .`), any local edit
|
|
78
|
+
to source files under `src/riplex/`, `src/riplex_cli/`, or `src/riplex_app/`
|
|
79
|
+
is live the next time you launch `riplex-ui` or run a `riplex` CLI command.
|
|
80
|
+
No reinstall step is needed for normal development.
|
|
81
|
+
|
|
82
|
+
## Upgrading dependencies
|
|
83
|
+
|
|
84
|
+
The only dependency that needs an explicit upgrade is `dvdcompare-scraper`,
|
|
85
|
+
since it's installed from PyPI (not editable). After a new version is
|
|
86
|
+
published (every push to its `main` branch auto-bumps the patch and
|
|
87
|
+
publishes), bump the pin in `pyproject.toml` and run:
|
|
88
|
+
```
|
|
89
|
+
pip install -e ".[dev,gui]" --upgrade
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Close `riplex-ui` first if it's running — the `.exe` shim is locked while
|
|
93
|
+
the process is alive and pip will fail with `WinError 32`.
|
|
94
|
+
|
|
95
|
+
To verify the upgrade picked up the new version:
|
|
96
|
+
```
|
|
97
|
+
py -m pip show dvdcompare-scraper | Select-String Version
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
|
|
63
101
|
## Dry-run default
|
|
64
102
|
|
|
65
103
|
All destructive commands (`rip`, `organize`, `orchestrate`) are dry-run by default. There is no `--dry-run` flag. Use `--execute` to actually perform the operation.
|
|
@@ -164,6 +164,11 @@ jobs:
|
|
|
164
164
|
- name: Create GitHub Release
|
|
165
165
|
uses: softprops/action-gh-release@v2
|
|
166
166
|
with:
|
|
167
|
+
# Auto-generate notes from commits and PRs since the previous tag,
|
|
168
|
+
# then prepend the tag annotation (if any) as a header. Using just
|
|
169
|
+
# the tag annotation produces single-line releases when the tag
|
|
170
|
+
# was created with `git tag -a -m "<subject>"` and no body.
|
|
171
|
+
generate_release_notes: true
|
|
167
172
|
body: ${{ steps.tag_notes.outputs.body }}
|
|
168
173
|
files: |
|
|
169
174
|
release/riplex-windows.exe
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: riplex
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.4
|
|
4
4
|
Summary: Automates the tedious manual work around MakeMKV: figuring out what to rip, which MKV files are actually what, and organizing everything into Plex-compatible folder structures.
|
|
5
5
|
License: MIT
|
|
6
6
|
Requires-Python: >=3.11
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Requires-Dist: httpx>=0.27
|
|
10
|
-
Requires-Dist: dvdcompare-scraper>=0.1.
|
|
10
|
+
Requires-Dist: dvdcompare-scraper>=0.1.15
|
|
11
11
|
Requires-Dist: platformdirs>=4.0
|
|
12
12
|
Provides-Extra: dev
|
|
13
13
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
@@ -4,6 +4,23 @@ All notable changes to the riplex documentation are recorded here.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
6
6
|
|
|
7
|
+
## 2026-05-13
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Bumped `dvdcompare-scraper` pin to `>=0.1.15`, which adds quoted-title disc-header parsing. Boxsets such as *Back to the Future 40th Anniversary Trilogy* that glue six physical discs into a single dvdcompare disc entry are now split correctly into one PlannedDisc per physical disc.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Disc Release screen: "View on dvdcompare.net" link showing the auto-selected film page so users can verify region/edition before committing to a long rip.
|
|
16
|
+
- Disc Release screen: manual film-id override input. Paste either a bare fid (e.g. `55540`) or a full URL (`https://www.dvdcompare.net/comparisons/film.php?fid=55540`) and riplex will fetch and use that film page instead. The chosen fid is persisted per `(title, disc_format)` so swapping discs in the same box set keeps the override, with a "Clear saved override" affordance.
|
|
17
|
+
|
|
18
|
+
## 2026-05-12
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Troubleshooting guide: new "GUI: disc not being detected" section covering the redesigned drive-list panel, manual drive selection, the `makemkvcon` status line, and the bundled bug-report flow.
|
|
23
|
+
|
|
7
24
|
## 2026-05-09
|
|
8
25
|
|
|
9
26
|
### Changed
|
|
@@ -35,6 +35,25 @@ Common issues and solutions reported by users.
|
|
|
35
35
|
|
|
36
36
|
---
|
|
37
37
|
|
|
38
|
+
## GUI: disc not being detected
|
|
39
|
+
|
|
40
|
+
**Symptom:** `riplex-ui` shows "No disc found" or sits on the disc detection screen even though a disc is inserted.
|
|
41
|
+
|
|
42
|
+
**What the GUI does:**
|
|
43
|
+
|
|
44
|
+
* On the **Disc Detection** screen, riplex now lists every optical drive your system reports, with a per-drive status badge (`Empty`, `Tray open`, `Disc loaded`, etc.).
|
|
45
|
+
* The list refreshes automatically every few seconds — inserting or ejecting a disc updates the screen without manual refresh. Click the circular ↻ button at the top right to force an immediate rescan.
|
|
46
|
+
* If exactly one drive has a loaded disc, riplex starts reading it automatically. With multiple drives or zero loaded drives, click `Read disc` next to the drive you want to use.
|
|
47
|
+
|
|
48
|
+
**If your drive is missing entirely:**
|
|
49
|
+
|
|
50
|
+
1. Confirm MakeMKV sees the drive. Open the MakeMKV GUI or run `makemkvcon -r info list` and look for a `DRV:` line with your device path.
|
|
51
|
+
2. If MakeMKV does not list it, the issue is at the OS/driver level — riplex only displays what MakeMKV reports.
|
|
52
|
+
3. Check the `makemkvcon: …` line at the top of the screen. If it shows `unavailable`, click the bundled "Download MakeMKV" link or follow the [installation guide](getting-started/installation.md).
|
|
53
|
+
4. Use the `Open bug report` button on the error panel — it pre-fills the GitHub issue with the captured MakeMKV diagnostics (executable path, version, last error) and points you at the log directory to attach.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
38
57
|
## Invalid config file (TOML parse error)
|
|
39
58
|
|
|
40
59
|
**Symptom:** Running any riplex command crashes with a `TOMLDecodeError` traceback mentioning your config file.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Consolidate riplex debug artifacts
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
riplex currently writes 11 distinct JSON/log artifacts across multiple
|
|
6
|
+
locations with overlapping naming. The word "manifest" is overloaded
|
|
7
|
+
(production `_rip_manifest.json` vs. debug `riplex-rip.manifest.json`),
|
|
8
|
+
two debug writers (`save_rip_manifest`, `save_scan_snapshot`) have no
|
|
9
|
+
production readers, and the organize snapshot lives at the title root
|
|
10
|
+
instead of in `_riplex/` like the other debug files. The `_riplex/README.txt`
|
|
11
|
+
template lists files that may not actually be present.
|
|
12
|
+
|
|
13
|
+
A related bug: failed rips silently produce a `_rip_manifest.json` with
|
|
14
|
+
`"filename": ""` because `run_rip` checks `proc.returncode == 0` to
|
|
15
|
+
determine success, but `makemkvcon` returns 0 even on HashCheck failures.
|
|
16
|
+
Surfaced by a real failure on Matrix Reloaded Disc 1 (corrupt
|
|
17
|
+
`/BDMV/STREAM/00002.m2ts`).
|
|
18
|
+
|
|
19
|
+
## Affected users
|
|
20
|
+
|
|
21
|
+
Anyone filing bug reports (confused about which JSON to attach), anyone
|
|
22
|
+
inspecting their rip output (unclear what each file is for), anyone
|
|
23
|
+
re-running organize on a failed rip (manifest claims success).
|
|
24
|
+
|
|
25
|
+
## Workaround
|
|
26
|
+
|
|
27
|
+
None — symptom is cosmetic confusion plus the failed-rip status bug,
|
|
28
|
+
which can be diagnosed by reading `_makemkvcon_tNN.log` directly.
|
|
29
|
+
|
|
30
|
+
## Proposed fix
|
|
31
|
+
|
|
32
|
+
### Target artifact layout
|
|
33
|
+
|
|
34
|
+
**Per-disc folder** (production + per-title logs):
|
|
35
|
+
|
|
36
|
+
- `Disc N/<canonical>_tNN.mkv` — actual rip
|
|
37
|
+
- `Disc N/_rip_manifest.json` — production; gains a per-title `status`
|
|
38
|
+
field (`"success"` | `"failed"` | `"cancelled"`) plus `error_message`
|
|
39
|
+
for failures, and top-level `success_count` / `failed_count`
|
|
40
|
+
- `Disc N/_makemkvcon_tNN.log` — stays here (per-title, too noisy for
|
|
41
|
+
the title-level debug folder)
|
|
42
|
+
|
|
43
|
+
**Title-root `_riplex/`** (single home for all debug):
|
|
44
|
+
|
|
45
|
+
- `riplex-rip.snapshot.json` — rip pipeline state (TMDb match,
|
|
46
|
+
dvdcompare, selected/ripped titles, phase)
|
|
47
|
+
- `riplex-organize.snapshot.json` — **renamed and moved** from
|
|
48
|
+
`<Title>.snapshot.json` at title root
|
|
49
|
+
- `organized.json` — already lives here, unchanged
|
|
50
|
+
- `riplex.log` — CLI session log, unchanged
|
|
51
|
+
- `README.txt` — rewritten to match what's actually written
|
|
52
|
+
|
|
53
|
+
**User-data folder** (`~/.../riplex/`) — unchanged:
|
|
54
|
+
|
|
55
|
+
- `riplex_app.log` — GUI runtime log
|
|
56
|
+
- `crashes/crash-*.txt` — GUI crash dumps
|
|
57
|
+
|
|
58
|
+
**Removed entirely**:
|
|
59
|
+
|
|
60
|
+
- `_riplex/riplex-rip.manifest.json` — duplicate of production manifest,
|
|
61
|
+
no readers
|
|
62
|
+
- `_riplex/riplex-scan.snapshot.json` — aborted parallel mechanism, no
|
|
63
|
+
production readers (only tests)
|
|
64
|
+
|
|
65
|
+
### Implementation phases
|
|
66
|
+
|
|
67
|
+
1. **Manifest status field.** Real success detection in `run_rip` (parse
|
|
68
|
+
`MSG:5004,...,"N titles saved, M failed"` summary line). Update
|
|
69
|
+
`build_rip_manifest` to include all attempted titles with `status` +
|
|
70
|
+
`error_message`. `build_scanned_from_manifests` skips non-success
|
|
71
|
+
entries. `load_manifest` defaults `status` to `"success"` when
|
|
72
|
+
missing for back-compat. Independent of other phases. (Partially
|
|
73
|
+
implemented: `_parse_rip_summary` already added in
|
|
74
|
+
`src/riplex/disc/makemkv.py`.)
|
|
75
|
+
|
|
76
|
+
2. **Consolidate organize snapshot.** New path
|
|
77
|
+
`_riplex/riplex-organize.snapshot.json`. `snapshot.py::load()` falls
|
|
78
|
+
back to legacy `<Title>.snapshot.json` for old folders (no
|
|
79
|
+
migration). Updates callers in `organize.py` and
|
|
80
|
+
`organize_preview.py`. Independent of phase 1.
|
|
81
|
+
|
|
82
|
+
3. **Remove dead writers.** Delete `snapshot.py::save_rip_manifest()`
|
|
83
|
+
and `snapshot.py::save_scan_snapshot()` plus their callers. Drop
|
|
84
|
+
corresponding tests. Depends on phase 2.
|
|
85
|
+
|
|
86
|
+
4. **Docs + README template.** Rewrite `_README_TEXT` in `snapshot.py`
|
|
87
|
+
to match reality. New "Output Artifacts" section in
|
|
88
|
+
`docs/architecture.md` with the full table (production vs debug,
|
|
89
|
+
location, writer, reader, safe-to-delete). Dated entry in
|
|
90
|
+
`docs/changelog.md`. Same commit as phases 2-3 so docs match code.
|
|
91
|
+
|
|
92
|
+
5. **Patch version bump** per repo convention.
|
|
93
|
+
|
|
94
|
+
### Decisions locked
|
|
95
|
+
|
|
96
|
+
- Heavy scope: consolidate file locations + rename + remove dead code +
|
|
97
|
+
docs (not just docs)
|
|
98
|
+
- "manifest" reserved for production data; debug duplicate is deleted,
|
|
99
|
+
not renamed
|
|
100
|
+
- Both `save_rip_manifest` and `save_scan_snapshot` removed
|
|
101
|
+
- `_makemkvcon_tNN.log` stays in per-disc folder (too noisy/per-title to
|
|
102
|
+
belong alongside the higher-level pipeline snapshots)
|
|
103
|
+
- Failed rips DO get a `_rip_manifest.json` entry with `status: "failed"`
|
|
104
|
+
- No migration tool for old organize snapshots — `load()` just tries new
|
|
105
|
+
path first, falls back to legacy
|
|
106
|
+
|
|
107
|
+
### Verification
|
|
108
|
+
|
|
109
|
+
1. `pytest` — existing tests pass; new tests for status field +
|
|
110
|
+
legacy snapshot fallback
|
|
111
|
+
2. Fresh GUI rip → output dirs contain only files in the north-star
|
|
112
|
+
list above
|
|
113
|
+
3. Cancel a rip mid-way → manifest has `status: "cancelled"` entry
|
|
114
|
+
4. Re-rip Matrix Reloaded Disc 1 (the damaged disc that prompted this)
|
|
115
|
+
→ manifest has `status: "failed"` with `error_message` populated
|
|
116
|
+
5. Run organize against a folder containing legacy
|
|
117
|
+
`<Title>.snapshot.json` → loads via fallback
|
|
118
|
+
6. Open `_riplex/README.txt` in a finished session → matches files
|
|
119
|
+
actually present
|
|
120
|
+
7. Visual: title folder structure matches `docs/architecture.md` table
|
|
121
|
+
exactly
|
|
122
|
+
|
|
123
|
+
### Out of scope
|
|
124
|
+
|
|
125
|
+
- User-data log locations (`riplex_app.log`, crash dumps)
|
|
126
|
+
- Migration tool for old `<Title>.snapshot.json` (just fallback-read)
|
|
127
|
+
- v1/v2 snapshot envelope format (already supported by `load`)
|
|
128
|
+
- `_makemkvcon_tNN.log` location/format
|
|
129
|
+
- GUI changes beyond the manifest status fix already started
|
|
130
|
+
|
|
131
|
+
## Relevant files
|
|
132
|
+
|
|
133
|
+
- `src/riplex/manifest.py` — `build_rip_manifest`,
|
|
134
|
+
`build_scanned_from_manifests`, `load_manifest`
|
|
135
|
+
- `src/riplex/snapshot.py` — `save_rip_snapshot`, `save_rip_manifest`
|
|
136
|
+
(DELETE), `save_scan_snapshot` (DELETE), `save_from_scanned`, `load`,
|
|
137
|
+
`_README_TEXT`, `get_debug_dir`
|
|
138
|
+
- `src/riplex/disc/makemkv.py` — `run_rip`, `_parse_rip_summary`
|
|
139
|
+
- `src/riplex_cli/commands/rip.py` — remove `save_rip_manifest` call
|
|
140
|
+
- `src/riplex_cli/commands/organize.py` — organize snapshot path
|
|
141
|
+
- `src/riplex_app/screens/organize_preview.py` — organize snapshot path
|
|
142
|
+
- `src/riplex_app/screens/progress.py` — `_write_manifest`
|
|
143
|
+
- `tests/test_snapshot.py`, `tests/test_manifest.py` — fixtures, drop
|
|
144
|
+
deleted-fn tests, add status-field tests
|
|
145
|
+
- `docs/architecture.md` — new Output Artifacts section
|
|
146
|
+
- `docs/changelog.md` — dated entry
|