diff --git a/lib/rss.js b/lib/rss.js index 9bb753b..e83548f 100644 --- a/lib/rss.js +++ b/lib/rss.js @@ -5,102 +5,71 @@ var XML = require('xml'), log = require('logging').from(__filename); -function RSS () { +function RSS (options, items) { + options = options || {}; - var site = { - title: '', - url: '', - description: '' - }; + this.title = options.title || 'Untitled RSS Feed'; + this.description = options.description || ''; + this.feed_url = options.feed_url; + this.site_url = options.site_url; + this.image_url = options.image_url; + this.author = options.author; + this.items = items || []; - var feed = { - url: '' - }; - - var author = { - - }; - - - var rss = { - title: '', - description: '', - link: '', - author: { - name: 'string', - uri: 'uri', - email: 'email' - }, - image: { - url: 'url', - title: 'text', - link: 'url' - }, - items: [] + this.item = function (options) { + options = options || {}; + var item = { + title: options.title || 'No title', + description: options.description || '', + url: options.url, + guid: options.guid, + categories: options.categories || [], + author: options.author, + date: options.date }; - Object.defineProperty(this, "items", { - get : function(){ return rss.items; }, - 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.items.push(item); + return this; }; this.xml = function(indent) { - return '\n' + XML(generateXML(rss), indent); + return '\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" var channel = [ - { title: rss.title }, - { description: rss.description }, + { title: { _cdata: data.title } }, + { description: { _cdata: data.description || data.title } }, + { link: data.site_url || 'http://github.com/dylan/node-rss' }, { generator: 'NodeJS RSS Module' }, - { 'atom:link': { _attr: { href: rss.url, rel: 'self', type: 'application/rss+xml' } } }, - { link: rss.link }, - { updated: new Date().toISOString() }, - { author: [ - { name: rss.author.name}, - { uri: rss.author.uri }, - { email: rss.author.email } - ]} - ]; + { lastBuildDate: new Date().toGMTString() } + ]; + ifTruePush(data.feed_url, channel, { 'atom:link': { _attr: { href: data.feed_url, rel: 'self', type: 'application/rss+xml' } } }); + // { updated: new Date().toGMTString() } + - 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 - - channel.push({ item: [ - { 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() } - ]}); + 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: item_values }); }); return { rss: [ diff --git a/readme.md b/readme.md index 2698452..72149df 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,112 @@ -# Node.js library for generating RSS and Atom feeds. +# RSS for Node -Documentation coming soon. \ No newline at end of file + 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)); + //http://www.google.com/search?aq=f&sourceid=chrome&ie=UTF-8&q=opower + + var example2 = [ { url: { _attr: { hostname: 'www.google.com', path: '/search?aq=f&sourceid=chrome&ie=UTF-8&q=opower' } } } ]; + console.log(XML(example2)); + // + + var example3 = [ { toys: [ { toy: 'Transformers' } , { toy: 'GI Joe' }, { toy: 'He-man' } ] } ]; + console.log(XML(example3)); + //TransformersGI JoeHe-man + console.log(XML(example3, true)); + /* + + Transformers + GI Joe + He-man + + */ + + var example4 = [ { toys: [ { _attr: { decade: '80s', locale: 'US'} }, { toy: 'Transformers' } , { toy: 'GI Joe' }, { toy: 'He-man' } ] } ]; + console.log(XML(example4, true)); + /* + + Transformers + GI Joe + He-man + + */ + + var example5 = [ { toys: [ { _attr: { decade: '80s', locale: 'US'} }, { toy: 'Transformers' } , { toy: [ { _attr: { knowing: 'half the battle' } }, 'GI Joe'] }, { toy: [ { name: 'He-man' }, { description: { _cdata: 'Master of the Universe!'} } ] } ] } ]; + console.log(XML(example5, true)); + /* + TransformersGI JoeHe-man + + Transformers + GI Joe + He-man + + + Transformers + GI Joe + He-man + + + Transformers + + GI Joe + + + He-man + Master of the Universe!]]> + + + */ + + + + +# 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 + +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. \ No newline at end of file diff --git a/test/test.js b/test/test.js index b77a282..d0514d9 100644 --- a/test/test.js +++ b/test/test.js @@ -4,10 +4,57 @@ var RSS = require('../index'); -var feed = new RSS(); -feed.item(); -feed.item(); -feed.item(); +module.exports = { + + 'empty feed': function(test) { + var feed = new RSS(); + test.equal(feed.xml(), '\n<![CDATA[Untitled RSS Feed]]>http://github.com/dylan/node-rssNodeJS RSS Module' + new Date().toUTCString() +''); + feed.item(); + test.equal(feed.xml(), '\n<![CDATA[Untitled RSS Feed]]>http://github.com/dylan/node-rssNodeJS RSS Module' + new Date().toUTCString() +'<![CDATA[No title]]>No title'); + 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 ', + description: 'description 4 uses some html', + url: 'http://example.com/article4?this&that', + author: 'Guest Author', + date: 'May 27, 2012' + }); + + console.log(feed.xml(true)); + test.equal(feed.xml(), '\n<![CDATA[title]]>http://example.comNodeJS RSS Module' + new Date().toUTCString() +'<![CDATA[item 1]]>http://example.com/article1Thu, 24 May 2012 04:00:00 GMT<![CDATA[item 2]]>http://example.com/article2Fri, 25 May 2012 04:00:00 GMT<![CDATA[item 3]]>item3Sat, 26 May 2012 04:00:00 GMT<![CDATA[item 4 & html test with <strong>]]>html]]>http://example.com/article4?this&thatSun, 27 May 2012 04:00:00 GMT'); + test.done(); + } +}; -console.log(feed.xml(true));