From 11193677cf64b44dd1a1274415735b40063ce569 Mon Sep 17 00:00:00 2001
From: Jan Schaufuss
Date: Fri, 15 Aug 2025 13:39:51 +0200
Subject: [PATCH] update README
---
README.md | 355 ++++++++++--------------------------------------------
1 file changed, 63 insertions(+), 292 deletions(-)
diff --git a/README.md b/README.md
index 70cabe7..e75b478 100644
--- a/README.md
+++ b/README.md
@@ -17,98 +17,97 @@
-->
-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
- 
- 
- 
- 
- 
-
+ 
+ 
+ 
+ 
+ 
+
-### 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
```
-2) Image bauen/Starten:
+2) Build and run:
```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).
-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)
+### Local (Pipenv)
```bash
pipenv sync
pipenv run python manage.py migrate
pipenv run python manage.py runserver
```
-## 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)
+## 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)
-## 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 `hasFile` is true (downloaded/present).
+- Movies: similar via Radarr `hasFile` and matching the release date (Digital/Disc/Cinema) for today.
+- 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
```
@@ -117,246 +116,18 @@ pipenv run python manage.py check_new_media
docker compose exec web 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
-
-
-
-
-
-
-
-
----
-
-## 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`).