Compare commits

...

1 Commits

Author SHA1 Message Date
11193677cf update README 2025-08-15 13:39:51 +02:00

345
README.md
View File

@@ -17,98 +17,97 @@
</p>
-->
Ein leichtgewichtiges WebFrontend für Benachrichtigungen und Abos rund um Sonarr/Radarr mit JellyfinLogin, Kalender, AboVerwaltung und flexiblen Notifications per EMail, ntfy und Apprise.
Lightweight web UI for Sonarr/Radarr subscriptions with Jellyfin login, calendar, and flexible notifications via Email, ntfy, and Apprise.
## Features
- JellyfinLogin (kein eigener Userstore nötig)
- Kalender im Sonarr/RadarrStil (kommende Episoden/Filme)
- Abonnieren/Abbestellen direkt aus dem UI (Serien & Filme)
- AdminÜbersicht aller Abos je Nutzer inkl. Poster
- Benachrichtigungen pro Nutzer wählbar:
- EMail (SMTP)
- ntfy (Token oder Basic Auth)
- Apprise (zahlreiche Ziele wie Discord, Gotify, Pushover, Webhooks u.v.m.)
- Dockerfertig, envgesteuerte SecuritySettings (ALLOWED_HOSTS, CSRF, Proxy)
## Schnellstart
- Sign in with Jellyfin (no separate user store)
- Sonarr/Radarrstyle calendar (upcoming episodes/movies)
- Subscribe/unsubscribe from the UI (series & movies)
- Admin overview of all users subscriptions with posters
- Peruser notification channels:
- Email (SMTP)
- ntfy (Bearer token or Basic Auth)
- Apprise (Discord, Gotify, Pushover, Webhooks, and many more)
- Dockerready; environmentdriven security (ALLOWED_HOSTS, CSRF, proxy)
## Screenshots
<p align="center">
<img src="./screenshots/SCR-20250811-lfrm.png" alt="Screenshot 1" width="800"><br/>
<img src="./screenshots/SCR-20250811-lfvc.png" alt="Screenshot 2" width="800"><br/>
<img src="./screenshots/SCR-20250811-lfod.png" alt="Screenshot 3" width="800"><br/>
<img src="./screenshots/SCR-20250811-lfyq.png" alt="Screenshot 4" width="800"><br/>
<img src="./screenshots/SCR-20250811-lgau.png" alt="Screenshot 5" width="800"><br/>
<img src="./screenshots/SCR-20250811-lgcz.png" alt="Screenshot 6" width="800">
<img src="./screenshots/SCR-20250811-lfrm.png" alt="Settings" width="800"><br/>
<img src="./screenshots/SCR-20250811-lfvc.png" alt="Subscriptions" width="800"><br/>
<img src="./screenshots/SCR-20250811-lfod.png" alt="Overview" width="800"><br/>
<img src="./screenshots/SCR-20250811-lfyq.png" alt="Search" width="800"><br/>
<img src="./screenshots/SCR-20250811-lgau.png" alt="Details" width="800"><br/>
<img src="./screenshots/SCR-20250811-lgcz.png" alt="Notifications" width="800">
</p>
### 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 FirstRunSetup (Jellyfin + ArrURLs/Keys) durch.
3) Open the app and complete the firstrun 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`
- ReverseProxy/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: ServerURL + APIKey
- Einstellungen → Sonarr/Radarr: BaseURLs + APIKeys (inkl. „Test“-Knopf)
- Einstellungen → Mailserver: SMTP (Host/Port/TLS/SSL/Benutzer/Passwort/From)
- Einstellungen → Notifications:
- ntfy: ServerURL, DefaultTopic, BasicAuth oder BearerToken
- Apprise: DefaultURL(s) (eine pro Zeile)
- Profil (pro Nutzer):
- Kanal wählen: EMail, ntfy oder Apprise
- ntfy Topic (optional, überschreibt Default)
- Apprise URL(s) (optional, ergänzen die Defaults)
## InApp 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
- ServerURL: z.B. `https://ntfy.sh` oder eigener Server
## ntfy Notes
- Server URL: e.g., `https://ntfy.sh` or your own server
- Auth:
- BearerToken (Header)
- BasicAuth (Benutzer/Passwort)
- Topic:
- pro Nutzer frei wählbar (Profil) oder globales DefaultTopic (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 ZielURLs ein (pro Zeile), z.B.:
## 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`
- Nutzer können eigene URLs ergänzen; die globalen Defaults bleiben zusätzlich aktiv.
## Benachrichtigungslogik
- Serien: Es wird pro Abo am ReleaseTag geprüft, ob die Episode bereits als Datei vorhanden ist (Sonarr `hasFile`).
- Filme: Analog über Radarr `hasFile` und ReleaseDatum (Digital/Disc/KinoTag).
- Doppelversand wird per `SentNotification` unterdrückt (täglich pro Item/Nutzer).
- Fallback: Wenn ntfy/Apprise scheitern, wird EMail 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 ReverseProxy TLS aktivieren: `USE_X_FORWARDED_HOST`, `DJANGO_SECURE_PROXY_SSL_HEADER`, CookieFlags.
## 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.
## TechStack
## 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://<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 todays 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 doesnt 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`).