Make the UI's Download button download the episode you clicked

POST /api/enclosures/{id}/download requeued the row and asked for a
normal scan, but a scan takes the lowest-id pending rows up to
max_new_per_check. With a large backlog and a small cap the requested
row was never a candidate, so other episodes downloaded while it stayed
pending.

A queue expresses what is outstanding, not what was asked for. Download
is now its own command that fetches one specific enclosure immediately,
ignoring queue order and the per-scan cap, still via the single worker.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPyeapneuXrCdojsaiXGbe
This commit is contained in:
2026-09-10 01:11:12 +00:00
parent 74ec6e9281
commit 93b4815d84
4 changed files with 100 additions and 5 deletions

View File

@@ -343,8 +343,9 @@ async fn set_flags(
Ok(StatusCode::NO_CONTENT)
}
/// Puts one enclosure back in the queue and kicks a scan of its feed. The queue is the
/// table, so this is all it takes -- including for something a filter once skipped.
/// Downloads one enclosure now. This cannot be "requeue and scan": a scan takes the
/// lowest-id pending rows up to max_new_per_check, so with a big backlog it would download
/// other episodes and leave the requested one pending.
async fn download_now(
State(state): State<WebState>,
Path(id): Path<i64>,
@@ -358,10 +359,11 @@ async fn download_now(
return Ok(StatusCode::NO_CONTENT); // Already here.
}
state.ctx.db.requeue(id)?;
let _ = state
state
.cmds
.send(Command::Fetch { feed: Some(enc.feed_id), force: true })
.await;
.send(Command::Download { enclosure: id })
.await
.map_err(|_| anyhow::anyhow!("the daemon is not accepting commands"))?;
Ok(StatusCode::ACCEPTED)
}