Record an episode that turns out to be a torrent, and run it off the worker (#155)
An enclosure advertised as audio whose body is a .torrent was handed to torrent_one from inside fetch_one, which returned without mark_downloaded, and in a scan nothing else recorded it. It stayed pending: the page never showed it downloaded, and every scan of its feed fetched the .torrent again and ran the torrent again, on the worker, for up to the stall limit and then the seeding time (30 and 60 minutes in production), with no other feed checked meanwhile. It now goes the way an advertised torrent does: in the daemon, marked downloading and handed to spawn_torrent, which records it when it finishes; in a one-off CLI run, run there and recorded. fetch_one answers None for the first, which a scan counts as a torrent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
26
src/main.rs
26
src/main.rs
@@ -1761,7 +1761,8 @@ async fn scan_one(
|
||||
continue;
|
||||
}
|
||||
match fetch_one(ctx, id, item.id, feed_cfg, &item.url, &dest_dir).await {
|
||||
Ok((path, bytes)) => {
|
||||
Ok(None) => scan.torrents += 1,
|
||||
Ok(Some((path, bytes))) => {
|
||||
ctx.out.emit(Event::DownloadDone {
|
||||
feed: id.to_string(),
|
||||
enclosure: item.id,
|
||||
@@ -1996,6 +1997,8 @@ fn merge_policy(subs: &[db::Sub], feed_cfg: &config::Feed, global: usize) -> Pol
|
||||
policy
|
||||
}
|
||||
|
||||
/// Downloads one file and records it. None when it turned out to be a torrent, handed off to run
|
||||
/// on its own, which records it when it finishes.
|
||||
#[tracing::instrument(name = "download", skip_all, fields(feed = feed_id, enclosure = enclosure, url = url))]
|
||||
async fn fetch_one(
|
||||
ctx: &Arc<Ctx>,
|
||||
@@ -2004,7 +2007,7 @@ async fn fetch_one(
|
||||
feed_cfg: &config::Feed,
|
||||
url: &str,
|
||||
dest_dir: &std::path::Path,
|
||||
) -> Result<(PathBuf, u64)> {
|
||||
) -> Result<Option<(PathBuf, u64)>> {
|
||||
// Throttled to whole percents, as the original's lastDLStepSize guard did.
|
||||
let mut last_pct = -1i64;
|
||||
let name = download::filename_for(url, None);
|
||||
@@ -2035,12 +2038,22 @@ async fn fetch_one(
|
||||
ctx.db.mark_enclosure(url, "skipped", Some("torrents disabled")).await?;
|
||||
anyhow::bail!("body is a torrent and torrents are disabled");
|
||||
}
|
||||
return torrent_one(ctx, feed_id, enclosure, url, dest_dir).await;
|
||||
// As one advertised as a torrent goes: off the worker where it can be, and recorded either
|
||||
// way. Run here and never recorded, it stayed pending, and every scan of its feed ran it
|
||||
// again, on the worker, for up to the stall limit and the seeding time (#155).
|
||||
if ctx.detach_torrents {
|
||||
ctx.db.mark_enclosure(url, "downloading", None).await?;
|
||||
spawn_torrent(ctx, feed_id.to_owned(), enclosure, url.to_owned(), dest_dir.to_owned());
|
||||
return Ok(None);
|
||||
}
|
||||
let (path, bytes) = torrent_one(ctx, feed_id, enclosure, url, dest_dir).await?;
|
||||
ctx.db.mark_downloaded(url, &path, bytes).await?;
|
||||
return Ok(Some((path, bytes)));
|
||||
}
|
||||
|
||||
let path = download::place(&got, dest_dir).await?;
|
||||
ctx.db.mark_downloaded(url, &path, got.bytes).await?;
|
||||
Ok((path, got.bytes))
|
||||
Ok(Some((path, got.bytes)))
|
||||
}
|
||||
|
||||
/// Runs a torrent off the command worker, so feed scans and HTTP downloads keep moving
|
||||
@@ -2114,14 +2127,15 @@ async fn download_one(ctx: &Arc<Ctx>, id: i64) -> Result<()> {
|
||||
if !cfg.torrent.enabled {
|
||||
Err(anyhow::anyhow!("torrents are disabled"))
|
||||
} else {
|
||||
torrent_one(ctx, &enc.feed_id, enc.id, &enc.url, &dest_dir).await
|
||||
torrent_one(ctx, &enc.feed_id, enc.id, &enc.url, &dest_dir).await.map(Some)
|
||||
}
|
||||
} else {
|
||||
fetch_one(ctx, &enc.feed_id, enc.id, feed_cfg, &enc.url, &dest_dir).await
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok((path, bytes)) => {
|
||||
Ok(None) => {} // A torrent after all, running on its own.
|
||||
Ok(Some((path, bytes))) => {
|
||||
ctx.db.mark_downloaded(&enc.url, &path, bytes).await?;
|
||||
ctx.out.emit(Event::DownloadDone {
|
||||
feed: enc.feed_id.clone(),
|
||||
|
||||
Reference in New Issue
Block a user