This commit is contained in:
2026-03-09 13:40:48 +00:00
parent 8e3c67565d
commit fa6594b163
10 changed files with 516 additions and 70 deletions

View File

@@ -2,13 +2,28 @@
Ripster ist eine lokale Web-Anwendung für halbautomatisches Disc-Ripping mit MakeMKV + HandBrake inklusive Metadaten-Auswahl, Titel-/Spurprüfung und Job-Historie.
---
> **Neu seit letztem Release**
>
> - **Cron-Job-System** Skripte und Skript-Ketten zeitgesteuert ausführen; eigener Expression-Parser, Ausführungs-Logs, manuelle Auslösung, PushOver-Integration
> - **DVD-Erkennung verbessert** robuste Media-Profil-Erkennung (Blu-ray / DVD / CD) aus UDF/ISO9660-Dateisystemtyp, Laufwerk-Modell und Disc-Label
> - **Pre-Encode-Ausführungen** Skripte und Ketten können nun auch *vor* dem Encode-Schritt ausgeführt werden (zusätzlich zu Post-Encode)
> - **Sortierbare Skripte & Ketten** Reihenfolge über Drag & Drop festlegen; wird persistent in der Datenbank gespeichert
> - **`rip_successful`-Flag in Jobs** separates Feld zur Nachverfolgung ob der Rip-Schritt abgeschlossen wurde (unabhängig vom Encode-Status)
---
## Was Ripster kann
- Disc-Erkennung mit Pipeline-Status in Echtzeit (WebSocket)
- Robuste Erkennung von Blu-ray, DVD und CD (UDF/ISO9660-Heuristik + Laufwerk-Modell)
- Metadaten-Suche und Zuordnung über OMDb
- MakeMKV-Analyse und Rip (MKV oder Backup-Modus)
- HandBrake-Encode mit Preset + Extra-Args + Track-Override
- Manuelle Playlist-/Titel-Auswahl bei komplexen Blu-rays
- Pre- und Post-Encode-Skripte & Skript-Ketten (inkl. Drag-and-Drop-Sortierung)
- Cron-Jobs: Skripte und Ketten zeitgesteuert ausführen (eigener Expression-Parser, Logs, PushOver)
- Historie mit Re-Encode, Löschfunktionen und Detailansicht
- Dateibasierte Logs (Backend + Job-Prozesslogs)
@@ -138,15 +153,30 @@ ripster/
## API-Überblick
**Pipeline**
- `GET /api/pipeline/state`
- `POST /api/pipeline/analyze`
- `POST /api/pipeline/start/:jobId`
- `POST /api/pipeline/confirm-encode/:jobId`
**History**
- `GET /api/history`
- `GET /api/history/:id`
**Settings**
- `GET /api/settings`
- `PUT /api/settings`
**Cron-Jobs** _(neu)_
- `GET /api/crons`
- `POST /api/crons`
- `GET /api/crons/:id`
- `PUT /api/crons/:id`
- `DELETE /api/crons/:id`
- `GET /api/crons/:id/logs`
- `POST /api/crons/:id/run`
- `POST /api/crons/validate-expression`
## Troubleshooting
- WebSocket verbindet nicht:

View File

@@ -81,15 +81,23 @@ else
fi
# --------------------------------------------------------------------------
# 3. Alte Installation entfernen
# 3. Alle vorhandenen HandBrake-Installationen entfernen
# --------------------------------------------------------------------------
if command -v HandBrakeCLI &>/dev/null; then
EXISTING=$(HandBrakeCLI --version 2>&1 | head -1)
warn "Entferne vorhandenes HandBrakeCLI: ${EXISTING}"
apt-get remove -y handbrake-cli 2>/dev/null || true
snap remove handbrake-cli 2>/dev/null || true
rm -f /usr/bin/HandBrakeCLI /usr/local/bin/HandBrakeCLI
fi
info "Entferne alle vorhandenen HandBrake-Installationen..."
apt-get remove -y handbrake-cli handbrake 2>/dev/null || true
snap remove handbrake-cli 2>/dev/null || true
rm -f /usr/bin/HandBrakeCLI \
/usr/local/bin/HandBrakeCLI \
/snap/bin/handbrake-cli \
/snap/bin/HandBrakeCLI
while true; do
FOUND=$(command -v HandBrakeCLI 2>/dev/null || true)
[[ -z "$FOUND" ]] && break
warn "Entferne: $FOUND"
rm -f "$FOUND"
done
hash -r 2>/dev/null || true
ok "Alte HandBrake-Installation(en) entfernt"
# --------------------------------------------------------------------------
# 4. Quellcode herunterladen

