Allow the subscription to multiple news feeds in one newsfeed instance.

This commit is contained in:
Michael Teeuw
2016-04-20 14:39:38 +02:00
parent 3b1f1a41dc
commit fd500ac411
5 changed files with 192 additions and 45 deletions

View File

@@ -56,7 +56,13 @@ var config = {
module: 'newsfeed',
position: 'bottom_bar',
config: {
feedUrl: 'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml',
feeds: [
{
title: "New York Times",
url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml"
}
],
showSourceTitle: true,
showPublishDate: true
}
},

View File

@@ -14,6 +14,18 @@ modules: [
// The config property is optional.
// If no config is set, an example calendar is shown.
// See 'Configuration options' for more information.
feeds: [
{
title: "New York Times",
url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml",
},
{
title: "BBC
",
url: "http://feeds.bbci.co.uk/news/video_and_audio/news_front_page/rss.xml?edition=uk",
},
]
}
}
]
@@ -35,12 +47,25 @@ The following properties can be configured:
<tbody>
<tr>
<td><code>feedUrl</code></td>
<td>The url of the feed used for the headlines.<br>
<br><b>Default value:</b> <code>'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml'</code>
<td><code>feeds</code></td>
<td>An array of feed urls that will be used as source.<br>
More info about this object can be found below.
<br><b>Default value:</b> <code>[
{
title: "New York Times",
url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml",
}
]</code>
</td>
</tr>
<tr>
<td><code>showSourceTitle</code></td>
<td>Display the title of the source.<br>
<br><b>Possible values:</b> <code>true</code> or <code>false</code>
<br><b>Default value:</b> <code>true</code>
</td>
</tr>
<tr>
<td><code>showPublishDate</code></td>
<td>Display the publish date of an headline.<br>
@@ -77,9 +102,40 @@ The following properties can be configured:
<br><b>Default value:</b> <code>2000</code> (2.5 seconds)
</td>
</tr>
</tbody>
</table>
The `feeds` property contains an array with multiple objects. These objects have the following properties:
<table width="100%">
<!-- why, markdown... -->
<thead>
<tr>
<th>Option</th>
<th width="100%">Description</th>
</tr>
<thead>
<tbody>
<tr>
<td><code>title</code></td>
<td>The name of the feed source to be displayed above the news items.<br>
<br>This property is optional.
</td>
</tr>
<tr>
<td><code>url</code></td>
<td>The url of the feed used for the headlines.<br>
<br><b>Example:</b> <code>'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml'</code>
</td>
</tr>
<tr>
<td><code>encoding</code></td>
<td>The encoding of the news feed.<br>
<br>This property is optional.
<br><b>Possible values:</b><code>'UTF-8'</code>, <code>'ISO-8859-1'</code>, etc ...
<br><b>Default value:</b> <code>'UTF-8'</code>
</td>

View File

