Do not auto-download enclosures that are not audio or video
Blog feeds put each article's header image in an <enclosure>, so a text feed read as a podcast full of episodes: 149 images, 74 MB across 11 feeds. media_types defaults to audio and video, with a per-feed override. Such enclosures stay listed and stay downloadable by hand; the row names what it is rather than saying "skipped". An unknown type is allowed, since the real type is only known after downloading, and a torrent is allowed as a container judged once unpacked. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdXho5tTkjFLeUXKbEjKBh
This commit is contained in:
22
src/main.rs
22
src/main.rs
@@ -412,6 +412,7 @@ pub async fn add_one(
|
||||
url: url.to_owned(),
|
||||
folder: folder.clone(),
|
||||
group: None,
|
||||
media_types: None,
|
||||
schedule: None,
|
||||
keywords: keywords.clone(),
|
||||
allow_explicit: false,
|
||||
@@ -494,6 +495,7 @@ async fn import(ctx: &Ctx, config_path: &std::path::Path, file: &std::path::Path
|
||||
url,
|
||||
folder: None,
|
||||
group: None,
|
||||
media_types: None,
|
||||
schedule: None,
|
||||
keywords: vec![],
|
||||
allow_explicit: false,
|
||||
@@ -711,6 +713,7 @@ pub fn subscriptions(ctx: &Ctx) -> Result<Vec<Sub>> {
|
||||
url: m.url.clone(),
|
||||
folder: Some(format!("{base}/{title}")),
|
||||
group: Some(m.group_id.clone()),
|
||||
media_types: parent.and_then(|p| p.media_types.clone()),
|
||||
schedule: parent.and_then(|p| p.schedule.clone()),
|
||||
keywords: parent.map(|p| p.keywords.clone()).unwrap_or_default(),
|
||||
allow_explicit: parent.is_some_and(|p| p.allow_explicit),
|
||||
@@ -837,7 +840,7 @@ async fn scan_one(
|
||||
}
|
||||
// Filters run once, at discovery, and are recorded in `state`. The download
|
||||
// queue below is then just "everything still pending".
|
||||
if let Some(reason) = reject(feed_cfg, entry, &enc.url) {
|
||||
if let Some(reason) = reject(&ctx.cfg(), feed_cfg, entry, enc) {
|
||||
ctx.db.mark_enclosure(&enc.url, "skipped", Some(reason))?;
|
||||
}
|
||||
}
|
||||
@@ -991,10 +994,25 @@ async fn sync_opml(
|
||||
}
|
||||
|
||||
/// Why this enclosure should not be downloaded, if it should not be.
|
||||
fn reject(feed_cfg: &config::Feed, entry: &feed::Entry, url: &str) -> Option<&'static str> {
|
||||
fn reject(
|
||||
cfg: &config::Config,
|
||||
feed_cfg: &config::Feed,
|
||||
entry: &feed::Entry,
|
||||
enc: &feed::Enclosure,
|
||||
) -> Option<&'static str> {
|
||||
let url = enc.url.as_str();
|
||||
if !feed_cfg.auto_download {
|
||||
return Some("auto_download is off");
|
||||
}
|
||||
// Blog feeds put the article's header image in an <enclosure>; without this a text
|
||||
// feed reads as a podcast full of episodes and fills the disk with artwork.
|
||||
let wanted = feed_cfg
|
||||
.media_types
|
||||
.as_deref()
|
||||
.unwrap_or(&cfg.general.media_types);
|
||||
if !config::wanted_media(enc.mime.as_deref(), wanted) {
|
||||
return Some("not a wanted media type");
|
||||
}
|
||||
if entry.explicit && !feed_cfg.allow_explicit {
|
||||
return Some("explicit");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user