Skip to content

Commit 9e98046

Browse files
authored
Merge pull request #3 from jameslawler/add-itunes
Add itunes
2 parents 4680f98 + d37cf5f commit 9e98046

File tree

12 files changed

+511
-50
lines changed

12 files changed

+511
-50
lines changed

README.md

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Parse RSS data into a simple object structure. Currently supports;
88
* RSS 2.0 specification
99
* Atom 1.0 specification
10+
* Itunes elements for both RSS 2.0 and Atom 1.0 feeds
1011

1112
## Installation
1213

@@ -32,50 +33,85 @@ return fetch('http://www.nasa.gov/rss/dyn/breaking_news.rss')
3233

3334
```js
3435
{
35-
type: undefined,
36-
title: undefined,
36+
type: undefined, // either `rss-v2` or `atom-v1`
37+
title: undefined, // title of the channel
3738
links: [{
38-
url: undefined,
39-
rel: undefined
39+
url: undefined, // url of the channel
40+
rel: undefined // type of url (eg. alternate)
4041
}],
41-
description: undefined,
42-
language: undefined,
43-
copyright: undefined,
42+
description: undefined, // description of the channel
43+
language: undefined, // language of the channel in `en-us`
44+
copyright: undefined, // copyright information about the channel
4445
authors: [{
45-
name: undefined
46+
name: undefined // channel author names
4647
}],
47-
lastUpdated: undefined,
48-
lastPublished: undefined,
48+
lastUpdated: undefined, // last updated date for the channel
49+
lastPublished: undefined, // last published date for the channel
4950
categories: [{
50-
name: undefined
51+
name: undefined // categories the channel belong too
5152
}],
5253
image: {
53-
url: undefined,
54-
title: undefined,
55-
description: undefined,
56-
width: undefined,
57-
height: undefined
54+
url: undefined, // channel image url
55+
title: undefined, // channel image title
56+
description: undefined, // channel image description
57+
width: undefined, // channel image width (pixels)
58+
height: undefined // channel image height (pixels)
5859
},
59-
items: [{
60-
title: undefined,
60+
itunes: { // itunes specific channel information
61+
author: [{
62+
name: undefined // channel author names
63+
}],
64+
block: undefined, // if `yes` then the entire podcast isn't shown in iTunes directory
65+
categories: [{
66+
name: undefined, // channel category names
67+
subCategories:[{
68+
name: undefined // sub category names
69+
}]
70+
}],
71+
image: undefined, // channel image url
72+
explicit: undefined, // `yes`/`no` to indicate if channel contains explicit content
73+
complete: undefined, // `yes` indicates the feed won't publish any new items in the future
74+
newFeedUrl: undefined, // a url pointing to the new feed location
75+
owner: {
76+
name: undefined, // owner name of the channel
77+
email: undefined, // owner email address of the channel
78+
},
79+
subtitle: undefined, // sub title of the channel
80+
summary: undefined, // summary of the channel
81+
},
82+
items: [{ // list of items in the feed
83+
title: undefined, // item title
6184
links: [{
62-
url: undefined,
63-
rel: undefined
85+
url: undefined, // item link url
86+
rel: undefined // type of item link
6487
}],
65-
description: undefined,
66-
content: undefined,
88+
description: undefined, // item description
89+
content: undefined, // item HTML content
6790
categories: [{
68-
name: undefined
91+
name: undefined // categories the item belongs too
6992
}],
7093
authors: [{
71-
name: undefined
94+
name: undefined // item author names
7295
}],
73-
published: undefined,
96+
published: undefined, // item published date
7497
enclosures: [{
75-
url: undefined,
76-
length: undefined,
77-
mimeType: undefined
78-
}]
98+
url: undefined, // item media url
99+
length: undefined, // item media length (bytes)
100+
mimeType: undefined // item media mime type (eg audio/mpeg)
101+
}],
102+
itunes: { // itunes specific item information
103+
authors: [{
104+
name: undefined, // item author names
105+
}],
106+
block: undefined, // `yes` indicates the item won't be displayed in the iTunes directory
107+
duration: undefined, // HH:MM:SS length of the item
108+
explicit: undefined, // `yes`/`no` to indicate if item contains explicit content
109+
image: undefined, // image url for the item
110+
isClosedCaptioned: undefined, // `yes` indicates if the item contains closed captioning
111+
order: undefined, // item order number
112+
subtitle: undefined, // item subtitle
113+
summary: undefined, // item summary
114+
}
79115
}]
80116
}
81117
```

