# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview MovieTagger is a PySide6/Qt desktop application for managing and tagging movie video files. It parses filenames, queries the TMDB API for metadata, and renames files to a standardized format. ## Commands ```bash # Install dependencies (including dev tools) pip install -e ".[dev]" # Run in development python -m movietagger # or python main.py # Build standalone executable (PyInstaller) pyinstaller MovieTagger.spec ``` **Required environment variables** (set in `~/.config/MovieTagger/config.ini` or shell): - `TMDB_KEY` — TMDB API key - `TMDB_LANGUAGE` — e.g. `en-US` - `TMDB_REGION` — e.g. `US` There are no tests or linting configurations. ## Architecture ### Layer Structure ``` core/ — Pure business logic (no Qt imports) services/ — External API clients qt/ — All UI and threading (Qt-dependent) qt/workers/ — Background QThread workers ``` ### Data Flow 1. **Load**: `LoadWorker` scans directories, calls `naming.parse_video_stem()` to extract `MovieRow` objects (title, year, tags, existing TMDB/IMDB IDs). 2. **Display**: `MovieTableModel` + `MovieProxyModel` hold and filter the `MovieRow` list in the main table view. 3. **Search**: `TmdbSearchWorker` (or `BatchScanWorker` for bulk) calls `TmdbService`, returns `MoviePick` objects. The user selects a pick via `MoviePickDialog`, which updates the row's IDs. 4. **Save**: `SaveWorker` calls `naming.build_video_stem()` on each row to construct the new filename, then renames files on disk. ### Key Design Patterns - **Threading**: Workers are `QObject` subclasses moved to `QThread`. Communication is strictly via Qt signals/slots. Cancellation uses `threading.Event`. - **Proxy model**: `MovieProxyModel` wraps `MovieTableModel` — handles both filtering (hide already-matched rows) and token-based title search without modifying the source model. - **Config**: `core/config.py` reads/writes `~/.config/MovieTagger/config.ini` via `platformdirs`. Settings schema is defined as a `SETTINGS` list of `SettingKind`-typed dicts in `config.py`. - **Rate limiting**: `RateLimiter` in `core/ratelimiter.py` throttles TMDB API calls across concurrent workers. ### Filename Format Parsed and generated by `core/naming.py`: ``` Title (YEAR) [tag1] [tag2] {edition-X} {tmdb-12345}.mkv ``` - Tags are freeform bracketed tokens (e.g. `[Directors Cut]`, `[2160p]`) - Edition is `{edition-...}` - Provider IDs are `{tmdb-...}` or `{imdb-...}` ### IMDB Service `services/imdb_service.py` and `qt/workers/imdb_search_worker.py` are stubs — they exist in the UI but return no results.