0.14.0-4 Merger
This commit is contained in:
+75
-67
@@ -1,27 +1,31 @@
|
||||
# History API
|
||||
|
||||
Endpunkte für Job-Historie, Orphan-Import und Löschoperationen.
|
||||
Endpunkte für Job-Historie, Metadaten-Nachpflege, Orphan-Import und Löschoperationen.
|
||||
|
||||
---
|
||||
|
||||
## GET /api/history
|
||||
|
||||
Liefert Jobs (optionale Filter).
|
||||
Liefert Jobs mit optionalen Filtern.
|
||||
|
||||
**Query-Parameter:**
|
||||
|
||||
| Parameter | Typ | Beschreibung |
|
||||
|----------|-----|-------------|
|
||||
| `status` | string | Filter nach Job-Status |
|
||||
| `search` | string | Suche in Titel-Feldern |
|
||||
| `status` | string | Einzelstatus-Filter (legacy-kompatibel). |
|
||||
| `statuses` | string | Mehrfachstatus als CSV, z. B. `FINISHED,ERROR`. |
|
||||
| `search` | string | Suche in Titel-/IMDb-Feldern. |
|
||||
| `limit` | number | Maximale Anzahl Ergebnisse. |
|
||||
| `lite` | bool | Ohne Dateisystem-Checks (schneller). |
|
||||
| `includeChildren` | bool | Child-Jobs (z. B. Serien-/Multipart-Kinder) explizit einbeziehen. |
|
||||
|
||||
**Beispiel:**
|
||||
|
||||
```text
|
||||
GET /api/history?status=FINISHED&search=Inception
|
||||
GET /api/history?statuses=FINISHED,ERROR&search=Inception&limit=50&lite=1
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**Response (Beispiel):**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -30,6 +34,7 @@ GET /api/history?status=FINISHED&search=Inception
|
||||
"id": 42,
|
||||
"status": "FINISHED",
|
||||
"title": "Inception",
|
||||
"job_kind": "bluray",
|
||||
"raw_path": "/mnt/raw/Inception - RAW - job-42",
|
||||
"output_path": "/mnt/movies/Inception (2010)/Inception (2010).mkv",
|
||||
"mediaType": "bluray",
|
||||
@@ -52,12 +57,13 @@ Liefert Job-Detail.
|
||||
|
||||
| Parameter | Typ | Standard | Beschreibung |
|
||||
|----------|-----|---------|-------------|
|
||||
| `includeLogs` | bool | `false` | Prozesslog laden |
|
||||
| `includeLiveLog` | bool | `false` | alias-artig ebenfalls Prozesslog laden |
|
||||
| `includeAllLogs` | bool | `false` | vollständiges Log statt Tail |
|
||||
| `logTailLines` | number | `800` | Tail-Länge falls nicht `includeAllLogs` |
|
||||
| `includeLogs` | bool | `false` | Prozesslog laden. |
|
||||
| `includeLiveLog` | bool | `false` | Live-/Tail-Log laden. |
|
||||
| `includeAllLogs` | bool | `false` | vollständiges Log statt Tail. |
|
||||
| `logTailLines` | number | `800` | Tail-Länge falls nicht `includeAllLogs`. |
|
||||
| `lite` | bool | `false` | Detailantwort ohne FS-Checks. |
|
||||
|
||||
**Response:**
|
||||
**Response (Beispiel):**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -86,33 +92,9 @@ Liefert Job-Detail.
|
||||
|
||||
Sucht RAW-Ordner ohne zugehörigen Job.
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"rawDir": "/mnt/raw",
|
||||
"rawDirs": ["/mnt/raw", "/mnt/raw-bluray"],
|
||||
"rows": [
|
||||
{
|
||||
"rawPath": "/mnt/raw/Inception (2010) [tt1375666] - RAW - job-99",
|
||||
"folderName": "Inception (2010) [tt1375666] - RAW - job-99",
|
||||
"title": "Inception",
|
||||
"year": 2010,
|
||||
"imdbId": "tt1375666",
|
||||
"folderJobId": 99,
|
||||
"entryCount": 4,
|
||||
"hasBlurayStructure": true,
|
||||
"lastModifiedAt": "2026-03-10T09:00:00.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## POST /api/history/orphan-raw/import
|
||||
|
||||
Importiert RAW-Ordner als FINISHED-Job.
|
||||
Importiert einen RAW-Ordner als Job und triggert optional die Analyse des Imports.
|
||||
|
||||
**Request:**
|
||||
|
||||
@@ -120,12 +102,13 @@ Importiert RAW-Ordner als FINISHED-Job.
|
||||
{ "rawPath": "/mnt/raw/Inception (2010) [tt1375666] - RAW - job-99" }
|
||||
```
|
||||
|
||||
**Response:**
|
||||
**Response (Beispiel):**
|
||||
|
||||
```json
|
||||
{
|
||||
"job": { "id": 77, "status": "FINISHED" },
|
||||
"uiReset": { "reset": true, "state": "IDLE" }
|
||||
"activation": { "started": true },
|
||||
"activationError": null
|
||||
}
|
||||
```
|
||||
|
||||
@@ -133,26 +116,43 @@ Importiert RAW-Ordner als FINISHED-Job.
|
||||
|
||||
## POST /api/history/:id/omdb/assign
|
||||
|
||||
Weist OMDb-/Metadaten nachträglich zu.
|
||||
Weist OMDb-/Filmdaten nachträglich zu.
|
||||
|
||||
**Request:**
|
||||
## POST /api/history/:id/cd/assign
|
||||
|
||||
Weist CD-Metadaten (z. B. MusicBrainz) nachträglich zu.
|
||||
|
||||
## POST /api/history/:id/error/ack
|
||||
|
||||
Quittiert einen Fehlerzustand im Historieneintrag.
|
||||
|
||||
---
|
||||
|
||||
## GET /api/history/:id/delete-preview
|
||||
|
||||
Liefert eine Vorschau der löschbaren Pfade (inkl. Scope auf verknüpfte Jobs).
|
||||
|
||||
**Query-Parameter:**
|
||||
|
||||
| Parameter | Typ | Standard | Beschreibung |
|
||||
|----------|-----|---------|-------------|
|
||||
| `includeRelated` | bool | `true` | Verknüpfte Jobs in die Vorschau einbeziehen. |
|
||||
|
||||
**Response (Beispiel):**
|
||||
|
||||
```json
|
||||
{
|
||||
"imdbId": "tt1375666",
|
||||
"title": "Inception",
|
||||
"year": 2010,
|
||||
"poster": "https://...",
|
||||
"fromOmdb": true
|
||||
"preview": {
|
||||
"jobId": 42,
|
||||
"relatedJobs": [{ "id": 42 }, { "id": 73 }],
|
||||
"pathCandidates": {
|
||||
"raw": [{ "path": "/mnt/raw/...", "exists": true, "isDirectory": true }],
|
||||
"movie": [{ "path": "/mnt/movies/...", "exists": true, "isDirectory": true }]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{ "job": { "id": 42, "imdb_id": "tt1375666" } }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## POST /api/history/:id/delete-files
|
||||
@@ -162,23 +162,17 @@ Löscht Dateien eines Jobs, behält DB-Eintrag.
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{ "target": "both" }
|
||||
{
|
||||
"target": "both",
|
||||
"includeRelated": true,
|
||||
"selectedRawPaths": ["/mnt/raw/Inception - RAW - Disc1"],
|
||||
"selectedMoviePaths": ["/mnt/movies/Inception (2010)"]
|
||||
}
|
||||
```
|
||||
|
||||
`target`: `raw` | `movie` | `both`
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"summary": {
|
||||
"target": "both",
|
||||
"raw": { "attempted": true, "deleted": true, "filesDeleted": 12, "dirsRemoved": 3, "reason": null },
|
||||
"movie": { "attempted": true, "deleted": false, "filesDeleted": 0, "dirsRemoved": 0, "reason": "Movie-Datei/Pfad existiert nicht." }
|
||||
},
|
||||
"job": { "id": 42 }
|
||||
}
|
||||
```
|
||||
`selectedRawPaths` / `selectedMoviePaths` sind optional und begrenzen die Löschung auf ausgewählte Pfade aus der Vorschau.
|
||||
|
||||
---
|
||||
|
||||
@@ -189,12 +183,20 @@ Löscht Job aus DB; optional auch Dateien.
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{ "target": "none" }
|
||||
{
|
||||
"target": "both",
|
||||
"includeRelated": true,
|
||||
"resetDriveState": false,
|
||||
"keepDetectedDevice": true,
|
||||
"preserveRawForImportJobs": false,
|
||||
"selectedRawPaths": ["/mnt/raw/Inception - RAW - Disc1"],
|
||||
"selectedMoviePaths": ["/mnt/movies/Inception (2010)"]
|
||||
}
|
||||
```
|
||||
|
||||
`target`: `none` | `raw` | `movie` | `both`
|
||||
|
||||
**Response:**
|
||||
**Response (Beispiel):**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -209,6 +211,11 @@ Löscht Job aus DB; optional auch Dateien.
|
||||
"uiReset": {
|
||||
"reset": true,
|
||||
"state": "IDLE"
|
||||
},
|
||||
"safeguards": {
|
||||
"containsOrphanRawImportJob": false,
|
||||
"resetDriveStateApplied": false,
|
||||
"keepDetectedDeviceApplied": true
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -218,4 +225,5 @@ Löscht Job aus DB; optional auch Dateien.
|
||||
## Hinweise
|
||||
|
||||
- Ein aktiver Pipeline-Job kann nicht gelöscht werden (`409`).
|
||||
- Alle Löschoperationen sind irreversibel.
|
||||
- Löschoperationen sind irreversibel.
|
||||
- Bei Serien-/Multipart-Containern steuern `includeRelated` und Pfadselektionen den genauen Scope.
|
||||
|
||||
+166
-1
@@ -95,6 +95,18 @@ Erzwingt erneute Laufwerksprüfung.
|
||||
|
||||
---
|
||||
|
||||
## POST /api/pipeline/rescan-drive
|
||||
|
||||
Erzwingt Rescan für ein konkretes Laufwerk.
|
||||
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{ "devicePath": "/dev/sr0" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## GET /api/pipeline/omdb/search?q=<query>
|
||||
|
||||
OMDb-Titelsuche.
|
||||
@@ -117,6 +129,78 @@ OMDb-Titelsuche.
|
||||
|
||||
---
|
||||
|
||||
## GET /api/pipeline/tmdb/series/search?q=<query>&season=<n>
|
||||
|
||||
TMDb-Seriensuche (für Serien-Workflow bei DVD/Blu-ray).
|
||||
|
||||
---
|
||||
|
||||
## GET /api/pipeline/cd/drives
|
||||
|
||||
Liefert Snapshot der aktuell bekannten CD-Laufwerke.
|
||||
|
||||
---
|
||||
|
||||
## GET /api/pipeline/cd/musicbrainz/search?q=<query>
|
||||
|
||||
MusicBrainz-Suche für CD-Metadaten.
|
||||
|
||||
## GET /api/pipeline/cd/musicbrainz/release/:mbId
|
||||
|
||||
Lädt Release-Details zu einer MusicBrainz-ID.
|
||||
|
||||
## POST /api/pipeline/cd/select-metadata
|
||||
|
||||
Übernimmt CD-Metadaten für einen Job.
|
||||
|
||||
**Request (Beispiel):**
|
||||
|
||||
```json
|
||||
{
|
||||
"jobId": 91,
|
||||
"title": "Album",
|
||||
"artist": "Artist",
|
||||
"year": 2020,
|
||||
"mbId": "f5093c06-23e3-404f-aeaa-40f72885ee3a",
|
||||
"coverUrl": "https://...",
|
||||
"tracks": []
|
||||
}
|
||||
```
|
||||
|
||||
## POST /api/pipeline/cd/start/:jobId
|
||||
|
||||
Startet/queued CD-Rip mit Format-/Script-/Chain-Konfiguration.
|
||||
|
||||
---
|
||||
|
||||
## POST /api/pipeline/audiobook/upload
|
||||
|
||||
Upload von AAX-Datei (Multipart/FormData).
|
||||
|
||||
**FormData-Felder:**
|
||||
|
||||
- `file` (Pflicht)
|
||||
- `format` (optional)
|
||||
- `startImmediately` (optional)
|
||||
|
||||
## GET /api/pipeline/audiobook/pending-activation
|
||||
|
||||
Zeigt AAX-Jobs mit fehlenden Activation-Bytes.
|
||||
|
||||
## POST /api/pipeline/audiobook/start/:jobId
|
||||
|
||||
Startet Audiobook-Job mit optionaler Konfiguration.
|
||||
|
||||
## GET /api/pipeline/audiobook/jobs
|
||||
|
||||
Liefert Audiobook-Jobliste.
|
||||
|
||||
## GET /api/pipeline/audiobook/output-tree
|
||||
|
||||
Read-only Baumansicht des Audiobook-Ausgabeordners.
|
||||
|
||||
---
|
||||
|
||||
## POST /api/pipeline/select-metadata
|
||||
|
||||
Setzt Metadaten (und optional Playlist) für einen Job.
|
||||
@@ -135,12 +219,69 @@ Setzt Metadaten (und optional Playlist) für einen Job.
|
||||
}
|
||||
```
|
||||
|
||||
Wichtige optionale Felder:
|
||||
|
||||
- `selectedHandBrakeTitleId` / `selectedHandBrakeTitleIds`: Titel-Auswahl für Review/MediaInfo.
|
||||
- `metadataProvider`: `omdb` oder `tmdb`.
|
||||
- `workflowKind`: bei Disc-Jobs typischerweise `film` oder `series`.
|
||||
- `discNumber`: Pflicht für Serien-Disc-Zuordnung (`workflowKind=series`).
|
||||
- `duplicateAction`: Duplikatverhalten bei Film-Metadaten (`allow_new` oder `multipart_movie`).
|
||||
- `existingJobId`: optionaler Referenzjob für `multipart_movie`.
|
||||
- `existingDiscNumber`: Disc-Nummer des bestehenden Jobs für `multipart_movie`.
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{ "job": { "id": 42, "status": "READY_TO_START" } }
|
||||
```
|
||||
|
||||
**Konflikt-Response (Beispiel, HTTP 409):**
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Metadaten bereits in der Historie gefunden. Bitte Auswahl übernehmen oder Multipart movie wählen.",
|
||||
"details": [
|
||||
{
|
||||
"code": "METADATA_DUPLICATE_FOUND",
|
||||
"mediaProfile": "bluray",
|
||||
"existingJob": {
|
||||
"id": 17,
|
||||
"title": "Inception",
|
||||
"year": 2010,
|
||||
"status": "FINISHED",
|
||||
"jobKind": "bluray",
|
||||
"discNumber": 1,
|
||||
"isMultipartMovie": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Relevante Fehlercodes (`POST /api/pipeline/select-metadata`):**
|
||||
|
||||
| Code | Bedeutung |
|
||||
|---|---|
|
||||
| `METADATA_DUPLICATE_FOUND` | Film-Metadaten existieren bereits in der Historie (Konfliktdialog im UI). |
|
||||
| `MULTIPART_DISC_REQUIRED` | Für Multipart fehlen Disc-Nummern (`discNumber`/`existingDiscNumber`). |
|
||||
| `MULTIPART_DISC_ALREADY_EXISTS` | Disc-Nummer im Multipart-Container bereits vergeben oder doppelt. |
|
||||
| `MULTIPART_MEDIA_MISMATCH` | Multipart nur bei gleichem Medientyp (DVD oder Blu-ray). |
|
||||
| `MULTIPART_SERIES_NOT_ALLOWED` | Multipart ist nur für Film-Jobs erlaubt, nicht für Serien-Workflow. |
|
||||
| `MULTIPART_METADATA_MISMATCH` | Ausgewählter bestehender Job passt nicht zu den Film-Metadaten. |
|
||||
| `SERIES_DISC_ALREADY_EXISTS` | Serien-Disc-Nummer innerhalb einer Staffel bereits vorhanden. |
|
||||
|
||||
---
|
||||
|
||||
## POST /api/pipeline/jobs/:jobId/raw-decision
|
||||
|
||||
Trifft Entscheidung bei vorhandenem RAW (`continue` oder `restart` je nach Dialogfluss).
|
||||
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{ "decision": "continue" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## POST /api/pipeline/start/:jobId
|
||||
@@ -233,10 +374,28 @@ Berechnet Review aus RAW neu.
|
||||
|
||||
Startet Encoding mit letzter bestätigter Review neu.
|
||||
|
||||
## POST /api/pipeline/restart-cd-review/:jobId
|
||||
|
||||
Berechnet CD-Review aus vorhandenem RAW neu.
|
||||
|
||||
## POST /api/pipeline/resume-ready/:jobId
|
||||
|
||||
Lädt `READY_TO_ENCODE`-Job nach Neustart wieder in aktive Session.
|
||||
|
||||
## GET /api/pipeline/output-folders/:jobId
|
||||
|
||||
Liefert bekannte Output-Ordner entlang der Job-Lineage.
|
||||
|
||||
## POST /api/pipeline/delete-output-folders/:jobId
|
||||
|
||||
Löscht ausgewählte Output-Ordner.
|
||||
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{ "folderPaths": ["/mnt/movies/Inception (2010)"] }
|
||||
```
|
||||
|
||||
Alle Endpunkte liefern `{ result: ... }` bzw. `{ job: ... }`.
|
||||
|
||||
---
|
||||
@@ -358,12 +517,18 @@ Entfernt Queue-Eintrag.
|
||||
| `DISC_DETECTED` | Medium erkannt |
|
||||
| `ANALYZING` | MakeMKV-Analyse läuft |
|
||||
| `METADATA_SELECTION` | Metadaten-Auswahl |
|
||||
| `WAITING_FOR_USER_DECISION` | Playlist-Entscheidung erforderlich |
|
||||
| `WAITING_FOR_USER_DECISION` | Nutzerentscheidung erforderlich (Playlist-Auswahl oder RAW-Entscheidung) |
|
||||
| `READY_TO_START` | Übergang vor Start |
|
||||
| `RIPPING` | MakeMKV-Rip läuft |
|
||||
| `MEDIAINFO_CHECK` | Titel-/Track-Auswertung |
|
||||
| `READY_TO_ENCODE` | Review bereit |
|
||||
| `ENCODING` | HandBrake-Encoding läuft |
|
||||
| `CD_METADATA_SELECTION` | CD-Metadatenauswahl aktiv |
|
||||
| `CD_READY_TO_RIP` | CD-Job ist startbereit |
|
||||
| `CD_ANALYZING` | CD-Struktur/Tracks werden vorbereitet |
|
||||
| `CD_RIPPING` | CD-Ripping läuft |
|
||||
| `CD_ENCODING` | CD-Encode läuft |
|
||||
| `FINISHED` | Abgeschlossen |
|
||||
| `DONE` | Abgeschlossen (v. a. Audiobook/Converter/CD-Varianten) |
|
||||
| `CANCELLED` | Abgebrochen |
|
||||
| `ERROR` | Fehler |
|
||||
|
||||
@@ -105,7 +105,7 @@ Alle Aktivitäts-Endpunkte geben einen Snapshot zurück:
|
||||
|
||||
## Endpunkte
|
||||
|
||||
### GET `/api/activities`
|
||||
### GET `/api/runtime/activities`
|
||||
|
||||
Aktuellen Aktivitäts-Snapshot abrufen.
|
||||
|
||||
@@ -136,7 +136,7 @@ Aktuellen Aktivitäts-Snapshot abrufen.
|
||||
|
||||
---
|
||||
|
||||
### POST `/api/activities/:id/cancel`
|
||||
### POST `/api/runtime/activities/:id/cancel`
|
||||
|
||||
Aktive Aktivität abbrechen (nur wenn `canCancel: true`).
|
||||
|
||||
@@ -172,7 +172,7 @@ Aktive Aktivität abbrechen (nur wenn `canCancel: true`).
|
||||
|
||||
---
|
||||
|
||||
### POST `/api/activities/:id/next-step`
|
||||
### POST `/api/runtime/activities/:id/next-step`
|
||||
|
||||
Nächsten Schritt einer Aktivität auslösen (nur wenn `canNextStep: true`).
|
||||
|
||||
@@ -201,7 +201,7 @@ Nächsten Schritt einer Aktivität auslösen (nur wenn `canNextStep: true`).
|
||||
|
||||
---
|
||||
|
||||
### POST `/api/activities/clear-recent`
|
||||
### POST `/api/runtime/activities/clear-recent`
|
||||
|
||||
Alle abgeschlossenen Aktivitäten aus `recent` löschen.
|
||||
|
||||
@@ -232,4 +232,4 @@ Gekürzte Ausgaben erhalten den Suffix ` ...[gekürzt]` (bei Inline-Text) bzw. `
|
||||
|
||||
## Echtzeit-Updates
|
||||
|
||||
Änderungen werden automatisch als [`RUNTIME_ACTIVITY_CHANGED`](websocket.md#runtime_activity_changed) WebSocket-Event gesendet. Die Frontend-Komponente braucht `GET /api/activities` nur beim initialen Laden aufzurufen.
|
||||
Änderungen werden automatisch als [`RUNTIME_ACTIVITY_CHANGED`](websocket.md#runtime_activity_changed) WebSocket-Event gesendet. Die Frontend-Komponente braucht `GET /api/runtime/activities` nur beim initialen Laden aufzurufen.
|
||||
|
||||
@@ -336,3 +336,89 @@ Body mit beliebigen Feldern aus `POST`, Response `{ "preset": { ... } }`.
|
||||
### DELETE /api/settings/user-presets/:id
|
||||
|
||||
Response `{ "removed": { ... } }`.
|
||||
|
||||
---
|
||||
|
||||
## Weitere Endpunkte
|
||||
|
||||
### GET /api/settings/effective-paths
|
||||
|
||||
Liefert aufgelöste, effektiv genutzte Pfade aus den Settings (für UI- und Diagnosezwecke).
|
||||
|
||||
### POST /api/settings/coverart/recover
|
||||
|
||||
Startet eine manuelle Coverart-Recovery.
|
||||
|
||||
**Response (Beispiel):**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": { "started": true },
|
||||
"scheduler": { "enabled": true }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Activation Bytes (AAX)
|
||||
|
||||
### GET /api/settings/activation-bytes
|
||||
|
||||
Liest gecachte AAX-Activation-Bytes.
|
||||
|
||||
### POST /api/settings/activation-bytes
|
||||
|
||||
Speichert Activation-Bytes.
|
||||
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{
|
||||
"checksum": "abc123...",
|
||||
"activationBytes": "1a2b3c4d"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Laufwerke
|
||||
|
||||
### GET /api/settings/drives
|
||||
|
||||
Liefert erkannte optische Laufwerke (`/dev/...`) inkl. MakeMKV-Disc-Index.
|
||||
|
||||
### POST /api/settings/drives/force-unlock
|
||||
|
||||
Erzwingt Entsperren aktiver Laufwerkslocks.
|
||||
|
||||
Hinweis: Expertenmodus (`ui_expert_mode`) ist erforderlich, sonst `403`.
|
||||
|
||||
**Request (ein Laufwerk):**
|
||||
|
||||
```json
|
||||
{ "devicePath": "/dev/sr0" }
|
||||
```
|
||||
|
||||
**Request (alle):**
|
||||
|
||||
```json
|
||||
{ "all": true }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## UI Preferences
|
||||
|
||||
### GET /api/settings/prefs/:key
|
||||
|
||||
Liest einen persistierten UI-Preference-Wert.
|
||||
|
||||
### PUT /api/settings/prefs/:key
|
||||
|
||||
Speichert einen persistierten UI-Preference-Wert.
|
||||
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{ "value": "{\"columns\":[\"id\",\"status\"]}" }
|
||||
```
|
||||
|
||||
@@ -38,9 +38,25 @@ Zentrale Felder:
|
||||
- Tool-Ausgaben: `makemkv_info_json`, `handbrake_info_json`, `mediainfo_info_json`, `encode_plan_json`
|
||||
- Kontrolle: `encode_review_confirmed`, `rip_successful`, `error_message`
|
||||
- Medientyp: `media_type` (`bluray|dvd|cd|audiobook|converter`)
|
||||
- Job-Typ/Beziehung: `job_kind`, `parent_job_id`
|
||||
- Multipart-/Disc-Merkmale: `is_multipart_movie`, `disc_number`, `metadata_fingerprint`
|
||||
- Prüfsumme: `aax_checksum` (für AAX-Dateien)
|
||||
- Audit: `created_at`, `updated_at`
|
||||
|
||||
Typische `job_kind`-Werte:
|
||||
|
||||
- Standard: `bluray`, `dvd`, `cd`, `audiobook`, `converter_audio`, `converter_video`, `converter_iso`
|
||||
- Serien: `dvd_series_container`, `dvd_series_child`
|
||||
- Multipart Film: `multipart_movie_container`, `multipart_movie_child`
|
||||
|
||||
Wichtige Indizes:
|
||||
|
||||
- `idx_jobs_status`
|
||||
- `idx_jobs_parent_job_id`
|
||||
- `idx_jobs_job_kind`
|
||||
- `idx_jobs_disc_number`
|
||||
- `idx_jobs_metadata_fingerprint`
|
||||
|
||||
---
|
||||
|
||||
## `job_lineage_artifacts`
|
||||
@@ -180,6 +196,7 @@ sqlite3 backend/data/ripster.db
|
||||
|
||||
.mode table
|
||||
SELECT id, status, title, media_type, created_at FROM jobs ORDER BY created_at DESC;
|
||||
SELECT id, parent_job_id, job_kind, is_multipart_movie, disc_number FROM jobs ORDER BY created_at DESC;
|
||||
SELECT key, value FROM settings_values ORDER BY key;
|
||||
SELECT checksum, activation_bytes FROM aax_activation_bytes;
|
||||
SELECT rel_path, job_id FROM converter_scan_entries;
|
||||
|
||||
@@ -6,6 +6,14 @@ Frontend: React + PrimeReact + Vite.
|
||||
|
||||
## Hauptseiten
|
||||
|
||||
### `JobsInboxPage.jsx`
|
||||
|
||||
Zentrale Job-Inbox:
|
||||
|
||||
- einheitliche Liste über Ripper-, Converter- und Audiobook-Jobs
|
||||
- View-/Status-Filter, Suche, Paginierung
|
||||
- Schnellsprung in passende Detailseite (`Ripper`/`Converter`)
|
||||
|
||||
### `RipperPage.jsx`
|
||||
|
||||
Pipeline-Steuerung:
|
||||
@@ -49,6 +57,14 @@ Datei-Converter:
|
||||
- Job-Start, Abbruch, Löschung
|
||||
- Automatischer Scan-Status
|
||||
|
||||
### `AudiobooksPage.jsx`
|
||||
|
||||
Dedizierter AAX-/Audiobook-Flow:
|
||||
|
||||
- Upload-Panel für AAX-Dateien
|
||||
- aktive Audiobook-Jobkarten mit Start/Cancel/Retry/Delete
|
||||
- Audiobook-Konfigurationspanel und Output-Explorer
|
||||
|
||||
### `DownloadsPage.jsx`
|
||||
|
||||
Download-Queue:
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# Audiobooks
|
||||
|
||||
Die Seite `Audiobooks` ist die dedizierte Oberfläche für AAX- und Audiobook-Jobs.
|
||||
|
||||
---
|
||||
|
||||
## Aufbau
|
||||
|
||||
1. `Audiobooks Upload`
|
||||
2. `Audiobook Jobs`
|
||||
3. `Audiobook Output Explorer`
|
||||
|
||||
---
|
||||
|
||||
## 1) Audiobooks Upload
|
||||
|
||||
Hier werden AAX-Dateien hochgeladen und als Job vorbereitet.
|
||||
|
||||
Typische Schritte:
|
||||
|
||||
1. Datei auswählen
|
||||
2. optional Format/Startverhalten setzen
|
||||
3. Upload starten
|
||||
|
||||
Während des Uploads zeigt die Seite Fortschritt und Status an.
|
||||
|
||||
---
|
||||
|
||||
## 2) Audiobook Jobs
|
||||
|
||||
Aktive Audiobook-Jobs werden als Karten dargestellt (mit Status und Fortschritt).
|
||||
|
||||
Pro Job sind je nach Zustand Aktionen verfügbar:
|
||||
|
||||
- Starten (mit aktueller Audiobook-Konfiguration)
|
||||
- Abbrechen
|
||||
- Retry
|
||||
- Löschen
|
||||
|
||||
Zusätzlich:
|
||||
|
||||
- `Im Ripper` springt in die Hauptansicht
|
||||
- Jobs laden periodisch nach und reagieren auf WebSocket-Updates
|
||||
|
||||
---
|
||||
|
||||
## 3) Audiobook Output Explorer
|
||||
|
||||
Read-only Baumansicht des konfigurierten Audiobook-Ausgabeordners:
|
||||
|
||||
- Ordner- und Dateiansicht
|
||||
- Größen-/Zeitstempelübersicht
|
||||
- schnelle Kontrolle der erzeugten Ergebnisse
|
||||
|
||||
---
|
||||
|
||||
## Abgrenzung zum Converter
|
||||
|
||||
Audio/Video-Datei-Konvertierung läuft weiterhin auf der Seite `Converter`.
|
||||
Der AAX-spezifische Flow (Upload, Start, Jobsteuerung, Output-Explorer) liegt auf `Audiobooks`.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Converter
|
||||
|
||||
Die Converter-Seite ermöglicht das Konvertieren vorhandener Audio- und Video-Dateien sowie das Verarbeiten von Audiobooks (AAX/M4B).
|
||||
Die Converter-Seite ermöglicht das Konvertieren vorhandener Audio- und Video-Dateien.
|
||||
|
||||
---
|
||||
|
||||
@@ -65,15 +65,9 @@ Das Scan-Intervall wird unter `Converter > Polling-Intervall (Sekunden)` konfigu
|
||||
|
||||
---
|
||||
|
||||
## Audiobook-Verarbeitung
|
||||
## Hinweis zu Audiobooks
|
||||
|
||||
Für AAX-Dateien (Audible) ist folgendes erforderlich:
|
||||
|
||||
1. AAX-Datei in den Eingangsordner hochladen
|
||||
2. Job mit Medientyp `Audiobook` erstellen
|
||||
3. Activation Bytes müssen verfügbar sein (werden beim ersten Mal abgefragt und gecacht)
|
||||
4. Ausgabeformat wählen: M4B (empfohlen), MP3 oder FLAC
|
||||
5. Kapitel-Splitting konfigurieren (optional)
|
||||
Der dedizierte AAX-/Audiobook-Flow ist auf der Seite [Audiobooks](audiobooks.md) dokumentiert.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@ Bereiche:
|
||||
- strukturierte JSON-Blöcke (OMDb/MakeMKV/MediaInfo/EncodePlan/HandBrake)
|
||||
- Log-Ladefunktionen (`Tail`, `Vollständig`)
|
||||
|
||||
Bei Serien-Containern zeigt der Dialog statt eines globalen Log-Blocks einen `Disks`-Bereich mit einzelnen Disk-Akkordeons.
|
||||
Jede Disk kann dort separat geprüft und bearbeitet werden.
|
||||
|
||||
## Typische Aktionen im Detaildialog
|
||||
|
||||
- `OMDb neu zuordnen`
|
||||
@@ -46,6 +49,12 @@ Bereiche:
|
||||
- `Historieneintrag löschen`
|
||||
- bei Queue-Lock: `Aus Queue löschen`
|
||||
|
||||
Zusätzlich bei Serien-Container-Disks:
|
||||
|
||||
- `Im Ripper öffnen` (für `READY_TO_ENCODE`-Kinder)
|
||||
- diskbezogene Löschaktionen (`RAW`, `Folgen`, `Beides`) mit Child-/Subjob-Scope
|
||||
- diskbezogenes Löschen des Historieneintrags (inkl. Subjobs)
|
||||
|
||||
## Wann welche Aktion?
|
||||
|
||||
| Ziel | Aktion |
|
||||
@@ -56,6 +65,23 @@ Bereiche:
|
||||
| aus vorhandenem RAW erneut encodieren | `RAW neu encodieren` |
|
||||
| Speicher freigeben | Dateilöschaktionen |
|
||||
|
||||
---
|
||||
|
||||
## Löschen mit Vorschau
|
||||
|
||||
Beim Löschen eines Historieneintrags (`Eintrag löschen`) gibt es eine Pfadvorschau:
|
||||
|
||||
- getrennt nach `RAW` und Ausgabe (`Movie`/`Folgen`)
|
||||
- für Serien-/Multipart-Fälle mit Scope auf verknüpfte Jobs
|
||||
- selektierbare Pfade vor dem finalen Löschen
|
||||
|
||||
Neu im RAW-Bereich:
|
||||
|
||||
- bei mehreren RAW-Kandidaten kann pro Pfad gewählt werden, was entfernt wird
|
||||
- mindestens ein RAW-Pfad muss gewählt sein, wenn RAW-Löschung Teil der Aktion ist
|
||||
|
||||
Die Buttons (`Eintrag + nur RAW`, `Eintrag + nur ...`, `Eintrag + RAW + ...`) berücksichtigen die aktuelle Pfadauswahl und deaktivieren sich bei unvollständiger Auswahl.
|
||||
|
||||
## Logs
|
||||
|
||||
- `Tail laden (800)` für schnelle Fehleranalyse
|
||||
|
||||
+12
-8
@@ -1,12 +1,14 @@
|
||||
# GUI-Seiten
|
||||
|
||||
Ripster hat fünf Hauptseiten in der Navigation plus eine Expert-Seite.
|
||||
Ripster hat sieben Hauptseiten in der Navigation plus eine Expert-Seite.
|
||||
|
||||
## Seitenüberblick
|
||||
|
||||
| Seite | Zweck |
|
||||
|---|---|
|
||||
| [Jobs](jobs.md) | zentrale Inbox mit allen Jobs (Ripper, Converter, Audiobooks) |
|
||||
| [Ripper](ripper.md) | Live-Betrieb: Pipeline, Queue, Aktivitäten, Disc-Infos |
|
||||
| [Audiobooks](audiobooks.md) | AAX-Upload, Audiobook-Jobsteuerung und Output-Explorer |
|
||||
| [Settings](settings.md) | Konfiguration, Skripte, Ketten, Presets, Cronjobs |
|
||||
| [Historie](history.md) | abgeschlossene/laufende Jobs durchsuchen und nachbearbeiten |
|
||||
| [Converter](converter.md) | Audio/Video-Dateien konvertieren, Datei-Explorer, Upload |
|
||||
@@ -15,14 +17,16 @@ Ripster hat fünf Hauptseiten in der Navigation plus eine Expert-Seite.
|
||||
|
||||
## Empfohlene Nutzung im Alltag
|
||||
|
||||
1. **Start eines neuen Disc-Jobs:** `Ripper`
|
||||
2. **Dateien konvertieren oder Audiobooks verarbeiten:** `Converter`
|
||||
3. **Regeln/Automatisierung anpassen:** `Settings`
|
||||
4. **Ergebnisse prüfen oder Jobs nachbearbeiten:** `Historie`
|
||||
5. **Dateien herunterladen:** `Downloads`
|
||||
6. **Sonderfälle/Recovery:** `Database`
|
||||
1. **Ersten Überblick über alle Jobs:** `Jobs`
|
||||
2. **Start eines neuen Disc-Jobs:** `Ripper`
|
||||
3. **Audio/Video-Dateien konvertieren:** `Converter`
|
||||
4. **AAX/Audiobook-Flow:** `Audiobooks`
|
||||
5. **Regeln/Automatisierung anpassen:** `Settings`
|
||||
6. **Ergebnisse prüfen oder Jobs nachbearbeiten:** `Historie`
|
||||
7. **Dateien herunterladen:** `Downloads`
|
||||
8. **Sonderfälle/Recovery:** `Database`
|
||||
|
||||
## Hinweise zur Navigation
|
||||
|
||||
- `Ripper`, `Settings`, `Historie`, `Converter` und `Downloads` sind direkt in der Kopfnavigation.
|
||||
- `Jobs`, `Ripper`, `Converter`, `Audiobooks`, `Settings`, `Historie` und `Downloads` sind direkt in der Kopfnavigation.
|
||||
- `Database` ist als Expert-Route verfügbar: `/database`.
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# Jobs
|
||||
|
||||
Die Seite `Jobs` ist die zentrale Inbox über alle Job-Typen.
|
||||
|
||||
---
|
||||
|
||||
## Zweck
|
||||
|
||||
`Jobs` zeigt denselben Datenbestand in einer einheitlichen Liste:
|
||||
|
||||
- Ripper-Jobs (Blu-ray/DVD/CD)
|
||||
- Converter-Jobs (Audio/Video/ISO)
|
||||
- Audiobook-Jobs
|
||||
|
||||
Die Seite eignet sich als schneller Einstieg, bevor man in den jeweiligen Fachbereich springt.
|
||||
|
||||
---
|
||||
|
||||
## Filter und Ansicht
|
||||
|
||||
### View-Filter
|
||||
|
||||
- `Alle Jobs`
|
||||
- `Ripper-View`
|
||||
- `Converter-View`
|
||||
- `Audiobooks`
|
||||
|
||||
### Status-Filter
|
||||
|
||||
- `Alle`
|
||||
- `Aktiv`
|
||||
- `Fehler/Abbruch`
|
||||
|
||||
Zusätzlich gibt es eine Freitextsuche (Titel, Status, IMDb, Job-Kind etc.) und eine Paginierung.
|
||||
|
||||
---
|
||||
|
||||
## Was ein Eintrag zeigt
|
||||
|
||||
- Job-ID und Titel
|
||||
- Status-Badge (inkl. Queue-Berücksichtigung)
|
||||
- Job-Typ-Badge (z. B. Blu-ray, Converter Audio, Audiobook)
|
||||
- Zeitstempel der letzten Aktualisierung
|
||||
|
||||
Die Liste aktualisiert sich zyklisch automatisch.
|
||||
|
||||
---
|
||||
|
||||
## Aktion
|
||||
|
||||
Pro Eintrag gibt es einen Schnellzugriff:
|
||||
|
||||
- `Im Ripper öffnen` für Disc-/Audiobook-orientierte Jobs
|
||||
- `Im Converter öffnen` für Converter-Jobs
|
||||
|
||||
So gelangst du mit einem Klick in die passende Detailoberfläche.
|
||||
@@ -65,6 +65,12 @@ Mögliche Aktionen:
|
||||
|
||||
Kompakte Jobliste mit Status, Fortschritt, ETA. Klick auf einen Job klappt die Detailsteuerung auf.
|
||||
|
||||
Zusätzliche Kennzeichnungen in der Liste:
|
||||
|
||||
- `Serien-Container`/`Serien-Disk` für Staffel-Workflows
|
||||
- `Multipart Movie` bei zusammengeführten Film-Discs
|
||||
- Untertitel mit Disc-/Container-Infos (z. B. `Disc 2 | Container #123`)
|
||||
|
||||
Im aufgeklappten Zustand erscheint die Karte `Pipeline-Status` mit allen zustandsabhängigen Aktionen.
|
||||
|
||||
### Zustandsabhängige Hauptaktionen
|
||||
@@ -105,6 +111,10 @@ Aktionen:
|
||||
- `Disk neu analysieren`
|
||||
- `Metadaten-Modal öffnen`
|
||||
|
||||
Hinweis:
|
||||
|
||||
- `Laufwerk neu lesen` ist nicht mehr an einen festen Pipeline-State gebunden und kann genutzt werden, solange kein Rescan-Request läuft.
|
||||
|
||||
---
|
||||
|
||||
## Wichtige Dialoge im Ripper
|
||||
@@ -115,6 +125,12 @@ Aktionen:
|
||||
- manuelle Eingabe als Fallback
|
||||
- `Auswahl übernehmen` startet den nächsten Pipeline-Schritt
|
||||
|
||||
Bei Film-Duplikaten in der Historie öffnet sich ein Konfliktdialog:
|
||||
|
||||
- `Übernahme erzwingen`: legt trotzdem einen neuen Job mit denselben Metadaten an
|
||||
- `Multipart movie`: verknüpft bestehenden und neuen Job in einem Multipart-Container (mit separaten Disc-Nummern)
|
||||
- `Zurück zur Auswahl`: zurück in die Metadatenliste
|
||||
|
||||
### Abbruch-Bereinigung
|
||||
|
||||
Nach Abbruch kann Ripster optional fragen, ob erzeugte RAW- oder Movie-Dateien gelöscht werden sollen.
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Dieses Dokumentationsset ist als **Benutzerhandbuch** aufgebaut: erst Bedienung
|
||||
|
||||
- **Benutzerhandbuch**
|
||||
- Installation
|
||||
- GUI-Seiten im Detail (`Ripper`, `Settings`, `Historie`, `Database`)
|
||||
- GUI-Seiten im Detail (`Jobs`, `Ripper`, `Converter`, `Audiobooks`, `Settings`, `Historie`, `Downloads`, `Database`)
|
||||
- typische Arbeitsabläufe aus Anwendersicht
|
||||
- **Technischer Anhang**
|
||||
- vollständige Einstellungsreferenz
|
||||
|
||||
@@ -35,11 +35,17 @@ flowchart LR
|
||||
| `Analyse` | MakeMKV-Analyse läuft |
|
||||
| `Metadatenauswahl` | Metadaten müssen bestätigt werden |
|
||||
| `Warte auf Auswahl` | Playlist-Auswahl ist erforderlich |
|
||||
| `Warte auf Auswahl` | auch für RAW-Entscheidung bei vorhandenen Quelldaten genutzt |
|
||||
| `Startbereit` | kurzer Übergang vor Start |
|
||||
| `Rippen` | MakeMKV-Rip läuft |
|
||||
| `Mediainfo-Pruefung` | Titel/Spuren werden ausgewertet |
|
||||
| `Bereit zum Encodieren` | Review ist bereit |
|
||||
| `Encodieren` | HandBrake läuft |
|
||||
| `CD-Metadatenauswahl` | CD-Metadaten müssen bestätigt werden |
|
||||
| `CD-Startbereit` | CD-Job wartet auf Start |
|
||||
| `CD-Analyse` | CD-Track-/Strukturaufbereitung |
|
||||
| `CD-Rippen` | Audio-CD-Rip läuft |
|
||||
| `CD-Encodieren` | CD-Encode läuft |
|
||||
| `Fertig` | erfolgreich abgeschlossen |
|
||||
| `Abgebrochen` | manuell oder technisch abgebrochen |
|
||||
| `Fehler` | fehlgeschlagen |
|
||||
@@ -66,6 +72,14 @@ flowchart LR
|
||||
|
||||
`Mediainfo-Pruefung` -> `Warte auf Auswahl` bis Playlist bestätigt wurde.
|
||||
|
||||
### Vorhandenes RAW mit Nutzerentscheidung
|
||||
|
||||
`Metadatenauswahl` -> `Warte auf Auswahl` bis Entscheidung für Weiterverarbeitung (`continue`) oder Neustart getroffen wurde.
|
||||
|
||||
### CD-Flow
|
||||
|
||||
`CD-Metadatenauswahl` -> `CD-Startbereit` -> `CD-Rippen` -> `CD-Encodieren` -> `Fertig`
|
||||
|
||||
---
|
||||
|
||||
## Queue-Verhalten
|
||||
|
||||
@@ -59,3 +59,26 @@ In `Historie` -> Detaildialog:
|
||||
- `/database` öffnen
|
||||
- Bereich `Gefundene RAW-Einträge`
|
||||
- `Job anlegen`
|
||||
|
||||
## Workflow 7: Duplikat als Multipart Movie zusammenführen
|
||||
|
||||
1. `Ripper` -> `Metadaten auswählen` für einen Film-Job
|
||||
2. bei Duplikat-Konflikt `Multipart movie` wählen
|
||||
3. Disc-Nummern für bestehenden und neuen Job setzen (jeweils >= 1, unterschiedlich)
|
||||
4. Metadaten übernehmen
|
||||
5. in `Historie` den gemeinsamen Multipart-Container prüfen
|
||||
|
||||
## Workflow 8: Selektives Löschen in der Historie
|
||||
|
||||
1. in `Historie` einen Job öffnen und `Historieneintrag löschen`
|
||||
2. Löschvorschau prüfen (`RAW` + Ausgabe)
|
||||
3. gewünschte RAW-/Ausgabepfade gezielt auswählen
|
||||
4. passende Aktion ausführen (`Eintrag + nur RAW`, `Eintrag + nur ...`, `Eintrag + RAW + ...`)
|
||||
|
||||
## Workflow 9: Audiobook (AAX) verarbeiten
|
||||
|
||||
1. Seite `Audiobooks` öffnen
|
||||
2. AAX-Datei hochladen
|
||||
3. Job-Konfiguration prüfen und starten
|
||||
4. Fortschritt im Job-Panel verfolgen
|
||||
5. Ergebnis im `Audiobook Output Explorer` und in der `Historie` prüfen
|
||||
|
||||
Reference in New Issue
Block a user