model/rss.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,28 @@ model.rss = {
2525
width: undefined,
2626
height: undefined
2727
},
28+
itunes: {
29+
author: [{
30+
name: undefined
31+
}],
32+
block: undefined,
33+
categories: [{
34+
name: undefined,
35+
subCategories:[{
36+
name: undefined
37+
}]
38+
}],
39+
image: undefined,
40+
explicit: undefined,
41+
complete: undefined,
42+
newFeedUrl: undefined,
43+
owner: {
44+
name: undefined,
45+
email: undefined,
46+
},
47+
subtitle: undefined,
48+
summary: undefined,
49+
},
2850
items: [{
2951
title: undefined,
3052
links: [{
@@ -44,6 +66,19 @@ model.rss = {
4466
url: undefined,
4567
length: undefined,
4668
mimeType: undefined
47-
}]
69+
}],
70+
itunes: {
71+
authors: [{
72+
name: undefined,
73+
}],
74+
block: undefined,
75+
duration: undefined,
76+
explicit: undefined,
77+
image: undefined,
78+
isClosedCaptioned: undefined,
79+
order: undefined,
80+
subtitle: undefined,
81+
summary: undefined,
82+
}
4883
}]
4984
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-rss-parser",
3-
"version": "1.0.1",
3+
"version": "1.1.0",
44
"description": "React Native compatible package to parse RSS feeds",
55
"main": "index.js",
66
"scripts": {

parsers/atomv1.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var utils = require('./utils');
22
var model = require('../model/rss');
3+
var itunesParser = require('./itunes');
34

45
exports.parse = function(document) {
56
let parsedFeed = Object.assign({}, model.rss);
@@ -29,6 +30,7 @@ function mapChannelFields(document, parsedFeed) {
2930
parsedFeed.lastPublished = getChannelLastPublished(channelNode);
3031
parsedFeed.categories = getChannelCategories(channelNode);
3132
parsedFeed.image = getChannelImage(channelNode);
33+
parsedFeed.itunes = itunesParser.parseChannel(channelNode);
3234

3335
return parsedFeed;
3436
}
@@ -106,7 +108,8 @@ function mapItems(document) {
106108
authors: getItemAuthors(item),
107109
categories: getItemCategories(item),
108110
published: getItemPublished(item),
109-
enclosures: getItemEnclosures(item)
111+
enclosures: getItemEnclosures(item),
112+
itunes: itunesParser.parseItem(item)
110113
};
111114
});
112115
}