243
docs/api/crons.md Normal file
View File

@@ -0,0 +1,243 @@
# Cron API
Ripster enthält ein eingebautes Cron-System, mit dem **Skripte** und **Skript-Ketten** zeitgesteuert oder manuell ausgeführt werden können. Der Cron-Dienst benötigt keine externen Pakete der Cron-Expression-Parser ist vollständig im Backend implementiert.
---
## Endpunkte
### `GET /api/crons`
Alle konfigurierten Cron-Jobs auflisten.
**Antwort:**
```json
{
"jobs": [
{
"id": 1,
"name": "Nachtlauf Backup",
"cronExpression": "0 2 * * *",
"sourceType": "script",
"sourceId": 3,
"enabled": true,
"pushoverEnabled": true,
"lastRunAt": "2026-03-09T02:00:00.000Z",
"lastRunStatus": "success",
"nextRunAt": "2026-03-10T02:00:00.000Z",
"createdAt": "2026-03-01T10:00:00.000Z",
"updatedAt": "2026-03-09T02:00:00.000Z"
}
]
}
```
---
### `POST /api/crons`
Neuen Cron-Job anlegen.
**Body:**
```json
{
"name": "Nachtlauf Backup",
"cronExpression": "0 2 * * *",
"sourceType": "script",
"sourceId": 3,
"enabled": true,
"pushoverEnabled": true
}
```
| Feld | Typ | Pflicht | Beschreibung |
|------|-----|---------|-------------|
| `name` | string | ✓ | Anzeigename |
| `cronExpression` | string | ✓ | 5-Felder-Cron-Ausdruck (Minute Stunde Tag Monat Wochentag) |
| `sourceType` | string | ✓ | `"script"` oder `"chain"` |
| `sourceId` | number | ✓ | ID des Skripts bzw. der Kette |
| `enabled` | boolean | | Aktiviert (default: `true`) |
| `pushoverEnabled` | boolean | | PushOver-Benachrichtigung nach Ausführung (default: `true`) |
**Antwort:** `201 Created`
```json
{ "job": { ... } }
```
---
### `GET /api/crons/:id`
Einzelnen Cron-Job abrufen.
**Antwort:**
```json
{ "job": { ... } }
```
---
### `PUT /api/crons/:id`
Cron-Job aktualisieren. Body-Felder entsprechen `POST /api/crons`.
**Antwort:**
```json
{ "job": { ... } }
```
---
### `DELETE /api/crons/:id`
Cron-Job löschen.
**Antwort:**
```json
{ "removed": { "id": 1 } }
```
---
### `GET /api/crons/:id/logs`
Ausführungs-Logs eines Cron-Jobs abrufen.
**Query-Parameter:**
| Parameter | Typ | Default | Beschreibung |
|-----------|-----|---------|-------------|
| `limit` | number | 20 | Anzahl Einträge (max. 100) |
**Antwort:**
```json
{
"logs": [
{
"id": 42,
"cronJobId": 1,
"startedAt": "2026-03-09T02:00:01.000Z",
"finishedAt": "2026-03-09T02:00:05.000Z",
"status": "success",
"exitCode": 0,
"stdout": "Backup abgeschlossen.",
"stderr": "",
"triggeredBy": "cron"
}
]
}
```
| Feld | Beschreibung |
|------|-------------|
| `status` | `"success"`, `"error"` oder `"running"` |
| `triggeredBy` | `"cron"` (zeitgesteuert) oder `"manual"` (manuell ausgelöst) |
---
### `POST /api/crons/:id/run`
Cron-Job sofort manuell auslösen (unabhängig vom Zeitplan).
**Antwort:**
```json
{
"status": "success",
"exitCode": 0,
"stdout": "...",
"stderr": ""
}
```
---
### `POST /api/crons/validate-expression`
Cron-Ausdruck validieren und nächsten Ausführungszeitpunkt berechnen.
**Body:**
```json
{ "cronExpression": "*/15 * * * *" }
```
**Antwort (gültig):**
```json
{
"valid": true,
"nextRunAt": "2026-03-09T14:15:00.000Z"
}
```
**Antwort (ungültig):**
```json
{
"valid": false,
"error": "Cron-Ausdruck muss genau 5 Felder haben (Minute Stunde Tag Monat Wochentag).",
"nextRunAt": null
}
```
---
## Cron-Expression-Format
Ripster verwendet **5-Felder-Cron-Ausdrücke** (kein Sekunden-Feld):
```
┌───────────── Minute (0-59)
│ ┌────────── Stunde (0-23)
│ │ ┌─────── Tag (1-31)
│ │ │ ┌──── Monat (1-12)
│ │ │ │ ┌─ Wochentag (0-7, 0 und 7 = Sonntag)
│ │ │ │ │
* * * * *
```
### Beispiele
| Ausdruck | Beschreibung |
|----------|-------------|
| `0 2 * * *` | Täglich um 02:00 Uhr |
| `*/15 * * * *` | Alle 15 Minuten |
| `0 6 * * 1-5` | MontagFreitag um 06:00 Uhr |
| `30 23 * * 0` | Sonntags um 23:30 Uhr |
| `0 0 1 * *` | Erster Tag des Monats um Mitternacht |
### Unterstützte Syntax
| Syntax | Bedeutung |
|--------|----------|
| `*` | Jeder Wert |
| `*/n` | Jeder n-te Wert (Step) |
| `a-b` | Bereich von a bis b |
| `a,b,c` | Liste von Werten |
| Kombinierbar | z. B. `1,5-10,*/3` |
---
## WebSocket-Event
Bei Änderungen an Cron-Jobs (Anlegen, Aktualisieren, Löschen) wird ein `CRON_JOBS_UPDATED`-Event gesendet:
```json
{
"type": "CRON_JOBS_UPDATED",
"payload": {
"action": "created",
"id": 1
}
}
```
`action` ist `"created"`, `"updated"` oder `"deleted"`.

