mirror of
https://github.com/LightAir/turbo-rss.git
synced 2026-02-04 03:56:19 +00:00
it's working, even have working tests
This commit is contained in:
125
lib/rss.js
125
lib/rss.js
@@ -5,102 +5,71 @@
|
|||||||
var XML = require('xml'),
|
var XML = require('xml'),
|
||||||
log = require('logging').from(__filename);
|
log = require('logging').from(__filename);
|
||||||
|
|
||||||
function RSS () {
|
function RSS (options, items) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
var site = {
|
this.title = options.title || 'Untitled RSS Feed';
|
||||||
title: '',
|
this.description = options.description || '';
|
||||||
url: '',
|
this.feed_url = options.feed_url;
|
||||||
description: ''
|
this.site_url = options.site_url;
|
||||||
};
|
this.image_url = options.image_url;
|
||||||
|
this.author = options.author;
|
||||||
|
this.items = items || [];
|
||||||
|
|
||||||
var feed = {
|
this.item = function (options) {
|
||||||
url: ''
|
options = options || {};
|
||||||
};
|
var item = {
|
||||||
|
title: options.title || 'No title',
|
||||||
var author = {
|
description: options.description || '',
|
||||||
|
url: options.url,
|
||||||
};
|
guid: options.guid,
|
||||||
|
categories: options.categories || [],
|
||||||
|
author: options.author,
|
||||||
var rss = {
|
date: options.date
|
||||||
title: '',
|
|
||||||
description: '',
|
|
||||||
link: '',
|
|
||||||
author: {
|
|
||||||
name: 'string',
|
|
||||||
uri: 'uri',
|
|
||||||
email: 'email'
|
|
||||||
},
|
|
||||||
image: {
|
|
||||||
url: 'url',
|
|
||||||
title: 'text',
|
|
||||||
link: 'url'
|
|
||||||
},
|
|
||||||
items: []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.defineProperty(this, "items", {
|
this.items.push(item);
|
||||||
get : function(){ return rss.items; },
|
return this;
|
||||||
set : function(new_items){ rss.items = new_items; },
|
|
||||||
enumerable : true
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.item = function (item) {
|
|
||||||
|
|
||||||
item = item || {
|
|
||||||
title: 'cdata',
|
|
||||||
link: 'url',
|
|
||||||
source: 'source',
|
|
||||||
description: 'cdata',
|
|
||||||
categories: ['category'],
|
|
||||||
guid: { permaLink: true, guid: 'guid'},
|
|
||||||
comments: 'comments',
|
|
||||||
author: 'author',
|
|
||||||
date: new Date()
|
|
||||||
};
|
|
||||||
|
|
||||||
rss.items.push(item);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.xml = function(indent) {
|
this.xml = function(indent) {
|
||||||
return '<?xml version="1.0" encoding="UTF-8"?>\n' + XML(generateXML(rss), indent);
|
return '<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||||
|
+ XML(generateXML(this), indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ifTruePush(bool, array, data) {
|
||||||
|
if (bool) {
|
||||||
|
array.push(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function generateXML (rss){
|
function generateXML (data){
|
||||||
// todo: xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
|
// todo: xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
|
||||||
|
|
||||||
var channel = [
|
var channel = [
|
||||||
{ title: rss.title },
|
{ title: { _cdata: data.title } },
|
||||||
{ description: rss.description },
|
{ description: { _cdata: data.description || data.title } },
|
||||||
|
{ link: data.site_url || 'http://github.com/dylan/node-rss' },
|
||||||
{ generator: 'NodeJS RSS Module' },
|
{ generator: 'NodeJS RSS Module' },
|
||||||
{ 'atom:link': { _attr: { href: rss.url, rel: 'self', type: 'application/rss+xml' } } },
|
{ lastBuildDate: new Date().toGMTString() }
|
||||||
{ link: rss.link },
|
];
|
||||||
{ updated: new Date().toISOString() },
|
ifTruePush(data.feed_url, channel, { 'atom:link': { _attr: { href: data.feed_url, rel: 'self', type: 'application/rss+xml' } } });
|
||||||
{ author: [
|
// { updated: new Date().toGMTString() }
|
||||||
{ name: rss.author.name},
|
|
||||||
{ uri: rss.author.uri },
|
|
||||||
{ email: rss.author.email }
|
|
||||||
]}
|
|
||||||
];
|
|
||||||
|
|
||||||
rss.items.forEach(function(item) {
|
data.items.forEach(function(item) {
|
||||||
|
var item_values = [
|
||||||
|
{ title: { _cdata: item.title } }
|
||||||
|
];
|
||||||
|
ifTruePush(item.description, item_values, { description: { _cdata: item.description } });
|
||||||
|
ifTruePush(item.link, item_values, { link: item.url });
|
||||||
|
ifTruePush(item.link || item.guid || item.title, item_values, { guid: [ { _attr: { isPermaLink: !item.guid && !!item.url } }, item.guid || item.url || item.title ] });
|
||||||
|
|
||||||
//TODO: categories
|
ifTruePush(item.author || data.author, item_values, { 'dc:creator': { _cdata: item.author || data.author } });
|
||||||
|
ifTruePush(item.date, item_values, { pubDate: new Date(item.date).toGMTString() });
|
||||||
channel.push({ item: [
|
channel.push({ item: item_values });
|
||||||
{ title: { _cdata: item.title } },
|
|
||||||
{ link: item.link },
|
|
||||||
{ guid: [ { _attr: { isPermaLink: item.guid.permaLink } }, item.guid.guid ] },
|
|
||||||
{ comments: item.comments },
|
|
||||||
{ description: { _cdata: item.description } },
|
|
||||||
{ 'dc:creator': { _cdata: item.author } },
|
|
||||||
{ pubDate: item.date.toISOString() }
|
|
||||||
]});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return { rss: [
|
return { rss: [
|
||||||
|
|||||||
113
readme.md
113
readme.md
@@ -1,3 +1,112 @@
|
|||||||
# Node.js library for generating RSS and Atom feeds.
|
# RSS for Node
|
||||||
|
|
||||||
Documentation coming soon.
|
Fast and simple Javascript-based RSS generator/builder for Node projects.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
$ npm install rss
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
Use [nodeunit](https://github.com/caolan/nodeunit) to run the tests.
|
||||||
|
|
||||||
|
$ npm install nodeunit
|
||||||
|
$ nodeunit test
|
||||||
|
|
||||||
|
## API
|
||||||
|
var RSS = require('rss');
|
||||||
|
|
||||||
|
var feed = RSS(feed_options, [array of items])
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
var XML = require('xml');
|
||||||
|
|
||||||
|
var example1 = [ { url: 'http://www.google.com/search?aq=f&sourceid=chrome&ie=UTF-8&q=opower' } ];
|
||||||
|
console.log(XML(example1));
|
||||||
|
//<url>http://www.google.com/search?aq=f&sourceid=chrome&ie=UTF-8&q=opower</url>
|
||||||
|
|
||||||
|
var example2 = [ { url: { _attr: { hostname: 'www.google.com', path: '/search?aq=f&sourceid=chrome&ie=UTF-8&q=opower' } } } ];
|
||||||
|
console.log(XML(example2));
|
||||||
|
//<url hostname="www.google.com" path="/search?aq=f&sourceid=chrome&ie=UTF-8&q=opower"/>
|
||||||
|
|
||||||
|
var example3 = [ { toys: [ { toy: 'Transformers' } , { toy: 'GI Joe' }, { toy: 'He-man' } ] } ];
|
||||||
|
console.log(XML(example3));
|
||||||
|
//<toys><toy>Transformers</toy><toy>GI Joe</toy><toy>He-man</toy></toys>
|
||||||
|
console.log(XML(example3, true));
|
||||||
|
/*
|
||||||
|
<toys>
|
||||||
|
<toy>Transformers</toy>
|
||||||
|
<toy>GI Joe</toy>
|
||||||
|
<toy>He-man</toy>
|
||||||
|
</toys>
|
||||||
|
*/
|
||||||
|
|
||||||
|
var example4 = [ { toys: [ { _attr: { decade: '80s', locale: 'US'} }, { toy: 'Transformers' } , { toy: 'GI Joe' }, { toy: 'He-man' } ] } ];
|
||||||
|
console.log(XML(example4, true));
|
||||||
|
/*
|
||||||
|
<toys decade="80s" locale="US">
|
||||||
|
<toy>Transformers</toy>
|
||||||
|
<toy>GI Joe</toy>
|
||||||
|
<toy>He-man</toy>
|
||||||
|
</toys>
|
||||||
|
*/
|
||||||
|
|
||||||
|
var example5 = [ { toys: [ { _attr: { decade: '80s', locale: 'US'} }, { toy: 'Transformers' } , { toy: [ { _attr: { knowing: 'half the battle' } }, 'GI Joe'] }, { toy: [ { name: 'He-man' }, { description: { _cdata: '<strong>Master of the Universe!</strong>'} } ] } ] } ];
|
||||||
|
console.log(XML(example5, true));
|
||||||
|
/*
|
||||||
|
<toys><toy>Transformers</toy><toy>GI Joe</toy><toy>He-man</toy></toys>
|
||||||
|
<toys>
|
||||||
|
<toy>Transformers</toy>
|
||||||
|
<toy>GI Joe</toy>
|
||||||
|
<toy>He-man</toy>
|
||||||
|
</toys>
|
||||||
|
<toys decade="80s" locale="US">
|
||||||
|
<toy>Transformers</toy>
|
||||||
|
<toy>GI Joe</toy>
|
||||||
|
<toy>He-man</toy>
|
||||||
|
</toys>
|
||||||
|
<toys decade="80s" locale="US">
|
||||||
|
<toy>Transformers</toy>
|
||||||
|
<toy knowing="half the battle">
|
||||||
|
GI Joe
|
||||||
|
</toy>
|
||||||
|
<toy>
|
||||||
|
<name>He-man</name>
|
||||||
|
<description><![CDATA[<strong>Master of the Universe!</strong>]]></description>
|
||||||
|
</toy>
|
||||||
|
</toys>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
Contributions to the project are welcome. Feel free to fork and improve. I accept pull requests and issues,
|
||||||
|
especially when tests are included.
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2011 Dylan Greene <dylang@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
'Software'), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
57
test/test.js
57
test/test.js
@@ -4,10 +4,57 @@
|
|||||||
|
|
||||||
var RSS = require('../index');
|
var RSS = require('../index');
|
||||||
|
|
||||||
var feed = new RSS();
|
|
||||||
|
|
||||||
feed.item();
|
module.exports = {
|
||||||
feed.item();
|
|
||||||
feed.item();
|
'empty feed': function(test) {
|
||||||
|
var feed = new RSS();
|
||||||
|
test.equal(feed.xml(), '<?xml version="1.0" encoding="UTF-8"?>\n<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"><channel><title><![CDATA[Untitled RSS Feed]]></title><description><![CDATA[Untitled RSS Feed]]></description><link>http://github.com/dylan/node-rss</link><generator>NodeJS RSS Module</generator><lastBuildDate>' + new Date().toUTCString() +'</lastBuildDate></channel></rss>');
|
||||||
|
feed.item();
|
||||||
|
test.equal(feed.xml(), '<?xml version="1.0" encoding="UTF-8"?>\n<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"><channel><title><![CDATA[Untitled RSS Feed]]></title><description><![CDATA[Untitled RSS Feed]]></description><link>http://github.com/dylan/node-rss</link><generator>NodeJS RSS Module</generator><lastBuildDate>' + new Date().toUTCString() +'</lastBuildDate><item><title><![CDATA[No title]]></title><guid isPermaLink="false">No title</guid></item></channel></rss>');
|
||||||
|
test.done();
|
||||||
|
},
|
||||||
|
|
||||||
|
'easy test': function(test) {
|
||||||
|
var feed = new RSS({
|
||||||
|
title: 'title',
|
||||||
|
description: 'description',
|
||||||
|
feed_url: 'http://example.com/rss.xml',
|
||||||
|
site_url: 'http://example.com',
|
||||||
|
image_url: 'http://example.com/icon.png',
|
||||||
|
author: 'Dylan Greene'
|
||||||
|
});
|
||||||
|
|
||||||
|
feed.item({
|
||||||
|
title: 'item 1',
|
||||||
|
description: 'description 1',
|
||||||
|
url: 'http://example.com/article1',
|
||||||
|
date: 'May 24, 2012'
|
||||||
|
})
|
||||||
|
.item({
|
||||||
|
title: 'item 2',
|
||||||
|
description: 'description 2',
|
||||||
|
url: 'http://example.com/article2',
|
||||||
|
date: 'May 25, 2012'
|
||||||
|
})
|
||||||
|
.item({
|
||||||
|
title: 'item 3',
|
||||||
|
description: 'description 3',
|
||||||
|
url: 'http://example.com/article3',
|
||||||
|
guid: 'item3',
|
||||||
|
date: 'May 26, 2012'
|
||||||
|
})
|
||||||
|
.item({
|
||||||
|
title: 'item 4 & html test with <strong>',
|
||||||
|
description: 'description 4 uses some <strong>html</strong>',
|
||||||
|
url: 'http://example.com/article4?this&that',
|
||||||
|
author: 'Guest Author',
|
||||||
|
date: 'May 27, 2012'
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(feed.xml(true));
|
||||||
|
test.equal(feed.xml(), '<?xml version="1.0" encoding="UTF-8"?>\n<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"><channel><title><![CDATA[title]]></title><description><![CDATA[description]]></description><link>http://example.com</link><generator>NodeJS RSS Module</generator><lastBuildDate>' + new Date().toUTCString() +'</lastBuildDate><atom:link href="http://example.com/rss.xml" rel="self" type="application/rss+xml"/><item><title><![CDATA[item 1]]></title><description><![CDATA[description 1]]></description><guid isPermaLink="true">http://example.com/article1</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Thu, 24 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 2]]></title><description><![CDATA[description 2]]></description><guid isPermaLink="true">http://example.com/article2</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Fri, 25 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 3]]></title><description><![CDATA[description 3]]></description><guid isPermaLink="false">item3</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Sat, 26 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 4 & html test with <strong>]]></title><description><![CDATA[description 4 uses some <strong>html</strong>]]></description><guid isPermaLink="true">http://example.com/article4?this&that</guid><dc:creator><![CDATA[Guest Author]]></dc:creator><pubDate>Sun, 27 May 2012 04:00:00 GMT</pubDate></item></channel></rss>');
|
||||||
|
test.done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
console.log(feed.xml(true));
|
|
||||||
|
|||||||
Reference in New Issue
Block a user