From a73e5252513b4db0101093f90d6e4b0ea1b824da Mon Sep 17 00:00:00 2001 From: Dylan Greene Date: Sat, 14 Sep 2013 16:29:34 -0400 Subject: [PATCH] added GeoRSS support thanks to @fredzilla. Fixes #15. --- lib/rss.js | 30 +++++++++++++++--------------- package.json | 7 ++++--- readme.md | 44 +++++++++++++++++++++----------------------- test/rss.test.js | 40 +++++++++++++++++++++++++++++++++++++--- 4 files changed, 77 insertions(+), 44 deletions(-) diff --git a/lib/rss.js b/lib/rss.js index 7e91cfa..09b7653 100755 --- a/lib/rss.js +++ b/lib/rss.js @@ -24,8 +24,8 @@ function RSS (options, items) { this.managingEditor = options.managingEditor; this.webMaster = options.webMaster; this.ttl = options.ttl; - //option to return feed as GeoRSS - this.georss = options.georss || false; + //option to return feed as GeoRSS is set automatically if feed.lat/long is used + this.geoRSS = options.geoRSS || false; this.items = items || []; this.item = function (options) { @@ -39,7 +39,7 @@ function RSS (options, items) { author: options.author, date: options.date, lat: options.lat, - lng: options.lng, + long: options.long, enclosure: options.enclosure || false }; @@ -61,7 +61,6 @@ function ifTruePush(bool, array, data) { } function generateXML (data){ - // todo: xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" var channel = []; channel.push({ title: { _cdata: data.title } }); @@ -105,11 +104,10 @@ function generateXML (data){ 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() }); - //Add lat and long if GeoRSS is true. - if(data.georss){ - ifTruePush(item.lat, item_values, {'geo:lat': item.lat}); - ifTruePush(item.lng, item_values, {'geo:long': item.lng}); - } + //Set GeoRSS to true if lat and long are set + data.geoRSS = data.geoRSS || (item.lat && item.long); + ifTruePush(item.lat, item_values, {'geo:lat': item.lat}); + ifTruePush(item.long, item_values, {'geo:long': item.long}); if( item.enclosure && item.enclosure.url ) { if( item.enclosure.file ) { @@ -144,18 +142,20 @@ function generateXML (data){ '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' + version: '2.0' }; //only add namespace if GeoRSS is true - if(data.georss){ + if(data.geoRSS){ _attr['xmlns:geo'] = 'http://www.w3.org/2003/01/geo/wgs84_pos#'; } - return { rss: [ - { '_attr': _attr }, - { 'channel': channel } - ] }; + return { + rss: [ + { _attr: _attr }, + { channel: channel } + ] + }; } module.exports = RSS; diff --git a/package.json b/package.json index b5ca975..cc35878 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "Michael R. Lange", "Victor Jonsson", "Danny Graham", - "Patrick Garman " + "Patrick Garman ", + "Fred Morstatter" ], "repository": { @@ -24,8 +25,8 @@ }, "dependencies": { - "xml": ">= 0.0.4", - "mime": ">= 1.2.9" + "xml": "~0.0.4", + "mime": "~1.2.11" }, "devDependencies": { "chai": "~1.7.2", diff --git a/readme.md b/readme.md index 802e8dd..856da62 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ [![NPM](https://nodei.co/npm/rss.png?downloads=true)](https://nodei.co/npm/rss/) -> Fast and simple RSS generator/builder for Node projects. +> Fast and simple RSS generator/builder for Node projects. Supports enclosures and GeoRSS. ## Install @@ -34,7 +34,6 @@ var feed = new RSS(feedOptions); * `language` _optional_ **string** The language of the content of this feed. * `categories` _optional_ **array of strings** One or more categories this feed belongs to. * `pubDate` _optional_ **Date object or date string** The publication date for content in the feed - * `georss` _optional_ **boolean** Whether to make the feed a GeoRSS feed. Default is `false`. * `ttl` _optional_ **integer** Number of minutes feed can be cached before refreshing from source. ### Add items to a feed @@ -61,8 +60,8 @@ feed.item(itemOptions); * `date` **Date object or date string** The date and time of when the item was created. Feed readers use this to determine the sort order. Some readers will also use it to determine if the content should be presented as unread. - * `lat` _required if is a GeoRSS feed_ **number** The latitude coordinate of the item. - * `lng` _required if is a GeoRSS feed_ **number** The longitude coordinate of the item. + * `lat` _optional_ **number** The latitude coordinate of the item. + * `long` _optional_ **number** The longitude coordinate of the item. #### Feed XML @@ -82,22 +81,21 @@ var RSS = require('rss'); /* lets create an rss feed */ 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', - docs: 'http://example.com/rss/docs.html', - author: 'Dylan Greene', - managingEditor: 'Dylan Greene', - webMaster: 'Dylan Greene', - copyright: '2013 Dylan Greene', - language: 'en', - categories: ['Category 1','Category 2','Category 3'], - pubDate: 'May 20, 2012 04:00:00 GMT', - georss: true, //set this flag if you wish for the feed to be returned in GeoRSS. A lat/lng field will be expected for each item. - ttl: '60' - }); + title: 'title', + description: 'description', + feed_url: 'http://example.com/rss.xml', + site_url: 'http://example.com', + image_url: 'http://example.com/icon.png', + docs: 'http://example.com/rss/docs.html', + author: 'Dylan Greene', + managingEditor: 'Dylan Greene', + webMaster: 'Dylan Greene', + copyright: '2013 Dylan Greene', + language: 'en', + categories: ['Category 1','Category 2','Category 3'], + pubDate: 'May 20, 2012 04:00:00 GMT', + ttl: '60' +}); /* loop over data and add to feed */ feed.item({ @@ -108,9 +106,9 @@ feed.item({ categories: ['Category 1','Category 2','Category 3','Category 4'], // optional - array of item categories author: 'Guest Author', // optional - defaults to feed author property date: 'May 27, 2012' // any format that js Date can parse. - // lat: 33.417974, //latitude field. Provide if georss is true in the feed setup. - // lng: -111.933231, //longitude field. Provide if georss is true in the feed setup. - enclosure : {url:'...', file:'path-to-file'} // optional + lat: 33.417974, //optional latitude field for GeoRSS + long: -111.933231, //optional longitude field for GeoRSS + enclosure : {url:'...', file:'path-to-file'} // optional enclosure }); // cache the xml to send to clients diff --git a/test/rss.test.js b/test/rss.test.js index 44c0bc3..b7651ac 100644 --- a/test/rss.test.js +++ b/test/rss.test.js @@ -72,7 +72,6 @@ describe('rss module', function(done) { var expectedResult = '\n<![CDATA[title]]>http://example.comhttp://example.com/icon.pngtitlehttp://example.comExample Generator' + new Date().toUTCString() +'Sun, 20 May 2012 04:00:00 GMThttp://example.com/rss/docs.html60<![CDATA[item 1]]>http://example.com/article1http://example.com/article1Thu, 24 May 2012 04:00:00 GMT<![CDATA[item 2]]>http://example.com/article2http://example.com/article2Fri, 25 May 2012 04:00:00 GMT<![CDATA[item 3]]>http://example.com/article3item3Sat, 26 May 2012 04:00:00 GMT<![CDATA[item 4 & html test with <strong>]]>html]]>http://example.com/article4?this&thathttp://example.com/article4?this&thatSun, 27 May 2012 04:00:00 GMT<![CDATA[item 5 & test for categories]]>http://example.com/article5http://example.com/article5Mon, 28 May 2012 04:00:00 GMT'; var result = feed.xml(); - expect(result).to.have.length(expectedResult.length); expect(result).to.equal(expectedResult); done(); }); @@ -132,7 +131,6 @@ describe('rss module', function(done) { var expectedResult = '\n<![CDATA[title]]>http://example.comRSS for Node' + new Date().toUTCString() +'Sun, 20 May 2012 04:00:00 GMThttp://example.com/rss/docs.html60<![CDATA[item 1]]>http://example.com/article1http://example.com/article1Thu, 24 May 2012 04:00:00 GMT<![CDATA[item 2]]>http://example.com/article2http://example.com/article2Fri, 25 May 2012 04:00:00 GMT<![CDATA[item 3]]>http://example.com/article3item3Sat, 26 May 2012 04:00:00 GMT<![CDATA[item 4 & html test with <strong>]]>html]]>http://example.com/article4?this&thathttp://example.com/article4?this&thatSun, 27 May 2012 04:00:00 GMT<![CDATA[item 5 & test for categories]]>http://example.com/article5http://example.com/article5Mon, 28 May 2012 04:00:00 GMT'; var result = feed.xml(); - expect(result).to.have.length(expectedResult.length); expect(result).to.equal(expectedResult); done(); }); @@ -178,7 +176,43 @@ describe('rss module', function(done) { ''; var result = feed.xml(); - expect(result).to.have.length(expectedResult.length); + expect(result).to.equal(expectedResult); + done(); + }); + + + it('should work with geoRSS', function(done) { + var feed = new RSS({ + title: 'title', + description: 'description', + feed_url: 'http://example.com/rss.xml', + site_url: 'http://example.com', + author: 'Dylan Greene' + }); + + feed.item({ + title: 'item 1', + description: 'description 1', + url: 'http://example.com/article1', + date: 'May 24, 2012 04:00:00 GMT', + lat: 12232, + long: 13333.23323 + }); + + feed.item({ + title: 'item 2', + description: 'description 2', + url: 'http://example.com/article1', + date: 'May 24, 2012 04:00:00 GMT' + }); + + var expectedResult = '\n<![CDATA[title]]>http://example.comRSS for Node' + new Date().toUTCString() +''+ + '' + + '<![CDATA[item 1]]>http://example.com/article1http://example.com/article1Thu, 24 May 2012 04:00:00 GMT1223213333.23323'+ + '<![CDATA[item 2]]>http://example.com/article1http://example.com/article1Thu, 24 May 2012 04:00:00 GMT'+ + ''; + var result = feed.xml(); + expect(result).to.equal(expectedResult); done(); });