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 importlib
|
||||||
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
def _check_python_version() -> tuple[bool, str]:
|
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})"
|
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:
|
def _windows_install_hint(tool: str) -> str:
|
||||||
"""Return a Windows-specific install hint."""
|
"""Return a Windows-specific install hint."""
|
||||||
hints = {
|
hints = {
|
||||||
@@ -68,6 +150,18 @@ def _windows_install_hint(tool: str) -> str:
|
|||||||
" pip install pymediainfo\n"
|
" pip install pymediainfo\n"
|
||||||
" Also requires MediaInfo DLL: https://mediaarea.net/en/MediaInfo/Download/Windows"
|
" 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}")
|
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)"
|
" Also install: sudo apt install libmediainfo0v5 (or equivalent)"
|
||||||
),
|
),
|
||||||
"eject": " Usually pre-installed. Ubuntu/Debian: sudo apt install eject",
|
"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}")
|
return hints.get(tool, f" pip install {tool}")
|
||||||
|
|
||||||
@@ -104,6 +213,19 @@ def _macos_install_hint(tool: str) -> str:
|
|||||||
" pip install pymediainfo\n"
|
" pip install pymediainfo\n"
|
||||||
" Also install: brew install media-info"
|
" 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}")
|
return hints.get(tool, f" pip install {tool}")
|
||||||
|
|
||||||
@@ -154,7 +276,6 @@ def check_all(verbose: bool = True) -> bool:
|
|||||||
|
|
||||||
# Optional binaries (platform-specific)
|
# Optional binaries (platform-specific)
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
# PowerShell is always available on Windows
|
|
||||||
ok, detail = _check_binary("powershell", "-Command \"echo ok\"")
|
ok, detail = _check_binary("powershell", "-Command \"echo ok\"")
|
||||||
checks.append(("PowerShell", ok, detail, False))
|
checks.append(("PowerShell", ok, detail, False))
|
||||||
elif sys.platform == "darwin":
|
elif sys.platform == "darwin":
|
||||||
@@ -164,6 +285,9 @@ def check_all(verbose: bool = True) -> bool:
|
|||||||
ok, detail = _check_binary("eject", "--version")
|
ok, detail = _check_binary("eject", "--version")
|
||||||
checks.append(("eject", ok, detail, False))
|
checks.append(("eject", ok, detail, False))
|
||||||
|
|
||||||
|
# Disc decryption libraries
|
||||||
|
checks.extend(_check_decryption_libs())
|
||||||
|
|
||||||
# Print results
|
# Print results
|
||||||
all_required_ok = all(ok for _, ok, _, req in checks if req)
|
all_required_ok = all(ok for _, ok, _, req in checks if req)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user