Skip to content

Commit

Permalink
Support sub-categories from iTunes NS
Browse files Browse the repository at this point in the history
iTunes defines nested subcategories. These are now extracted into a
nested 'subcategories' field on Category.
  • Loading branch information
markpritchard committed Apr 25, 2024
1 parent 36c5dea commit 62d533c
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 3 deletions.
63 changes: 63 additions & 0 deletions feed-rs/fixture/rss2/rss_2.0_anchorfm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
xmlns:anchor="https://anchor.fm/xmlns">
<channel>
<title><![CDATA[It’s Not Always Special ]]></title>
<description>
<![CDATA[This is a podcast about families who have a special needs child. We will talk about what it is to be a parent, sibling and friend. We will also explore what is wrong with the system of care we currently have and where we can do better. We will also introduce new and groundbreaking programs and services you may not be aware of. ]]></description>
<link>https://podcasters.spotify.com/pod/show/lisa-mccoy</link>
<image>
<url>
https://d3t3ozftmdmh3i.cloudfront.net/production/podcast_uploaded/23591441/23591441-1649013735716-25c2d16df92e8.jpg
</url>
<title>It’s Not Always Special</title>
<link>https://podcasters.spotify.com/pod/show/lisa-mccoy</link>
</image>
<generator>Anchor Podcasts</generator>
<lastBuildDate>Fri, 23 Feb 2024 22:19:40 GMT</lastBuildDate>
<atom:link href="https://anchor.fm/s/8d364524/podcast/rss" rel="self" type="application/rss+xml"/>
<author><![CDATA[Lisa McCoy]]></author>
<copyright><![CDATA[Lisa McCoy]]></copyright>
<language><![CDATA[en]]></language>
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com/"/>
<itunes:author>Lisa McCoy</itunes:author>
<itunes:summary>This is a podcast about families who have a special needs child. We will talk about what it is
to be a parent, sibling and friend. We will also explore what is wrong with the system of care we currently
have and where we can do better. We will also introduce new and groundbreaking programs and services you may
not be aware of.
</itunes:summary>
<itunes:type>episodic</itunes:type>
<itunes:owner>
<itunes:name>Lisa McCoy</itunes:name>
<itunes:email>c2fn9prc85@privaterelay.appleid.com</itunes:email>
</itunes:owner>
<itunes:explicit>No</itunes:explicit>
<itunes:category text="Kids &amp; Family">
<itunes:category text="Parenting"/>
</itunes:category>
<itunes:image
href="https://d3t3ozftmdmh3i.cloudfront.net/production/podcast_uploaded/23591441/23591441-1649013735716-25c2d16df92e8.jpg"/>
<item>
<title><![CDATA[Advocating for our children ]]></title>
<description><![CDATA[Taking care of a child with special needs is more than what is considered traditional care. Learn more about advocacy!]]></description>
<link>https://podcasters.spotify.com/pod/show/lisa-mccoy/episodes/Advocating-for-our-children-e1oq9fb</link>
<guid isPermaLink="false">2fea9218-f154-47be-a501-0a78ea2f36f8</guid>
<dc:creator><![CDATA[Lisa McCoy]]></dc:creator>
<pubDate>Wed, 08 Feb 2023 20:34:49 GMT</pubDate>
<enclosure
url="https://anchor.fm/s/8d364524/podcast/play/58581931/https%3A%2F%2Fd3ctxlq1ktw2nl.cloudfront.net%2Fproduction%2Fexports%2F8d364524%2F58581931%2Fa48be9475fbbb5c00427f7e733079b03.m4a"
length="36030594" type="audio/x-m4a"/>
<itunes:summary>Taking care of a child with special needs is more than what is considered traditional care.
Learn more about advocacy!
</itunes:summary>
<itunes:explicit>No</itunes:explicit>
<itunes:duration>00:37:07</itunes:duration>
<itunes:image
href="https://d3t3ozftmdmh3i.cloudfront.net/production/podcast_uploaded/23591441/23591441-1649013735716-25c2d16df92e8.jpg"/>
<itunes:season>1</itunes:season>
<itunes:episode>7</itunes:episode>
<itunes:episodeType>full</itunes:episodeType>
</item>
</channel>
</rss>
3 changes: 3 additions & 0 deletions feed-rs/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,8 @@ pub struct Category {
pub scheme: Option<String>,
/// Atom (optional): Provides a human-readable label for display.
pub label: Option<String>,
/// Sub-categories (typically from the iTunes namespace i.e. https://help.apple.com/itc/podcasts_connect/#/itcb54353390)
pub subcategories: Vec<Category>,
}

impl Category {
Expand All @@ -427,6 +429,7 @@ impl Category {
term: term.trim().into(),
scheme: None,
label: None,
subcategories: Vec::new(),
}
}
}
Expand Down
23 changes: 20 additions & 3 deletions feed-rs/src/parser/itunes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub(crate) fn handle_itunes_channel_element<R: BufRead>(element: Element<R>, fee
}
}),

(NS::Itunes, "category") => if_some_then(handle_category(element), |category| feed.categories.push(category)),
(NS::Itunes, "category") => if_some_then(handle_category(element)?, |category| feed.categories.push(category)),

(NS::Itunes, "explicit") => if_some_then(handle_explicit(element), |rating| {
// Assign if not already set from media
Expand Down Expand Up @@ -61,8 +61,25 @@ fn handle_author<R: BufRead>(element: Element<R>) -> Option<MediaCredit> {
}

// Handles <itunes:category>
fn handle_category<R: BufRead>(element: Element<R>) -> Option<Category> {
element.attr_value("text").map(|text| Category::new(&text))
fn handle_category<R: BufRead>(element: Element<R>) -> ParseFeedResult<Option<Category>> {
Ok(if let Some(text) = element.attr_value("text") {
// Create a new category for this level
let mut category = Category::new(&text);

// Add any sub-categories
for child in element.children() {
let child = child?;
if child.ns_and_tag() == (NS::Itunes, "category") {
if let Some(subcat) = handle_category(child)? {
category.subcategories.push(subcat);
}
}
}

Some(category)
} else {
None
})
}

// Handles <itunes:duration>
Expand Down
13 changes: 13 additions & 0 deletions feed-rs/src/parser/rss2/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,3 +765,16 @@ fn test_custom_timestamp_parser() {
let entry = actual.entries.get(0).expect("feed has 1 entry");
assert_eq!(entry.published.unwrap(), Utc.with_ymd_and_hms(2023, 12, 16, 19, 2, 33).unwrap());
}

// Verifies we correctly extract subcategories from the iTunes NS
#[test]
fn test_subcategories() {
let test_data = test::fixture_as_string("rss2/rss_2.0_anchorfm.xml");
let actual = parser::parse(test_data.as_bytes()).unwrap();

let category = &actual.categories[0];
assert_eq!("Kids & Family", category.term.as_str());

let subcat = &category.subcategories[0];
assert_eq!("Parenting", subcat.term.as_str());
}

0 comments on commit 62d533c

Please sign in to comment.