Files
ripper/ripper/config.py
2026-02-10 16:56:19 +01:00

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",
}