mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-08-21 12:55:22 +00:00
Merge pull request #2089 from rejas/newsfeed
Cleaned up newsfeed module code
This commit is contained in:
@@ -18,6 +18,7 @@ _This release is scheduled to be released on 2020-10-01._
|
|||||||
### Updated
|
### Updated
|
||||||
|
|
||||||
- Change incorrect weather.js default properties.
|
- Change incorrect weather.js default properties.
|
||||||
|
- Cleaned up newsfeed module.
|
||||||
|
|
||||||
### Deleted
|
### Deleted
|
||||||
|
|
||||||
|
@@ -84,11 +84,11 @@ Module.register("newsfeed", {
|
|||||||
|
|
||||||
// Override dom generator.
|
// Override dom generator.
|
||||||
getDom: function () {
|
getDom: function () {
|
||||||
var wrapper = document.createElement("div");
|
const wrapper = document.createElement("div");
|
||||||
|
|
||||||
if (this.config.feedUrl) {
|
if (this.config.feedUrl) {
|
||||||
wrapper.className = "small bright";
|
wrapper.className = "small bright";
|
||||||
wrapper.innerHTML = this.translate("configuration_changed");
|
wrapper.innerHTML = this.translate("MODULE_CONFIG_CHANGED", { MODULE_NAME: "Newsfeed" });
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ Module.register("newsfeed", {
|
|||||||
if (this.newsItems.length > 0) {
|
if (this.newsItems.length > 0) {
|
||||||
// this.config.showFullArticle is a run-time configuration, triggered by optional notifications
|
// this.config.showFullArticle is a run-time configuration, triggered by optional notifications
|
||||||
if (!this.config.showFullArticle && (this.config.showSourceTitle || this.config.showPublishDate)) {
|
if (!this.config.showFullArticle && (this.config.showSourceTitle || this.config.showPublishDate)) {
|
||||||
var sourceAndTimestamp = document.createElement("div");
|
const sourceAndTimestamp = document.createElement("div");
|
||||||
sourceAndTimestamp.className = "newsfeed-source light small dimmed";
|
sourceAndTimestamp.className = "newsfeed-source light small dimmed";
|
||||||
|
|
||||||
if (this.config.showSourceTitle && this.newsItems[this.activeItem].sourceTitle !== "") {
|
if (this.config.showSourceTitle && this.newsItems[this.activeItem].sourceTitle !== "") {
|
||||||
@@ -157,22 +157,22 @@ Module.register("newsfeed", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.config.showFullArticle) {
|
if (!this.config.showFullArticle) {
|
||||||
var title = document.createElement("div");
|
const title = document.createElement("div");
|
||||||
title.className = "newsfeed-title bright medium light" + (!this.config.wrapTitle ? " no-wrap" : "");
|
title.className = "newsfeed-title bright medium light" + (!this.config.wrapTitle ? " no-wrap" : "");
|
||||||
title.innerHTML = this.newsItems[this.activeItem].title;
|
title.innerHTML = this.newsItems[this.activeItem].title;
|
||||||
wrapper.appendChild(title);
|
wrapper.appendChild(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isShowingDescription) {
|
if (this.isShowingDescription) {
|
||||||
var description = document.createElement("div");
|
const description = document.createElement("div");
|
||||||
description.className = "newsfeed-desc small light" + (!this.config.wrapDescription ? " no-wrap" : "");
|
description.className = "newsfeed-desc small light" + (!this.config.wrapDescription ? " no-wrap" : "");
|
||||||
var txtDesc = this.newsItems[this.activeItem].description;
|
const txtDesc = this.newsItems[this.activeItem].description;
|
||||||
description.innerHTML = this.config.truncDescription ? (txtDesc.length > this.config.lengthDescription ? txtDesc.substring(0, this.config.lengthDescription) + "..." : txtDesc) : txtDesc;
|
description.innerHTML = this.config.truncDescription ? (txtDesc.length > this.config.lengthDescription ? txtDesc.substring(0, this.config.lengthDescription) + "..." : txtDesc) : txtDesc;
|
||||||
wrapper.appendChild(description);
|
wrapper.appendChild(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.config.showFullArticle) {
|
if (this.config.showFullArticle) {
|
||||||
var fullArticle = document.createElement("iframe");
|
const fullArticle = document.createElement("iframe");
|
||||||
fullArticle.className = "";
|
fullArticle.className = "";
|
||||||
fullArticle.style.width = "100vw";
|
fullArticle.style.width = "100vw";
|
||||||
// very large height value to allow scrolling
|
// very large height value to allow scrolling
|
||||||
@@ -332,17 +332,6 @@ Module.register("newsfeed", {
|
|||||||
}, this.config.updateInterval);
|
}, this.config.updateInterval);
|
||||||
},
|
},
|
||||||
|
|
||||||
/* capitalizeFirstLetter(string)
|
|
||||||
* Capitalizes the first character of a string.
|
|
||||||
*
|
|
||||||
* argument string string - Input string.
|
|
||||||
*
|
|
||||||
* return string - Capitalized output string.
|
|
||||||
*/
|
|
||||||
capitalizeFirstLetter: function (string) {
|
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
||||||
},
|
|
||||||
|
|
||||||
resetDescrOrFullArticleAndTimer: function () {
|
resetDescrOrFullArticleAndTimer: function () {
|
||||||
this.isShowingDescription = this.config.showDescription;
|
this.isShowingDescription = this.config.showDescription;
|
||||||
this.config.showFullArticle = false;
|
this.config.showFullArticle = false;
|
||||||
@@ -356,7 +345,7 @@ Module.register("newsfeed", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
notificationReceived: function (notification, payload, sender) {
|
notificationReceived: function (notification, payload, sender) {
|
||||||
var before = this.activeItem;
|
const before = this.activeItem;
|
||||||
if (notification === "ARTICLE_NEXT") {
|
if (notification === "ARTICLE_NEXT") {
|
||||||
this.activeItem++;
|
this.activeItem++;
|
||||||
if (this.activeItem >= this.newsItems.length) {
|
if (this.activeItem >= this.newsItems.length) {
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
/* Magic Mirror
|
/* Magic Mirror
|
||||||
* Fetcher
|
* Node Helper: Newsfeed - NewsfeedFetcher
|
||||||
*
|
*
|
||||||
* By Michael Teeuw https://michaelteeuw.nl
|
* By Michael Teeuw https://michaelteeuw.nl
|
||||||
* MIT Licensed.
|
* MIT Licensed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const Log = require("../../../js/logger.js");
|
const Log = require("../../../js/logger.js");
|
||||||
const FeedMe = require("feedme");
|
const FeedMe = require("feedme");
|
||||||
const request = require("request");
|
const request = require("request");
|
||||||
@@ -17,39 +16,39 @@ const iconv = require("iconv-lite");
|
|||||||
* attribute reloadInterval number - Reload interval in milliseconds.
|
* attribute reloadInterval number - Reload interval in milliseconds.
|
||||||
* attribute logFeedWarnings boolean - Log warnings when there is an error parsing a news article.
|
* attribute logFeedWarnings boolean - Log warnings when there is an error parsing a news article.
|
||||||
*/
|
*/
|
||||||
|
const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
let reloadTimer = null;
|
||||||
|
let items = [];
|
||||||
|
|
||||||
|
let fetchFailedCallback = function () {};
|
||||||
|
let itemsReceivedCallback = function () {};
|
||||||
|
|
||||||
var Fetcher = function (url, reloadInterval, encoding, logFeedWarnings) {
|
|
||||||
var self = this;
|
|
||||||
if (reloadInterval < 1000) {
|
if (reloadInterval < 1000) {
|
||||||
reloadInterval = 1000;
|
reloadInterval = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
var reloadTimer = null;
|
|
||||||
var items = [];
|
|
||||||
|
|
||||||
var fetchFailedCallback = function () {};
|
|
||||||
var itemsReceivedCallback = function () {};
|
|
||||||
|
|
||||||
/* private methods */
|
/* private methods */
|
||||||
|
|
||||||
/* fetchNews()
|
/* fetchNews()
|
||||||
* Request the new items.
|
* Request the new items.
|
||||||
*/
|
*/
|
||||||
var fetchNews = function () {
|
const fetchNews = function () {
|
||||||
clearTimeout(reloadTimer);
|
clearTimeout(reloadTimer);
|
||||||
reloadTimer = null;
|
reloadTimer = null;
|
||||||
items = [];
|
items = [];
|
||||||
|
|
||||||
var parser = new FeedMe();
|
const parser = new FeedMe();
|
||||||
|
|
||||||
parser.on("item", function (item) {
|
parser.on("item", function (item) {
|
||||||
var title = item.title;
|
const title = item.title;
|
||||||
var description = item.description || item.summary || item.content || "";
|
let description = item.description || item.summary || item.content || "";
|
||||||
var pubdate = item.pubdate || item.published || item.updated || item["dc:date"];
|
const pubdate = item.pubdate || item.published || item.updated || item["dc:date"];
|
||||||
var url = item.url || item.link || "";
|
const url = item.url || item.link || "";
|
||||||
|
|
||||||
if (title && pubdate) {
|
if (title && pubdate) {
|
||||||
var regex = /(<([^>]+)>)/gi;
|
const regex = /(<([^>]+)>)/gi;
|
||||||
description = description.toString().replace(regex, "");
|
description = description.toString().replace(regex, "");
|
||||||
|
|
||||||
items.push({
|
items.push({
|
||||||
@@ -77,10 +76,17 @@ var Fetcher = function (url, reloadInterval, encoding, logFeedWarnings) {
|
|||||||
scheduleTimer();
|
scheduleTimer();
|
||||||
});
|
});
|
||||||
|
|
||||||
var nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
|
const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
|
||||||
var headers = { "User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)", "Cache-Control": "max-age=0, no-cache, no-store, must-revalidate", Pragma: "no-cache" };
|
const opts = {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)",
|
||||||
|
"Cache-Control": "max-age=0, no-cache, no-store, must-revalidate",
|
||||||
|
Pragma: "no-cache"
|
||||||
|
},
|
||||||
|
encoding: null
|
||||||
|
};
|
||||||
|
|
||||||
request({ uri: url, encoding: null, headers: headers })
|
request(url, opts)
|
||||||
.on("error", function (error) {
|
.on("error", function (error) {
|
||||||
fetchFailedCallback(self, error);
|
fetchFailedCallback(self, error);
|
||||||
scheduleTimer();
|
scheduleTimer();
|
||||||
@@ -92,7 +98,7 @@ var Fetcher = function (url, reloadInterval, encoding, logFeedWarnings) {
|
|||||||
/* scheduleTimer()
|
/* scheduleTimer()
|
||||||
* Schedule the timer for the next update.
|
* Schedule the timer for the next update.
|
||||||
*/
|
*/
|
||||||
var scheduleTimer = function () {
|
const scheduleTimer = function () {
|
||||||
clearTimeout(reloadTimer);
|
clearTimeout(reloadTimer);
|
||||||
reloadTimer = setTimeout(function () {
|
reloadTimer = setTimeout(function () {
|
||||||
fetchNews();
|
fetchNews();
|
||||||
@@ -148,4 +154,4 @@ var Fetcher = function (url, reloadInterval, encoding, logFeedWarnings) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Fetcher;
|
module.exports = NewsfeedFetcher;
|
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
const NodeHelper = require("node_helper");
|
const NodeHelper = require("node_helper");
|
||||||
const validUrl = require("valid-url");
|
const validUrl = require("valid-url");
|
||||||
const Fetcher = require("./fetcher.js");
|
const NewsfeedFetcher = require("./newsfeedfetcher.js");
|
||||||
const Log = require("../../../js/logger");
|
const Log = require("../../../js/logger");
|
||||||
|
|
||||||
module.exports = NodeHelper.create({
|
module.exports = NodeHelper.create({
|
||||||
@@ -32,37 +32,35 @@ module.exports = NodeHelper.create({
|
|||||||
* attribute config object - A configuration object containing reload interval in milliseconds.
|
* attribute config object - A configuration object containing reload interval in milliseconds.
|
||||||
*/
|
*/
|
||||||
createFetcher: function (feed, config) {
|
createFetcher: function (feed, config) {
|
||||||
var self = this;
|
const url = feed.url || "";
|
||||||
|
const encoding = feed.encoding || "UTF-8";
|
||||||
var url = feed.url || "";
|
const reloadInterval = feed.reloadInterval || config.reloadInterval || 5 * 60 * 1000;
|
||||||
var encoding = feed.encoding || "UTF-8";
|
|
||||||
var reloadInterval = feed.reloadInterval || config.reloadInterval || 5 * 60 * 1000;
|
|
||||||
|
|
||||||
if (!validUrl.isUri(url)) {
|
if (!validUrl.isUri(url)) {
|
||||||
self.sendSocketNotification("INCORRECT_URL", url);
|
this.sendSocketNotification("INCORRECT_URL", url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fetcher;
|
let fetcher;
|
||||||
if (typeof self.fetchers[url] === "undefined") {
|
if (typeof this.fetchers[url] === "undefined") {
|
||||||
Log.log("Create new news fetcher for url: " + url + " - Interval: " + reloadInterval);
|
Log.log("Create new news fetcher for url: " + url + " - Interval: " + reloadInterval);
|
||||||
fetcher = new Fetcher(url, reloadInterval, encoding, config.logFeedWarnings);
|
fetcher = new NewsfeedFetcher(url, reloadInterval, encoding, config.logFeedWarnings);
|
||||||
|
|
||||||
fetcher.onReceive(function (fetcher) {
|
fetcher.onReceive(() => {
|
||||||
self.broadcastFeeds();
|
this.broadcastFeeds();
|
||||||
});
|
});
|
||||||
|
|
||||||
fetcher.onError(function (fetcher, error) {
|
fetcher.onError((fetcher, error) => {
|
||||||
self.sendSocketNotification("FETCH_ERROR", {
|
this.sendSocketNotification("FETCH_ERROR", {
|
||||||
url: fetcher.url(),
|
url: fetcher.url(),
|
||||||
error: error
|
error: error
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
self.fetchers[url] = fetcher;
|
this.fetchers[url] = fetcher;
|
||||||
} else {
|
} else {
|
||||||
Log.log("Use existing news fetcher for url: " + url);
|
Log.log("Use existing news fetcher for url: " + url);
|
||||||
fetcher = self.fetchers[url];
|
fetcher = this.fetchers[url];
|
||||||
fetcher.setReloadInterval(reloadInterval);
|
fetcher.setReloadInterval(reloadInterval);
|
||||||
fetcher.broadcastItems();
|
fetcher.broadcastItems();
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"configuration_changed": "Die Konfigurationsoptionen für das Newsfeed-Modul haben sich geändert. \nBitte überprüfen Sie die Dokumentation."
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"configuration_changed": "The configuration options for the newsfeed module have changed.\nPlease check the documentation."
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"configuration_changed": "Las opciones de configuración para el módulo de suministro de noticias han cambiado. \nVerifique la documentación."
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"configuration_changed": "Les options de configuration du module newsfeed ont changé. \nVeuillez consulter la documentation."
|
|
||||||
}
|
|
@@ -1,29 +1,15 @@
|
|||||||
const expect = require("chai").expect;
|
const expect = require("chai").expect;
|
||||||
|
|
||||||
describe("Functions into modules/default/newsfeed/newsfeed.js", function () {
|
describe("Functions into modules/default/newsfeed/newsfeed.js", function () {
|
||||||
|
// Fake for use by newsletter.js
|
||||||
Module = {};
|
Module = {};
|
||||||
Module.definitions = {};
|
Module.definitions = {};
|
||||||
Module.register = function (name, moduleDefinition) {
|
Module.register = function (name, moduleDefinition) {
|
||||||
Module.definitions[name] = moduleDefinition;
|
Module.definitions[name] = moduleDefinition;
|
||||||
};
|
};
|
||||||
|
|
||||||
// load newsfeed.js
|
before(function () {
|
||||||
require("../../../modules/default/newsfeed/newsfeed.js");
|
// load newsfeed.js
|
||||||
|
require("../../../modules/default/newsfeed/newsfeed.js");
|
||||||
describe("capitalizeFirstLetter", function () {
|
|
||||||
const words = {
|
|
||||||
rodrigo: "Rodrigo",
|
|
||||||
"123m": "123m",
|
|
||||||
"magic mirror": "Magic mirror",
|
|
||||||
",a": ",a",
|
|
||||||
ñandú: "Ñandú",
|
|
||||||
".!": ".!"
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.keys(words).forEach((word) => {
|
|
||||||
it(`for ${word} should return ${words[word]}`, function () {
|
|
||||||
expect(Module.definitions.newsfeed.capitalizeFirstLetter(word)).to.equal(words[word]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
"NW": "NW",
|
"NW": "NW",
|
||||||
"NNW": "NNW",
|
"NNW": "NNW",
|
||||||
|
|
||||||
|
"MODULE_CONFIG_CHANGED": "Die Konfigurationsoptionen für das {MODULE_NAME} Modul haben sich geändert. \nBitte überprüfen Sie die Dokumentation.",
|
||||||
|
|
||||||
"UPDATE_NOTIFICATION": "Aktualisierung für MagicMirror² verfügbar.",
|
"UPDATE_NOTIFICATION": "Aktualisierung für MagicMirror² verfügbar.",
|
||||||
"UPDATE_NOTIFICATION_MODULE": "Aktualisierung für das {MODULE_NAME} Modul verfügbar.",
|
"UPDATE_NOTIFICATION_MODULE": "Aktualisierung für das {MODULE_NAME} Modul verfügbar.",
|
||||||
"UPDATE_INFO_SINGLE": "Die aktuelle Installation ist {COMMIT_COUNT} Commit hinter dem {BRANCH_NAME} Branch.",
|
"UPDATE_INFO_SINGLE": "Die aktuelle Installation ist {COMMIT_COUNT} Commit hinter dem {BRANCH_NAME} Branch.",
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
"NW": "NW",
|
"NW": "NW",
|
||||||
"NNW": "NNW",
|
"NNW": "NNW",
|
||||||
|
|
||||||
|
"MODULE_CONFIG_CHANGED": "The configuration options for the {MODULE_NAME} module have changed.\nPlease check the documentation.",
|
||||||
|
|
||||||
"UPDATE_NOTIFICATION": "MagicMirror² update available.",
|
"UPDATE_NOTIFICATION": "MagicMirror² update available.",
|
||||||
"UPDATE_NOTIFICATION_MODULE": "Update available for {MODULE_NAME} module.",
|
"UPDATE_NOTIFICATION_MODULE": "Update available for {MODULE_NAME} module.",
|
||||||
"UPDATE_INFO_SINGLE": "The current installation is {COMMIT_COUNT} commit behind on the {BRANCH_NAME} branch.",
|
"UPDATE_INFO_SINGLE": "The current installation is {COMMIT_COUNT} commit behind on the {BRANCH_NAME} branch.",
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
"NW": "NO",
|
"NW": "NO",
|
||||||
"NNW": "NNO",
|
"NNW": "NNO",
|
||||||
|
|
||||||
|
"MODULE_CONFIG_CHANGED": "Las opciones de configuración para el módulo {MODULE_NAME} han cambiado. \nVerifique la documentación.",
|
||||||
|
|
||||||
"UPDATE_NOTIFICATION": "MagicMirror² actualización disponible.",
|
"UPDATE_NOTIFICATION": "MagicMirror² actualización disponible.",
|
||||||
"UPDATE_NOTIFICATION_MODULE": "Disponible una actualización para el módulo {MODULE_NAME}.",
|
"UPDATE_NOTIFICATION_MODULE": "Disponible una actualización para el módulo {MODULE_NAME}.",
|
||||||
"UPDATE_INFO_SINGLE": "Tu actual instalación está {COMMIT_COUNT} commit cambios detrás de la rama {BRANCH_NAME}.",
|
"UPDATE_INFO_SINGLE": "Tu actual instalación está {COMMIT_COUNT} commit cambios detrás de la rama {BRANCH_NAME}.",
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
"NW": "NO",
|
"NW": "NO",
|
||||||
"NNW": "NNO",
|
"NNW": "NNO",
|
||||||
|
|
||||||
|
"MODULE_CONFIG_CHANGED": "Les options de configuration du module {MODULE_NAME} ont changé. \nVeuillez consulter la documentation.",
|
||||||
|
|
||||||
"UPDATE_NOTIFICATION": "Une mise à jour de MagicMirror² est disponible",
|
"UPDATE_NOTIFICATION": "Une mise à jour de MagicMirror² est disponible",
|
||||||
"UPDATE_NOTIFICATION_MODULE": "Une mise à jour est disponible pour le module {MODULE_NAME} .",
|
"UPDATE_NOTIFICATION_MODULE": "Une mise à jour est disponible pour le module {MODULE_NAME} .",
|
||||||
"UPDATE_INFO_SINGLE": "L'installation actuelle est {COMMIT_COUNT} commit en retard sur la branche {BRANCH_NAME} .",
|
"UPDATE_INFO_SINGLE": "L'installation actuelle est {COMMIT_COUNT} commit en retard sur la branche {BRANCH_NAME} .",
|
||||||
|
Reference in New Issue
Block a user