171 lines
5.3 KiB
Python
171 lines
5.3 KiB
Python
"""Shared configuration, constants, and rich Console.
|
|
|
|
Loads settings from a TOML config file:
|
|
Linux/macOS: $XDG_CONFIG_HOME/ripper/config.toml (default ~/.config/ripper/config.toml)
|
|
Windows: %APPDATA%\\ripper\\config.toml
|
|
|
|
Missing keys fall back to platform-aware defaults.
|
|
Environment variables override config values where noted.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import tomllib
|
|
from pathlib import Path
|
|
|
|
from rich.console import Console
|
|
|
|
console = Console(stderr=True)
|
|
|
|
|
|
# ── Config directory ─────────────────────────────────────────────────────────
|
|
|
|
def _config_dir() -> Path:
|
|
"""Return the platform-appropriate config directory for ripper."""
|
|
if sys.platform == "win32":
|
|
base = Path(os.environ.get("APPDATA", Path.home() / "AppData" / "Roaming"))
|
|
else:
|
|
base = Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config"))
|
|
return base / "ripper"
|
|
|
|
|
|
CONFIG_DIR = _config_dir()
|
|
CONFIG_FILE = CONFIG_DIR / "config.toml"
|
|
|
|
# Default TOML template (written when user runs --init-config)
|
|
DEFAULT_CONFIG = """\
|
|
# ripper configuration
|
|
# Generated automatically — edit as needed.
|
|
|
|
[paths]
|
|
# Default disc input path
|
|
# Linux: "/mnt/dvd" or "/dev/sr0"
|
|
# Windows: "D:\\\\" (your optical drive letter)
|
|
# input = "/mnt/dvd"
|
|
|
|
# Where ripped files are saved
|
|
# output_base = "/mnt/shared/ripped"
|
|
|
|
[encoder]
|
|
# Video codec: "hevc", "h264", or "av1"
|
|
# The best available encoder (HW-accelerated if possible) is auto-selected.
|
|
# codec = "hevc"
|
|
|
|
# Encoder preset: "speed", "balanced", or "quality"
|
|
# preset = "speed"
|
|
|
|
# Constant quality / rate factor (lower = better quality, bigger file)
|
|
# Typical ranges: HEVC 18-28, H.264 18-24, AV1 25-35
|
|
# quality = 22
|
|
|
|
# Seconds without progress before the disc is considered stuck (0 to disable)
|
|
# stall_timeout = 120
|
|
|
|
[api]
|
|
# TMDB API key for --imdb lookups
|
|
# Get a free key at https://www.themoviedb.org/settings/api
|
|
# Can also be set via TMDB_API_KEY environment variable
|
|
# tmdb_api_key = ""
|
|
"""
|
|
|
|
|
|
def _platform_defaults() -> dict:
|
|
"""Return sensible defaults for the current platform."""
|
|
if sys.platform == "win32":
|
|
input_path = "D:\\"
|
|
output_base = str(Path.home() / "Videos" / "Ripped")
|
|
elif sys.platform == "darwin":
|
|
input_path = "/dev/disk1"
|
|
output_base = str(Path.home() / "Movies" / "Ripped")
|
|
else:
|
|
input_path = "/mnt/dvd"
|
|
output_base = "/mnt/shared/ripped"
|
|
|
|
return {
|
|
"input_path": input_path,
|
|
"output_base": output_base,
|
|
"codec": "hevc",
|
|
"encoder_preset": "speed",
|
|
"quality": 22,
|
|
"stall_timeout": 120,
|
|
"tmdb_api_key": "",
|
|
}
|
|
|
|
|
|
def _load_config() -> dict:
|
|
"""Load config from TOML file, falling back to platform defaults."""
|
|
defaults = _platform_defaults()
|
|
|
|
if CONFIG_FILE.is_file():
|
|
with open(CONFIG_FILE, "rb") as f:
|
|
toml = tomllib.load(f)
|
|
paths = toml.get("paths", {})
|
|
encoder = toml.get("encoder", {})
|
|
api = toml.get("api", {})
|
|
|
|
defaults["input_path"] = paths.get("input", defaults["input_path"])
|
|
defaults["output_base"] = paths.get("output_base", defaults["output_base"])
|
|
defaults["codec"] = encoder.get("codec", defaults["codec"])
|
|
defaults["encoder_preset"] = encoder.get("preset", defaults["encoder_preset"])
|
|
defaults["quality"] = encoder.get("quality", defaults["quality"])
|
|
defaults["stall_timeout"] = encoder.get("stall_timeout", defaults["stall_timeout"])
|
|
defaults["tmdb_api_key"] = api.get("tmdb_api_key", defaults["tmdb_api_key"])
|
|
|
|
# Environment variables override config file
|
|
if env_key := os.environ.get("TMDB_API_KEY"):
|
|
defaults["tmdb_api_key"] = env_key
|
|
|
|
return defaults
|
|
|
|
|
|
def init_config() -> None:
|
|
"""Create a default config file if one doesn't exist."""
|
|
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
if CONFIG_FILE.exists():
|
|
console.print(f" [yellow]⚠[/] Config already exists: [dim]{CONFIG_FILE}[/]")
|
|
else:
|
|
CONFIG_FILE.write_text(DEFAULT_CONFIG, encoding="utf-8")
|
|
console.print(f" [green]✓[/] Created config: [bold]{CONFIG_FILE}[/]")
|
|
console.print(f" [dim]Edit this file to set your paths, encoder, and API key.[/]")
|
|
|
|
|
|
# ── Load config at import time ───────────────────────────────────────────────
|
|
|
|
_cfg = _load_config()
|
|
|
|
INPUT_PATH: str = _cfg["input_path"]
|
|
OUTPUT_BASE: str = _cfg["output_base"]
|
|
CODEC: str = _cfg["codec"]
|
|
ENCODER_PRESET: str = _cfg["encoder_preset"]
|
|
QUALITY: int = _cfg["quality"]
|
|
STALL_TIMEOUT: int = _cfg["stall_timeout"]
|
|
TMDB_API_KEY: str = _cfg["tmdb_api_key"]
|
|
|
|
|
|
# ── Scene-naming maps (not platform-specific) ───────────────────────────────
|
|
|
|
AUDIO_CODEC_SCENE = {
|
|
"truehd": "TrueHD",
|
|
"dtshd": "DTS-HD.MA",
|
|
"dts": "DTS",
|
|
"ac3": "DD",
|
|
"eac3": "DDP", # Dolby Digital Plus
|
|
"aac": "AAC",
|
|
"mp3": "MP3",
|
|
"flac": "FLAC",
|
|
"opus": "OPUS",
|
|
"pcm": "LPCM",
|
|
"lpcm": "LPCM",
|
|
"mp2": "MP2",
|
|
"vorbis": "Vorbis",
|
|
}
|
|
|
|
CHANNEL_SCENE = {
|
|
1: "1.0",
|
|
2: "2.0",
|
|
3: "2.1",
|
|
6: "5.1",
|
|
7: "6.1",
|
|
8: "7.1",
|
|
}
|