Skip to content

Commit 67f38f8

Browse files
committed
complement itunes tag
per [official recommendation](https://help.apple.com/itc/podcasts_connect/#/itcb54353390)
1 parent d6f4906 commit 67f38f8

File tree

9 files changed

+195
-59
lines changed

9 files changed

+195
-59
lines changed

lib/domain/rss_item_itunes.dart

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,28 @@ import 'package:webfeed/util/helpers.dart';
22
import 'package:xml/xml.dart';
33

44
import 'rss_itunes_category.dart';
5+
import 'rss_itunes_episode_type.dart';
56
import 'rss_itunes_image.dart';
67

78
class RssItemItunes {
9+
final String title;
810
final int episode;
11+
final int season;
912
final Duration duration;
10-
final String episodeType;
13+
final RssItunesEpisodeType episodeType;
1114
final String author;
1215
final String summary;
1316
final bool explicit;
1417
final String subtitle;
1518
final List<String> keywords;
1619
final RssItunesImage image;
1720
final RssItunesCategory category;
21+
final bool block;
1822

1923
RssItemItunes({
24+
this.title,
2025
this.episode,
26+
this.season,
2127
this.duration,
2228
this.episodeType,
2329
this.author,
@@ -27,31 +33,32 @@ class RssItemItunes {
2733
this.keywords,
2834
this.image,
2935
this.category,
36+
this.block,
3037
});
3138

3239
factory RssItemItunes.parse(XmlElement element) {
3340
if (element == null) {
3441
return null;
3542
}
36-
var explicitStr =
37-
findElementOrNull(element, "itunes:explicit")?.text?.toLowerCase()?.trim();
3843
var episodeStr = findElementOrNull(element, "itunes:episode")?.text?.trim();
44+
var seasonStr = findElementOrNull(element, "itunes:season")?.text?.trim();
3945
var durationStr = findElementOrNull(element, "itunes:duration")?.text?.trim();
4046

4147
return RssItemItunes(
48+
title: findElementOrNull(element, "itunes:title")?.text?.trim(),
4249
episode: episodeStr == null ? null : int.parse(episodeStr),
50+
season: seasonStr == null ? null : int.parse(seasonStr),
4351
duration: durationStr == null ? null : parseDuration(durationStr),
44-
episodeType: findElementOrNull(element, "itunes:episodeType")?.text?.trim(),
52+
episodeType: newRssItunesEpisodeType(findElementOrNull(element, "itunes:episodeType")),
4553
author: findElementOrNull(element, "itunes:author")?.text?.trim(),
4654
summary: findElementOrNull(element, "itunes:summary")?.text?.trim(),
47-
explicit: explicitStr == null
48-
? null
49-
: explicitStr == "yes" || explicitStr == "true",
55+
explicit: parseBoolLiteral(element, "itunes:explicit"),
5056
subtitle: findElementOrNull(element, "itunes:subtitle")?.text?.trim(),
5157
keywords: findElementOrNull(element, "itunes:keywords")?.text?.split(",")?.map((keyword) => keyword.trim())?.toList(),
5258
image: RssItunesImage.parse(findElementOrNull(element, "itunes:image")),
5359
category: RssItunesCategory.parse(
5460
findElementOrNull(element, "itunes:category")),
61+
block: parseBoolLiteral(element, "itunes:block"),
5562
);
5663
}
5764
}

lib/domain/rss_itunes.dart

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,62 +4,66 @@ import 'package:webfeed/util/helpers.dart';
44

55
import 'rss_itunes_category.dart';
66
import 'rss_itunes_image.dart';
7+
import 'rss_itunes_owner.dart';
8+
import 'rss_itunes_type.dart';
79

810
class RssItunes {
911
final String author;
1012
final String summary;
1113
final bool explicit;
14+
final String title;
1215
final String subtitle;
1316
final RssItunesOwner owner;
1417
final List<String> keywords;
1518
final RssItunesImage image;
16-
final RssItunesCategory category;
19+
final List<RssItunesCategory> categories;
20+
final RssItunesType type;
21+
final String newFeedUrl;
22+
final bool block;
23+
final bool complete;
1724

1825
RssItunes({
1926
this.author,
2027
this.summary,
2128
this.explicit,
29+
this.title,
2230
this.subtitle,
2331
this.owner,
2432
this.keywords,
2533
this.image,
26-
this.category,
34+
this.categories,
35+
this.type,
36+
this.newFeedUrl,
37+
this.block,
38+
this.complete,
2739
});
2840

2941
factory RssItunes.parse(XmlElement element) {
3042
if (element == null) {
3143
return null;
3244
}
33-
var explicitStr =
34-
findElementOrNull(element, "itunes:explicit")?.text?.toLowerCase()?.trim();
35-
3645
return RssItunes(
3746
author: findElementOrNull(element, "itunes:author")?.text?.trim(),
3847
summary: findElementOrNull(element, "itunes:summary")?.text?.trim(),
39-
explicit: explicitStr == null
40-
? null
41-
: explicitStr == "yes" || explicitStr == "true",
48+
explicit: parseBoolLiteral(element, "itunes:explicit"),
49+
title: findElementOrNull(element, "itunes:title")?.text?.trim(),
4250
subtitle: findElementOrNull(element, "itunes:subtitle")?.text?.trim(),
4351
owner: RssItunesOwner.parse(findElementOrNull(element, "itunes:owner")),
44-
keywords: findElementOrNull(element, "itunes:keywords")?.text?.split(",")?.map((keyword) => keyword.trim())?.toList(),
52+
keywords: findElementOrNull(element, "itunes:keywords")
53+
?.text
54+
?.split(",")
55+
?.map((keyword) => keyword.trim())
56+
?.toList(),
4557
image: RssItunesImage.parse(findElementOrNull(element, "itunes:image")),
46-
category: RssItunesCategory.parse(
47-
findElementOrNull(element, "itunes:category")),
58+
categories: findAllDirectElementsOrNull(element, "itunes:category")
59+
.map((ele) => RssItunesCategory.parse(ele))
60+
.toList(),
61+
type: newRssItunesType(findElementOrNull(element, "itunes:type")),
62+
newFeedUrl:
63+
findElementOrNull(element, "itunes:new-feed-url")?.text?.trim(),
64+
block: parseBoolLiteral(element, "itunes:block"),
65+
complete: parseBoolLiteral(element, "itunes:complete"),
4866
);
4967
}
5068
}
5169

52-
class RssItunesOwner {
53-
final String name;
54-
final String email;
55-
56-
RssItunesOwner({this.name, this.email});
57-
58-
factory RssItunesOwner.parse(XmlElement element) {
59-
if (element == null) return null;
60-
return RssItunesOwner(
61-
name: findElementOrNull(element, "itunes:name")?.text?.trim(),
62-
email: findElementOrNull(element, "itunes:email")?.text?.trim(),
63-
);
64-
}
65-
}

lib/domain/rss_itunes_category.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class RssItunesCategory {
1111

1212
Iterable<XmlElement> subCategories;
1313
try {
14-
subCategories = element.findAllElements("itunes:category");
14+
subCategories = element.findElements("itunes:category");
1515
} on StateError {
1616
subCategories = null;
1717
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import 'package:xml/xml.dart';
2+
3+
enum RssItunesEpisodeType {full, trailer, bonus}
4+
5+
RssItunesEpisodeType newRssItunesEpisodeType(XmlElement element) {
6+
// "full" is default type
7+
if (element == null) return RssItunesEpisodeType.full;
8+
9+
switch (element.text) {
10+
case "full":
11+
return RssItunesEpisodeType.full;
12+
case "trailer":
13+
return RssItunesEpisodeType.trailer;
14+
case "bonus":
15+
return RssItunesEpisodeType.bonus;
16+
default:
17+
return null;
18+
}
19+
}

lib/domain/rss_itunes_owner.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'package:xml/xml.dart';
2+
3+
import '../util/helpers.dart';
4+
5+
class RssItunesOwner {
6+
final String name;
7+
final String email;
8+
9+
RssItunesOwner({this.name, this.email});
10+
11+
factory RssItunesOwner.parse(XmlElement element) {
12+
if (element == null) return null;
13+
return RssItunesOwner(
14+
name: findElementOrNull(element, "itunes:name")?.text?.trim(),
15+
email: findElementOrNull(element, "itunes:email")?.text?.trim(),
16+
);
17+
}
18+
}

lib/domain/rss_itunes_type.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import 'package:xml/xml.dart';
2+
3+
enum RssItunesType { episodic, serial }
4+
5+
RssItunesType newRssItunesType(XmlElement element) {
6+
// "episodic" is default type
7+
if (element == null) return RssItunesType.episodic;
8+
9+
switch (element.text) {
10+
case "episodic":
11+
return RssItunesType.episodic;
12+
case "serial":
13+
return RssItunesType.serial;
14+
default:
15+
return null;
16+
}
17+
}

lib/util/helpers.dart

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,27 @@ import 'dart:core';
22

33
import 'package:xml/xml.dart';
44

5-
XmlElement findElementOrNull(XmlElement element, String name, {String namespace}) {
5+
XmlElement findElementOrNull(XmlElement element, String name,
6+
{String namespace}) {
67
try {
78
return element.findAllElements(name, namespace: namespace).first;
89
} on StateError {
910
return null;
1011
}
1112
}
13+
14+
List<XmlElement> findAllDirectElementsOrNull(XmlElement element, String name,
15+
{String namespace}) {
16+
try {
17+
return element.findElements(name, namespace: namespace).toList();
18+
} on StateError {
19+
return null;
20+
}
21+
}
22+
23+
bool parseBoolLiteral(XmlElement element, String tagName) {
24+
var v = findElementOrNull(element, tagName)?.text?.toLowerCase()?.trim();
25+
if (v == null) return null;
26+
return ["yes", "true"].contains(v);
27+
}
28+

0 commit comments

Comments
 (0)