mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 20:15:10 +00:00
feat(serve): relay service prompts from download jobs to the REST client
A job's input_prompt carries a service's request_input() prompt; the client answers it with POST /api/download/jobs/{job_id}/input.
This commit is contained in:
@@ -551,7 +551,8 @@ Show download jobs, with optional filtering and sorting.
|
||||
"segments_done": 120,
|
||||
"segments_total": 300,
|
||||
"speed": "5.2 MB/s",
|
||||
"skipped_subtitles": []
|
||||
"skipped_subtitles": [],
|
||||
"input_prompt": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -709,6 +710,36 @@ Move a queued job to the front of the download queue.
|
||||
| `404` | `JOB_NOT_FOUND` | No such job. |
|
||||
| `409` | `CONFLICT` | Job is not queued. |
|
||||
|
||||
### `POST /api/download/jobs/{job_id}/input`
|
||||
|
||||
Answer the prompt that a running job waits on. A service can ask for input during a job, for
|
||||
example an OTP code, a PIN, or a device-code confirmation. The job then shows the prompt in its
|
||||
`input_prompt` field and in its `progress` events. Show the prompt to the user and send the
|
||||
answer here.
|
||||
|
||||
=== "Request"
|
||||
|
||||
```json
|
||||
{ "response": "123456" }
|
||||
```
|
||||
|
||||
=== "Response `200`"
|
||||
|
||||
```json
|
||||
{ "status": "accepted" }
|
||||
```
|
||||
|
||||
| Status | Error code | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `200` | - | Answer sent to the job. The `input_prompt` field goes back to `null`. |
|
||||
| `400` | `INVALID_INPUT` | The body is not JSON, or it has no `response`. |
|
||||
| `404` | `JOB_NOT_FOUND` | No such job. |
|
||||
| `409` | `CONFLICT` | The job does not wait on a prompt. |
|
||||
|
||||
!!! warning
|
||||
The job keeps its download slot while it waits. It fails with `AUTH_FAILED` if nobody
|
||||
answers the prompt within 10 minutes.
|
||||
|
||||
---
|
||||
|
||||
## Server management
|
||||
|
||||
@@ -166,6 +166,7 @@ request and response in full.
|
||||
| `DELETE` | `/api/download/jobs/{job_id}` | Cancel a running job, or remove a finished one. |
|
||||
| `POST` | `/api/download/jobs/{job_id}/retry` | Re-queue a finished job's parameters as a new job. |
|
||||
| `POST` | `/api/download/jobs/{job_id}/priority` | Move a queued job to the front. |
|
||||
| `POST` | `/api/download/jobs/{job_id}/input` | Answer the prompt that a running job waits on. |
|
||||
|
||||
### History and server info
|
||||
|
||||
|
||||
@@ -162,6 +162,7 @@ full detail:
|
||||
| `segments_total` | number | Total segments for the track in progress. |
|
||||
| `speed` | string | Transfer speed of the track in progress, e.g. `4.20 MB/s`. |
|
||||
| `skipped_subtitles` | list | Subtitles that were skipped as non-fatal failures (when `skip_subtitle_errors` is set). |
|
||||
| `input_prompt` | string or `null` | The prompt the service waits on. Answer it with `POST /api/download/jobs/{job_id}/input`. |
|
||||
|
||||
The full detail adds `started_time`, `completed_time`, `output_files`, the redacted
|
||||
`parameters`, and, for failed jobs, `error_message`, `error_details`, `error_code`,
|
||||
@@ -364,6 +365,10 @@ Three temporary files bridge the parent and the job worker:
|
||||
- **`progress.json`**: the job worker writes it continuously as the download proceeds.
|
||||
- **`result.json`**: the job worker writes it at the end.
|
||||
|
||||
The job worker has no terminal. When a service asks the user for input, the job worker writes
|
||||
the prompt to `progress.json` as `input_prompt` and waits. The answer from
|
||||
`POST /api/download/jobs/{job_id}/input` goes to the job worker on its stdin.
|
||||
|
||||
Running each download out-of-process isolates the server from crashes, memory growth,
|
||||
and blocking work inside the download engine, and makes hard cancellation (killing the
|
||||
process) reliable.
|
||||
|
||||
Reference in New Issue
Block a user