apostrophe-rss
Advanced tools
Comparing version 0.5.13 to 0.5.14
99
index.js
var feedparser = require('feedparser'); | ||
var extend = require('extend'); | ||
var _ = require('lodash'); | ||
var cache = {}; | ||
var pending = {}; | ||
@@ -32,2 +33,3 @@ module.exports = function(options, callback) { | ||
// resources needed also by non-editing users.) | ||
self.pushAsset('script', 'content', { when: 'always' }); | ||
self.pushAsset('script', 'editor', { when: 'user' }); | ||
@@ -40,2 +42,5 @@ self.pushAsset('stylesheet', 'content', { when: 'always' }); | ||
self.icon = options.icon || 'icon-rss'; | ||
self.jsonProperties = [ '_ajax' ]; | ||
self.sanitize = function(item) { | ||
@@ -47,6 +52,50 @@ if (!item.feed.match(/^https?\:\/\//)) { | ||
}; | ||
self.renderWidget = function(data) { | ||
return self.render('rss', data); | ||
if (data.item._ajax) { | ||
// We've decided to let the browser | ||
// fetch this with a separate AJAX requet | ||
return ''; | ||
} else { | ||
// We're rendering it now, during the page load, | ||
// server side | ||
return self.render('rss', data); | ||
} | ||
}; | ||
app.get('/apos-rss/render-feed', function(req, res) { | ||
var item = { | ||
feed: apos.sanitizeString(req.query.feed), | ||
limit: apos.sanitizeInteger(req.query.limit) | ||
}; | ||
return self.loadFeed(item, function() { | ||
return res.send(self.renderWidget({ item: item })); | ||
}); | ||
}); | ||
// Loader method for the widget | ||
self.load = function(req, item, callback) { | ||
var key = self.getKey(item); | ||
// If it's in the cache, "load" it now. Avoid a separate | ||
// AJAX request. | ||
if (cache[key]) { | ||
return self.loadFeed(item, callback); | ||
} | ||
// It's not in the cache. Mark it as needing to be | ||
// loaded by the browser so we don't block the | ||
// rest of the page from loading now. We can do that | ||
// because it's not important for Google to see | ||
// RSS content on the page. | ||
item._ajax = true; | ||
return setImmediate(callback); | ||
}; | ||
// Generate a cache key for this item | ||
self.getKey = function(item) { | ||
return JSON.stringify({ feed: item.feed, limit: item.limit }); | ||
}; | ||
// Load the feed. Shared by self.load and the render-feed route | ||
self.loadFeed = function(item, callback) { | ||
// Asynchronously load the actual RSS feed | ||
@@ -57,12 +106,31 @@ // The properties you add should start with an _ to denote that | ||
var now = new Date(); | ||
var now = Date.now(); | ||
// Take all properties into account, not just the feed, so the cache | ||
// doesn't prevent us from seeing a change in the limit property right away | ||
var key = JSON.stringify({ feed: item.feed, limit: item.limit }); | ||
if (cache.hasOwnProperty(key) && ((cache[key].when + lifetime) > now.getTime())) { | ||
var key = self.getKey(item); | ||
// If we already have it, deliver it | ||
if (cache[key] && ((cache[key].when + lifetime) > now)) { | ||
item._entries = cache[key].data; | ||
item._failed = cache[key].failed; | ||
return callback(); | ||
} | ||
// If we're already waiting for it, wait for it | ||
if (pending[key]) { | ||
pending[key].push({ | ||
item: item, | ||
callback: function() { | ||
return callback(); | ||
} | ||
}); | ||
return; | ||
} | ||
// Start a pending queue for this request | ||
pending[key] = []; | ||
feedparser.parseUrl(item.feed).on('complete', function(meta, articles) { | ||
var end = Date.now(); | ||
articles = articles.slice(0, item.limit); | ||
@@ -79,9 +147,24 @@ | ||
}); | ||
// Cache for fast access later | ||
cache[key] = { when: now.getTime(), data: item._entries }; | ||
return callback(); | ||
cache[key] = { when: now, data: item._entries }; | ||
return done(); | ||
}).on('error', function(error) { | ||
// Cache failures too, don't go crazy trying to get | ||
// to a feed that's down | ||
item._failed = true; | ||
cache[key] = { when: now, failed: true }; | ||
return done(); | ||
}); | ||
function done() { | ||
// Notify everyone else who was waiting for this | ||
// fetch to finish | ||
_.each(pending[key], function(i) { | ||
i.item._entries = item._entries; | ||
i.item._failed = item._failed; | ||
return i.callback(); | ||
}); | ||
delete pending[key]; | ||
return callback(); | ||
}); | ||
} | ||
}; | ||
@@ -88,0 +171,0 @@ |
{ | ||
"name": "apostrophe-rss", | ||
"version": "0.5.13", | ||
"version": "0.5.14", | ||
"description": "Adds an RSS feed widget to the Apostrophe content management system", | ||
@@ -25,6 +25,7 @@ "main": "index.js", | ||
"dependencies": { | ||
"extend": "~1.1.3", | ||
"feedparser": "~0.11.0", | ||
"extend": "~1.1.3" | ||
"lodash": "^2.4.1" | ||
}, | ||
"devDependencies": {} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10257
11
197
3
+ Addedlodash@^2.4.1
+ Addedlodash@2.4.2(transitive)