View File

@@ -42,6 +42,14 @@ Konfigurierbar über die Umgebungsvariable `PORT`.
[:octicons-arrow-right-24: History API](history.md)
- :material-clock-outline: **Cron API**
---
Cron-Jobs verwalten, manuell auslösen und Ausführungs-Logs abrufen.
[:octicons-arrow-right-24: Cron API](crons.md)
- :material-lightning-bolt: **WebSocket Events**
---

View File

@@ -113,12 +113,19 @@ Disc erkannt.
"payload": {
"device": {
"path": "/dev/sr0",
"discLabel": "INCEPTION"
"discLabel": "INCEPTION",
"label": "INCEPTION",
"model": "ASUS BW-16D1HT",
"fstype": "udf",
"mountpoint": null,
"mediaProfile": "bluray"
}
}
}
```
`mediaProfile` ist `"bluray"`, `"dvd"`, `"other"` oder `null` (wenn nicht bestimmbar). Der Wert wird aus Dateisystemtyp (UDF/ISO9660), Laufwerk-Modell und Disc-Label abgeleitet.
### DISC_REMOVED
Disc entfernt.
@@ -160,6 +167,22 @@ Fehler im Laufwerkserkennungsdienst.
}
```
### CRON_JOBS_UPDATED
Wird gesendet, wenn ein Cron-Job angelegt, aktualisiert oder gelöscht wurde.
```json
{
"type": "CRON_JOBS_UPDATED",
"payload": {
"action": "created",
"id": 1
}
}
```
`action` ist `"created"`, `"updated"` oder `"deleted"`.
---
## Reconnect-Verhalten

View File

