From ee3ebeeb93bf0d380a353db0b84f35c3661a2556 Mon Sep 17 00:00:00 2001 From: Jan Schaufuss Date: Sat, 16 Aug 2025 15:32:10 +0200 Subject: [PATCH] updated README --- README.md | 374 ++++++++++-------------------------------------------- 1 file changed, 69 insertions(+), 305 deletions(-) diff --git a/README.md b/README.md index 70cabe7..9e350be 100644 --- a/README.md +++ b/README.md @@ -17,346 +17,110 @@

--> -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 -- Jellyfin‑Login (kein eigener Userstore nötig) -- Kalender im Sonarr/Radarr‑Stil (kommende Episoden/Filme) -- Abonnieren/Abbestellen direkt aus dem UI (Serien & Filme) -- Admin‑Übersicht aller Abos je Nutzer inkl. Poster -- Benachrichtigungen pro Nutzer wählbar: - - E‑Mail (SMTP) - - ntfy (Token oder Basic Auth) - - Apprise (zahlreiche Ziele wie Discord, Gotify, Pushover, Webhooks u. v. m.) -- Docker‑fertig, env‑gesteuerte Security‑Settings (ALLOWED_HOSTS, CSRF, Proxy) - -## Schnellstart +- Sign in with Jellyfin (no separate user store) +- Sonarr/Radarr‑style calendar (upcoming episodes/movies) +- Subscribe/unsubscribe from the UI (series & movies) +- Admin overview of all users’ subscriptions with posters +- Per‑user notification channels: + - Email (SMTP) + - ntfy (Bearer token or Basic Auth) + - Apprise (Discord, Gotify, Pushover, Webhooks, and many more) +- Docker‑ready; environment‑driven security (ALLOWED_HOSTS, CSRF, proxy) ## Screenshots

- Screenshot 1
- Screenshot 2
- Screenshot 3
- Screenshot 4
- Screenshot 5
- Screenshot 6 + Settings
+ Subscriptions
+ Overview
+ Search
+ Details
+ Notifications

-### Mit Docker Compose -1) Lockfile aktuell halten (wenn `Pipfile` geändert wurde): +## Quickstart (Docker Compose) +1) Ensure the lockfile matches your Pipfile (e.g., after adding packages): ```bash -pipenv lock +git clone https://github.com/jschaufuss/subscribarr.git +cd subscribarr ``` -2) Image bauen/Starten: +2) run the container: ```bash -docker compose build 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_CSRF_TRUSTED_ORIGINS=https://subscribarr.example.com,http://subscribarr.example.com` -- Reverse‑Proxy/TLS: +- Reverse proxy/TLS: - `USE_X_FORWARDED_HOST=true` - `DJANGO_SECURE_PROXY_SSL_HEADER=true` - `DJANGO_CSRF_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) -```bash -pipenv sync -pipenv run python manage.py migrate -pipenv run python manage.py runserver -``` +## In‑App Configuration +- Settings → Jellyfin: server URL + API key +- Settings →Sonarr/Radarr: base URLs + API keys (with “Test” button) +- Settings →Mail server: SMTP (host/port/TLS/SSL/user/password/from) +- 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 -- Einstellungen → Jellyfin: Server‑URL + API‑Key -- 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 +## ntfy Notes +- Server URL: e.g., `https://ntfy.sh` or your own server - Auth: - - Bearer‑Token (Header) - - Basic‑Auth (Benutzer/Passwort) -- Topic: - - pro Nutzer frei wählbar (Profil) oder globales Default‑Topic (Einstellungen) + - Bearer token (Authorization header) + - Basic Auth (username/password) +- Topic selection: + - Per user in the profile, or a global default topic in Settings -## Apprise – Hinweise -- Trag eine oder mehrere Ziel‑URLs ein (pro Zeile), z. B.: - - `gotify://TOKEN@gotify.example.com/` - - `discord://webhook_id/webhook_token` - - `mailto://user:pass@smtp.example.com` - - `pover://user@token` - - `json://webhook.example.com/path` -- Nutzer können eigene URLs ergänzen; die globalen Defaults bleiben zusätzlich aktiv. +## Apprise Notes +Provide one or more destination URLs (one per line), e.g.: +- `gotify://TOKEN@gotify.example.com/` +- `discord://webhook_id/webhook_token` +- `mailto://user:pass@smtp.example.com` +- `pover://user@token` +- `json://webhook.example.com/path` -## Benachrichtigungslogik -- 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). +User URLs are added in addition to global defaults. -## Jobs / Manuell anstoßen -- Regelmäßiger Check per Management Command (z. B. via Cron): +## Notification Logic +- 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 -pipenv run python manage.py check_new_media -``` -- In Docker: -```bash -docker compose exec web python manage.py check_new_media +docker exec -it subscribarr python manage.py check_new_media ``` -## Sicherheit & Proxy -- Setze `DJANGO_ALLOWED_HOSTS` auf deine(n) Hostnamen. -- Füge alle genutzten Ursprünge in `DJANGO_CSRF_TRUSTED_ORIGINS` hinzu (http/https und Port beachten). -- Hinter Reverse‑Proxy TLS aktivieren: `USE_X_FORWARDED_HOST`, `DJANGO_SECURE_PROXY_SSL_HEADER`, Cookie‑Flags. +## Security & Proxy +- Set `DJANGO_ALLOWED_HOSTS` to your hostnames. +- Include all used origins in `DJANGO_CSRF_TRUSTED_ORIGINS` (http/https and port where applicable). +- 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 -- Integrationen: Sonarr/Radarr (API v3) +- Integrations: Sonarr/Radarr (API v3) - Auth: Jellyfin - Notifications: SMTP, ntfy (HTTP), Apprise - Frontend: Templates + FullCalendar - 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 - -![Overview](screenshots/SCR-20250811-lfod.png) -![Settings](screenshots/SCR-20250811-lfrm.png) -![Subscriptions](screenshots/SCR-20250811-lfvc.png) -![Search](screenshots/SCR-20250811-lfyq.png) -![Details](screenshots/SCR-20250811-lgau.png) -![Notifications](screenshots/SCR-20250811-lgcz.png) - ---- - -## 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://: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//`, `POST /api/series/unsubscribe//` - - `POST /api/movies/subscribe//`, `POST /api/movies/unsubscribe//` - ---- - -## 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 - MIT (see `LICENSE`). +