CLI Tool zum Downloaden von Original-Dateien aus Plex
Project description
Plex Downloader CLI
Ein modernes Kommandozeilen-Tool (CLI), um Filme und TV Shows von einem Plex-Server in Originalqualität (Direct Stream) herunterzuladen.
Entwickelt von Patrick Kurmann mit Python, Typer und Rich.
Features
- Neueste Inhalte: Zeige die 12 neuesten Filme oder TV-Serien an, die deiner Plex-Bibliothek hinzugefügt wurden.
- Interaktive Suche: Suche blitzschnell nach Filmen und TV Shows in deinen Plex-Bibliotheken.
- Unattended Filmsuche: Suche per Titel nach Filmen und erhalte strukturierte Treffer mit Rating-Key, Titel und Jahr – ohne interaktive Rückfragen. Mit
--jsonals vollständige maschinenlesbare JSON-Ausgabe inklusive Edition, Dateigrösse, Auflösung und externen IDs. - Externe IDs optional anzeigen: Verfügbare TMDB-, IMDB- und TVDB-IDs lassen sich bei Bedarf mit
--show-idsin Such- und Auswahlansichten einblenden. - Deterministischer Film-Download: Lade einen Film direkt per eindeutigem Plex-Rating-Key herunter – deterministisch und skriptbar. Kein Suche-Schritt, kein Zufall.
- Unattended Film-Download: Lade einen Film direkt per Titel herunter, ohne interaktive Rückfragen – skriptbar und automatisierbar. Unterstützt auch geplante Nacht-Downloads via
--night. - Optionale externe ID im Dateinamen: Film-Downloads können per
--append-id tmdb|imdb|tvdbeine vorhandene externe ID als Suffix wie[tmdb-27205]an den Dateinamen anhängen. - Flexibles Verzeichnis-Layout: Standardmäßig werden Filme direkt im Download-Verzeichnis abgelegt (flaches Layout). Mit
--movie-subdiroder der Config-Einstellungcreate_movie_subdirlässt sich das klassische Emby-Unterverzeichnis ({Titel} ({Jahr})/Datei) aktivieren. - TV Show Support: Lade ganze Serien, einzelne Episoden oder alle Episoden ab einer bestimmten Episode bis zum Ende der Staffel herunter.
- Geplanter Download: Plane Downloads für 2 Uhr morgens direkt im interaktiven Ablauf.
- Medienserver-Integration: Automatisches Verschieben von Downloads zum Medienserver (lokal oder per rclone zu NAS/Cloud).
- Originalqualität: Lädt die rohe Videodatei (z. B. MKV, MP4) herunter, ohne Transcodierung oder Qualitätsverlust.
- Optional ohne eingebettetes Artwork: Entfernt auf Wunsch eingebettete Vorschaubilder/Cover-Art aus Filmdateien (z. B. MKV, MP4, M4V) nach dem Download.
- Schicke UI: Fortschrittsbalken, farbige Ausgaben und formatierte Tabellen.
- Sicherer Login: Verbindet sich mit deinen Plex-Zugangsdaten und nutzt Tokens zur Authentifizierung.
- Konfigurierbar: Speichert deine Einstellungen (Server, Token, Pfad) lokal ab.
Installation
Option 1: Installation via PyPI (Empfohlen)
pipx install kurmann-plex-downloader
Oder mit pip in einer virtuellen Umgebung:
pip install kurmann-plex-downloader
Option 2: Installation via pipx aus GitHub
pipx install git+https://github.com/kurmann/plex-downloader.git
Option 3: Lokale Entwicklung
Wenn du den Code verändern oder erweitern möchtest:
- Repository klonen:
git clone https://github.com/kurmann/plex-downloader.git
cd plex-downloader
- Abhängigkeiten installieren (empfohlen: uv):
uv sync
Oder mit pip:
pip install -e ".[dev]"
Benutzung
Sobald das Tool installiert ist, steht dir der Befehl plex-dl systemweit zur Verfügung.
1. Ersteinrichtung (Konfiguration)
Bevor du starten kannst, musst du dich einmalig einloggen und den gewünschten Server auswählen.
plex-dl init
Folge den Anweisungen im Terminal, um dich bei plex.tv einzuloggen und deinen Server zu wählen.
Hinweis:
initist für die Ersteinrichtung gedacht. Um einzelne Einstellungen (Server, Download-Pfad) anzupassen, nutzeconfig set:
plex-dl config set server_name "Neuer Server"
plex-dl config set download_path ~/Downloads
plex-dl config set remove_embedded_artwork_movies true
2. Interaktiven Auswahl- und Download-Flow starten
Starte den interaktiven Flow explizit mit dem select-Unterbefehl:
plex-dl select
Optional mit externen IDs in der Anzeige (neu in 2.4.0):
plex-dl select --show-ids
Im Hauptmenü kannst du:
- Option 1: Nach Filmen oder TV-Serien suchen
- Option 2: Die 12 neuesten Filme anzeigen
- Option 3: Die 12 neuesten TV-Serien anzeigen
Nach der Anzeige der Liste kannst du einen Film oder eine Serie auswählen, in die Warteschlange legen und herunterladen.
Hinweis:
plex-dlohne Unterbefehl zeigt nur die Hilfe an. Die interaktive Sitzung muss explizit mitplex-dl selectgestartet werden.
3. Unattended Film-Download (neu in 2.1.0)
Der Befehl movie download-first lädt das erste Suchresultat für einen Filmtitel direkt herunter – ohne interaktive Rückfragen. Er eignet sich ideal für Skripte und automatisierte Abläufe.
plex-dl movie download-first "Inception"
Verhalten:
- Verbindet sich mit dem konfigurierten Plex-Server.
- Sucht in den Film-Bibliotheken nach dem angegebenen Titel.
- Wählt das erste Suchresultat aus.
- Lädt den Film herunter.
- Existierende Dateien werden stillschweigend übersprungen (kein Prompt).
Ausgabe:
- Ergebnisdaten auf
stdout, z. B.:downloaded: Inception (2010) - Fehler- und Diagnosemeldungen auf
stderr
Exit-Codes:
| Code | Bedeutung |
|---|---|
0 |
Download erfolgreich |
1 |
Kein Treffer oder Download fehlgeschlagen |
2 |
Fehlende oder ungültige Konfiguration |
Optionen:
# Anderen Download-Pfad angeben
plex-dl movie download-first "The Matrix" --download-path ~/Downloads
# Download auf 2 Uhr morgens verschieben (unattended, kein Prompt)
plex-dl movie download-first "War Machine" --night
# Eingebettete Vorschaubilder/Cover-Art nach dem Download entfernen
plex-dl movie download-first "Skyfall" --remove-embedded-artwork
# Vorhandene TMDB-ID als Suffix an den Dateinamen anhängen
plex-dl movie download-first "Inception" --append-id tmdb
# Unterverzeichnis nach Emby-Konvention erstellen ({Titel} ({Jahr})/Datei)
plex-dl movie download-first "Inception" --movie-subdir
# Hilfe anzeigen
plex-dl movie download-first --help
Nachtmodus (--night):
Mit dem Flag --night wird der Download bis 2 Uhr morgens verzögert – vollständig unattended und ohne interaktive Rückfragen. Die Statusmeldungen erscheinen auf stderr:
Geplanter Nacht-Download um 2:00 Uhr
Aktuelle Zeit: 22:15:00
Zielzeit: 14.03.2026 02:00:00
Wartezeit: 3 Stunden, 44 Minuten
Warte bis 2 Uhr morgens … (Ctrl+C zum Abbrechen)
Hinweis:
download-firstist eine Convenience-Funktion und wählt bewusst das erste Suchresultat. Für deterministischen Download per eindeutiger ID stehtmovie download --rating-key <id>zur Verfügung (neu in 2.3.0).Hinweis: Für
--remove-embedded-artworkwerden lokal verfügbareffprobe/ffmpeg-Tools verwendet. Ohne diese Tools bleibt die heruntergeladene Datei unverändert.
4. Unattended Filmsuche (neu in 2.2.0)
Der Befehl movie search sucht nach Filmen in den Plex-Bibliotheken und zeigt die Treffer als Tabelle an – ohne Download. Er eignet sich ideal als Grundlage für spätere Skripte, die gezielt per Rating-Key herunterladen wollen.
plex-dl movie search "Dune"
Erwartete Ausgabe:
Suchergebnisse für 'Dune'
┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━┓
┃ Rating-Key ┃ Titel ┃ Jahr ┃
┡━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━┩
│ 123456 │ Dune │ 2021 │
│ 123789 │ Dune: Part Two │ 2024 │
│ 124000 │ Dune │ 1984 │
└────────────┴────────────────────┴──────┘
Verhalten:
- Verbindet sich mit dem konfigurierten Plex-Server.
- Sucht in den Film-Bibliotheken nach dem angegebenen Titel.
- Zeigt alle Treffer als Tabelle an – ohne Download.
- Der Rating-Key kann für deterministische Downloads per
movie download --rating-keyverwendet werden (neu in 2.3.0).
Ausgabe:
- Ergebnistabelle auf
stdout - Fehler- und Diagnosemeldungen auf
stderr
Exit-Codes:
| Code | Bedeutung |
|---|---|
0 |
Suche erfolgreich (auch bei 0 Treffern) |
1 |
Allgemeiner Fehler (z. B. Verbindungsfehler) |
2 |
Fehlende oder ungültige Konfiguration |
Optionen:
# Anzahl Treffer begrenzen
plex-dl movie search "Dune" --limit 5
# Maschinenlesbare JSON-Ausgabe (neu in 2.3.0)
plex-dl movie search "Rocky" --json
# Verfügbare externe IDs in der Trefferliste anzeigen (neu in 2.4.0)
plex-dl movie search "Inception" --show-ids
# Hilfe anzeigen
plex-dl movie search --help
JSON-Ausgabe mit --json (neu in 2.3.0)
Mit dem Flag --json liefert movie search eine vollständige, maschinenlesbare JSON-Ausgabe auf stdout. Ideal für Shell-Skripte und Automatisierungen.
plex-dl movie search "Rocky" --json
Beispiel-Ausgabe:
{
"query": "Rocky",
"success": true,
"message": "2 Treffer für 'Rocky'.",
"total": 2,
"items": [
{
"rating_key": "35502",
"title": "Rocky",
"year": 1976,
"media_type": "movie",
"edition": null,
"file_size_bytes": 54858234880,
"resolution": "1080",
"container": "mkv",
"external_ids": {
"tmdb": "1366",
"imdb": "tt0075148"
}
},
{
"rating_key": "35501",
"title": "Rocky II",
"year": 1979,
"media_type": "movie",
"edition": "Director's Cut",
"file_size_bytes": 54858234880,
"resolution": "1080",
"container": "mkv",
"external_ids": {}
}
]
}
Fehlen Felder wie Edition oder Dateigrösse in Plex, werden sie konsistent als null zurückgegeben.
5. Deterministischer Film-Download per Rating-Key (neu in 2.3.0)
Der Befehl movie download --rating-key lädt einen Film anhand seines eindeutigen Plex-Rating-Keys herunter. Im Gegensatz zu download-first wird kein Suche-Schritt durchgeführt – der Download ist deterministisch und wiederholbar.
Der Rating-Key ist in den Suchergebnissen von movie search sichtbar.
plex-dl movie download --rating-key 35502
Mit --night wird der Download bis 2 Uhr morgens verzögert – ohne interaktive Bestätigung:
plex-dl movie download --rating-key 35502 --night
Mit --append-id tmdb|imdb|tvdb wird – falls vorhanden – genau eine externe ID als Suffix im Format [tmdb-27205] an den finalen Dateinamen angehängt:
plex-dl movie download --rating-key 35502 --append-id tmdb
Typischer Workflow:
# 1. Film suchen und Rating-Key ermitteln
plex-dl movie search "Rocky"
# Ausgabe:
# Rating-Key │ Titel │ Jahr
# 35502 │ Rocky │ 1976
# 2. Film gezielt herunterladen
plex-dl movie download --rating-key 35502
# 3. Oder als Nacht-Download planen
plex-dl movie download --rating-key 35502 --night
Verhalten:
- Verbindet sich mit dem konfigurierten Plex-Server.
- Löst das Filmobjekt anhand des Rating-Keys auf.
- Validiert, dass es sich um einen Film handelt (kein TV-Show, Episode o. ä.).
- Wenn
--nightgesetzt: wartet unattended bis 2 Uhr morgens, dann Download. - Lädt den Film deterministisch herunter.
- Existierende Dateien werden stillschweigend übersprungen (kein Prompt).
Ausgabe:
- Ergebnisdaten auf
stdout, z. B.:downloaded: Rocky (1976) - Fehler- und Diagnosemeldungen auf
stderr
Exit-Codes:
| Code | Bedeutung |
|---|---|
0 |
Download erfolgreich |
1 |
Rating-Key nicht gefunden, falscher Medientyp oder Download fehlgeschlagen |
2 |
Fehlende oder ungültige Konfiguration |
Optionen:
# Anderen Download-Pfad angeben
plex-dl movie download --rating-key 35502 --download-path ~/Downloads
# Nacht-Download planen
plex-dl movie download --rating-key 35502 --night
# Vorhandene IMDB-ID an den Dateinamen anhängen
plex-dl movie download --rating-key 35502 --append-id imdb
# Unterverzeichnis nach Emby-Konvention erstellen ({Titel} ({Jahr})/Datei)
plex-dl movie download --rating-key 35502 --movie-subdir
# Hilfe anzeigen
plex-dl movie download --help
6. Suchen & Herunterladen (interaktiv)
Starte plex-dl select und wähle im Hauptmenü Option 1, dann gib einen Film- oder Serientitel ein. Das Tool zeigt dir alle Treffer an und lässt dich auswählen, welchen du laden möchtest.
Für TV Shows wirst du gefragt, ob du die ganze Serie, nur eine bestimmte Episode oder alle Episoden ab einer bestimmten Episode bis zum Ende der Staffel herunterladen möchtest.
Geplanter Download (Nachtmodus)
Nach der Auswahl des gewünschten Inhalts wirst du interaktiv gefragt, ob der Download sofort oder um 2 Uhr morgens starten soll:
Wann möchtest du den Download starten?
1. Jetzt sofort
2. Um 2:00 Uhr morgens
Im Nachtmodus (Option 2):
- Wartet die Anwendung aktiv bis 2 Uhr morgens
- Zeigt die verbleibende Wartezeit alle 60 Sekunden an
- Führt den Download automatisch um 2 Uhr aus
Beispiel:
# Interaktiven Flow starten und im Menü suchen
plex-dl select
# Nach der Auswahl des Inhalts wirst du gefragt:
# "Wann möchtest du den Download starten?"
# 1. Jetzt sofort
# 2. Um 2:00 Uhr morgens
4. Medienserver-Integration
Bei der Erstkonfiguration (plex-dl init) kannst du ein oder mehrere Download-Ziele konfigurieren. Nach jedem erfolgreichen Download werden die Dateien automatisch in das gewählte Ziel verschoben.
Beispiele:
- Lokaler Pfad:
/mnt/mediaoder~/Media - rclone Remote:
mynas:media/plex(für NAS oder Cloud-Speicher)
Vorteile:
- Automatische Organisation der Medienbibliothek
- Bei Serien wird jede Episode sofort nach Download verschoben → Platz wird für die nächste Episode frei
- Unterstützt sowohl lokale als auch Remote-Ziele via rclone
Hinweis: Falls rclone nicht installiert ist, erfolgt bei lokalen Pfaden ein automatischer Fallback auf Python's Standardmethoden.
Konfiguration
Die Konfigurationsdatei wird standardmäßig hier gespeichert:
~/.config/plex-downloader/config.toml
Konfigurationswerte werden über dedizierte Unterbefehle gelesen und geschrieben:
# Wert setzen
plex-dl config set token <dein-plex-token>
plex-dl config set server_name "Mein Plex Server"
plex-dl config set download_path ~/Downloads/plex
# Einzelnen Wert abfragen
plex-dl config get server_name
# Alle Werte anzeigen
plex-dl config list
Unterstützte Konfigurationsschlüssel:
| Schlüssel | Beschreibung |
|---|---|
token |
Plex Authentifizierungs-Token |
server_name |
Name deines Plex-Servers |
download_path |
Temporäres Verzeichnis für Downloads |
remove_embedded_artwork_movies |
Eingebettete Vorschaubilder bei Filmen nach dem Download entfernen (true/false) |
create_movie_subdir |
Unterverzeichnis pro Film erstellen (Emby-Konvention, Standard: false) |
targets |
Liste von Zielverzeichnissen (via plex-dl init) |
Hinweis:
targets(Zielverzeichnisse) werden überplex-dl initoder die interaktive Erstkonfiguration gepflegt, da es sich um eine Liste von Objekten handelt.
Projektstruktur
Dieses Projekt nutzt das moderne src-Layout für Python-Pakete:
plex-downloader/
├── pyproject.toml # Abhängigkeiten & Entry Point
├── src/
│ └── plex_downloader/
│ ├── __init__.py
│ ├── main.py # Kompatibilitäts-Layer (Re-Exporte)
│ ├── core/
│ │ ├── config.py # Konfigurationsmanagement (reine I/O-Funktionen)
│ │ └── scheduler.py # Zeitplanungslogik (Nacht-Download-Berechnung)
│ ├── api/
│ │ ├── models.py # Request/Result-Datenmodelle
│ │ └── facade.py # Öffentliche API-Fassade
│ ├── services/
│ │ └── plex_service.py # Plex-Server-Verbindung
│ ├── cli/
│ │ ├── app.py # Typer-CLI (Subcommands: init, config, select, movie)
│ │ ├── movie.py # Unterbefehlsgruppe 'movie' (download-first, download, search, …)
│ │ └── interactive.py # Interaktive Sitzungslogik
│ └── modules/
│ ├── downloader.py # Download-Logik
│ ├── rclone_mover.py # Medienserver-Integration
│ └── cleanup.py # Temporäre Dateien bereinigen
Änderungsverlauf
2.4.0 – 2026-03-19
- Neue normalisierte externe IDs (
tmdb,imdb,tvdb) imMediaMatch-Modell und inmovie search --json - Neuer
--show-ids-Flag fürplex-dl selectundplex-dl movie searchzur optionalen Anzeige externer IDs in Listen- und Auswahlansichten
2.3.0 – 2026-03-13
- Neuer
--json-Flag fürplex-dl movie search: maschinenlesbare JSON-Ausgabe inkl. Edition/Version, Dateigrösse, Auflösung und Container-Format - Erweitertes
MediaMatch-Modell mitedition,file_size_bytes,resolutionundcontainer - Neuer unattended CLI-Befehl
plex-dl movie download --rating-key <id>für den deterministischen Film-Download per eindeutiger Plex-ID - Neue öffentliche API-Methode
download_movie_by_rating_key()als stabiler Einstiegspunkt - Validierung, dass der Rating-Key auf einen Film verweist (Fehler bei falschem Medientyp)
DownloadRequest.download_pathist jetzt optional (analog zudownload-first)
2.2.0 – 2026-03-13
- Neuer unattended CLI-Befehl
plex-dl movie search "<titel>"für die Filmsuche ohne Download - Suchergebnisse enthalten Rating-Key, Titel und Jahr – als Grundlage für deterministische Downloads
--limit-Option für die Suche (Standard: 10 Treffer)- Öffentliche API-Methode
search_movies()als stabiler Einstiegspunkt dokumentiert und genutzt
2.1.0 – 2026-03-13
- Neuer unattended CLI-Befehl
plex-dl movie download-first "<titel>"für den direkten Film-Download per Titel ohne interaktive Rückfragen - Neuer
--night-Flag: verschiebt den Download unattended bis 2 Uhr morgens (vollständig skriptbar) - Neue
movie-Unterbefehlsgruppe als Grundlage für spätere Befehle (movie search,movie download --rating-key) - Neue öffentliche API-Methoden
search_movies()unddownload_first_movie_by_title()in der API-Fassade - Neues Modell
MediaMatchfür typisierte Suchresultate ohne rohe Plex-Objekte in der öffentlichen API - Neues Modul
core/scheduler.pymit wiederverwendbarer Zeitplanungslogik für Nacht-Downloads download_video()unterstützt jetztskip_existing=Truefür den unattended Pfad ohne interaktiven Prompt
Vollständige Historie: CHANGELOG.md
Lizenz
Dieses Projekt ist unter der MIT Lizenz veröffentlicht. Siehe LICENSE für Details.
Haftungsausschluss
Dieses Tool ist nur für den persönlichen Gebrauch gedacht. Bitte respektiere das Urheberrecht und lade nur Inhalte herunter, an denen du die Rechte besitzt oder auf die du legitimen Zugriff hast.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kurmann_plex_downloader-2.4.0.tar.gz.
File metadata
- Download URL: kurmann_plex_downloader-2.4.0.tar.gz
- Upload date:
- Size: 62.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc48e5ba62db185edb16c68502d26687274cc2ec9b5244a0f30a50d22c17b7b6
|
|
| MD5 |
ff1b758f8bd6f14744e5d60de505b00a
|
|
| BLAKE2b-256 |
f63da3008bcd35745dc57fefdc67d2c2d2ddf7f877403b447c9ccd3ae0239fed
|
Provenance
The following attestation bundles were made for kurmann_plex_downloader-2.4.0.tar.gz:
Publisher:
publish.yml on kurmann/plex-downloader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kurmann_plex_downloader-2.4.0.tar.gz -
Subject digest:
fc48e5ba62db185edb16c68502d26687274cc2ec9b5244a0f30a50d22c17b7b6 - Sigstore transparency entry: 1136917120
- Sigstore integration time:
-
Permalink:
kurmann/plex-downloader@3b901782038610ea9a2f957e73a241e411a2ddd7 -
Branch / Tag:
refs/tags/v2.4.0 - Owner: https://github.com/kurmann
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3b901782038610ea9a2f957e73a241e411a2ddd7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file kurmann_plex_downloader-2.4.0-py3-none-any.whl.
File metadata
- Download URL: kurmann_plex_downloader-2.4.0-py3-none-any.whl
- Upload date:
- Size: 45.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9445ff02da558a7d14c3d7c0e45436a7f93553905facbaa9acb162b094a1afcf
|
|
| MD5 |
2108b847a04c0e6e5266e93d78914625
|
|
| BLAKE2b-256 |
32c33879f296a5db53b7725bbf45ae1385c193aa9e5fda6712629d8a2c58b036
|
Provenance
The following attestation bundles were made for kurmann_plex_downloader-2.4.0-py3-none-any.whl:
Publisher:
publish.yml on kurmann/plex-downloader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kurmann_plex_downloader-2.4.0-py3-none-any.whl -
Subject digest:
9445ff02da558a7d14c3d7c0e45436a7f93553905facbaa9acb162b094a1afcf - Sigstore transparency entry: 1136917184
- Sigstore integration time:
-
Permalink:
kurmann/plex-downloader@3b901782038610ea9a2f957e73a241e411a2ddd7 -
Branch / Tag:
refs/tags/v2.4.0 - Owner: https://github.com/kurmann
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3b901782038610ea9a2f957e73a241e411a2ddd7 -
Trigger Event:
release
-
Statement type: