Skip to content

Commit bad2ed5

Browse files
committed
Detect RSS podcast media enclosures
1 parent 8f46915 commit bad2ed5

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

plugins/feed-discovery/src/feed-discovery.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,26 @@ describe("feed parsing", () => {
3636
expect(atom.ok).toBe(true);
3737
expect(json.ok).toBe(true);
3838
});
39+
40+
it("classifies RSS feeds with audio enclosures as podcasts", () => {
41+
const result = parseFeedDocument(
42+
"https://example.com/podcast.xml",
43+
`<?xml version="1.0"?>
44+
<rss version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
45+
<channel>
46+
<title>Example Podcast</title>
47+
<itunes:author>Example Host</itunes:author>
48+
<item>
49+
<title>Episode 1</title>
50+
<enclosure url="https://example.com/episode-1.mp3" type="audio/mpeg" />
51+
</item>
52+
</channel>
53+
</rss>`
54+
);
55+
56+
expect(result.ok).toBe(true);
57+
expect(result.kind).toBe("podcast");
58+
});
3959
});
4060

4161
describe("site probing helpers", () => {

plugins/feed-discovery/src/feed-parsing.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ function parseRss(feedUrl: string, rss: Record<string, unknown>): ValidationResu
9696
title: title || "Untitled RSS Feed",
9797
description: stringValue(channel.description),
9898
homepageUrl: linkValue(channel.link),
99-
kind: detectRssKind(channel),
99+
kind: detectRssKind(channel, items),
100100
language: stringValue(channel.language),
101101
imageUrl: imageValue(channel.image),
102102
lastPublishedAt: newestDate([stringValue(channel.lastBuildDate), stringValue(channel.pubDate), ...sampleItems.map((item) => item.publishedAt)]),
@@ -132,10 +132,21 @@ function parseAtom(feedUrl: string, feed: Record<string, unknown>): ValidationRe
132132
};
133133
}
134134

135-
function detectRssKind(channel: Record<string, unknown>): FeedKind {
135+
function detectRssKind(channel: Record<string, unknown>, items: Record<string, unknown>[]): FeedKind {
136136
if (channel.itunes || channel["itunes:author"] || channel.enclosure) {
137137
return "podcast";
138138
}
139+
const hasMediaEnclosure = items.some((item) =>
140+
asArray(item.enclosure)
141+
.filter(isRecord)
142+
.some((enclosure) => {
143+
const type = stringValue(enclosure.type)?.toLowerCase();
144+
return type?.startsWith("audio/") || type?.startsWith("video/");
145+
})
146+
);
147+
if (hasMediaEnclosure) {
148+
return "podcast";
149+
}
139150
return "blog";
140151
}
141152

0 commit comments

Comments
 (0)