riplex 0.1.0__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.1.0/.github/copilot-instructions.md +17 -0
- riplex-0.1.0/.github/workflows/publish.yml +34 -0
- riplex-0.1.0/.gitignore +11 -0
- riplex-0.1.0/PKG-INFO +106 -0
- riplex-0.1.0/PLANNED_FEATURES.md +57 -0
- riplex-0.1.0/README.md +91 -0
- riplex-0.1.0/docs/architecture.md +129 -0
- riplex-0.1.0/docs/changelog.md +56 -0
- riplex-0.1.0/docs/getting-started/configuration.md +35 -0
- riplex-0.1.0/docs/getting-started/installation.md +45 -0
- riplex-0.1.0/docs/guide/lookup.md +138 -0
- riplex-0.1.0/docs/guide/orchestrate.md +105 -0
- riplex-0.1.0/docs/guide/organize.md +163 -0
- riplex-0.1.0/docs/guide/workflow.md +114 -0
- riplex-0.1.0/docs/index.md +49 -0
- riplex-0.1.0/docs/naming-rules.md +163 -0
- riplex-0.1.0/docs/planned-mkdocs-migration.md +22 -0
- riplex-0.1.0/docs/reference/cli.md +131 -0
- riplex-0.1.0/issues/compilation-contains-missing-targets.md +29 -0
- riplex-0.1.0/issues/dvdcompare-4k-sparse-extras.md +57 -0
- riplex-0.1.0/issues/dvdcompare-zero-runtime-film-entries.md +27 -0
- riplex-0.1.0/issues/waterworld-unmatched-ulysses-cut.md +24 -0
- riplex-0.1.0/mkdocs.yml +59 -0
- riplex-0.1.0/plex_naming_rules.md +154 -0
- riplex-0.1.0/pyproject.toml +32 -0
- riplex-0.1.0/scripts/generate_rip_snapshots.py +175 -0
- riplex-0.1.0/setup.cfg +4 -0
- riplex-0.1.0/src/riplex/__init__.py +3 -0
- riplex-0.1.0/src/riplex/cache.py +111 -0
- riplex-0.1.0/src/riplex/cli.py +2635 -0
- riplex-0.1.0/src/riplex/config.py +121 -0
- riplex-0.1.0/src/riplex/dedup.py +504 -0
- riplex-0.1.0/src/riplex/detect.py +150 -0
- riplex-0.1.0/src/riplex/disc_analysis.py +331 -0
- riplex-0.1.0/src/riplex/disc_provider.py +211 -0
- riplex-0.1.0/src/riplex/formatter.py +115 -0
- riplex-0.1.0/src/riplex/makemkv.py +573 -0
- riplex-0.1.0/src/riplex/matcher.py +445 -0
- riplex-0.1.0/src/riplex/metadata_provider.py +87 -0
- riplex-0.1.0/src/riplex/metadata_sources/__init__.py +0 -0
- riplex-0.1.0/src/riplex/metadata_sources/tmdb.py +208 -0
- riplex-0.1.0/src/riplex/models.py +137 -0
- riplex-0.1.0/src/riplex/normalize.py +147 -0
- riplex-0.1.0/src/riplex/organizer.py +674 -0
- riplex-0.1.0/src/riplex/planner.py +178 -0
- riplex-0.1.0/src/riplex/scanner.py +189 -0
- riplex-0.1.0/src/riplex/snapshot.py +144 -0
- riplex-0.1.0/src/riplex/splitter.py +126 -0
- riplex-0.1.0/src/riplex/tagger.py +146 -0
- riplex-0.1.0/src/riplex/ui.py +217 -0
- riplex-0.1.0/src/riplex.egg-info/PKG-INFO +106 -0
- riplex-0.1.0/src/riplex.egg-info/SOURCES.txt +83 -0
- riplex-0.1.0/src/riplex.egg-info/dependency_links.txt +1 -0
- riplex-0.1.0/src/riplex.egg-info/entry_points.txt +2 -0
- riplex-0.1.0/src/riplex.egg-info/requires.txt +8 -0
- riplex-0.1.0/src/riplex.egg-info/top_level.txt +1 -0
- riplex-0.1.0/tests/__init__.py +0 -0
- riplex-0.1.0/tests/fixtures/makemkvcon_frozen_planet_ii_d2.txt +723 -0
- riplex-0.1.0/tests/fixtures/makemkvcon_list.txt +17 -0
- riplex-0.1.0/tests/snapshots/Batman Begins.snapshot.json +344 -0
- riplex-0.1.0/tests/snapshots/Blade Runner (Blu-ray 4k).snapshot.json +838 -0
- riplex-0.1.0/tests/snapshots/Blade Runner The Final Cut.snapshot.json +191 -0
- riplex-0.1.0/tests/snapshots/Seven Worlds One Planet.snapshot.json +306 -0
- riplex-0.1.0/tests/snapshots/The Dark Knight Rises.snapshot.json +460 -0
- riplex-0.1.0/tests/snapshots/The Dark Knight.snapshot.json +878 -0
- riplex-0.1.0/tests/snapshots/Waterworld.snapshot.json +203 -0
- riplex-0.1.0/tests/test_cache.py +103 -0
- riplex-0.1.0/tests/test_cli_utils.py +576 -0
- riplex-0.1.0/tests/test_config.py +34 -0
- riplex-0.1.0/tests/test_dedup.py +394 -0
- riplex-0.1.0/tests/test_detect.py +226 -0
- riplex-0.1.0/tests/test_disc_analysis.py +232 -0
- riplex-0.1.0/tests/test_disc_provider.py +201 -0
- riplex-0.1.0/tests/test_formatter.py +105 -0
- riplex-0.1.0/tests/test_makemkv.py +286 -0
- riplex-0.1.0/tests/test_matcher.py +622 -0
- riplex-0.1.0/tests/test_normalize.py +131 -0
- riplex-0.1.0/tests/test_organizer.py +1000 -0
- riplex-0.1.0/tests/test_planner.py +199 -0
- riplex-0.1.0/tests/test_rip_guide.py +260 -0
- riplex-0.1.0/tests/test_scanner.py +101 -0
- riplex-0.1.0/tests/test_snapshot.py +215 -0
- riplex-0.1.0/tests/test_splitter.py +90 -0
- riplex-0.1.0/tests/test_tagger.py +276 -0
- riplex-0.1.0/tests/test_ui.py +163 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Copilot Instructions for riplex
|
|
2
|
+
|
|
3
|
+
## Documentation changelog
|
|
4
|
+
|
|
5
|
+
When any file under `docs/` is added, modified, or removed, update `docs/changelog.md` with a dated entry describing the change. Follow the [Keep a Changelog](https://keepachangelog.com/) format with sections like Added, Changed, Removed, or Fixed under a date heading.
|
|
6
|
+
|
|
7
|
+
## CLI executable
|
|
8
|
+
|
|
9
|
+
Always use `py` to run Python on this project (not `python` or `python3`). The installed `riplex.exe` in PATH may point to the wrong Python version. Prefer `py -m riplex` to ensure the correct interpreter.
|
|
10
|
+
|
|
11
|
+
## Dry-run default
|
|
12
|
+
|
|
13
|
+
The `organize` subcommand is dry-run by default. There is no `--dry-run` flag. Use `--execute` to actually move files.
|
|
14
|
+
|
|
15
|
+
## Testing
|
|
16
|
+
|
|
17
|
+
Run tests with `pytest` from the project root. All tests must pass before committing.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.12"
|
|
16
|
+
- run: pip install build
|
|
17
|
+
- run: python -m build
|
|
18
|
+
- uses: actions/upload-artifact@v4
|
|
19
|
+
with:
|
|
20
|
+
name: dist
|
|
21
|
+
path: dist/
|
|
22
|
+
|
|
23
|
+
publish:
|
|
24
|
+
needs: build
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
environment: pypi
|
|
27
|
+
permissions:
|
|
28
|
+
id-token: write
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/download-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/
|
|
34
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
riplex-0.1.0/.gitignore
ADDED
riplex-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: riplex
|
|
3
|
+
Version: 0.1.0
|
|
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
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: httpx>=0.27
|
|
9
|
+
Requires-Dist: dvdcompare-scraper>=0.1.0
|
|
10
|
+
Requires-Dist: platformdirs>=4.0
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
13
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
14
|
+
Requires-Dist: respx>=0.21; extra == "dev"
|
|
15
|
+
|
|
16
|
+
# riplex
|
|
17
|
+
|
|
18
|
+
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.
|
|
19
|
+
|
|
20
|
+
## Why?
|
|
21
|
+
|
|
22
|
+
MakeMKV is great at one thing: reading a disc and dumping raw MKV files. But that's where its job ends and yours begins.
|
|
23
|
+
|
|
24
|
+
You're left with a pile of generically-named files (`title_t00.mkv`, `title_t01.mkv`, ...) and no idea which is the main film, which are featurettes, which are duplicates, and which is the play-all compilation you didn't need. For a multi-disc TV series, you're looking at hours of manual effort: reading disc cases, Googling runtimes, renaming files one by one, and building the exact folder hierarchy Plex demands.
|
|
25
|
+
|
|
26
|
+
We identified the best sources of disc metadata (TMDb for canonical titles and episode info, dvdcompare.net for per-disc content breakdowns) and automated the entire pipeline. riplex pulls that data, figures out what's on every disc in a release, tells you exactly which MakeMKV titles to rip (and which to skip), then matches, renames, deduplicates, splits, and organizes everything into the correct Plex structure automatically.
|
|
27
|
+
|
|
28
|
+
## What it does
|
|
29
|
+
|
|
30
|
+
| Command | What it does |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `orchestrate` | Full pipeline: insert a disc, riplex handles detection, metadata lookup, ripping, and organizing. Multi-disc with swap prompts. |
|
|
33
|
+
| `rip` | Single-disc rip with smart title selection (skips play-alls, duplicates, junk). |
|
|
34
|
+
| `organize` | Scan existing MKV rips, deduplicate, match to metadata by runtime, move into Plex layout. |
|
|
35
|
+
| `lookup` | Preview disc contents and recommended rip strategy before touching MakeMKV. |
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install -e ".[dev]"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Configure
|
|
46
|
+
|
|
47
|
+
Create a config file at `%APPDATA%\riplex\config.toml` (Windows) or `~/.config/riplex/config.toml`:
|
|
48
|
+
|
|
49
|
+
```toml
|
|
50
|
+
tmdb_api_key = "your_key_here"
|
|
51
|
+
output_root = "E:/Media"
|
|
52
|
+
rip_output = "E:/Media/Rips"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Get a free TMDb API key at https://www.themoviedb.org/settings/api.
|
|
56
|
+
|
|
57
|
+
### Rip a disc (interactive)
|
|
58
|
+
|
|
59
|
+
Insert a disc and run:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
riplex orchestrate --execute
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
riplex auto-detects the title from the volume label, looks up disc metadata, shows you what's on each disc, lets you choose which to rip, and organizes everything into Plex folders when done.
|
|
66
|
+
|
|
67
|
+
### Rip a disc (unattended)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
riplex orchestrate --execute --auto
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Skips all prompts, uses best-guess defaults. Good for scripted or scheduled runs.
|
|
74
|
+
|
|
75
|
+
### Organize existing rips
|
|
76
|
+
|
|
77
|
+
Already ripped with MakeMKV manually? Point `organize` at the folder:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
riplex organize path/to/rips/Oppenheimer --execute
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Requirements
|
|
84
|
+
|
|
85
|
+
- Python 3.11+
|
|
86
|
+
- [TMDb API key](https://www.themoviedb.org/settings/api) (free)
|
|
87
|
+
- [MakeMKV](https://www.makemkv.com/) with `makemkvcon` on PATH
|
|
88
|
+
- [ffmpeg](https://ffmpeg.org/) (`ffprobe`) for metadata extraction
|
|
89
|
+
- [MKVToolNix](https://mkvtoolnix.download/) (`mkvmerge`, `mkvpropedit`) for chapter splitting and tagging
|
|
90
|
+
|
|
91
|
+
## Related Projects
|
|
92
|
+
|
|
93
|
+
- **[dvdcompare-scraper](https://github.com/ashergarland/dvdcompare-scraper)**: Scrapes per-disc content metadata from dvdcompare.net (featurettes, interviews, deleted scenes, runtimes). Required dependency that powers riplex's disc content lookup. Contributions welcome.
|
|
94
|
+
|
|
95
|
+
## Documentation
|
|
96
|
+
|
|
97
|
+
Full documentation is in the [docs/](docs/) folder:
|
|
98
|
+
|
|
99
|
+
- [Getting Started](docs/getting-started/installation.md): installation, configuration
|
|
100
|
+
- [User Guide](docs/guide/workflow.md): workflows, command-by-command guides
|
|
101
|
+
- [CLI Reference](docs/reference/cli.md): all options for all commands
|
|
102
|
+
- [Architecture](docs/architecture.md): design, data flow, project structure
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Planned Features
|
|
2
|
+
|
|
3
|
+
## Recently Implemented
|
|
4
|
+
|
|
5
|
+
### Orchestrate Mode
|
|
6
|
+
|
|
7
|
+
The `riplex orchestrate` command is now fully implemented. It handles
|
|
8
|
+
the complete multi-disc rip-then-organize workflow in a single session:
|
|
9
|
+
insert a disc, auto-detect the title, look up dvdcompare for disc contents,
|
|
10
|
+
select which discs to rip, rip each one with disc-swap prompts, then
|
|
11
|
+
organize all files into Plex folder structure.
|
|
12
|
+
|
|
13
|
+
See the orchestrate guide in the docs for full usage details.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Multi-Resolution Support (4K + Standard Blu-ray)
|
|
17
|
+
|
|
18
|
+
Many 4K boxsets include standard Blu-ray discs with the same content at 1080p.
|
|
19
|
+
Some users may want to rip both so Plex can serve the lower-resolution version
|
|
20
|
+
to mobile devices without transcoding.
|
|
21
|
+
|
|
22
|
+
### Plex support status
|
|
23
|
+
|
|
24
|
+
**Movies**: Fully supported via "Multi-Version Movies." Multiple files in the
|
|
25
|
+
same folder with different suffixes are collapsed into one library item. Plex
|
|
26
|
+
auto-selects the best version per device, and many apps let the user choose
|
|
27
|
+
manually. Naming convention:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
/Movies/MovieName (Year)/
|
|
31
|
+
MovieName (Year) - 4K.mkv
|
|
32
|
+
MovieName (Year) - 1080p.mkv
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**TV Shows**: NOT officially supported. Plex's TV naming documentation does not
|
|
36
|
+
mention multi-version episodes. There is no documented way to have 4K and 1080p
|
|
37
|
+
versions of the same episode collapse into a single item. Community workarounds
|
|
38
|
+
exist (separate libraries, or relying on Plex's automatic version detection
|
|
39
|
+
which sometimes works for TV but is undocumented and unreliable).
|
|
40
|
+
|
|
41
|
+
### Plan
|
|
42
|
+
|
|
43
|
+
- **Movies**: Support ripping both 4K and standard Blu-ray discs. During
|
|
44
|
+
organize, name them with resolution suffixes so Plex collapses them.
|
|
45
|
+
- **TV Shows**: Since Plex does not officially support multi-version TV
|
|
46
|
+
episodes, we should:
|
|
47
|
+
1. Warn the user during rip if they attempt to rip a standard Blu-ray disc
|
|
48
|
+
for a TV show that already has 4K rips.
|
|
49
|
+
2. Offer to skip it with an explanation of why.
|
|
50
|
+
3. If Plex adds official TV multi-version support in the future, revisit.
|
|
51
|
+
4. Optionally allow it anyway for users who use separate libraries or
|
|
52
|
+
other workarounds, but make the limitation clear.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
## Other Ideas
|
|
56
|
+
|
|
57
|
+
(Add future feature ideas here as they come up.)
|
riplex-0.1.0/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# riplex
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
## Why?
|
|
6
|
+
|
|
7
|
+
MakeMKV is great at one thing: reading a disc and dumping raw MKV files. But that's where its job ends and yours begins.
|
|
8
|
+
|
|
9
|
+
You're left with a pile of generically-named files (`title_t00.mkv`, `title_t01.mkv`, ...) and no idea which is the main film, which are featurettes, which are duplicates, and which is the play-all compilation you didn't need. For a multi-disc TV series, you're looking at hours of manual effort: reading disc cases, Googling runtimes, renaming files one by one, and building the exact folder hierarchy Plex demands.
|
|
10
|
+
|
|
11
|
+
We identified the best sources of disc metadata (TMDb for canonical titles and episode info, dvdcompare.net for per-disc content breakdowns) and automated the entire pipeline. riplex pulls that data, figures out what's on every disc in a release, tells you exactly which MakeMKV titles to rip (and which to skip), then matches, renames, deduplicates, splits, and organizes everything into the correct Plex structure automatically.
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
| Command | What it does |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `orchestrate` | Full pipeline: insert a disc, riplex handles detection, metadata lookup, ripping, and organizing. Multi-disc with swap prompts. |
|
|
18
|
+
| `rip` | Single-disc rip with smart title selection (skips play-alls, duplicates, junk). |
|
|
19
|
+
| `organize` | Scan existing MKV rips, deduplicate, match to metadata by runtime, move into Plex layout. |
|
|
20
|
+
| `lookup` | Preview disc contents and recommended rip strategy before touching MakeMKV. |
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### Install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install -e ".[dev]"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Configure
|
|
31
|
+
|
|
32
|
+
Create a config file at `%APPDATA%\riplex\config.toml` (Windows) or `~/.config/riplex/config.toml`:
|
|
33
|
+
|
|
34
|
+
```toml
|
|
35
|
+
tmdb_api_key = "your_key_here"
|
|
36
|
+
output_root = "E:/Media"
|
|
37
|
+
rip_output = "E:/Media/Rips"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Get a free TMDb API key at https://www.themoviedb.org/settings/api.
|
|
41
|
+
|
|
42
|
+
### Rip a disc (interactive)
|
|
43
|
+
|
|
44
|
+
Insert a disc and run:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
riplex orchestrate --execute
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
riplex auto-detects the title from the volume label, looks up disc metadata, shows you what's on each disc, lets you choose which to rip, and organizes everything into Plex folders when done.
|
|
51
|
+
|
|
52
|
+
### Rip a disc (unattended)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
riplex orchestrate --execute --auto
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Skips all prompts, uses best-guess defaults. Good for scripted or scheduled runs.
|
|
59
|
+
|
|
60
|
+
### Organize existing rips
|
|
61
|
+
|
|
62
|
+
Already ripped with MakeMKV manually? Point `organize` at the folder:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
riplex organize path/to/rips/Oppenheimer --execute
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Requirements
|
|
69
|
+
|
|
70
|
+
- Python 3.11+
|
|
71
|
+
- [TMDb API key](https://www.themoviedb.org/settings/api) (free)
|
|
72
|
+
- [MakeMKV](https://www.makemkv.com/) with `makemkvcon` on PATH
|
|
73
|
+
- [ffmpeg](https://ffmpeg.org/) (`ffprobe`) for metadata extraction
|
|
74
|
+
- [MKVToolNix](https://mkvtoolnix.download/) (`mkvmerge`, `mkvpropedit`) for chapter splitting and tagging
|
|
75
|
+
|
|
76
|
+
## Related Projects
|
|
77
|
+
|
|
78
|
+
- **[dvdcompare-scraper](https://github.com/ashergarland/dvdcompare-scraper)**: Scrapes per-disc content metadata from dvdcompare.net (featurettes, interviews, deleted scenes, runtimes). Required dependency that powers riplex's disc content lookup. Contributions welcome.
|
|
79
|
+
|
|
80
|
+
## Documentation
|
|
81
|
+
|
|
82
|
+
Full documentation is in the [docs/](docs/) folder:
|
|
83
|
+
|
|
84
|
+
- [Getting Started](docs/getting-started/installation.md): installation, configuration
|
|
85
|
+
- [User Guide](docs/guide/workflow.md): workflows, command-by-command guides
|
|
86
|
+
- [CLI Reference](docs/reference/cli.md): all options for all commands
|
|
87
|
+
- [Architecture](docs/architecture.md): design, data flow, project structure
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
MIT
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
riplex is a Python CLI application with four commands, each targeting a different stage of the disc ripping workflow:
|
|
6
|
+
|
|
7
|
+
- **`orchestrate`**: The primary workflow. Multi-disc rip-then-organize in a single session. Combines disc detection, dvdcompare lookup, disc selection, ripping, and organizing.
|
|
8
|
+
- **`rip`**: Single-disc rip via makemkvcon. Disc analysis, auto title selection, and optional post-rip organize.
|
|
9
|
+
- **`organize`**: The file organization pipeline. Scans MKV files, deduplicates, looks up TMDb + dvdcompare, matches files by runtime, and moves everything into Plex folder layout.
|
|
10
|
+
- **`lookup`**: TMDb + dvdcompare lookup. Shows disc contents and recommended rip strategy before ripping. Helps users decide which MakeMKV titles to rip vs skip, and creates correct folder structure.
|
|
11
|
+
|
|
12
|
+
## Metadata provider
|
|
13
|
+
|
|
14
|
+
The metadata provider is abstracted behind a clean interface (`MetadataProvider`). The default implementation uses TMDb, which is the same source Plex uses for its metadata agents. The provider can be swapped out for TheTVDB or any other source by implementing the interface.
|
|
15
|
+
|
|
16
|
+
## Project structure
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
src/riplex/
|
|
20
|
+
__init__.py
|
|
21
|
+
cli.py # CLI entry point (orchestrate, rip, organize, lookup subcommands)
|
|
22
|
+
config.py # Config file loading and setting resolution
|
|
23
|
+
models.py # Data models (ScannedFile, PlannedDisc, MatchCandidate, etc.)
|
|
24
|
+
metadata_provider.py # Abstract provider interface
|
|
25
|
+
metadata_sources/
|
|
26
|
+
tmdb.py # TMDb API implementation
|
|
27
|
+
normalize.py # Filename/path normalization
|
|
28
|
+
formatter.py # Text and JSON output formatters
|
|
29
|
+
planner.py # Core planning orchestrator
|
|
30
|
+
matcher.py # Runtime-based file matching with disc constraints
|
|
31
|
+
scanner.py # MakeMKV folder scanner (ffprobe-based metadata extraction)
|
|
32
|
+
snapshot.py # Snapshot capture and loading (JSON serialization of scan results)
|
|
33
|
+
detect.py # Format auto-detection, title grouping, incomplete file detection
|
|
34
|
+
dedup.py # Duplicate MKV detection (metadata fingerprint + perceptual hash)
|
|
35
|
+
cache.py # File-based JSON cache with TTL (dvdcompare, TMDb)
|
|
36
|
+
disc_provider.py # dvdcompare.net disc extras metadata bridge
|
|
37
|
+
disc_analysis.py # Live disc analysis via makemkvcon (title classification, rip recommendations)
|
|
38
|
+
makemkv.py # makemkvcon wrapper (disc reading, title ripping, progress parsing)
|
|
39
|
+
organizer.py # Plex destination path builder and file mover
|
|
40
|
+
splitter.py # Chapter-based MKV splitting via mkvmerge
|
|
41
|
+
tagger.py # MKV organized tagging via mkvpropedit
|
|
42
|
+
ui.py # Interactive prompts (multi-select, confirmations, text input)
|
|
43
|
+
tests/
|
|
44
|
+
test_cache.py
|
|
45
|
+
test_cli_utils.py
|
|
46
|
+
test_config.py
|
|
47
|
+
test_dedup.py
|
|
48
|
+
test_detect.py
|
|
49
|
+
test_disc_analysis.py
|
|
50
|
+
test_disc_provider.py
|
|
51
|
+
test_formatter.py
|
|
52
|
+
test_makemkv.py
|
|
53
|
+
test_matcher.py
|
|
54
|
+
test_normalize.py
|
|
55
|
+
test_organizer.py
|
|
56
|
+
test_planner.py
|
|
57
|
+
test_rip_guide.py
|
|
58
|
+
test_scanner.py
|
|
59
|
+
test_splitter.py
|
|
60
|
+
test_tagger.py
|
|
61
|
+
test_ui.py
|
|
62
|
+
snapshots/ # MKV metadata snapshots for offline test replay
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Key data flow
|
|
66
|
+
|
|
67
|
+
### Orchestrate mode
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Physical disc
|
|
71
|
+
-> Drive detection (auto-scan optical drives)
|
|
72
|
+
-> Volume label parsing (title auto-detection)
|
|
73
|
+
-> TMDb API (canonical title lookup, disambiguation)
|
|
74
|
+
-> dvdcompare (disc breakdown, content listings)
|
|
75
|
+
-> Disc selection (interactive or --discs flag)
|
|
76
|
+
-> Per-disc loop:
|
|
77
|
+
-> makemkvcon (disc reading, title analysis)
|
|
78
|
+
-> Disc analysis (classification, rip recommendations)
|
|
79
|
+
-> makemkvcon (title ripping with progress)
|
|
80
|
+
-> Manifest writing (disc metadata snapshot)
|
|
81
|
+
-> Organize pipeline (dedup, match, move, split, tag)
|
|
82
|
+
-> Archive (move rip folder to archive_root, optional)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Rip mode
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
Physical disc
|
|
89
|
+
-> Drive detection + volume label parsing
|
|
90
|
+
-> TMDb API (canonical title lookup)
|
|
91
|
+
-> dvdcompare (disc breakdown)
|
|
92
|
+
-> makemkvcon (disc reading, title analysis)
|
|
93
|
+
-> Disc analysis (classification, rip/skip recommendations)
|
|
94
|
+
-> makemkvcon (title ripping with progress)
|
|
95
|
+
-> Optional: Organize pipeline
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Plan mode
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
User input (title, year)
|
|
102
|
+
-> TMDb API (via MetadataProvider)
|
|
103
|
+
-> Planner (builds PlannedMovie or PlannedShow)
|
|
104
|
+
-> Formatter (text or JSON output)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Organize mode
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
MakeMKV rip folder
|
|
111
|
+
-> Scanner (ffprobe metadata extraction)
|
|
112
|
+
-> Dedup (duplicate detection and removal)
|
|
113
|
+
-> Detect (play-all detection, format inference, title grouping)
|
|
114
|
+
-> TMDb API (canonical title lookup)
|
|
115
|
+
-> dvdcompare (disc extras metadata)
|
|
116
|
+
-> Matcher (runtime-based file-to-entry matching)
|
|
117
|
+
-> Organizer (destination path builder)
|
|
118
|
+
-> Splitter (chapter-based MKV splitting, if needed)
|
|
119
|
+
-> Tagger (mark files as organized)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Rip guide mode
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
User input (title, year)
|
|
126
|
+
-> TMDb API (canonical title lookup)
|
|
127
|
+
-> dvdcompare (disc breakdown)
|
|
128
|
+
-> CLI (formatted disc guide output)
|
|
129
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Documentation Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the riplex documentation are recorded here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
6
|
+
|
|
7
|
+
## 2026-04-30
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Orchestrate guide (`docs/guide/orchestrate.md`): full documentation for the new primary workflow command
|
|
12
|
+
- `orchestrate` subcommand in CLI Reference with complete options table
|
|
13
|
+
- `rip` subcommand added to README (features block, usage examples, CLI reference table)
|
|
14
|
+
- `orchestrate` subcommand added to README (features block, usage examples, CLI reference table)
|
|
15
|
+
- New config keys documented: `rip_output` and `archive_root` (README, configuration.md, CLI reference)
|
|
16
|
+
- Orchestrate and Rip data flow diagrams in architecture.md
|
|
17
|
+
- MakeMKV/makemkvcon added to Requirements section
|
|
18
|
+
- New source files documented in project structure: `ui.py`, `disc_analysis.py`, `makemkv.py`
|
|
19
|
+
- Orchestrate entry in mkdocs.yml navigation
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- README Features section reordered: orchestrate and rip are now listed first as the primary commands
|
|
24
|
+
- `plan` marked as deprecated (alias for `rip-guide`) throughout README and CLI reference
|
|
25
|
+
- Organize output examples updated to new grouped format (subfolder headings, `<-` arrow notation)
|
|
26
|
+
- Rip-guide output examples updated to use configurable rip output path instead of hardcoded `_MakeMKV`
|
|
27
|
+
- Architecture section updated from 4 modes to 6 modes (added orchestrate, rip)
|
|
28
|
+
- Project structure listings updated to include all current source and test files
|
|
29
|
+
- `docs/guide/workflow.md` updated to recommend orchestrate as the primary workflow
|
|
30
|
+
- `docs/architecture.md` updated with orchestrate and rip modes and data flows
|
|
31
|
+
- `PLANNED_FEATURES.md` orchestrate section moved to "Recently Implemented"
|
|
32
|
+
- CLI reference tables for organize (added `--snapshot`, `--auto`) and rip-guide (added `--drive`) updated
|
|
33
|
+
|
|
34
|
+
## 2025-04-20
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- Replaced all personal/machine-specific paths with generic placeholders across all docs and README
|
|
39
|
+
- CLI examples now use `path/to/rips/Title` for user-supplied input paths
|
|
40
|
+
- Tool output examples (rip-guide folder structure) use `<output_root>/_MakeMKV/` to clarify the staging directory
|
|
41
|
+
- Output destination examples use relative paths (e.g. `Movies/...`, `TV Shows/...`)
|
|
42
|
+
- Config examples use `/path/to/media` placeholder
|
|
43
|
+
- Debug log references changed to "OS temp directory" instead of platform-specific paths
|
|
44
|
+
- Removed personal Python install path from `.github/copilot-instructions.md`
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- Initial documentation structure in `docs/` folder
|
|
49
|
+
- Home page with feature overview and quick start (`index.md`)
|
|
50
|
+
- Getting Started section: Installation, Configuration
|
|
51
|
+
- User Guide section: Typical Workflow, Rip Guide, Organizing Files, Planning, Snapshots
|
|
52
|
+
- CLI Reference page with all subcommands and options
|
|
53
|
+
- Architecture overview with data flow diagrams
|
|
54
|
+
- Plex Naming Rules reference
|
|
55
|
+
- `mkdocs.yml` configuration (ready for MkDocs Material when published)
|
|
56
|
+
- This changelog
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
riplex reads settings from three sources, in priority order:
|
|
4
|
+
|
|
5
|
+
1. CLI flags (highest priority)
|
|
6
|
+
2. Environment variables
|
|
7
|
+
3. Config file (lowest priority)
|
|
8
|
+
|
|
9
|
+
## Config file
|
|
10
|
+
|
|
11
|
+
Create a config file at one of these locations:
|
|
12
|
+
|
|
13
|
+
| Platform | Path |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Windows | `%APPDATA%\riplex\config.toml` |
|
|
16
|
+
| Linux/macOS | `~/.config/riplex/config.toml` |
|
|
17
|
+
| Any (local) | `riplex.toml` in the current working directory |
|
|
18
|
+
|
|
19
|
+
Example:
|
|
20
|
+
|
|
21
|
+
```toml
|
|
22
|
+
tmdb_api_key = "your_api_key_here"
|
|
23
|
+
output_root = "/path/to/media"
|
|
24
|
+
rip_output = "/path/to/media/Rips"
|
|
25
|
+
archive_root = "/path/to/media/Rips/_archive"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Settings
|
|
29
|
+
|
|
30
|
+
| Setting | CLI flag | Env var | Config key | Description |
|
|
31
|
+
|---|---|---|---|---|
|
|
32
|
+
| TMDb API key | `--api-key` | `TMDB_API_KEY` | `tmdb_api_key` | Required for all commands |
|
|
33
|
+
| Output root | `--output` | `PLEX_ROOT` | `output_root` | Root directory for organized output. Plex subfolders like `Movies/` and `TV Shows/` are created under this. |
|
|
34
|
+
| Rip output | `--output` | - | `rip_output` | Directory for MakeMKV rip output. Default: `{output_root}/Rips`. Used by `rip` and `orchestrate`. |
|
|
35
|
+
| Archive root | - | - | `archive_root` | Directory to move rip folders after successful organize. Optional; if not set, rip folders are left in place. |
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
## Requirements
|
|
4
|
+
|
|
5
|
+
- Python 3.11+
|
|
6
|
+
- A TMDb API key (free at <https://www.themoviedb.org/settings/api>)
|
|
7
|
+
- ffprobe (from ffmpeg, required for `organize` mode)
|
|
8
|
+
- mkvmerge (from MKVToolNix, required for chapter splitting in `organize` mode)
|
|
9
|
+
- mkvpropedit (from MKVToolNix, required for organized tagging in `organize` mode)
|
|
10
|
+
- [dvdcompare-scraper](https://github.com/OWNER/dvdcompare-scraper) (sibling project, required for `organize` and `lookup` modes)
|
|
11
|
+
|
|
12
|
+
## Install from source
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cd Projects/riplex
|
|
16
|
+
pip install -e ".[dev]"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
This installs the `riplex` CLI command and all dependencies including test tooling.
|
|
20
|
+
|
|
21
|
+
## Verify installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
riplex --help
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
You should see the four subcommands: `orchestrate`, `rip`, `organize`, and `lookup`.
|
|
28
|
+
|
|
29
|
+
## External tools
|
|
30
|
+
|
|
31
|
+
### ffprobe / ffmpeg
|
|
32
|
+
|
|
33
|
+
Download from <https://ffmpeg.org/download.html> and ensure `ffprobe` is on your PATH.
|
|
34
|
+
|
|
35
|
+
On Windows, you can verify with:
|
|
36
|
+
|
|
37
|
+
```powershell
|
|
38
|
+
ffprobe -version
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### MKVToolNix
|
|
42
|
+
|
|
43
|
+
Download from <https://mkvtoolnix.download/downloads.html>. The installer adds `mkvmerge` and `mkvpropedit` to your PATH automatically.
|
|
44
|
+
|
|
45
|
+
On Windows, the default install location is `C:\Program Files\MKVToolNix\`.
|