updated README
This commit is contained in:
		
							
								
								
									
										374
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										374
									
								
								README.md
									
									
									
									
									
								
							| @@ -17,346 +17,110 @@ | |||||||
| </p> | </p> | ||||||
| --> | --> | ||||||
|  |  | ||||||
| Ein leichtgewichtiges Web‑Frontend für Benachrichtigungen und Abos rund um Sonarr/Radarr – mit Jellyfin‑Login, Kalender, Abo‑Verwaltung und flexiblen Notifications per E‑Mail, ntfy und Apprise. | Lightweight web UI for Sonarr/Radarr subscriptions with Jellyfin login, calendar, and flexible notifications via Email, ntfy, and Apprise. | ||||||
|  |  | ||||||
| ## Features | ## Features | ||||||
| - Jellyfin‑Login (kein eigener Userstore nötig) | - Sign in with Jellyfin (no separate user store) | ||||||
| - Kalender im Sonarr/Radarr‑Stil (kommende Episoden/Filme) | - Sonarr/Radarr‑style calendar (upcoming episodes/movies) | ||||||
| - Abonnieren/Abbestellen direkt aus dem UI (Serien & Filme) | - Subscribe/unsubscribe from the UI (series & movies) | ||||||
| - Admin‑Übersicht aller Abos je Nutzer inkl. Poster | - Admin overview of all users’ subscriptions with posters | ||||||
| - Benachrichtigungen pro Nutzer wählbar: | - Per‑user notification channels: | ||||||
|   - E‑Mail (SMTP) |   - Email (SMTP) | ||||||
|   - ntfy (Token oder Basic Auth) |   - ntfy (Bearer token or Basic Auth) | ||||||
|   - Apprise (zahlreiche Ziele wie Discord, Gotify, Pushover, Webhooks u. v. m.) |   - Apprise (Discord, Gotify, Pushover, Webhooks, and many more) | ||||||
| - Docker‑fertig, env‑gesteuerte Security‑Settings (ALLOWED_HOSTS, CSRF, Proxy) | - Docker‑ready; environment‑driven security (ALLOWED_HOSTS, CSRF, proxy) | ||||||
|  |  | ||||||
| ## Schnellstart |  | ||||||
|  |  | ||||||
| ## Screenshots | ## Screenshots | ||||||
| <p align="center"> | <p align="center"> | ||||||
|   <img src="./screenshots/SCR-20250811-lfrm.png" alt="Screenshot 1" width="800"><br/> |   <img src="./screenshots/SCR-20250811-lfrm.png" alt="Settings" width="800"><br/> | ||||||
|   <img src="./screenshots/SCR-20250811-lfvc.png" alt="Screenshot 2" width="800"><br/> |   <img src="./screenshots/SCR-20250811-lfvc.png" alt="Subscriptions" width="800"><br/> | ||||||
|   <img src="./screenshots/SCR-20250811-lfod.png" alt="Screenshot 3" width="800"><br/> |   <img src="./screenshots/SCR-20250811-lfod.png" alt="Overview" width="800"><br/> | ||||||
|   <img src="./screenshots/SCR-20250811-lfyq.png" alt="Screenshot 4" width="800"><br/> |   <img src="./screenshots/SCR-20250811-lfyq.png" alt="Search" width="800"><br/> | ||||||
|   <img src="./screenshots/SCR-20250811-lgau.png" alt="Screenshot 5" width="800"><br/> |   <img src="./screenshots/SCR-20250811-lgau.png" alt="Details" width="800"><br/> | ||||||
|   <img src="./screenshots/SCR-20250811-lgcz.png" alt="Screenshot 6" width="800"> |   <img src="./screenshots/SCR-20250811-lgcz.png" alt="Notifications" width="800"> | ||||||
| </p> | </p> | ||||||
|  |  | ||||||
| ### Mit Docker Compose | ## Quickstart (Docker Compose) | ||||||
| 1) Lockfile aktuell halten (wenn `Pipfile` geändert wurde): | 1) Ensure the lockfile matches your Pipfile (e.g., after adding packages): | ||||||
| ```bash | ```bash | ||||||
| pipenv lock | git clone https://github.com/jschaufuss/subscribarr.git | ||||||
|  | cd subscribarr | ||||||
| ``` | ``` | ||||||
| 2) Image bauen/Starten: | 2) run the container: | ||||||
| ```bash | ```bash | ||||||
| docker compose build |  | ||||||
| docker compose up -d | docker compose up -d | ||||||
| ``` | ``` | ||||||
| 3) Öffne die App und führe das First‑Run‑Setup (Jellyfin + Arr‑URLs/Keys) durch. | 3) Open the app and complete the first‑run setup (Jellyfin + Arr URLs/keys). | ||||||
|  | ``` | ||||||
|  | http://127.0.0.1:8081 | ||||||
|  | ``` | ||||||
|  |  | ||||||
| Wichtige Umgebungsvariablen (Beispiele): | Important environment variables (examples): | ||||||
| - `DJANGO_ALLOWED_HOSTS=subscribarr.example.com,localhost,127.0.0.1` | - `DJANGO_ALLOWED_HOSTS=subscribarr.example.com,localhost,127.0.0.1` | ||||||
| - `DJANGO_CSRF_TRUSTED_ORIGINS=https://subscribarr.example.com,http://subscribarr.example.com` | - `DJANGO_CSRF_TRUSTED_ORIGINS=https://subscribarr.example.com,http://subscribarr.example.com` | ||||||
| - Reverse‑Proxy/TLS: | - Reverse proxy/TLS: | ||||||
|   - `USE_X_FORWARDED_HOST=true` |   - `USE_X_FORWARDED_HOST=true` | ||||||
|   - `DJANGO_SECURE_PROXY_SSL_HEADER=true` |   - `DJANGO_SECURE_PROXY_SSL_HEADER=true` | ||||||
|   - `DJANGO_CSRF_COOKIE_SECURE=true` |   - `DJANGO_CSRF_COOKIE_SECURE=true` | ||||||
|   - `DJANGO_SESSION_COOKIE_SECURE=true` |   - `DJANGO_SESSION_COOKIE_SECURE=true` | ||||||
|  |  | ||||||
| > Hinweis: In `DJANGO_CSRF_TRUSTED_ORIGINS` muss Schema+Host (und ggf. Port) exakt stimmen. | > Note: `DJANGO_CSRF_TRUSTED_ORIGINS` must include the exact scheme+host (+port if used). | ||||||
|  |  | ||||||
| ### Lokal (Pipenv) | ## In‑App Configuration | ||||||
| ```bash | - Settings → Jellyfin: server URL + API key | ||||||
| pipenv sync | - Settings →Sonarr/Radarr: base URLs + API keys (with “Test” button) | ||||||
| pipenv run python manage.py migrate | - Settings →Mail server: SMTP (host/port/TLS/SSL/user/password/from) | ||||||
| pipenv run python manage.py runserver | - Settings →Notifications: | ||||||
| ``` |   - ntfy: server URL, default topic, Basic Auth or Bearer token | ||||||
|  |   - Apprise: default URL(s) (one per line) | ||||||
|  | - Profile (per user): | ||||||
|  |   - Choose channel: Email, ntfy, or Apprise | ||||||
|  |   - ntfy topic (optional, overrides default) | ||||||
|  |   - Apprise URL(s) (optional, appended to defaults) | ||||||
|  |  | ||||||
| ## Konfiguration im UI | ## ntfy Notes | ||||||
| - Einstellungen → Jellyfin: Server‑URL + API‑Key | - Server URL: e.g., `https://ntfy.sh` or your own server | ||||||
| - Einstellungen → Sonarr/Radarr: Base‑URLs + API‑Keys (inkl. „Test“-Knopf) |  | ||||||
| - Einstellungen → Mailserver: SMTP (Host/Port/TLS/SSL/Benutzer/Passwort/From) |  | ||||||
| - Einstellungen → Notifications: |  | ||||||
|   - ntfy: Server‑URL, Default‑Topic, Basic‑Auth oder Bearer‑Token |  | ||||||
|   - Apprise: Default‑URL(s) (eine pro Zeile) |  | ||||||
| - Profil (pro Nutzer): |  | ||||||
|   - Kanal wählen: E‑Mail, ntfy oder Apprise |  | ||||||
|   - ntfy Topic (optional, überschreibt Default) |  | ||||||
|   - Apprise URL(s) (optional, ergänzen die Defaults) |  | ||||||
|  |  | ||||||
| ## ntfy – Hinweise |  | ||||||
| - Server‑URL: z. B. `https://ntfy.sh` oder eigener Server |  | ||||||
| - Auth: | - Auth: | ||||||
|   - Bearer‑Token (Header) |   - Bearer token (Authorization header) | ||||||
|   - Basic‑Auth (Benutzer/Passwort) |   - Basic Auth (username/password) | ||||||
| - Topic: | - Topic selection: | ||||||
|   - pro Nutzer frei wählbar (Profil) oder globales Default‑Topic (Einstellungen) |   - Per user in the profile, or a global default topic in Settings | ||||||
|  |  | ||||||
| ## Apprise – Hinweise | ## Apprise Notes | ||||||
| - Trag eine oder mehrere Ziel‑URLs ein (pro Zeile), z. B.: | Provide one or more destination URLs (one per line), e.g.: | ||||||
|   - `gotify://TOKEN@gotify.example.com/`   | - `gotify://TOKEN@gotify.example.com/` | ||||||
|   - `discord://webhook_id/webhook_token`   | - `discord://webhook_id/webhook_token` | ||||||
|   - `mailto://user:pass@smtp.example.com`   | - `mailto://user:pass@smtp.example.com` | ||||||
|   - `pover://user@token`   | - `pover://user@token` | ||||||
|   - `json://webhook.example.com/path` | - `json://webhook.example.com/path` | ||||||
| - Nutzer können eigene URLs ergänzen; die globalen Defaults bleiben zusätzlich aktiv. |  | ||||||
|  |  | ||||||
| ## Benachrichtigungslogik | User URLs are added in addition to global defaults. | ||||||
| - Serien: Es wird pro Abo am Release‑Tag geprüft, ob die Episode bereits als Datei vorhanden ist (Sonarr `hasFile`). |  | ||||||
| - Filme: Analog über Radarr `hasFile` und Release‑Datum (Digital/Disc/Kino‐Tag). |  | ||||||
| - Doppelversand wird per `SentNotification` unterdrückt (täglich pro Item/Nutzer). |  | ||||||
| - Fallback: Wenn ntfy/Apprise scheitern, wird E‑Mail versendet (falls konfiguriert). |  | ||||||
|  |  | ||||||
| ## Jobs / Manuell anstoßen | ## Notification Logic | ||||||
| - Regelmäßiger Check per Management Command (z. B. via Cron): | - Series: on the air date, Subscribarr checks Sonarr for the episode and only notifies when episode is downloaded and present. | ||||||
|  | - Movies: similar via Radarr when movie is downloaded and present. | ||||||
|  | - Duplicate suppression: entries are recorded in `SentNotification` per user/title/day; if sending fails, no record is stored. | ||||||
|  | - Fallback: if ntfy/Apprise fail, Subscribarr falls back to Email (when configured). | ||||||
|  |  | ||||||
|  | ## Jobs / Manual Trigger | ||||||
|  | - Periodic check via management command (e.g., cron): | ||||||
| ```bash | ```bash | ||||||
| pipenv run python manage.py check_new_media | docker exec -it subscribarr python manage.py check_new_media | ||||||
| ``` |  | ||||||
| - In Docker: |  | ||||||
| ```bash |  | ||||||
| docker compose exec web python manage.py check_new_media |  | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## Sicherheit & Proxy | ## Security & Proxy | ||||||
| - Setze `DJANGO_ALLOWED_HOSTS` auf deine(n) Hostnamen. | - Set `DJANGO_ALLOWED_HOSTS` to your hostnames. | ||||||
| - Füge alle genutzten Ursprünge in `DJANGO_CSRF_TRUSTED_ORIGINS` hinzu (http/https und Port beachten). | - Include all used origins in `DJANGO_CSRF_TRUSTED_ORIGINS` (http/https and port where applicable). | ||||||
| - Hinter Reverse‑Proxy TLS aktivieren: `USE_X_FORWARDED_HOST`, `DJANGO_SECURE_PROXY_SSL_HEADER`, Cookie‑Flags. | - Behind a reverse proxy with TLS: enable `USE_X_FORWARDED_HOST`, `DJANGO_SECURE_PROXY_SSL_HEADER`, and secure cookie flags. | ||||||
|  |  | ||||||
| ## Tech‑Stack | ## Tech Stack | ||||||
| - Backend: Django 5 + DRF | - Backend: Django 5 + DRF | ||||||
| - Integrationen: Sonarr/Radarr (API v3) | - Integrations: Sonarr/Radarr (API v3) | ||||||
| - Auth: Jellyfin | - Auth: Jellyfin | ||||||
| - Notifications: SMTP, ntfy (HTTP), Apprise | - Notifications: SMTP, ntfy (HTTP), Apprise | ||||||
| - Frontend: Templates + FullCalendar | - Frontend: Templates + FullCalendar | ||||||
| - DB: SQLite (default) | - DB: SQLite (default) | ||||||
|  |  | ||||||
| ## Lizenz |  | ||||||
| MIT |  | ||||||
| # Subscribarr |  | ||||||
|  |  | ||||||
| # Subscribarr |  | ||||||
|  |  | ||||||
| Subscribarr is a notification tool for the *Arr ecosystem (Sonarr, Radarr) and Jellyfin. Users can subscribe to shows/movies; when new episodes/releases are available (and actually present), Subscribarr sends email notifications. |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## Screenshots |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## Features |  | ||||||
|  |  | ||||||
| - **Login via Jellyfin** (use your Jellyfin account; admin status respected) |  | ||||||
| - **Subscriptions** for series and movies; duplicate-send protection per user/day |  | ||||||
| - **Email notifications** (SMTP configurable) |  | ||||||
| - **Sonarr/Radarr integration** (calendar/status; optional file-presence check) |  | ||||||
| - **Settings UI** for Jellyfin/Arr/Mail/Account |  | ||||||
| - **Periodic check via cron** calling `manage.py check_new_media` |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## Architecture / Tech Stack |  | ||||||
|  |  | ||||||
| - **Backend:** Django + Django REST Framework   |  | ||||||
| - **Apps (examples):** `arr_api`, `accounts`, `settingspanel`   |  | ||||||
| - **Database:** SQLite by default (path configurable via env)   |  | ||||||
| - **Auth:** Jellyfin API (admin mirrored from Jellyfin policy) |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## Quickstart (Docker) |  | ||||||
|  |  | ||||||
| ### 1) Clone & run |  | ||||||
| ```bash |  | ||||||
| git clone https://gitea.js-devop.de/jschaufuss/Subscribarr.git |  | ||||||
| cd Subscribarr |  | ||||||
| docker compose up -d --build |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| - Default app port inside the container: **8000**   |  | ||||||
| - Optional: set `CRON_SCHEDULE` (e.g., `*/30 * * * *`) to enable periodic checks |  | ||||||
|  |  | ||||||
| ### 2) Minimal `docker-compose.yml` (example) |  | ||||||
| ```yaml |  | ||||||
| --- |  | ||||||
| services: |  | ||||||
|   subscribarr: |  | ||||||
|     build: . |  | ||||||
|     container_name: subscribarr |  | ||||||
|     ports: |  | ||||||
|       - "8081:8000" |  | ||||||
|     environment: |  | ||||||
|       # Django |  | ||||||
|       - DJANGO_DEBUG=true |  | ||||||
|       - USE_X_FORWARDED_HOST=true |  | ||||||
|       - DJANGO_SECURE_PROXY_SSL_HEADER=true |  | ||||||
|       - DJANGO_CSRF_COOKIE_SECURE=true |  | ||||||
|       - DJANGO_SESSION_COOKIE_SECURE=true |  | ||||||
|       - DJANGO_ALLOWED_HOSTS=* |  | ||||||
|       - DJANGO_SECRET_KEY=change-me |  | ||||||
|       - DB_PATH=/app/data/db.sqlite3 |  | ||||||
|       - NOTIFICATIONS_ALLOW_DUPLICATES=false |  | ||||||
|       - DJANGO_CSRF_TRUSTED_ORIGINS="https://subscribarr.local.js-devop.de" |  | ||||||
|       # App Settings (optional, otherwise use first-run setup) |  | ||||||
|       #- JELLYFIN_URL= |  | ||||||
|       #- JELLYFIN_API_KEY= |  | ||||||
|       #- SONARR_URL= |  | ||||||
|       #- SONARR_API_KEY= |  | ||||||
|       #- RADARR_URL= |  | ||||||
|       #- RADARR_API_KEY= |  | ||||||
|       #- MAIL_HOST= |  | ||||||
|       #- MAIL_PORT= |  | ||||||
|       #- MAIL_SECURE= |  | ||||||
|       #- MAIL_USER= |  | ||||||
|       #- MAIL_PASSWORD= |  | ||||||
|       #- MAIL_FROM= |  | ||||||
|       # Admin bootstrap (optional) |  | ||||||
|       #- ADMIN_USERNAME= |  | ||||||
|       #- ADMIN_PASSWORD= |  | ||||||
|       #- ADMIN_EMAIL= |  | ||||||
|       # Cron schedule (default every 30min) |  | ||||||
|       - CRON_SCHEDULE=*/30 * * * * |  | ||||||
|     volumes: |  | ||||||
|       - ./data:/app/data |  | ||||||
|     restart: unless-stopped |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## Environment Variables (selection) |  | ||||||
|  |  | ||||||
| | Variable | Purpose | |  | ||||||
| |---|---| |  | ||||||
| | `DJANGO_DEBUG` | `true` / `false` (disable in production). | |  | ||||||
| | `DJANGO_ALLOWED_HOSTS` | Comma list of allowed hosts (e.g., `example.com,localhost`). | |  | ||||||
| | `DJANGO_SECRET_KEY` | Django secret key. | |  | ||||||
| | `DB_PATH` | SQLite path, e.g., `/app/data/db.sqlite3`. | |  | ||||||
| | `NOTIFICATIONS_ALLOW_DUPLICATES` | Allow duplicate sends (`true`/`false`). | |  | ||||||
| | `ADMIN_USERNAME` / `ADMIN_PASSWORD` / `ADMIN_EMAIL` | Optional: bootstrap an admin user on first run. | |  | ||||||
| | `JELLYFIN_URL` / `JELLYFIN_API_KEY` | Base URL + API key for Jellyfin. | |  | ||||||
| | `SONARR_URL` / `SONARR_API_KEY` | Base URL + API key for Sonarr. | |  | ||||||
| | `RADARR_URL` / `RADARR_API_KEY` | Base URL + API key for Radarr. | |  | ||||||
| | `MAIL_HOST` / `MAIL_PORT` / `MAIL_SECURE` | SMTP host/port/security (`starttls` / `ssl` / empty). | |  | ||||||
| | `MAIL_USER` / `MAIL_PASSWORD` / `MAIL_FROM` | SMTP auth + sender address. | |  | ||||||
| | `CRON_SCHEDULE` | Cron interval for periodic checks (e.g., `*/30 * * * *`). | |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## First Run |  | ||||||
|  |  | ||||||
| 1. Start the container (or dev server) and open `http://<host>:8081`.   |  | ||||||
| 2. Complete the **first-time setup**: Jellyfin URL/API key (required), optional Sonarr/Radarr, SMTP.   |  | ||||||
| 3. **Sign in** with Jellyfin credentials (admin users in Jellyfin become admins in Subscribarr).   |  | ||||||
| 4. Adjust settings later at `/settings/`. |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## Notifications & Cron |  | ||||||
|  |  | ||||||
| - The periodic job calls `check_new_media` which determines today’s items via Sonarr/Radarr calendars.   |  | ||||||
| - Email is sent only if the item is **present** (e.g., `hasFile`/downloaded) and not already recorded in the sent-log (duplicate guard).   |  | ||||||
| - Cron is configured using `CRON_SCHEDULE` and runs `python manage.py check_new_media`. Output is typically logged to `/app/cron.log` in the container. |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## Routes / Endpoints (selected) |  | ||||||
|  |  | ||||||
| - `GET /` — Overview page with search/filter and subscribe actions   |  | ||||||
| - `GET/POST /settings/` — Jellyfin/Arr/Mail/Account configuration (auth required; admin for some actions)   |  | ||||||
| - Example subscribe endpoints (subject to change):   |  | ||||||
|   - `POST /api/series/subscribe/<series_id>/`, `POST /api/series/unsubscribe/<series_id>/`   |  | ||||||
|   - `POST /api/movies/subscribe/<movie_id>/`, `POST /api/movies/unsubscribe/<movie_id>/` |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## Local Development (without Docker) |  | ||||||
|  |  | ||||||
| > Requires Python 3.12+ (recommended). |  | ||||||
|  |  | ||||||
| ### 1) Clone |  | ||||||
| ```bash |  | ||||||
| git clone https://gitea.js-devop.de/jschaufuss/Subscribarr.git |  | ||||||
| cd Subscribarr |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### 2) Create & activate a virtualenv |  | ||||||
| ```bash |  | ||||||
| python -m venv .venv |  | ||||||
| # Linux/macOS: |  | ||||||
| source .venv/bin/activate |  | ||||||
| # Windows (PowerShell): |  | ||||||
| # .venv\Scripts\Activate.ps1 |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### 3) Install dependencies (including Django) |  | ||||||
| If the repository provides `requirements.txt`: |  | ||||||
| ```bash |  | ||||||
| pip install --upgrade pip wheel |  | ||||||
| pip install -r requirements.txt |  | ||||||
| ``` |  | ||||||
| If not, install the core stack explicitly: |  | ||||||
| ```bash |  | ||||||
| pip install --upgrade pip wheel |  | ||||||
| pip install "Django>=5" djangorestframework python-dotenv |  | ||||||
| # add any additional libs your project uses as needed |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### 4) Configure environment (dev) |  | ||||||
| Create a `.env` (or export env vars) with at least: |  | ||||||
| ```env |  | ||||||
| DJANGO_DEBUG=true |  | ||||||
| DJANGO_SECRET_KEY=dev-secret |  | ||||||
| DJANGO_ALLOWED_HOSTS=* |  | ||||||
| DB_PATH=./data/db.sqlite3 |  | ||||||
| ``` |  | ||||||
| Create the `data/` directory if it doesn’t exist. |  | ||||||
|  |  | ||||||
| ### 5) Database setup |  | ||||||
| ```bash |  | ||||||
| python manage.py makemigrations |  | ||||||
| python manage.py migrate |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### 6) (Optional) Create a superuser for the Django admin |  | ||||||
| ```bash |  | ||||||
| python manage.py createsuperuser |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### 7) Run the dev server |  | ||||||
| ```bash |  | ||||||
| python manage.py runserver 0.0.0.0:8000 |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## Data Model (high level) |  | ||||||
|  |  | ||||||
| - **User** (`accounts.User`): custom user with Jellyfin link and admin flag.   |  | ||||||
| - **Subscriptions** (`arr_api.SeriesSubscription`, `arr_api.MovieSubscription`): unique per user/title.   |  | ||||||
| - **SentNotification**: records delivered emails to avoid duplicates.   |  | ||||||
| - **AppSettings**: singleton for Jellyfin/Arr/Mail/Account configuration. |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## Production Notes |  | ||||||
|  |  | ||||||
| - Set **`DEBUG=false`**, a strong **`DJANGO_SECRET_KEY`**, and proper **`DJANGO_ALLOWED_HOSTS`**.   |  | ||||||
| - Run behind a reverse proxy with HTTPS.   |  | ||||||
| - Collect static files if served by Django:   |  | ||||||
|   ```bash |  | ||||||
|   python manage.py collectstatic --noinput |  | ||||||
|   ``` |  | ||||||
| - Use a persistent database volume (or switch to Postgres/MySQL) for production. |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| ## License | ## License | ||||||
|  |  | ||||||
| MIT (see `LICENSE`). | MIT (see `LICENSE`). | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user