parsers/itunes.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
var utils = require('./utils');
2+
var namespaces = require('./namespaces');
3+
4+
exports.parseChannel = function(node) {
5+
return {
6+
authors: getAuthors(node),
7+
block: getBlock(node),
8+
categories: getCategories(node),
9+
complete: getComplete(node),
10+
explicit: getExplicit(node),
11+
image: getImage(node),
12+
newFeedUrl: getNewFeedUrl(node),
13+
owner: getOwner(node),
14+
subtitle: getSubtitle(node),
15+
summary: getSummary(node)
16+
}
17+
};
18+
19+
exports.parseItem = function(node) {
20+
return {
21+
authors: getAuthors(node),
22+
block: getBlock(node),
23+
duration: getDuration(node),
24+
explicit: getExplicit(node),
25+
image: getImage(node),
26+
isClosedCaptioned: getIsClosedCaptioned(node),
27+
order: getOrder(node),
28+
subtitle: getSubtitle(node),
29+
summary: getSummary(node),
30+
};
31+
};
32+
33+
function getAuthors(node) {
34+
const authors = utils.getElementTextContentArray(node, 'author', namespaces.itunes);
35+
36+
return authors.map(function(author) {
37+
return {
38+
name: author
39+
};
40+
});
41+
}
42+
43+
function getBlock(node) {
44+
return utils.getElementTextContent(node, 'block', namespaces.itunes);
45+
}
46+
47+
function getCategories(node) {
48+
const categories = utils.getChildElements(node, 'category', namespaces.itunes);
49+
50+
return categories.map(function(category) {
51+
return {
52+
name: category.getAttribute('text'),
53+
subCategories: getSubCategories(category)
54+
}
55+
});
56+
}
57+
58+
function getSubCategories(node) {
59+
const categories = utils.getChildElements(node, 'category', namespaces.itunes);
60+
61+
if (categories.length === 0) {
62+
return [];
63+
}
64+
65+
return categories.map(function(category) {
66+
return {
67+
name: category.getAttribute('text')
68+
}
69+
});
70+
}
71+
72+
function getComplete(node) {
73+
return utils.getElementTextContent(node, 'complete', namespaces.itunes);
74+
}
75+
76+
function getDuration(node) {
77+
return utils.getElementTextContent(node, 'duration', namespaces.itunes);
78+
}
79+
80+
function getExplicit(node) {
81+
return utils.getElementTextContent(node, 'explicit', namespaces.itunes);
82+
}
83+
84+
function getImage(node) {
85+
const images = utils.getChildElements(node, 'image', namespaces.itunes);
86+
87+
if (images.length > 0) {
88+
return images[0].getAttribute('href');
89+
}
90+
91+
return undefined;
92+
}
93+
94+
function getIsClosedCaptioned(node) {
95+
return utils.getElementTextContent(node, 'isClosedCaptioned', namespaces.itunes);
96+
}
97+
98+
function getNewFeedUrl(node) {
99+
return utils.getElementTextContent(node, 'new-feed-url', namespaces.itunes);
100+
}
101+
102+
function getOrder(node) {
103+
return utils.getElementTextContent(node, 'order', namespaces.itunes);
104+
}
105+
106+
function getOwner(node) {
107+
const owners = utils.getChildElements(node, 'owner', namespaces.itunes);
108+
109+
if (owners.length === 0) {
110+
return {
111+
name: undefined,
112+
email: undefined
113+
};
114+
}
115+
116+
return {
117+
name: utils.getElementTextContent(owners[0], 'name', namespaces.itunes),
118+
email: utils.getElementTextContent(owners[0], 'email', namespaces.itunes),
119+
};
120+
}
121+
122+
function getSubtitle(node) {
123+
return utils.getElementTextContent(node, 'subtitle', namespaces.itunes);
124+
}
125+
126+
function getSummary(node) {
127+
return utils.getElementTextContent(node, 'summary', namespaces.itunes);
128+
}

parsers/namespaces.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exports.itunes = 'http://www.itunes.com/dtds/podcast-1.0.dtd';

parsers/rssv2.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var utils = require('./utils');
22
var model = require('../model/rss');
3+
var itunesParser = require('./itunes');
34

45
exports.parse = function(document) {
56
let parsedFeed = Object.assign({}, model.rss);
@@ -30,6 +31,7 @@ function mapChannelFields(document, parsedFeed) {
3031
parsedFeed.lastPublished = getChannelLastPublished(channelNode);
3132
parsedFeed.categories = getChannelCategories(channelNode);
3233
parsedFeed.image = getChannelImage(channelNode);
34+
parsedFeed.itunes = itunesParser.parseChannel(channelNode);
3335

3436
return parsedFeed;
3537
}
@@ -124,7 +126,8 @@ function mapItems(document) {
124126
authors: getItemAuthors(item),
125127
categories: getItemCategories(item),
126128
published: getItemPublished(item),
127-
enclosures: getItemEnclosures(item)
129+
enclosures: getItemEnclosures(item),
130+
itunes: itunesParser.parseItem(item)
128131
};
129132
});
130133
}

0 commit comments

Comments
 (0)