# HomelabToolkit

A self-hosted control room for your media stack. HomelabToolkit pairs an Emby
artwork toolkit with a Navidrome music-library manager behind one beautiful React
UI, served by a FastAPI backend.

## Categories

### Emby
- **Thumbnail Generator** — composite landscape thumbnails from posters, logos and
  backdrops (subject-aware), then push them back to Emby as custom Thumb images.
- **Collection Art** — design Thumb/Primary cover artwork for your collections.
- **Airing & New Seasons** — track currently-airing series and stamp "New Season"
  artwork on eligible premieres.
- **Bulk Assign** — generate and apply thumbnails across the whole library, plus
  per-studio artwork resets.
- **User Favorites** — browse collections with per-user watched status, prune
  watched items, and top up with recommendations (dry-run by default).
- **Weekly Preroll Rotation** — schedule your Emby preroll folder to rotate once
  per week from the Settings page, with a manual "Run now" action for testing.

### Navidrome
- **Music Library** — browse artists and albums over the Subsonic API.
- **Cover Manager** — the former `music-covers.py` script, now a web tool: scan the
  library, normalize album folders, rename tracks, remove stray files, and fetch
  missing covers/lyrics. **Runs in dry-run mode by default** — nothing on disk
  changes until you explicitly switch to apply mode.

## Architecture

- **Backend:** Python, FastAPI, Pillow, rembg (U2-Net). API-only; serves the built
  SPA and owns every `/api/*` route.
- **Frontend:** React + TypeScript + Vite (`frontend/`), built to `frontend/dist`.
- **Music tooling:** mutagen + musicbrainzngs + Cover Art Archive + LRCLIB.

## Configuration (environment variables)

| Variable | Purpose |
| --- | --- |
| `EMBY_URL` | Emby server URL |
| `EMBY_API_KEY` | Emby API key |
| `NAVIDROME_URL` | Navidrome server URL (Subsonic API) |
| `NAVIDROME_USER` | Navidrome username |
| `NAVIDROME_PASSWORD` | Navidrome password |
| `MUSIC_ROOT` | Path to the music library for the Cover Manager |
| `PREROLL_ENABLED` | Enable the weekly preroll task by default |
| `PREROLL_ACTIVE_DIR` / `PREROLL_INACTIVE_DIR` | Mounted preroll folders to rotate between |
| `PREROLL_STATE_FILE` | Where weekly rotation state is stored |
| `PREROLL_WEEKDAY` / `PREROLL_TIME` | Default weekly schedule for the preroll task |
| `TMDB_BEARER_TOKEN` / `TMDB_API_KEY` | Optional artwork providers |
| `GOOGLE_CUSTOM_SEARCH_API_KEY` / `..._ENGINE_ID` | Optional artwork search |

## Run with Docker (recommended)

1. Edit `docker-compose.yml` with your Emby/Navidrome details and mount your music
   share to match `MUSIC_ROOT`. If you want weekly preroll rotation, also mount
   the active/inactive preroll folders and either set the `PREROLL_*` defaults
   there or configure the task in the app's Settings page.
2. Build and run:
   ```bash
   docker compose up -d --build
   ```
   The image builds the React SPA in a Node stage, then serves it from FastAPI.
3. Open `http://localhost:8500`.

## Local development

Backend:
```bash
pip install -r requirements.txt
python app.py            # http://localhost:8500
```

Frontend (hot reload, proxies /api to :8500):
```bash
cd frontend
npm install
npm run dev              # http://localhost:5173
```

Production build of the SPA (served by FastAPI):
```bash
cd frontend && npm run build
```

## Deploy to a NAS

`deploy.ps1` syncs the project (including the `frontend/` source) over SSH and runs
`docker compose build && up -d` remotely. The frontend is built inside the image:
```powershell
.\deploy.ps1 -NasHost MATT-NAS -NasUser ssh
```