@@ -46,11 +46,13 @@ var Fetcher = function(url, reloadInterval, encoding) {
var regex = /(<([^>]+)>)/ig;
description = description.replace(regex, "");
if (item.title && description && item.pubdate) {
items.push({
title: item.title,
description: description,
pubdate: item.pubdate,
});
}
});
parser.on("end", function() {

View File

@@ -11,13 +11,19 @@ Module.register("newsfeed",{
// Default module config.
defaults: {
feedUrl: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml",
feeds: [
{
title: "New York Times",
url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml",
encoding: "UTF-8" //ISO-8859-1
}
],
showSourceTitle: true,
showPublishDate: true,
showDescription: false,
reloadInterval: 5 * 60 * 1000, // every 5 minutes
updateInterval: 10 * 1000,
animationSpeed: 2.5 * 1000,
encoding: "UTF-8" //ISO-8859-1
},
// Define required scripts.
@@ -36,34 +42,32 @@ Module.register("newsfeed",{
this.loaded = false;
this.activeItem = 0;
this.fetchNews();
this.registerFeeds();
},
// Override socket notification handler.
socketNotificationReceived: function(notification, payload) {
if (notification === "NEWS_ITEMS") {
if (payload.url === this.config.feedUrl) {
this.newsItems = payload.items;
this.generateFeed(payload);
if (!this.loaded) {
this.scheduleUpdateInterval();
}
this.loaded = true;
}
}
},
// Override dom generator.
getDom: function() {
var wrapper = document.createElement("div");
// wrapper.className = "small";
// for (var n in this.newsItems) {
// var item = this.newsItems[n];
// wrapper.innerHTML += item.title + '<br>';
// }
// return wrapper;
if (this.config.feedUrl) {
wrapper.className = "small bright";
wrapper.innerHTML = "The configuration options for the newsfeed module have changed.<br>Please check the documentation.";
return wrapper;
}
if (this.activeItem >= this.newsItems.length) {
this.activeItem = 0;
@@ -71,12 +75,16 @@ Module.register("newsfeed",{
if (this.newsItems.length > 0) {
if (this.config.showPublishDate) {
var timestamp = document.createElement("div");
timestamp.className = "light small dimmed";
timestamp.innerHTML = this.capitalizeFirstLetter(moment(new Date(this.newsItems[this.activeItem].pubdate)).fromNow() + ":");
//timestamp.innerHTML = this.config.feedUrl;
wrapper.appendChild(timestamp);
if (this.config.showSourceTitle || this.config.showPublishDate) {
var sourceAndTimestamp = document.createElement("div");
sourceAndTimestamp.className = "light small dimmed";
if (this.config.showSourceTitle && this.newsItems[this.activeItem].sourceTitle !== '') sourceAndTimestamp.innerHTML = this.newsItems[this.activeItem].sourceTitle;
if (this.config.showSourceTitle && this.newsItems[this.activeItem].sourceTitle !== '' && this.config.showPublishDate) sourceAndTimestamp.innerHTML += ', ';
if (this.config.showPublishDate) sourceAndTimestamp.innerHTML += moment(new Date(this.newsItems[this.activeItem].pubdate)).fromNow();
if (this.config.showSourceTitle && this.newsItems[this.activeItem].sourceTitle !== '' || this.config.showPublishDate) sourceAndTimestamp.innerHTML += ':';
wrapper.appendChild(sourceAndTimestamp);
}
var title = document.createElement("div");
@@ -99,16 +107,78 @@ Module.register("newsfeed",{
return wrapper;
},
/* fetchNews(compliments)
* Requests new data from news proxy.
/* registerFeeds()
* registers the feeds to be used by the backend.
*/
fetchNews: function() {
Log.log("Add news feed to fetcher: " + this.config.feedUrl);
registerFeeds: function() {
for (var f in this.config.feeds) {
var feed = this.config.feeds[f];
this.sendSocketNotification("ADD_FEED", {
url: this.config.feedUrl,
reloadInterval: this.config.reloadInterval,
encoding: this.config.encoding
feed: feed,
config: this.config
});
}
},
/* registerFeeds()
* Generate an ordered list of items for this configured module.
*
* attribute feeds object - An object with feeds returned by the nod helper.
*/
generateFeed: function(feeds) {
var newsItems = [];
for (var feed in feeds) {
var feedItems = feeds[feed];
if (this.subscribedToFeed(feed)) {
for (var i in feedItems) {
var item = feedItems[i];
item.sourceTitle = this.titleForFeed(feed);
newsItems.push(item);
}
}
}
newsItems.sort(function(a,b) {
var dateA = new Date(a.pubdate);
var dateB = new Date(b.pubdate);
return dateB - dateA;
});
this.newsItems = newsItems;
},
/* subscribedToFeed(feedUrl)
* Check if this module is configured to show this feed.
*
* attribute feedUrl string - Url of the feed to check.
*
* returns bool
*/
subscribedToFeed: function(feedUrl) {
for (var f in this.config.feeds) {
var feed = this.config.feeds[f];
if (feed.url === feedUrl) {
return true;
}
}
return false;
},
/* subscribedToFeed(feedUrl)
* Returns title for a specific feed Url.
*
* attribute feedUrl string - Url of the feed to check.
*
* returns string
*/
titleForFeed: function(feedUrl) {
for (var f in this.config.feeds) {
var feed = this.config.feeds[f];
if (feed.url === feedUrl) {
return feed.title || '';
}
}
return '';
},
/* scheduleUpdateInterval()

View File

@@ -13,14 +13,14 @@ module.exports = NodeHelper.create({
// Subclass start method.
start: function() {
console.log("Starting module: " + this.name);
this.fetchers = [];
},
// Subclass socketNotificationReceived received.
socketNotificationReceived: function(notification, payload) {
if (notification === "ADD_FEED") {
this.createFetcher(payload.url, payload.reloadInterval, payload.encoding);
this.createFetcher(payload.feed, payload.config);
return;
}
},
@@ -32,9 +32,13 @@ module.exports = NodeHelper.create({
* attribute reloadInterval number - Reload interval in milliseconds.
*/
createFetcher: function(url, reloadInterval, encoding) {
createFetcher: function(feed, config) {
var self = this;
var url = feed.url || '';
var encoding = feed.encoding || 'UTF-8';
var reloadInterval = config.reloadInterval || 5 * 60 * 1000;
if (!validUrl.isUri(url)) {
self.sendSocketNotification("INCORRECT_URL", url);
return;
@@ -46,10 +50,7 @@ module.exports = NodeHelper.create({
fetcher = new Fetcher(url, reloadInterval, encoding);
fetcher.onReceive(function(fetcher) {
self.sendSocketNotification("NEWS_ITEMS", {
url: fetcher.url(),
items: fetcher.items()
});
self.broadcastFeeds();
});
fetcher.onError(function(fetcher, error) {
@@ -68,5 +69,17 @@ module.exports = NodeHelper.create({
}
fetcher.startFetch();
},
/* broadcastFeeds()
* Creates an object with all feed items of the different registered feeds,
* and broadcasts these using sendSocketNotification.
*/
broadcastFeeds: function() {
var feeds = {};
for (var f in this.fetchers) {
feeds[f] = this.fetchers[f].items();
}
this.sendSocketNotification("NEWS_ITEMS", feeds);
}
});