Directory: chips by kind and category over a grid of cover art
Feeds take their channel's first <itunes:category> into a new feeds.category column; the migration drops ETag and Last-Modified once so every feed re-reads on its normal schedule and picks one up. /api/popular and /api/directory carry category and podcast (any audio or video enclosure). Directory becomes a grid of cover-art tiles under a chip rail: All, Podcasts, Blogs, and a podcast's categories once Podcasts is picked. Popular and Add a feed keep their rows. Closes #4, closes #5, closes #6, closes #7. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
10
src/feed.rs
10
src/feed.rs
@@ -11,6 +11,8 @@ pub struct ParsedFeed {
|
||||
pub title: Option<String>,
|
||||
pub ttl_mins: Option<u64>,
|
||||
pub image: Option<String>,
|
||||
/// The channel's first `<itunes:category>`, for the Directory's chips.
|
||||
pub category: Option<String>,
|
||||
pub entries: Vec<Entry>,
|
||||
}
|
||||
|
||||
@@ -535,6 +537,12 @@ fn from_rss(ch: rss::Channel, bytes: &[u8]) -> ParsedFeed {
|
||||
.and_then(|i| i.image())
|
||||
.map(str::to_owned)
|
||||
.or_else(|| ch.image().map(|i| i.url().to_owned())),
|
||||
// Only the iTunes one: Apple's list is fixed, while a plain <category> is freeform and
|
||||
// would fill the Directory with one-off tags. The top level only, for the same reason.
|
||||
category: ch
|
||||
.itunes_ext()
|
||||
.and_then(|i| i.categories().first())
|
||||
.and_then(|c| non_empty(Some(c.text().trim()))),
|
||||
entries,
|
||||
}
|
||||
}
|
||||
@@ -591,6 +599,7 @@ fn from_atom(feed: atom_syndication::Feed) -> ParsedFeed {
|
||||
title: non_empty(Some(feed.title().as_str())),
|
||||
ttl_mins: None,
|
||||
image: feed.logo().or_else(|| feed.icon()).map(str::to_owned),
|
||||
category: None,
|
||||
entries,
|
||||
}
|
||||
}
|
||||
@@ -708,6 +717,7 @@ mod tests {
|
||||
|
||||
assert_eq!(feed.title.as_deref(), Some("Test Cast"));
|
||||
assert_eq!(feed.ttl_mins, Some(45));
|
||||
assert_eq!(feed.category.as_deref(), Some("Technology"), "the first, top level only");
|
||||
assert_eq!(feed.entries.len(), 3);
|
||||
|
||||
let ep = &feed.entries[0];
|
||||
|
||||
Reference in New Issue
Block a user