@@ -7,11 +7,15 @@ Ripster verwendet **SQLite3** als Datenbank. Die Datenbankdatei liegt unter `bac
## Schema-Übersicht
```sql
-- Vier Haupt-Tabellen
settings_schema -- Einstellungs-Definitionen
settings_values -- Benutzer-Werte
jobs -- Rip-Job-Datensätze
pipeline_state -- Aktueller Pipeline-Zustand (Singleton)
scripts -- Shell-Skripte für Pre-/Post-Encode-Ausführung
script_chains -- Geordnete Ketten aus mehreren Skripten
script_chain_steps -- Einzelschritte einer Skript-Kette
cron_jobs -- Zeitgesteuerte Aufgaben (eigener Cron-Parser)
cron_run_logs -- Ausführungs-Protokolle für Cron-Jobs
```
---
@@ -22,27 +26,31 @@ Die wichtigste Tabelle speichert alle Ripping-Jobs.
```sql
CREATE TABLE jobs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL, -- Aktueller Status
title TEXT, -- Filmtitel (von OMDb)
imdb_id TEXT, -- IMDb-ID
omdb_year TEXT, -- Erscheinungsjahr
omdb_type TEXT, -- movie/series
omdb_poster TEXT, -- Poster-URL
raw_path TEXT, -- Pfad zur Raw-MKV
output_path TEXT, -- Pfad zur Ausgabedatei
playlist TEXT, -- Gewählte Blu-ray Playlist
makemkv_output TEXT, -- MakeMKV-Ausgabe (JSON)
mediainfo_output TEXT, -- MediaInfo-Ausgabe (JSON)
encode_plan TEXT, -- Encode-Plan (JSON)
handbrake_log TEXT, -- HandBrake Log-Pfad
error_message TEXT, -- Fehlermeldung bei ERROR
error_details TEXT -- Detaillierte Fehler-Infos
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL, -- Aktueller Status
title TEXT, -- Filmtitel (von OMDb)
imdb_id TEXT, -- IMDb-ID
omdb_year TEXT, -- Erscheinungsjahr
omdb_type TEXT, -- movie/series
omdb_poster TEXT, -- Poster-URL
raw_path TEXT, -- Pfad zur Raw-MKV
output_path TEXT, -- Pfad zur Ausgabedatei
playlist TEXT, -- Gewählte Blu-ray Playlist
rip_successful INTEGER NOT NULL DEFAULT 0, -- 1 wenn Rip abgeschlossen
makemkv_output TEXT, -- MakeMKV-Ausgabe (JSON)
mediainfo_output TEXT, -- MediaInfo-Ausgabe (JSON)
encode_plan TEXT, -- Encode-Plan (JSON)
handbrake_log TEXT, -- HandBrake Log-Pfad
error_message TEXT, -- Fehlermeldung bei ERROR
error_details TEXT -- Detaillierte Fehler-Infos
);
```
!!! info "rip_successful"
Das Feld `rip_successful` wird auf `1` gesetzt, sobald MakeMKV den Rip-Schritt erfolgreich abgeschlossen hat unabhängig davon, ob danach ein Encode-Fehler auftritt. Damit lässt sich in der History unterscheiden, ob eine Raw-Datei vorhanden ist.
### Job-Status-Werte
| Status | Beschreibung |
@@ -111,6 +119,87 @@ CREATE TABLE settings_values (
---
## Tabelle: scripts
Verwaltet Shell-Skripte, die vor oder nach dem Encode-Schritt ausgeführt werden können.
```sql
CREATE TABLE scripts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
script_body TEXT NOT NULL,
order_index INTEGER NOT NULL DEFAULT 0, -- Sortierposition in der UI
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```
## Tabelle: script_chains
Geordnete Ketten, die mehrere Skripte sequenziell zusammenfassen.
```sql
CREATE TABLE script_chains (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
order_index INTEGER NOT NULL DEFAULT 0, -- Sortierposition in der UI
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE script_chain_steps (
id INTEGER PRIMARY KEY AUTOINCREMENT,
chain_id INTEGER NOT NULL REFERENCES script_chains(id) ON DELETE CASCADE,
script_id INTEGER NOT NULL REFERENCES scripts(id) ON DELETE CASCADE,
step_order INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```
!!! info "Sortierung"
`order_index` in `scripts` und `script_chains` wird über die API (`reorderScripts` / `reorderChains`) per Drag & Drop in der UI gesetzt und bleibt persistent gespeichert.
---
## Tabellen: cron_jobs & cron_run_logs
Speichern den Zeitplan und die Ausführungs-Historie des eingebauten Cron-Systems.
```sql
CREATE TABLE cron_jobs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
cron_expression TEXT NOT NULL, -- 5-Felder-Ausdruck (min h d m wd)
source_type TEXT NOT NULL, -- "script" oder "chain"
source_id INTEGER NOT NULL, -- ID des Skripts/der Kette
enabled INTEGER NOT NULL DEFAULT 1,
pushover_enabled INTEGER NOT NULL DEFAULT 1,
last_run_at TEXT,
last_run_status TEXT, -- "success", "error", "running"
next_run_at TEXT,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE cron_run_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
cron_job_id INTEGER NOT NULL REFERENCES cron_jobs(id) ON DELETE CASCADE,
started_at TEXT NOT NULL,
finished_at TEXT,
status TEXT NOT NULL, -- "success", "error", "running"
exit_code INTEGER,
stdout TEXT,
stderr TEXT,
triggered_by TEXT NOT NULL DEFAULT 'cron', -- "cron" oder "manual"
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```
!!! info "Log-Rotation"
Pro Cron-Job werden maximal **50 Log-Einträge** gespeichert; ältere Einträge werden automatisch gelöscht. Stdout/Stderr werden auf **100.000 Zeichen** begrenzt.
---
## Schema-Migrationen
`database.js` implementiert **automatische Migrationen**:
@@ -126,7 +215,7 @@ Falls die Datenbankdatei korrupt ist:
```
1. Korrupte Datei wird erkannt (Verbindungsfehler / Integritätsprüfung)
2. Datei wird in /backend/data/quarantine/ verschoben
2. Datei wird in backend/data/corrupt-backups/ verschoben
3. Neue, leere Datenbank wird erstellt
4. Schema wird neu initialisiert
5. Log-Eintrag mit Warnung

View File

@@ -1,34 +1,34 @@
# Post-Encode-Skripte
# Encode-Skripte (Pre & Post)
Post-Encode-Skripte ermöglichen es, nach erfolgreichem Encoding automatisch beliebige Shell-Befehle oder Programme auszuführen z. B. zum Verschieben von Dateien, Benachrichtigen externer Dienste oder Auslösen weiterer Verarbeitungsschritte.
Ripster unterstützt **Pre-Encode-** und **Post-Encode-Ausführungen**: Beliebige Shell-Skripte oder Skript-Ketten können automatisch vor und/oder nach dem Encoding-Schritt laufen z. B. zum Vorbereiten von Verzeichnissen, Verschieben von Dateien oder Benachrichtigen externer Dienste.
---
## Funktionsweise
Nach einem erfolgreich abgeschlossenen Encoding-Schritt führt Ripster die konfigurierten Skripte **sequenziell** in der festgelegten Reihenfolge aus:
```
ENCODING abgeschlossen
READY_TO_ENCODE
Skript 1 ausführen ← Fehler? → Abbruch
[Pre-Encode-Ausführungen] ← Fehler? → Abbruch
Skript/Kette 1, 2, …
Skript 2 ausführen ← Fehler? → Abbruch
ENCODING
...
[Post-Encode-Ausführungen] ← Fehler? → Abbruch
Skript/Kette 1, 2, …
FINISHED
```
!!! warning "Abbruch bei Fehler"
Schlägt ein Skript fehl (Exit-Code ≠ 0), werden alle nachfolgenden Skripte **nicht mehr ausgeführt**.
Der Job bleibt im Abschlusszustand `FINISHED`; der Fehler wird in Log/Status-Text und im `postEncodeScripts`-Summary festgehalten.
Schlägt eine Ausführung fehl (Exit-Code ≠ 0), werden alle nachfolgenden Ausführungen der gleichen Phase **nicht mehr ausgeführt**.
Der Job bleibt im Abschlusszustand `FINISHED`; der Fehler wird in Log/Status-Text und im Summary festgehalten.
---
## Skript-Verwaltung
## Skript- und Ketten-Verwaltung
Skripte werden über die **Einstellungen-Seite** angelegt und verwaltet. Sie stehen danach in jedem Encode-Review zur Auswahl.
Skripte und Skript-Ketten werden über die **Einstellungen-Seite** angelegt und verwaltet. Die Reihenfolge in der Liste kann per **Drag & Drop** geändert werden und bleibt persistent gespeichert.
### Skript anlegen
@@ -40,6 +40,10 @@ Navigiere zu **Einstellungen → Skripte** und klicke **"Neues Skript"**:
| **Befehl** | Shell-Befehl oder Skriptpfad (z. B. `/home/michael/scripts/move-to-plex.sh`) |
| **Beschreibung** | Optionale Erklärung |
### Skript-Ketten
Eine **Skript-Kette** fasst mehrere Skripte zu einer benannten Einheit zusammen, die als ganzes ausgewählt werden kann. Nützlich für wiederkehrende Kombinationen (z. B. „Move + Notify Plex + Webhook"). Ketten werden genauso wie einzelne Skripte im Review-Panel ausgewählt.
### Verfügbare Umgebungsvariablen
Jedes Skript wird mit folgenden Umgebungsvariablen aufgerufen:
@@ -78,26 +82,35 @@ curl -s -X POST https://mein-webhook.example.com/ripster \
---
## Skript im Encode-Review auswählen
## Im Encode-Review auswählen
Im `READY_TO_ENCODE`-Zustand zeigt das **MediaInfoReviewPanel** einen Skript-Abschnitt:
Im `READY_TO_ENCODE`-Zustand zeigt das **MediaInfoReviewPanel** zwei Abschnitte:
```
┌──────────────────────────────────────────────────────────┐
│ Post-Encode-Skripte
│ Pre-Encode Ausführungen (optional)
├──────────────────────────────────────────────────────────┤
Ausgewählte Skripte (Reihenfolge per Drag & Drop):
│ ≡ 1. Zu Plex verschieben [Entfernen]│
│ ≡ 2. Webhook auslösen [Entfernen]│
≡ 1. Verzeichnis vorbereiten (Skript) [Entfernen]
├──────────────────────────────────────────────────────────┤
Skript hinzufügen: [Zu Jellyfin verschieben ▾] [+ Hinzuf.]│
Hinzufügen: [Skript/Kette auswählen ▾] [+ Hinzuf.]│
└──────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Post-Encode Ausführungen (optional) │
├──────────────────────────────────────────────────────────┤
│ ≡ 1. Zu Plex verschieben (Skript) [Entfernen]│
│ ≡ 2. Notify-Kette (Kette) [Entfernen]│
├──────────────────────────────────────────────────────────┤
│ Hinzufügen: [Skript/Kette auswählen ▾] [+ Hinzuf.]│
└──────────────────────────────────────────────────────────┘
```
- **Reihenfolge** per Drag & Drop ändern
- **Hinzufügen** aus der Dropdown-Liste aller konfigurierten Skripte
- **Entfernen** einzelner Skripte aus der aktuellen Auswahl
- Skripte können pro Job unterschiedlich gewählt werden
- **Pre-Encode** und **Post-Encode** werden separat konfiguriert
- Sowohl **einzelne Skripte** als auch **Skript-Ketten** können in beiden Phasen ausgewählt werden
- **Reihenfolge** per Drag & Drop innerhalb jeder Phase ändern
- **Hinzufügen** aus der Dropdown-Liste aller konfigurierten Skripte und Ketten
- **Entfernen** einzelner Einträge
- Auswahl kann pro Job frei variiert werden
---

View File

@@ -183,6 +183,25 @@ install_makemkv() {
warn "Beta-Key: https://www.makemkv.com/forum/viewtopic.php?t=1053"
}
remove_all_handbrake() {
info "Entferne alle vorhandenen HandBrake-Installationen..."
apt-get remove -y handbrake-cli handbrake 2>/dev/null || true
snap remove handbrake-cli 2>/dev/null || true
rm -f /usr/bin/HandBrakeCLI \
/usr/local/bin/HandBrakeCLI \
/snap/bin/handbrake-cli \
/snap/bin/HandBrakeCLI
while true; do
local found
found=$(command -v HandBrakeCLI 2>/dev/null || true)
[[ -z "$found" ]] && break
warn "Entferne: $found"
rm -f "$found"
done
hash -r 2>/dev/null || true
ok "Alte HandBrake-Installation(en) entfernt"
}
build_handbrake_nvdec() {
header "HandBrake ${HANDBRAKE_VERSION} mit NVDEC aus Quellcode bauen"
@@ -191,6 +210,9 @@ build_handbrake_nvdec() {
local src_url="https://github.com/HandBrake/HandBrake/releases/download/${HANDBRAKE_VERSION}/HandBrake-${HANDBRAKE_VERSION}-source.tar.bz2"
local tarball="${tmp_dir}/handbrake-src.tar.bz2"
# Alte Installationen vollständig entfernen
remove_all_handbrake
# Build-Abhängigkeiten
info "Installiere Build-Abhängigkeiten..."
apt-get install -y \
@@ -220,14 +242,6 @@ build_handbrake_nvdec() {
fi
ok "Build-Abhängigkeiten installiert"
# Alte Installation entfernen
if command_exists HandBrakeCLI; then
warn "Entferne vorhandenes HandBrakeCLI..."
apt-get remove -y handbrake-cli 2>/dev/null || true
snap remove handbrake-cli 2>/dev/null || true
rm -f /usr/bin/HandBrakeCLI /usr/local/bin/HandBrakeCLI
fi
# Quellcode herunterladen
info "Lade HandBrake ${HANDBRAKE_VERSION} herunter..."
curl -fsSL "$src_url" -o "$tarball" 2>/dev/null || \

View File

@@ -188,6 +188,29 @@ install_makemkv() {
warn "Beta-Key: https://www.makemkv.com/forum/viewtopic.php?t=1053"
}
remove_all_handbrake() {
info "Entferne alle vorhandenen HandBrake-Installationen..."
# apt
apt-get remove -y handbrake-cli handbrake 2>/dev/null || true
# snap
snap remove handbrake-cli 2>/dev/null || true
# bekannte Binär-Pfade
rm -f /usr/bin/HandBrakeCLI \
/usr/local/bin/HandBrakeCLI \
/snap/bin/handbrake-cli \
/snap/bin/HandBrakeCLI
# alle weiteren Fundstellen über PATH
while true; do
local found
found=$(command -v HandBrakeCLI 2>/dev/null || true)
[[ -z "$found" ]] && break
warn "Entferne: $found"
rm -f "$found"
done
hash -r 2>/dev/null || true
ok "Alte HandBrake-Installation(en) entfernt"
}
build_handbrake_nvdec() {
header "HandBrake ${HANDBRAKE_VERSION} mit NVDEC aus Quellcode bauen"
@@ -196,6 +219,9 @@ build_handbrake_nvdec() {
local src_url="https://github.com/HandBrake/HandBrake/releases/download/${HANDBRAKE_VERSION}/HandBrake-${HANDBRAKE_VERSION}-source.tar.bz2"
local tarball="${tmp_dir}/handbrake-src.tar.bz2"
# Alte Installationen vollständig entfernen
remove_all_handbrake
# Build-Abhängigkeiten
info "Installiere Build-Abhängigkeiten..."
apt-get install -y \
@@ -213,7 +239,6 @@ build_handbrake_nvdec() {
if ! dpkg -l 2>/dev/null | grep -q '^ii.*nvidia-cuda-toolkit'; then
apt-get install -y nvidia-cuda-toolkit >/dev/null 2>&1 || {
warn "nvidia-cuda-toolkit nicht verfügbar versuche Fallback-Header..."
# Fallback: nur die minimalen Header aus dem NVIDIA-CUDA-Repo
local cuda_keyring="/tmp/cuda-keyring.deb"
local ubuntu_ver="${VERSION_ID//./}"
curl -fsSL "https://developer.download.nvidia.com/compute/cuda/repos/ubuntu${ubuntu_ver}/x86_64/cuda-keyring_1.1-1_all.deb" \
@@ -226,14 +251,6 @@ build_handbrake_nvdec() {
fi
ok "Build-Abhängigkeiten installiert"
# Alte Installation entfernen
if command_exists HandBrakeCLI; then
warn "Entferne vorhandenes HandBrakeCLI..."
apt-get remove -y handbrake-cli 2>/dev/null || true
snap remove handbrake-cli 2>/dev/null || true
rm -f /usr/bin/HandBrakeCLI /usr/local/bin/HandBrakeCLI
fi
# Quellcode herunterladen
info "Lade HandBrake ${HANDBRAKE_VERSION} herunter..."
curl -fsSL "$src_url" -o "$tarball" 2>/dev/null || \

View File

@@ -62,12 +62,13 @@ nav:
- Workflow & Zustände: pipeline/workflow.md
- Encode-Planung & Track-Auswahl: pipeline/encoding.md
- Playlist-Analyse: pipeline/playlist-analysis.md
- Post-Encode-Skripte: pipeline/post-encode-scripts.md
- Encode-Skripte (Pre & Post): pipeline/post-encode-scripts.md
- API-Referenz:
- api/index.md
- Pipeline API: api/pipeline.md
- Settings API: api/settings.md
- History API: api/history.md
- Cron API: api/crons.md
- WebSocket Events: api/websocket.md
- Konfiguration:
- configuration/index.md