diff --git a/lib/index.js b/lib/index.js index 2ad40a4..13f7efa 100755 --- a/lib/index.js +++ b/lib/index.js @@ -1,5 +1,5 @@ 'use strict'; - +var _ = require('underscore'); var mime = require('mime-types'); var xml = require('xml'); var fs = require('fs'); @@ -29,7 +29,39 @@ function getSize(filename) { } function generateXML (data){ + var channel = convertChannel(data); + data.items.forEach(function(item) { + channel.push(convertItem(item, data)); + }); + return { + rss: [ + { _attr: getRssFeedAttributes(data) }, + { channel: channel } + ] + }; +} +function getRssFeedAttributes(data) { + //set up the attributes for the RSS feed. + var _attr = { + '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' + }; + + Object.keys(data.custom_namespaces).forEach(function(name) { + _attr['xmlns:' + name] = data.custom_namespaces[name]; + }); + + //only add namespace if GeoRSS is true + if(data.geoRSS){ + _attr['xmlns:geo'] = 'http://www.w3.org/2003/01/geo/wgs84_pos#'; + } + return _attr; +} + +function convertChannel(data) { var channel = []; channel.push({ title: { _cdata: data.title } }); channel.push({ description: { _cdata: data.description || data.title } }); @@ -59,80 +91,58 @@ function generateXML (data){ } ifTruePushArray(data.custom_elements, channel, data.custom_elements); + return channel; +} - data.items.forEach(function(item) { - var item_values = [ - { title: { _cdata: item.title } } - ]; - ifTruePush(item.description, item_values, { description: { _cdata: item.description } }); - ifTruePush(item.url, 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 ] }); +function convertItem(item, data) { + var item_values = [ + { title: { _cdata: item.title } } + ]; + ifTruePush(item.description, item_values, { description: { _cdata: item.description } }); + ifTruePush(item.url, 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 ] }); + if (item.categories) { item.categories.forEach(function(category) { ifTruePush(category, item_values, { category: { _cdata: category } }); }); + } - 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() }); - - //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 ) { - item_values.push({ - enclosure : { - _attr : { - url : item.enclosure.url, - length : item.enclosure.size || getSize(item.enclosure.file), - type : item.enclosure.type || mime.lookup(item.enclosure.file) - } + 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() }); + + //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 ) { + item_values.push({ + enclosure : { + _attr : { + url : item.enclosure.url, + length : item.enclosure.size || getSize(item.enclosure.file), + type : item.enclosure.type || mime.lookup(item.enclosure.file) } - }); - } else { - item_values.push({ - enclosure : { - _attr : { - url : item.enclosure.url, - length : item.enclosure.size || 0, - type : item.enclosure.type || mime.lookup(item.enclosure.url) - } + } + }); + } else { + item_values.push({ + enclosure : { + _attr : { + url : item.enclosure.url, + length : item.enclosure.size || 0, + type : item.enclosure.type || mime.lookup(item.enclosure.url) } - }); - } + } + }); } - - ifTruePushArray(item.custom_elements, item_values, item.custom_elements); - - channel.push({ item: item_values }); - - }); - - //set up the attributes for the RSS feed. - var _attr = { - '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' - }; - - Object.keys(data.custom_namespaces).forEach(function(name) { - _attr['xmlns:' + name] = data.custom_namespaces[name]; - }); - - //only add namespace if GeoRSS is true - if(data.geoRSS){ - _attr['xmlns:geo'] = 'http://www.w3.org/2003/01/geo/wgs84_pos#'; } - return { - rss: [ - { _attr: _attr }, - { channel: channel } - ] - }; + ifTruePushArray(item.custom_elements, item_values, item.custom_elements); + + return { item: item_values }; } function RSS (options, items) { @@ -180,6 +190,48 @@ function RSS (options, items) { return this; }; + if (options.stream) { + this.streamXml = function (options) { + var mainAttributes = options.mainAttributes || {}; + this.root = xml.element({_attr: _.extend(mainAttributes, getRssFeedAttributes(options))}); + var root = options.root || 'rss'; + var rootElement = {}; + rootElement[root] = this.root; + this.stream = xml(rootElement, _.extend({stream: true ,declaration: true}, options.xmlOptions || {})); + }; + this.pushChannel = function (data) { + if (this.root) { + this.channel = xml.element(convertChannel(data)); + this.root.push({channel: this.channel}); + } + }; + + this.pushItem = function (item) { + if (this.channel) { + if (!this.items) { + this.items = xml.element([]); + this.channel.push({items: this.items}); + } + this.items.push(convertItem(item, {})); + } + }; + + this.closeItems = function () { + if (this.items) + this.items.close(); + }; + + this.closeChannel = function () { + if (this.channel) + this.channel.close(); + }; + + this.closeRoot = function () { + if (this.root) + this.root.close(); + }; + } + this.xml = function(indent) { return '' + xml(generateXML(this), indent); diff --git a/package.json b/package.json index 5947e8f..c15dfa8 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ }, "dependencies": { "mime-types": "^2.1.7", + "underscore": "~1.8.3", "xml": "^1.0.0" }, "devDependencies": {