riplex 0.3.2__tar.gz → 0.3.3__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.
Files changed (113) hide show
  1. {riplex-0.3.2/src/riplex.egg-info → riplex-0.3.3}/PKG-INFO +1 -1
  2. {riplex-0.3.2 → riplex-0.3.3}/docs/getting-started/installation.md +1 -1
  3. {riplex-0.3.2 → riplex-0.3.3/src/riplex.egg-info}/PKG-INFO +1 -1
  4. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/welcome.py +24 -27
  5. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_cli/commands/setup.py +1 -1
  6. {riplex-0.3.2 → riplex-0.3.3}/tests/test_updater.py +6 -6
  7. {riplex-0.3.2 → riplex-0.3.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  8. {riplex-0.3.2 → riplex-0.3.3}/.github/agents/riplex.agent.md +0 -0
  9. {riplex-0.3.2 → riplex-0.3.3}/.github/copilot-instructions.md +0 -0
  10. {riplex-0.3.2 → riplex-0.3.3}/.github/workflows/publish.yml +0 -0
  11. {riplex-0.3.2 → riplex-0.3.3}/.github/workflows/release.yml +0 -0
  12. {riplex-0.3.2 → riplex-0.3.3}/.gitignore +0 -0
  13. {riplex-0.3.2 → riplex-0.3.3}/MONOREPO_PLAN.md +0 -0
  14. {riplex-0.3.2 → riplex-0.3.3}/PLANNED_FEATURES.md +0 -0
  15. {riplex-0.3.2 → riplex-0.3.3}/README.md +0 -0
  16. {riplex-0.3.2 → riplex-0.3.3}/REFACTOR_PLAN.md +0 -0
  17. {riplex-0.3.2 → riplex-0.3.3}/docs/architecture.md +0 -0
  18. {riplex-0.3.2 → riplex-0.3.3}/docs/changelog.md +0 -0
  19. {riplex-0.3.2 → riplex-0.3.3}/docs/getting-started/configuration.md +0 -0
  20. {riplex-0.3.2 → riplex-0.3.3}/docs/guide/lookup.md +0 -0
  21. {riplex-0.3.2 → riplex-0.3.3}/docs/guide/orchestrate.md +0 -0
  22. {riplex-0.3.2 → riplex-0.3.3}/docs/guide/organize.md +0 -0
  23. {riplex-0.3.2 → riplex-0.3.3}/docs/guide/workflow.md +0 -0
  24. {riplex-0.3.2 → riplex-0.3.3}/docs/index.md +0 -0
  25. {riplex-0.3.2 → riplex-0.3.3}/docs/naming-rules.md +0 -0
  26. {riplex-0.3.2 → riplex-0.3.3}/docs/reference/cli.md +0 -0
  27. {riplex-0.3.2 → riplex-0.3.3}/issues/cross-disc-dvdcompare-matching.md +0 -0
  28. {riplex-0.3.2 → riplex-0.3.3}/mkdocs.yml +0 -0
  29. {riplex-0.3.2 → riplex-0.3.3}/plex_naming_rules.md +0 -0
  30. {riplex-0.3.2 → riplex-0.3.3}/pyproject.toml +0 -0
  31. {riplex-0.3.2 → riplex-0.3.3}/setup.cfg +0 -0
  32. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/__init__.py +0 -0
  33. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/cache.py +0 -0
  34. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/config.py +0 -0
  35. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/dedup.py +0 -0
  36. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/detect.py +0 -0
  37. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/disc/__init__.py +0 -0
  38. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/disc/analysis.py +0 -0
  39. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/disc/makemkv.py +0 -0
  40. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/disc/provider.py +0 -0
  41. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/formatter.py +0 -0
  42. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/lookup.py +0 -0
  43. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/manifest.py +0 -0
  44. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/matcher.py +0 -0
  45. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/metadata/__init__.py +0 -0
  46. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/metadata/planner.py +0 -0
  47. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/metadata/provider.py +0 -0
  48. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/metadata/sources/__init__.py +0 -0
  49. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/metadata/sources/tmdb.py +0 -0
  50. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/models.py +0 -0
  51. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/normalize.py +0 -0
  52. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/organizer.py +0 -0
  53. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/scanner.py +0 -0
  54. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/snapshot.py +0 -0
  55. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/splitter.py +0 -0
  56. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/tagger.py +0 -0
  57. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/title.py +0 -0
  58. {riplex-0.3.2 → riplex-0.3.3}/src/riplex/ui.py +0 -0
  59. {riplex-0.3.2 → riplex-0.3.3}/src/riplex.egg-info/SOURCES.txt +0 -0
  60. {riplex-0.3.2 → riplex-0.3.3}/src/riplex.egg-info/dependency_links.txt +0 -0
  61. {riplex-0.3.2 → riplex-0.3.3}/src/riplex.egg-info/entry_points.txt +0 -0
  62. {riplex-0.3.2 → riplex-0.3.3}/src/riplex.egg-info/requires.txt +0 -0
  63. {riplex-0.3.2 → riplex-0.3.3}/src/riplex.egg-info/top_level.txt +0 -0
  64. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/__init__.py +0 -0
  65. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/main.py +0 -0
  66. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/__init__.py +0 -0
  67. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/disc_detection.py +0 -0
  68. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/done.py +0 -0
  69. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/folder_picker.py +0 -0
  70. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/metadata.py +0 -0
  71. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/organize_done.py +0 -0
  72. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/organize_preview.py +0 -0
  73. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/progress.py +0 -0
  74. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/release.py +0 -0
  75. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/screens/selection.py +0 -0
  76. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_app/updater.py +0 -0
  77. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_cli/__init__.py +0 -0
  78. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_cli/commands/__init__.py +0 -0
  79. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_cli/commands/lookup.py +0 -0
  80. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_cli/commands/orchestrate.py +0 -0
  81. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_cli/commands/organize.py +0 -0
  82. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_cli/commands/rip.py +0 -0
  83. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_cli/formatting.py +0 -0
  84. {riplex-0.3.2 → riplex-0.3.3}/src/riplex_cli/main.py +0 -0
  85. {riplex-0.3.2 → riplex-0.3.3}/tests/__init__.py +0 -0
  86. {riplex-0.3.2 → riplex-0.3.3}/tests/fixtures/makemkvcon_frozen_planet_ii_d2.txt +0 -0
  87. {riplex-0.3.2 → riplex-0.3.3}/tests/fixtures/makemkvcon_list.txt +0 -0
  88. {riplex-0.3.2 → riplex-0.3.3}/tests/snapshots/Batman Begins.snapshot.json +0 -0
  89. {riplex-0.3.2 → riplex-0.3.3}/tests/snapshots/Blade Runner (Blu-ray 4k).snapshot.json +0 -0
  90. {riplex-0.3.2 → riplex-0.3.3}/tests/snapshots/Blade Runner The Final Cut.snapshot.json +0 -0
  91. {riplex-0.3.2 → riplex-0.3.3}/tests/snapshots/Seven Worlds One Planet.snapshot.json +0 -0
  92. {riplex-0.3.2 → riplex-0.3.3}/tests/snapshots/The Dark Knight Rises.snapshot.json +0 -0
  93. {riplex-0.3.2 → riplex-0.3.3}/tests/snapshots/The Dark Knight.snapshot.json +0 -0
  94. {riplex-0.3.2 → riplex-0.3.3}/tests/snapshots/Waterworld.snapshot.json +0 -0
  95. {riplex-0.3.2 → riplex-0.3.3}/tests/test_cache.py +0 -0
  96. {riplex-0.3.2 → riplex-0.3.3}/tests/test_cli_utils.py +0 -0
  97. {riplex-0.3.2 → riplex-0.3.3}/tests/test_config.py +0 -0
  98. {riplex-0.3.2 → riplex-0.3.3}/tests/test_dedup.py +0 -0
  99. {riplex-0.3.2 → riplex-0.3.3}/tests/test_detect.py +0 -0
  100. {riplex-0.3.2 → riplex-0.3.3}/tests/test_disc_analysis.py +0 -0
  101. {riplex-0.3.2 → riplex-0.3.3}/tests/test_disc_provider.py +0 -0
  102. {riplex-0.3.2 → riplex-0.3.3}/tests/test_formatter.py +0 -0
  103. {riplex-0.3.2 → riplex-0.3.3}/tests/test_makemkv.py +0 -0
  104. {riplex-0.3.2 → riplex-0.3.3}/tests/test_matcher.py +0 -0
  105. {riplex-0.3.2 → riplex-0.3.3}/tests/test_normalize.py +0 -0
  106. {riplex-0.3.2 → riplex-0.3.3}/tests/test_organizer.py +0 -0
  107. {riplex-0.3.2 → riplex-0.3.3}/tests/test_planner.py +0 -0
  108. {riplex-0.3.2 → riplex-0.3.3}/tests/test_rip_guide.py +0 -0
  109. {riplex-0.3.2 → riplex-0.3.3}/tests/test_scanner.py +0 -0
  110. {riplex-0.3.2 → riplex-0.3.3}/tests/test_snapshot.py +0 -0
  111. {riplex-0.3.2 → riplex-0.3.3}/tests/test_splitter.py +0 -0
  112. {riplex-0.3.2 → riplex-0.3.3}/tests/test_tagger.py +0 -0
  113. {riplex-0.3.2 → riplex-0.3.3}/tests/test_ui.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: riplex
3
- Version: 0.3.2
3
+ Version: 0.3.3
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
@@ -132,6 +132,6 @@ MakeMKV requires a registration key. A free beta key is available at https://for
132
132
 
133
133
  ### MKVToolNix (mkvmerge, mkvpropedit)
134
134
 
135
- - **Windows**: `winget install MKVToolNix.MKVToolNix` (or download from https://mkvtoolnix.download/)
135
+ - **Windows**: `winget install MoritzBunkus.MKVToolNix` (or download from https://mkvtoolnix.download/)
136
136
  - **macOS**: `brew install mkvtoolnix`
137
137
  - **Linux**: `sudo apt install mkvtoolnix`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: riplex
3
- Version: 0.3.2
3
+ Version: 0.3.3
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
@@ -38,6 +38,7 @@ class WelcomeScreen:
38
38
  missing_tools.append("ffprobe")
39
39
  if not has_mkvmerge:
40
40
  missing_tools.append("mkvmerge")
41
+ self._missing_tools = missing_tools
41
42
 
42
43
  status_rows = []
43
44
  for label, ok in checks:
@@ -61,7 +62,7 @@ class WelcomeScreen:
61
62
  ft.ElevatedButton(
62
63
  "Install Missing Tools",
63
64
  icon=ft.Icons.DOWNLOAD,
64
- on_click=lambda _: self._install_tools(missing_tools),
65
+ on_click=self._on_install_click,
65
66
  ),
66
67
  ft.TextButton(
67
68
  "MakeMKV ↗",
@@ -286,15 +287,20 @@ class WelcomeScreen:
286
287
  url = get_download_url(self._update_info)
287
288
  webbrowser.open(url)
288
289
 
290
+ def _on_install_click(self, e):
291
+ """Handle Install Missing Tools button click."""
292
+ self._install_status.value = "Starting installation..."
293
+ self.app.page.update()
294
+ self._install_tools(self._missing_tools)
295
+
289
296
  def _install_tools(self, missing: list[str]):
290
297
  """Install missing tools via system package manager in background."""
291
298
  import platform
292
299
  import subprocess
293
- import sys
294
300
 
295
301
  system = platform.system()
296
302
  packages = {
297
- "Windows": {"makemkvcon": "MakeMKV.MakeMKV", "ffprobe": "Gyan.FFmpeg", "mkvmerge": "MKVToolNix.MKVToolNix"},
303
+ "Windows": {"makemkvcon": "GuinpinSoft.MakeMKV", "ffprobe": "Gyan.FFmpeg", "mkvmerge": "MoritzBunkus.MKVToolNix"},
298
304
  "Darwin": {"makemkvcon": "makemkv", "ffprobe": "ffmpeg", "mkvmerge": "mkvtoolnix"},
299
305
  }
300
306
 
@@ -306,34 +312,28 @@ class WelcomeScreen:
306
312
  return
307
313
 
308
314
  def _do_install():
309
- async def _update_status(msg):
310
- self._install_status.value = msg
311
- self.app.page.update()
312
-
313
315
  try:
314
316
  if system == "Windows":
315
- # Build a single winget command string to run elevated
316
317
  cmds = " && ".join(
317
318
  f'winget install --accept-source-agreements --accept-package-agreements {pkg}'
318
319
  for pkg in to_install
319
320
  )
320
- self.app.page.run_task(
321
- lambda: _update_status(f"Installing {', '.join(to_install)}... (accept the admin prompt)")
322
- )
323
- # Run elevated via powershell Start-Process
321
+ self._install_status.value = f"Installing {', '.join(to_install)}... (accept the admin prompt)"
322
+ self.app.page.update()
324
323
  result = subprocess.run(
325
324
  ["powershell", "-Command",
326
- f'Start-Process cmd -ArgumentList \'/c {cmds} & pause\' -Verb RunAs -Wait'],
327
- creationflags=subprocess.CREATE_NO_WINDOW,
325
+ f"Start-Process cmd -ArgumentList '/c {cmds} & pause' -Verb RunAs -Wait"],
326
+ capture_output=True,
327
+ text=True,
328
328
  )
329
329
  if result.returncode != 0:
330
- raise subprocess.CalledProcessError(result.returncode, "winget")
330
+ raise subprocess.CalledProcessError(result.returncode, "winget", output=result.stdout, stderr=result.stderr)
331
331
  elif system == "Darwin":
332
332
  if shutil.which("brew"):
333
- self.app.page.run_task(lambda: _update_status("Installing via brew..."))
333
+ self._install_status.value = "Installing via brew..."
334
+ self.app.page.update()
334
335
  subprocess.run(["brew", "install"] + to_install, check=True)
335
336
  else:
336
- # No Homebrew — open download pages in browser
337
337
  download_urls = {
338
338
  "makemkv": "https://www.makemkv.com/download/",
339
339
  "ffmpeg": "https://ffmpeg.org/download.html",
@@ -342,18 +342,15 @@ class WelcomeScreen:
342
342
  for pkg in to_install:
343
343
  if pkg in download_urls:
344
344
  webbrowser.open(download_urls[pkg])
345
- self.app.page.run_task(
346
- lambda: _update_status("Opened download pages in your browser. Install the tools, then restart the app.")
347
- )
345
+ self._install_status.value = "Opened download pages in your browser. Install the tools, then restart the app."
346
+ self.app.page.update()
348
347
  return
349
348
 
350
- self.app.page.run_task(
351
- lambda: _update_status("Done! Restart the app for changes to take effect.")
352
- )
353
- except (subprocess.CalledProcessError, FileNotFoundError, OSError) as exc:
354
- self.app.page.run_task(
355
- lambda: _update_status(f"Install failed: {exc}. Try the manual links above.")
356
- )
349
+ self._install_status.value = "Done! Restart the app for changes to take effect."
350
+ self.app.page.update()
351
+ except Exception as exc:
352
+ self._install_status.value = f"Install failed: {exc}. Try the manual links above."
353
+ self.app.page.update()
357
354
 
358
355
  threading.Thread(target=_do_install, daemon=True).start()
359
356
 
@@ -12,7 +12,7 @@ def _offer_install(missing: list[str]) -> None:
12
12
 
13
13
  system = platform.system()
14
14
  packages: dict[str, dict[str, str]] = {
15
- "Windows": {"makemkvcon": "MakeMKV.MakeMKV", "ffprobe": "Gyan.FFmpeg", "mkvmerge": "MKVToolNix.MKVToolNix", "mkvpropedit": "MKVToolNix.MKVToolNix"},
15
+ "Windows": {"makemkvcon": "GuinpinSoft.MakeMKV", "ffprobe": "Gyan.FFmpeg", "mkvmerge": "MoritzBunkus.MKVToolNix", "mkvpropedit": "MoritzBunkus.MKVToolNix"},
16
16
  "Darwin": {"makemkvcon": "makemkv", "ffprobe": "ffmpeg", "mkvmerge": "mkvtoolnix", "mkvpropedit": "mkvtoolnix"},
17
17
  "Linux": {"makemkvcon": "", "ffprobe": "ffmpeg", "mkvmerge": "mkvtoolnix", "mkvpropedit": "mkvtoolnix"},
18
18
  }
@@ -142,13 +142,13 @@ class TestInstallToolsLogic:
142
142
  def test_windows_package_mapping(self):
143
143
  """Verify correct winget package IDs for missing tools."""
144
144
  packages = {
145
- "makemkvcon": "MakeMKV.MakeMKV",
145
+ "makemkvcon": "GuinpinSoft.MakeMKV",
146
146
  "ffprobe": "Gyan.FFmpeg",
147
- "mkvmerge": "MKVToolNix.MKVToolNix",
147
+ "mkvmerge": "MoritzBunkus.MKVToolNix",
148
148
  }
149
149
  missing = ["ffprobe", "mkvmerge"]
150
150
  to_install = sorted(set(packages[t] for t in missing if packages.get(t)))
151
- assert to_install == ["Gyan.FFmpeg", "MKVToolNix.MKVToolNix"]
151
+ assert to_install == ["Gyan.FFmpeg", "MoritzBunkus.MKVToolNix"]
152
152
 
153
153
  def test_macos_package_mapping(self):
154
154
  """Verify correct brew package names for missing tools."""
@@ -164,9 +164,9 @@ class TestInstallToolsLogic:
164
164
  def test_deduplicates_packages(self):
165
165
  """mkvmerge and mkvpropedit map to same package."""
166
166
  packages = {
167
- "mkvmerge": "MKVToolNix.MKVToolNix",
168
- "mkvpropedit": "MKVToolNix.MKVToolNix",
167
+ "mkvmerge": "MoritzBunkus.MKVToolNix",
168
+ "mkvpropedit": "MoritzBunkus.MKVToolNix",
169
169
  }
170
170
  missing = ["mkvmerge", "mkvpropedit"]
171
171
  to_install = sorted(set(packages[t] for t in missing if packages.get(t)))
172
- assert to_install == ["MKVToolNix.MKVToolNix"]
172
+ assert to_install == ["MoritzBunkus.MKVToolNix"]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes