Merge branch 'develop' into Issue-TranslateEncodedHtml

This commit is contained in:
Michael Teeuw 2021-01-21 15:10:14 +01:00 committed by GitHub
commit 78190d9c7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 358 additions and 217 deletions

View File

@ -12,7 +12,9 @@ _This release is scheduled to be released on 2021-04-01._
### Added
- Added GitHub workflows for automated testing and changelog enforcement.
- Add CodeCov badge to Readme.
- Added CodeCov badge to Readme.
- Added CURRENTWEATHER_TYPE notification to currentweather and weather module, use it in compliments module.
- Added `start:dev` command to the npm scripts for starting electron with devTools open.
### Updated
@ -20,6 +22,7 @@ _This release is scheduled to be released on 2021-04-01._
- Cleaned up old code on server side.
- Convert `-0` to `0` when displaying temperature.
- Code cleanup for FEELS like and added {DEGREE} placeholder for FEELSLIKE for each language
- Converted newsfeed module to use templates.
### Removed
@ -30,6 +33,8 @@ _This release is scheduled to be released on 2021-04-01._
- Added default log levels to stop calendar log spamming.
- Fix socket.io cors errors, see [breaking change since socket.io v3](https://socket.io/docs/v3/handling-cors/)
- Fix Issue with weather forecast icons due to fixed day start and end time (#2221)
- Fix empty directory for each module's main javascript file in the inspector
- Fix Issue with weather forecast icons unit tests with different timezones (#2221)
- Fix issue with unencoded characters in translated strings when using nunjuck template (`Loading …` as an example)
## [2.14.0] - 2021-01-01

View File

@ -114,7 +114,7 @@ var Loader = (function () {
* @param {Function} callback Function called when done.
*/
var loadModule = function (module, callback) {
var url = module.path + "/" + module.file;
var url = module.path + module.file;
var afterLoad = function () {
var moduleObject = Module.create(module.name);

View File

@ -182,34 +182,14 @@ Module.register("compliments", {
},
// From data currentweather set weather type
setCurrentWeatherType: function (data) {
var weatherIconTable = {
"01d": "day_sunny",
"02d": "day_cloudy",
"03d": "cloudy",
"04d": "cloudy_windy",
"09d": "showers",
"10d": "rain",
"11d": "thunderstorm",
"13d": "snow",
"50d": "fog",
"01n": "night_clear",
"02n": "night_cloudy",
"03n": "night_cloudy",
"04n": "night_cloudy",
"09n": "night_showers",
"10n": "night_rain",
"11n": "night_thunderstorm",
"13n": "night_snow",
"50n": "night_alt_cloudy_windy"
};
this.currentWeatherType = weatherIconTable[data.weather[0].icon];
setCurrentWeatherType: function (type) {
this.currentWeatherType = type;
},
// Override notification handler.
notificationReceived: function (notification, payload, sender) {
if (notification === "CURRENTWEATHER_DATA") {
this.setCurrentWeatherType(payload.data);
if (notification === "CURRENTWEATHER_TYPE") {
this.setCurrentWeatherType(payload.type);
}
}
});

View File

@ -47,24 +47,24 @@ Module.register("currentweather", {
roundTemp: false,
iconTable: {
"01d": "wi-day-sunny",
"02d": "wi-day-cloudy",
"03d": "wi-cloudy",
"04d": "wi-cloudy-windy",
"09d": "wi-showers",
"10d": "wi-rain",
"11d": "wi-thunderstorm",
"13d": "wi-snow",
"50d": "wi-fog",
"01n": "wi-night-clear",
"02n": "wi-night-cloudy",
"03n": "wi-night-cloudy",
"04n": "wi-night-cloudy",
"09n": "wi-night-showers",
"10n": "wi-night-rain",
"11n": "wi-night-thunderstorm",
"13n": "wi-night-snow",
"50n": "wi-night-alt-cloudy-windy"
"01d": "day-sunny",
"02d": "day-cloudy",
"03d": "cloudy",
"04d": "cloudy-windy",
"09d": "showers",
"10d": "rain",
"11d": "thunderstorm",
"13d": "snow",
"50d": "fog",
"01n": "night-clear",
"02n": "night-cloudy",
"03n": "night-cloudy",
"04n": "night-cloudy",
"09n": "night-showers",
"10n": "night-rain",
"11n": "night-thunderstorm",
"13n": "night-snow",
"50n": "night-alt-cloudy-windy"
}
},
@ -219,7 +219,7 @@ Module.register("currentweather", {
if (this.config.hideTemp === false) {
var weatherIcon = document.createElement("span");
weatherIcon.className = "wi weathericon " + this.weatherType;
weatherIcon.className = "wi weathericon wi-" + this.weatherType;
large.appendChild(weatherIcon);
var temperature = document.createElement("span");
@ -502,6 +502,7 @@ Module.register("currentweather", {
this.loaded = true;
this.updateDom(this.config.animationSpeed);
this.sendNotification("CURRENTWEATHER_DATA", { data: data });
this.sendNotification("CURRENTWEATHER_TYPE", { type: this.config.iconTable[data.weather[0].icon].replace("-", "_") });
},
/* scheduleUpdate()

View File

@ -0,0 +1,3 @@
<div>
<iframe class="newsfeed-fullarticle" src="{{ url }}"></iframe>
</div>

View File

@ -0,0 +1,14 @@
iframe.newsfeed-fullarticle {
width: 100vw;
/* very large height value to allow scrolling */
height: 3000px;
top: 0;
left: 0;
border: none;
z-index: 1;
}
.region.bottom.bar.newsfeed-fullarticle {
bottom: inherit;
top: -90px;
}

View File

@ -44,6 +44,11 @@ Module.register("newsfeed", {
return ["moment.js"];
},
//Define required styles.
getStyles: function () {
return ["newsfeed.css"];
},
// Define required translations.
getTranslations: function () {
// The translations for the default modules are defined in the core translation files.
@ -75,6 +80,9 @@ Module.register("newsfeed", {
this.generateFeed(payload);
if (!this.loaded) {
if (this.config.hideLoading) {
this.show();
}
this.scheduleUpdateInterval();
}
@ -82,123 +90,43 @@ Module.register("newsfeed", {
}
},
// Override dom generator.
getDom: function () {
const wrapper = document.createElement("div");
//Override fetching of template name
getTemplate: function () {
if (this.config.feedUrl) {
wrapper.className = "small bright";
wrapper.innerHTML = this.translate("MODULE_CONFIG_CHANGED", { MODULE_NAME: "Newsfeed" });
return wrapper;
return "oldconfig.njk";
} else if (this.config.showFullArticle) {
return "fullarticle.njk";
}
return "newsfeed.njk";
},
//Override template data and return whats used for the current template
getTemplateData: function () {
// this.config.showFullArticle is a run-time configuration, triggered by optional notifications
if (this.config.showFullArticle) {
return {
url: this.getActiveItemURL()
};
}
if (this.newsItems.length === 0) {
return {
loaded: false
};
}
if (this.activeItem >= this.newsItems.length) {
this.activeItem = 0;
}
const item = this.newsItems[this.activeItem];
if (this.newsItems.length > 0) {
// this.config.showFullArticle is a run-time configuration, triggered by optional notifications
if (!this.config.showFullArticle && (this.config.showSourceTitle || this.config.showPublishDate)) {
const sourceAndTimestamp = document.createElement("div");
sourceAndTimestamp.className = "newsfeed-source 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);
}
//Remove selected tags from the beginning of rss feed items (title or description)
if (this.config.removeStartTags === "title" || this.config.removeStartTags === "both") {
for (let f = 0; f < this.config.startTags.length; f++) {
if (this.newsItems[this.activeItem].title.slice(0, this.config.startTags[f].length) === this.config.startTags[f]) {
this.newsItems[this.activeItem].title = this.newsItems[this.activeItem].title.slice(this.config.startTags[f].length, this.newsItems[this.activeItem].title.length);
}
}
}
if (this.config.removeStartTags === "description" || this.config.removeStartTags === "both") {
if (this.isShowingDescription) {
for (let f = 0; f < this.config.startTags.length; f++) {
if (this.newsItems[this.activeItem].description.slice(0, this.config.startTags[f].length) === this.config.startTags[f]) {
this.newsItems[this.activeItem].description = this.newsItems[this.activeItem].description.slice(this.config.startTags[f].length, this.newsItems[this.activeItem].description.length);
}
}
}
}
//Remove selected tags from the end of rss feed items (title or description)
if (this.config.removeEndTags) {
for (let f = 0; f < this.config.endTags.length; f++) {
if (this.newsItems[this.activeItem].title.slice(-this.config.endTags[f].length) === this.config.endTags[f]) {
this.newsItems[this.activeItem].title = this.newsItems[this.activeItem].title.slice(0, -this.config.endTags[f].length);
}
}
if (this.isShowingDescription) {
for (let f = 0; f < this.config.endTags.length; f++) {
if (this.newsItems[this.activeItem].description.slice(-this.config.endTags[f].length) === this.config.endTags[f]) {
this.newsItems[this.activeItem].description = this.newsItems[this.activeItem].description.slice(0, -this.config.endTags[f].length);
}
}
}
}
if (!this.config.showFullArticle) {
const title = document.createElement("div");
title.className = "newsfeed-title bright medium light" + (!this.config.wrapTitle ? " no-wrap" : "");
title.innerHTML = this.newsItems[this.activeItem].title;
wrapper.appendChild(title);
}
if (this.isShowingDescription) {
const description = document.createElement("div");
description.className = "newsfeed-desc small light" + (!this.config.wrapDescription ? " no-wrap" : "");
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;
wrapper.appendChild(description);
}
if (this.config.showFullArticle) {
const fullArticle = document.createElement("iframe");
fullArticle.className = "";
fullArticle.style.width = "100vw";
// very large height value to allow scrolling
fullArticle.height = "3000";
fullArticle.style.height = "3000";
fullArticle.style.top = "0";
fullArticle.style.left = "0";
fullArticle.style.border = "none";
fullArticle.src = this.getActiveItemURL();
fullArticle.style.zIndex = 1;
wrapper.appendChild(fullArticle);
}
if (this.config.hideLoading) {
this.show();
}
} else {
if (this.config.hideLoading) {
this.hide();
} else {
wrapper.innerHTML = this.translate("LOADING");
wrapper.className = "small dimmed";
}
}
return wrapper;
return {
loaded: true,
config: this.config,
sourceTitle: item.sourceTitle,
publishDate: moment(new Date(item.pubdate)).fromNow(),
title: item.title,
description: item.description
};
},
getActiveItemURL: function () {
@ -257,6 +185,45 @@ Module.register("newsfeed", {
}, this);
}
newsItems.forEach((item) => {
//Remove selected tags from the beginning of rss feed items (title or description)
if (this.config.removeStartTags === "title" || this.config.removeStartTags === "both") {
for (let f = 0; f < this.config.startTags.length; f++) {
if (item.title.slice(0, this.config.startTags[f].length) === this.config.startTags[f]) {
item.title = item.title.slice(this.config.startTags[f].length, item.title.length);
}
}
}
if (this.config.removeStartTags === "description" || this.config.removeStartTags === "both") {
if (this.isShowingDescription) {
for (let f = 0; f < this.config.startTags.length; f++) {
if (item.description.slice(0, this.config.startTags[f].length) === this.config.startTags[f]) {
item.description = item.description.slice(this.config.startTags[f].length, item.description.length);
}
}
}
}
//Remove selected tags from the end of rss feed items (title or description)
if (this.config.removeEndTags) {
for (let f = 0; f < this.config.endTags.length; f++) {
if (item.title.slice(-this.config.endTags[f].length) === this.config.endTags[f]) {
item.title = item.title.slice(0, -this.config.endTags[f].length);
}
}
if (this.isShowingDescription) {
for (let f = 0; f < this.config.endTags.length; f++) {
if (item.description.slice(-this.config.endTags[f].length) === this.config.endTags[f]) {
item.description = item.description.slice(0, -this.config.endTags[f].length);
}
}
}
}
});
// get updated news items and broadcast them
var updatedItems = [];
newsItems.forEach((value) => {
@ -335,8 +302,7 @@ Module.register("newsfeed", {
this.config.showFullArticle = false;
this.scrollPosition = 0;
// reset bottom bar alignment
document.getElementsByClassName("region bottom bar")[0].style.bottom = "0";
document.getElementsByClassName("region bottom bar")[0].style.top = "inherit";
document.getElementsByClassName("region bottom bar")[0].classList.remove("newsfeed-fullarticle");
if (!this.timer) {
this.scheduleUpdateInterval();
}
@ -344,7 +310,9 @@ Module.register("newsfeed", {
notificationReceived: function (notification, payload, sender) {
const before = this.activeItem;
if (notification === "ARTICLE_NEXT") {
if (notification === "MODULE_DOM_CREATED" && this.config.hideLoading) {
this.hide();
} else if (notification === "ARTICLE_NEXT") {
this.activeItem++;
if (this.activeItem >= this.newsItems.length) {
this.activeItem = 0;
@ -406,8 +374,7 @@ Module.register("newsfeed", {
this.config.showFullArticle = !this.isShowingDescription;
// make bottom bar align to top to allow scrolling
if (this.config.showFullArticle === true) {
document.getElementsByClassName("region bottom bar")[0].style.bottom = "inherit";
document.getElementsByClassName("region bottom bar")[0].style.top = "-90px";
document.getElementsByClassName("region bottom bar")[0].classList.add("newsfeed-fullarticle");
}
clearInterval(this.timer);
this.timer = null;

View File

@ -0,0 +1,28 @@
{% if loaded %}
<div>
{% if (config.showSourceTitle and sourceTitle) or config.showPublishDate %}
<div class="newsfeed-source light small dimmed">
{% if sourceTitle and config.showSourceTitle %}
{{ sourceTitle }}{% if config.showPublishDate %}, {% else %}: {% endif %}
{% endif %}
{% if config.showPublishDate %}
{{ publishDate }}:
{% endif %}
</div>
{% endif %}
<div class="newsfeed-title bright medium light{{ ' no-wrap' if config.wrapTitle }}">
{{ title }}
</div>
<div class="newsfeed-desc small light{{ ' no-wrap' if config.wrapDescription }}">
{% if config.truncDescription %}
{{ description | truncate(config.lengthDescription) }}
{% else %}
{{ description }}
{% endif %}
</div>
</div>
{% else %}
<div class="small dimmed">
{{ "LOADING" | translate | safe }}
</div>
{% endif %}

View File

@ -0,0 +1,3 @@
<div class="small bright">
{{ "MODULE_CONFIG_CHANGED" | translate({MODULE_NAME: "Newsfeed"}) | safe }}
</div>

View File

@ -154,6 +154,10 @@ Module.register("weather", {
Log.log("New weather information available.");
this.updateDom(0);
this.scheduleUpdate();
if (this.weatherProvider.currentWeather()) {
this.sendNotification("CURRENTWEATHER_TYPE", { type: this.weatherProvider.currentWeather().weatherType.replace("-", "_") });
}
},
scheduleUpdate: function (delay = null) {

View File

@ -355,8 +355,8 @@ Module.register("weatherforecast", {
var dayEnds = 17;
if (data.city && data.city.sunrise && data.city.sunset) {
dayStarts = moment.unix(data.city.sunrise).toDate().getHours();
dayEnds = moment.unix(data.city.sunset).toDate().getHours();
dayStarts = new Date(moment.unix(data.city.sunrise).locale("en").format("YYYY/MM/DD HH:mm:ss")).getHours();
dayEnds = new Date(moment.unix(data.city.sunset).locale("en").format("YYYY/MM/DD HH:mm:ss")).getHours();
}
// Handle different structs between forecast16 and onecall endpoints
@ -378,10 +378,10 @@ Module.register("weatherforecast", {
var hour;
if (forecast.dt_txt) {
day = moment(forecast.dt_txt, "YYYY-MM-DD hh:mm:ss").format("ddd");
hour = moment(forecast.dt_txt, "YYYY-MM-DD hh:mm:ss").toDate().getHours();
hour = new Date(moment(forecast.dt_txt).locale("en").format("YYYY-MM-DD HH:mm:ss")).getHours();
} else {
day = moment(forecast.dt, "X").format("ddd");
hour = moment(forecast.dt, "X").toDate().getHours();
hour = new Date(moment(forecast.dt, "X")).getHours();
}
if (day !== lastDay) {

148
package-lock.json generated
View File

@ -266,9 +266,9 @@
}
},
"@eslint/eslintrc": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz",
"integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==",
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz",
"integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==",
"requires": {
"ajv": "^6.12.4",
"debug": "^4.1.1",
@ -277,7 +277,7 @@
"ignore": "^4.0.6",
"import-fresh": "^3.2.1",
"js-yaml": "^3.13.1",
"lodash": "^4.17.19",
"lodash": "^4.17.20",
"minimatch": "^3.0.4",
"strip-json-comments": "^3.1.1"
}
@ -1270,9 +1270,9 @@
}
},
"comment-parser": {
"version": "0.7.6",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.6.tgz",
"integrity": "sha512-GKNxVA7/iuTnAqGADlTWX4tkhzxZKXp5fLJqKTlQLHkE65XDUKutZ3BHaJC5IGcper2tT3QRD1xr4o3jNpgXXg==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.0.tgz",
"integrity": "sha512-Q4dQ9niTWOF01ufvH/z6Z3RsBkwr7G42IsaFjuNliL6CY9ZeOEU3jRwTNY2mTY1ibAsASMrXnlQtx2tOb7Q8MA==",
"dev": true
},
"commondir": {
@ -1966,9 +1966,9 @@
}
},
"engine.io": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.0.6.tgz",
"integrity": "sha512-rf7HAVZpcRrcKEKddgIzYUnwg0g5HE1RvJaTLwkcfJmce4g+po8aMuE6vxzp6JwlK8FEq/vi0KWN6tA585DjaA==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.0.tgz",
"integrity": "sha512-vW7EAtn0HDQ4MtT5QbmCHF17TaYLONv2/JwdYsq9USPRZVM4zG7WB3k0Nc321z8EuSOlhGokrYlYx4176QhD0A==",
"requires": {
"accepts": "~1.3.4",
"base64id": "2.0.0",
@ -2119,12 +2119,12 @@
}
},
"eslint": {
"version": "7.17.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.17.0.tgz",
"integrity": "sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ==",
"version": "7.18.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz",
"integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==",
"requires": {
"@babel/code-frame": "^7.0.0",
"@eslint/eslintrc": "^0.2.2",
"@eslint/eslintrc": "^0.3.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@ -2148,7 +2148,7 @@
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash": "^4.17.19",
"lodash": "^4.17.20",
"minimatch": "^3.0.4",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
@ -2235,12 +2235,12 @@
"dev": true
},
"eslint-plugin-jsdoc": {
"version": "30.7.13",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-30.7.13.tgz",
"integrity": "sha512-YM4WIsmurrp0rHX6XiXQppqKB8Ne5ATiZLJe2+/fkp9l9ExXFr43BbAbjZaVrpCT+tuPYOZ8k1MICARHnURUNQ==",
"version": "31.0.6",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-31.0.6.tgz",
"integrity": "sha512-wGd83EcR+M0HHBgVx3f4gf78z5gMyEil6fqebpAFPeG9fgbUcP1XiWikTWSW3rJrjj7rQvCud6A/IRFMFzanLQ==",
"dev": true,
"requires": {
"comment-parser": "^0.7.6",
"comment-parser": "1.1.0",
"debug": "^4.3.1",
"jsdoctypeparser": "^9.0.0",
"lodash": "^4.17.20",
@ -2693,12 +2693,12 @@
}
},
"find-versions": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
"integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz",
"integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==",
"dev": true,
"requires": {
"semver-regex": "^2.0.0"
"semver-regex": "^3.1.2"
}
},
"flat": {
@ -3218,18 +3218,18 @@
"dev": true
},
"husky": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/husky/-/husky-4.3.6.tgz",
"integrity": "sha512-o6UjVI8xtlWRL5395iWq9LKDyp/9TE7XMOTvIpEVzW638UcGxTmV5cfel6fsk/jbZSTlvfGVJf2svFtybcIZag==",
"version": "4.3.8",
"resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz",
"integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
"ci-info": "^2.0.0",
"compare-versions": "^3.6.0",
"cosmiconfig": "^7.0.0",
"find-versions": "^3.2.0",
"find-versions": "^4.0.0",
"opencollective-postinstall": "^2.0.2",
"pkg-dir": "^4.2.0",
"pkg-dir": "^5.0.0",
"please-upgrade-node": "^3.2.0",
"slash": "^3.0.0",
"which-pm-runs": "^1.0.0"
@ -3269,12 +3269,64 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
"requires": {
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"requires": {
"p-locate": "^5.0.0"
}
},
"p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"requires": {
"yocto-queue": "^0.1.0"
}
},
"p-locate": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"requires": {
"p-limit": "^3.0.2"
}
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"pkg-dir": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz",
"integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==",
"dev": true,
"requires": {
"find-up": "^5.0.0"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@ -5940,9 +5992,9 @@
"integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w="
},
"semver-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz",
"integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz",
"integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==",
"dev": true
},
"send": {
@ -6142,9 +6194,9 @@
}
},
"socket.io": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.0.5.tgz",
"integrity": "sha512-5yWQ43P/4IttmPCGKDQ3CVocBiJWGpibyhYJxgUhf69EHMzmK8XW0DkmHIoYdLmZaVZJyiEkUqpeC7rSCIqekw==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.0.tgz",
"integrity": "sha512-Aqg2dlRh6xSJvRYK31ksG65q4kmBOqU4g+1ukhPcoT6wNGYoIwSYPlCPuRwOO9pgLUajojGFztl6+V2opmKcww==",
"requires": {
"@types/cookie": "^0.4.0",
"@types/cors": "^2.8.8",
@ -6152,15 +6204,15 @@
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"debug": "~4.3.1",
"engine.io": "~4.0.6",
"socket.io-adapter": "~2.0.3",
"engine.io": "~4.1.0",
"socket.io-adapter": "~2.1.0",
"socket.io-parser": "~4.0.3"
},
"dependencies": {
"@types/node": {
"version": "14.14.20",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz",
"integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A=="
"version": "14.14.21",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.21.tgz",
"integrity": "sha512-cHYfKsnwllYhjOzuC5q1VpguABBeecUp24yFluHpn/BQaVxB1CuQ1FSRZCzrPxrkIfWISXV2LbeoBthLWg0+0A=="
},
"debug": {
"version": "4.3.1",
@ -6173,14 +6225,14 @@
}
},
"socket.io-adapter": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.0.3.tgz",
"integrity": "sha512-2wo4EXgxOGSFueqvHAdnmi5JLZzWqMArjuP4nqC26AtLh5PoCPsaRbRdah2xhcwTAMooZfjYiNVNkkmmSMaxOQ=="
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz",
"integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg=="
},
"socket.io-parser": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.3.tgz",
"integrity": "sha512-m4ybFiP4UYVORRt7jcdqf8UWx+ywVdAqqsJyruXxAdD3Sv6MDemijWij34mOWdMJ55bEdIb9jACBhxUgNK6sxw==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
"integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
"requires": {
"@types/component-emitter": "^1.2.10",
"component-emitter": "~1.3.0",
@ -7819,6 +7871,12 @@
"fd-slicer": "~1.1.0"
}
},
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true
},
"zip-stream": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz",

View File

@ -5,6 +5,7 @@
"main": "js/electron.js",
"scripts": {
"start": "DISPLAY=\"${DISPLAY:=:0}\" ./node_modules/.bin/electron js/electron.js",
"start:dev": "DISPLAY=\"${DISPLAY:=:0}\" ./node_modules/.bin/electron js/electron.js dev",
"server": "node ./serveronly",
"install": "echo \"Installing vendor files ...\n\" && cd vendor && npm install --loglevel=error",
"install-fonts": "echo \"Installing fonts ...\n\" && cd fonts && npm install --loglevel=error",
@ -45,10 +46,10 @@
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"eslint-config-prettier": "^7.1.0",
"eslint-plugin-jsdoc": "^30.7.13",
"eslint-plugin-jsdoc": "^31.0.6",
"eslint-plugin-prettier": "^3.3.1",
"express-basic-auth": "^1.2.0",
"husky": "^4.3.6",
"husky": "^4.3.8",
"jsdom": "^16.4.0",
"lodash": "^4.17.20",
"mocha": "^8.2.1",
@ -69,7 +70,7 @@
"dependencies": {
"colors": "^1.4.0",
"console-stamp": "^3.0.0-rc4.2",
"eslint": "^7.17.0",
"eslint": "^7.18.0",
"express": "^4.17.1",
"express-ipfilter": "^1.1.2",
"feedme": "^2.0.2",
@ -83,7 +84,7 @@
"rrule": "^2.6.6",
"rrule-alt": "^2.2.8",
"simple-git": "^2.31.0",
"socket.io": "^3.0.5",
"socket.io": "^3.1.0",
"valid-url": "^1.0.9"
},
"_moduleAliases": {

View File

@ -0,0 +1,48 @@
/* Magic Mirror Test config current weather compliments
*
* By rejas https://github.com/rejas
*
* MIT Licensed.
*/
let config = {
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "en",
timeFormat: 24,
units: "metric",
electronOptions: {
fullscreen: false,
webPreferences: {
nodeIntegration: true
}
},
modules: [
{
module: "compliments",
position: "top_bar",
config: {
compliments: {
snow: ["snow"]
},
updateInterval: 4000
}
},
{
module: "weather",
position: "bottom_bar",
config: {
location: "Munich",
apiKey: "fake key",
initialLoadDelay: 3000
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@ -87,6 +87,19 @@ describe("Weather module", function () {
});
});
describe("Compliments Integration", function () {
before(function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/currentweather_compliments.js";
});
it("should render a compliment based on the current weather", async function () {
const weather = generateWeather();
await setup({ template, data: weather });
return app.client.waitUntilTextExists(".compliments .module-content span", "snow", 10000);
});
});
describe("Configuration Options", function () {
before(function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/currentweather_options.js";

View File

@ -1,5 +1,6 @@
/* eslint no-multi-spaces: 0 */
const expect = require("chai").expect;
const moment = require("moment-timezone");
var data = require("../functions/weatherforecast_data.json");
describe("Functions module weatherforecast", function () {
@ -69,6 +70,16 @@ describe("Functions module weatherforecast", function () {
Log = {
error: function () {}
};
var originalLocale;
var originalTimeZone;
before(function () {
originalLocale = moment.locale();
originalTimeZone = moment.tz.guess();
moment.locale("hi");
moment.tz.setDefault("Europe/Warsaw");
});
describe("forecastIcons sunset specified", function () {
before(function () {
Module.definitions.weatherforecast.Log = {};
@ -97,5 +108,10 @@ describe("Functions module weatherforecast", function () {
expect(forecastData[2].icon).to.equal("wi-rain");
});
});
after(function () {
moment.locale(originalLocale);
moment.tz.setDefault(originalTimeZone);
});
});
});

6
vendor/package-lock.json generated vendored
View File

@ -4,9 +4,9 @@
"lockfileVersion": 1,
"dependencies": {
"@fortawesome/fontawesome-free": {
"version": "5.15.1",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.1.tgz",
"integrity": "sha512-OEdH7SyC1suTdhBGW91/zBfR6qaIhThbcN8PUXtXilY4GYnSBbVqOntdHbC1vXwsDnX0Qix2m2+DSU1J51ybOQ=="
"version": "5.15.2",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.2.tgz",
"integrity": "sha512-7l/AX41m609L/EXI9EKH3Vs3v0iA8tKlIOGtw+kgcoanI7p+e4I4GYLqW3UXWiTnjSFymKSmTTPKYrivzbxxqA=="
},
"a-sync-waterfall": {
"version": "1.0.1",

2
vendor/package.json vendored
View File

@ -10,7 +10,7 @@
"url": "https://github.com/MichMich/MagicMirror/issues"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^5.15.1",
"@fortawesome/fontawesome-free": "^5.15.2",
"moment": "^2.29.1",
"moment-timezone": "^0.5.32",
"nunjucks": "^3.2.2",