feat(preflight): chekc for makemkv libs
This commit is contained in:
@@ -5,9 +5,11 @@ starting a rip, with platform-specific install instructions.
|
||||
"""
|
||||
|
||||
import importlib
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _check_python_version() -> tuple[bool, str]:
|
||||
@@ -55,6 +57,86 @@ def _check_binary(name: str, version_flag: str = "--version") -> tuple[bool, str
|
||||
return True, f"{name} ({path})"
|
||||
|
||||
|
||||
def _check_library(name: str, search_paths: list[str | Path]) -> tuple[bool, str]:
|
||||
"""Check if a shared library exists in any of the given paths."""
|
||||
for search_dir in search_paths:
|
||||
p = Path(search_dir)
|
||||
if not p.is_dir():
|
||||
continue
|
||||
for f in p.iterdir():
|
||||
# Match libmmbd.so, libmmbd.so.0, libmmbd.dylib, mmbd.dll, etc.
|
||||
if name.lower() in f.name.lower() and f.is_file():
|
||||
return True, f"{name} ({f})"
|
||||
return False, f"{name} — not found"
|
||||
|
||||
|
||||
def _check_decryption_libs() -> list[tuple[str, bool, str, bool]]:
|
||||
"""Check for disc decryption libraries (libmmbd, libdvdcss, MakeMKV)."""
|
||||
results = []
|
||||
|
||||
# Platform-specific library search paths
|
||||
if sys.platform == "win32":
|
||||
lib_paths = [
|
||||
Path(os.environ.get("ProgramFiles", "C:/Program Files")) / "MakeMKV",
|
||||
Path(os.environ.get("ProgramFiles(x86)", "C:/Program Files (x86)")) / "MakeMKV",
|
||||
Path(os.environ.get("SYSTEMROOT", "C:/Windows")) / "System32",
|
||||
# HandBrakeCLI directory
|
||||
]
|
||||
hb_path = shutil.which("HandBrakeCLI")
|
||||
if hb_path:
|
||||
lib_paths.append(Path(hb_path).parent)
|
||||
css_name = "libdvdcss"
|
||||
mmbd_name = "libmmbd"
|
||||
elif sys.platform == "darwin":
|
||||
lib_paths = [
|
||||
Path("/usr/local/lib"),
|
||||
Path("/opt/homebrew/lib"),
|
||||
Path("/usr/lib"),
|
||||
Path.home() / "lib",
|
||||
Path("/Applications/MakeMKV.app/Contents/lib"),
|
||||
]
|
||||
css_name = "libdvdcss"
|
||||
mmbd_name = "libmmbd"
|
||||
else:
|
||||
lib_paths = [
|
||||
Path("/usr/lib"),
|
||||
Path("/usr/lib64"),
|
||||
Path("/usr/local/lib"),
|
||||
Path("/usr/lib/x86_64-linux-gnu"),
|
||||
Path("/usr/lib/aarch64-linux-gnu"),
|
||||
Path.home() / "lib",
|
||||
Path.home() / ".local" / "lib",
|
||||
]
|
||||
# Also check snap / flatpak MakeMKV paths
|
||||
snap_lib = Path("/snap/makemkv/current/usr/lib")
|
||||
if snap_lib.is_dir():
|
||||
lib_paths.append(snap_lib)
|
||||
css_name = "libdvdcss"
|
||||
mmbd_name = "libmmbd"
|
||||
|
||||
# Check MakeMKV binary
|
||||
ok, detail = _check_binary("makemkvcon", "--version")
|
||||
if not ok:
|
||||
# Also check common non-PATH locations
|
||||
for candidate in ["/usr/bin/makemkvcon", "/usr/local/bin/makemkvcon",
|
||||
"/snap/bin/makemkvcon"]:
|
||||
if Path(candidate).is_file():
|
||||
ok = True
|
||||
detail = f"makemkvcon ({candidate})"
|
||||
break
|
||||
results.append(("MakeMKV", ok, detail, False))
|
||||
|
||||
# Check libmmbd (Blu-ray decryption via MakeMKV)
|
||||
ok, detail = _check_library(mmbd_name, lib_paths)
|
||||
results.append(("libmmbd", ok, detail, False))
|
||||
|
||||
# Check libdvdcss (DVD decryption)
|
||||
ok, detail = _check_library(css_name, lib_paths)
|
||||
results.append(("libdvdcss", ok, detail, False))
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def _windows_install_hint(tool: str) -> str:
|
||||
"""Return a Windows-specific install hint."""
|
||||
hints = {
|
||||
@@ -68,6 +150,18 @@ def _windows_install_hint(tool: str) -> str:
|
||||
" pip install pymediainfo\n"
|
||||
" Also requires MediaInfo DLL: https://mediaarea.net/en/MediaInfo/Download/Windows"
|
||||
),
|
||||
"MakeMKV": (
|
||||
" Download from https://www.makemkv.com/download/\n"
|
||||
" Or: winget install MakeMKV.MakeMKV"
|
||||
),
|
||||
"libmmbd": (
|
||||
" Install MakeMKV, then copy libmmbd.dll next to HandBrakeCLI.exe\n"
|
||||
" Guide: https://www.makemkv.com/forum/viewtopic.php?t=224"
|
||||
),
|
||||
"libdvdcss": (
|
||||
" Download from https://www.videolan.org/developers/libdvdcss.html\n"
|
||||
" Or install VLC (bundles libdvdcss)"
|
||||
),
|
||||
}
|
||||
return hints.get(tool, f" pip install {tool}")
|
||||
|
||||
@@ -88,6 +182,21 @@ def _linux_install_hint(tool: str) -> str:
|
||||
" Also install: sudo apt install libmediainfo0v5 (or equivalent)"
|
||||
),
|
||||
"eject": " Usually pre-installed. Ubuntu/Debian: sudo apt install eject",
|
||||
"MakeMKV": (
|
||||
" Download from https://www.makemkv.com/download/\n"
|
||||
" Arch: yay -S makemkv\n"
|
||||
" Snap: sudo snap install makemkv"
|
||||
),
|
||||
"libmmbd": (
|
||||
" Install MakeMKV, then symlink:\n"
|
||||
" sudo ln -sf /usr/lib/libmmbd.so.0 /usr/lib/libdvdcss.so.2\n"
|
||||
" Guide: https://www.makemkv.com/forum/viewtopic.php?t=224"
|
||||
),
|
||||
"libdvdcss": (
|
||||
" Ubuntu/Debian: sudo apt install libdvdcss2\n"
|
||||
" Fedora: sudo dnf install libdvdcss\n"
|
||||
" Arch: sudo pacman -S libdvdcss"
|
||||
),
|
||||
}
|
||||
return hints.get(tool, f" pip install {tool}")
|
||||
|
||||
@@ -104,6 +213,19 @@ def _macos_install_hint(tool: str) -> str:
|
||||
" pip install pymediainfo\n"
|
||||
" Also install: brew install media-info"
|
||||
),
|
||||
"MakeMKV": (
|
||||
" Download from https://www.makemkv.com/download/\n"
|
||||
" Or: brew install --cask makemkv"
|
||||
),
|
||||
"libmmbd": (
|
||||
" Install MakeMKV, then symlink from the .app bundle:\n"
|
||||
" sudo ln -sf /Applications/MakeMKV.app/Contents/lib/libmmbd.dylib /usr/local/lib/\n"
|
||||
" Guide: https://www.makemkv.com/forum/viewtopic.php?t=224"
|
||||
),
|
||||
"libdvdcss": (
|
||||
" brew install libdvdcss\n"
|
||||
" Or: download from https://www.videolan.org/developers/libdvdcss.html"
|
||||
),
|
||||
}
|
||||
return hints.get(tool, f" pip install {tool}")
|
||||
|
||||
@@ -154,7 +276,6 @@ def check_all(verbose: bool = True) -> bool:
|
||||
|
||||
# Optional binaries (platform-specific)
|
||||
if sys.platform == "win32":
|
||||
# PowerShell is always available on Windows
|
||||
ok, detail = _check_binary("powershell", "-Command \"echo ok\"")
|
||||
checks.append(("PowerShell", ok, detail, False))
|
||||
elif sys.platform == "darwin":
|
||||
@@ -164,6 +285,9 @@ def check_all(verbose: bool = True) -> bool:
|
||||
ok, detail = _check_binary("eject", "--version")
|
||||
checks.append(("eject", ok, detail, False))
|
||||
|
||||
# Disc decryption libraries
|
||||
checks.extend(_check_decryption_libs())
|
||||
|
||||
# Print results
|
||||
all_required_ok = all(ok for _, ok, _, req in checks if req)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user