diff --git a/CHANGELOG.md b/CHANGELOG.md
index c79358c4..3e0f65f3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,29 +5,55 @@ This project adheres to [Semantic Versioning](http://semver.org/).
---
-## [2.7.0] - Unreleased
+❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² core.
+
+## [2.8.0] - Unreleased
*This release is scheduled to be released on 2019-04-01.*
+### Added
+- Option to show event location in calendar
+
+- Finnish translation for "Feels" and "Weeks"
+
+- Russian translation for “Feels”
+
+### Updated
+
+### Fixed
+- Handle SIGTERM messages
+- Fixes sliceMultiDayEvents so it respects maximumNumberOfDays
+
+## [2.7.1] - 2019-04-02
+
+Fixed `package.json` version number.
+
+## [2.7.0] - 2019-04-01
+
ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md).
### Added
- Italian translation for "Feels"
-- Disabled the screensaver on raspbian with installation script
+- Basic Klingon (tlhIngan Hol) translations
+- Disabled the screensaver on raspbian with installation script
- Added option to truncate the number of vertical lines a calendar item can span if `wrapEvents` is enabled.
-- Added autoLocation options for weather forcast and current weather modules.
-- Added autoTimezone option for the default clock module.
- Danish translation for "Feels" and "Weeks"
- Added option to split multiple day events in calendar to separate numbered events
- Slovakian translation
- Alerts now can contain Font Awesome icons
+- Notifications display time can be set in request
+- Newsfeed: added support for `ARTICLE_INFO_REQUEST` notification
+- Add `name` config option for calendars to be sent along with event broadcasts
### Updated
- Bumped the Electron dependency to v3.0.13 to support the most recent Raspbian. [#1500](https://github.com/MichMich/MagicMirror/issues/1500)
+- Updated modernizr code in alert module, fixed a small typo there too
+- More verbose error message on console if the config is malformed
+- Updated installer script to install Node.js version 10.x
### Fixed
- Fixed temperature displays in currentweather and weatherforecast modules [#1503](https://github.com/MichMich/MagicMirror/issues/1503), [#1511](https://github.com/MichMich/MagicMirror/issues/1511).
-- Fixed unhandled error on bad git data in updatenotiifcation module [#1285](https://github.com/MichMich/MagicMirror/issues/1285).
+- Fixed unhandled error on bad git data in updatenotification module [#1285](https://github.com/MichMich/MagicMirror/issues/1285).
- Weather forecast now works with openweathermap in new weather module. Daily data are displayed, see issue [#1504](https://github.com/MichMich/MagicMirror/issues/1504).
- Fixed analogue clock border display issue where non-black backgrounds used (previous fix for issue 611)
- Fixed compatibility issues caused when modules request different versions of Font Awesome, see issue [#1522](https://github.com/MichMich/MagicMirror/issues/1522). MagicMirror now uses [Font Awesome 5 with v4 shims included for backwards compatibility](https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4#shims).
@@ -38,6 +64,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Fix null dereference in moduleNeedsUpdate when the module isn't visible
- Calendar: Fixed event end times by setting default calendarEndTime to "LT" (Local time format). [#1479]
- Calendar: Fixed missing calendar fetchers after server process restarts [#1589](https://github.com/MichMich/MagicMirror/issues/1589)
+- Notification: fixed background color (was white text on white background)
+- Use getHeader instead of data.header when creating the DOM so overwriting the function also propagates into it
+- Fix documentation of `useKMPHwind` option in currentweather
### New weather module
- Fixed weather forecast table display [#1499](https://github.com/MichMich/MagicMirror/issues/1499).
@@ -109,7 +138,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Fixed gzip encoded calendar loading issue #1400.
- Mixup between german and spanish translation for newsfeed.
- Fixed close dates to be absolute, if no configured in the config.js - module Calendar
-- Fixed the UpdateNotification module message about new commits in the repository, so they can be correctly localized in singular and plural form.
+- Fixed the updatenotification module message about new commits in the repository, so they can be correctly localized in singular and plural form.
- Fix for weatherforecast rainfall rounding [#1374](https://github.com/MichMich/MagicMirror/issues/1374)
- Fix calendar parsing issue for Midori on RasperryPi Zero w, related to issue #694.
- Fix weather city ID link in sample config
@@ -259,7 +288,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Add `clientonly` script to start only the electron client for a remote server.
- Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module.
- Add `.vscode/` folder to `.gitignore` to keep custom Visual Studio Code config out of git.
-- Add unit test the capitalizeFirstLetter function of newfeed module.
+- Add unit test the capitalizeFirstLetter function of newsfeed module.
- Add new unit tests for function `shorten` in calendar module.
- Add new unit tests for function `getLocaleSpecification` in calendar module.
- Add unit test for js/class.js.
@@ -280,7 +309,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Set version of the `express-ipfilter` on 0.3.1.
### Fixed
-- Fixed issue with incorrect allignment of analog clock when displayed in the center column of the MM.
+- Fixed issue with incorrect alignment of analog clock when displayed in the center column of the MM.
- Fixed ipWhitelist behaviour to make empty whitelist ([]) allow any and all hosts access to the MM.
- Fixed issue with calendar module where 'excludedEvents' count towards 'maximumEntries'.
- Fixed issue with calendar module where global configuration of maximumEntries was not overridden by calendar specific config (see module doc).
@@ -304,7 +333,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Add unit test calendar_modules function capFirst.
- Add test for check if exists the directories present in defaults modules.
- Add support for showing wind direction as an arrow instead of abbreviation in currentWeather module.
-- Add support for writing translation fucntions to support flexible word order
+- Add support for writing translation functions to support flexible word order
- Add test for check if exits the directories present in defaults modules.
- Add calendar option to set a separate date format for full day events.
- Add ability for `currentweather` module to display indoor temperature via INDOOR_TEMPERATURE notification
@@ -323,7 +352,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Fix double message about port when server is starting
- Corrected Swedish translations for TODAY/TOMORROW/DAYAFTERTOMORROW.
- Removed unused import from js/electron.js
-- Made calendar.js respect config.timeFormat irrespecive of locale setting.
+- Made calendar.js respect config.timeFormat irrespective of locale setting.
- Fixed alignment of analog clock when a large calendar is displayed in the same side bar.
## [2.1.1] - 2017-04-01
@@ -341,7 +370,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Added `DAYAFTERTOMORROW`, `UPDATE_NOTIFICATION` and `UPDATE_NOTIFICATION_MODULE` to Finnish translations.
- Run `npm test` on Travis automatically.
- Show the splash screen image even when is reboot or halted.
-- Added some missing translaton strings in the sv.json file.
+- Added some missing translation strings in the sv.json file.
- Run task jsonlint to check translation files.
- Restructured Test Suite.
@@ -358,12 +387,12 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Option to use RegExp in Calendar's titleReplace.
- Hungarian Translation.
- Icelandic Translation.
-- Add use a script to prevent when is run by SSH session set DISPLAY enviroment.
-- Enable ability to set configuration file by the enviroment variable called MM_CONFIG_FILE.
+- Add use a script to prevent when is run by SSH session set DISPLAY environment.
+- Enable ability to set configuration file by the environment variable called MM_CONFIG_FILE.
- Option to give each calendar a different color.
- Option for colored min-temp and max-temp.
- Add test e2e helloworld.
-- Add test e2e enviroment.
+- Add test e2e environment.
- Add `chai-as-promised` npm module to devDependencies.
- Basic set of tests for clock module.
- Run e2e test in Travis.
@@ -381,10 +410,10 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Added tests for Translations, dev argument, version, dev console.
- Added test anytime feature compliments module.
- Added test ipwhitelist configuration directive.
-- Added test for calendar module: default, basic-auth, backward compability, fail-basic-auth.
+- Added test for calendar module: default, basic-auth, backward compatibility, fail-basic-auth.
- Added meta tags to support fullscreen mode on iOS (for server mode)
- Added `ignoreOldItems` and `ignoreOlderThan` options to the News Feed module
-- Added test for MM_PORT enviroment variable.
+- Added test for MM_PORT environment variable.
- Added a configurable Week section to the clock module.
### Fixed
@@ -396,7 +425,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Module currentWeather: check if temperature received from api is defined.
- Fix an issue with module hidden status changing to `true` although lock string prevented showing it.
- Fix newsfeed module bug (removeStartTags)
-- Fix when is set MM_PORT enviroment variable.
+- Fix when is set MM_PORT environment variable.
- Fixed missing animation on `this.show(speed)` when module is alone in a region.
## [2.1.0] - 2016-12-31
@@ -418,8 +447,8 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Calendar module now broadcasts the event list to all other modules using the notification system. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/calendar) for more information.
- Possibility to use the the calendar feed as the source for the weather (currentweather & weatherforecast) location data. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/weatherforecast) for more information.
- Added option to show rain amount in the weatherforecast default module
-- Add module `updatenotification` to get an update whenever a new version is availabe. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/updatenotification) for more information.
-- Add the abilty to set timezone on the date display in the Clock Module
+- Add module `updatenotification` to get an update whenever a new version is available. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/updatenotification) for more information.
+- Add the ability to set timezone on the date display in the Clock Module
- Ability to set date format in calendar module
- Possibility to use currentweather for the compliments
- Added option `disabled` for modules.
@@ -458,7 +487,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Added ability to define "the day after tomorrow" for calendar events (Definition for German and Dutch already included).
- Added CII Badge (we are compliant with the CII Best Practices)
- Add support for doing http basic auth when loading calendars
-- Add the abilty to turn off and on the date display in the Clock Module
+- Add the ability to turn off and on the date display in the Clock Module
### Fixed
- Fix typo in installer.
@@ -481,8 +510,8 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
### Fixed
- Prevent `getModules()` selectors from returning duplicate entries.
-- Append endpoints of weather modules with `/` to retreive the correct data. (Issue [#337](https://github.com/MichMich/MagicMirror/issues/337))
-- Corrected grammer in `module.js` from 'suspend' to 'suspended'.
+- Append endpoints of weather modules with `/` to retrieve the correct data. (Issue [#337](https://github.com/MichMich/MagicMirror/issues/337))
+- Corrected grammar in `module.js` from 'suspend' to 'suspended'.
- Fixed openweathermap.org URL in config sample.
- Prevent currentweather module from crashing when received data object is incorrect.
- Fix issue where translation loading prevented the UI start-up when the language was set to 'en'. (Issue [#388](https://github.com/MichMich/MagicMirror/issues/388))
diff --git a/README.md b/README.md
index 1cadc57a..ee92ca92 100644
--- a/README.md
+++ b/README.md
@@ -128,7 +128,7 @@ The following wiki links are helpful for the initial configuration of your Magic
**Note:** If you used the installer script. This step is already done for you.
2. Modify your required settings. \
- Note: You'll can check your configuration running `npm run config:check` in `/home/pi/MagicMirror`.
+ Note: You can check your configuration running `npm run config:check` in `/home/pi/MagicMirror`.
The following properties can be configured:
diff --git a/installers/raspberry.sh b/installers/raspberry.sh
index 1551b5fb..c698bb83 100644
--- a/installers/raspberry.sh
+++ b/installers/raspberry.sh
@@ -82,7 +82,7 @@ if $NODE_INSTALL; then
# The NODE_STABLE_BRANCH variable will need to be manually adjusted when a new branch is released. (e.g. 7.x)
# Only tested (stable) versions are recommended as newer versions could break MagicMirror.
- NODE_STABLE_BRANCH="9.x"
+ NODE_STABLE_BRANCH="10.x"
curl -sL https://deb.nodesource.com/setup_$NODE_STABLE_BRANCH | sudo -E bash -
sudo apt-get install -y nodejs
echo -e "\e[92mNode.js installation Done!\e[0m"
diff --git a/js/app.js b/js/app.js
index bfec5baf..4a10ba6d 100644
--- a/js/app.js
+++ b/js/app.js
@@ -70,7 +70,7 @@ var App = function() {
if (e.code == "ENOENT") {
console.error(Utils.colors.error("WARNING! Could not find config file. Please create one. Starting with default configuration."));
} else if (e instanceof ReferenceError || e instanceof SyntaxError) {
- console.error(Utils.colors.error("WARNING! Could not validate config file. Please correct syntax errors. Starting with default configuration."));
+ console.error(Utils.colors.error("WARNING! Could not validate config file. Starting with default configuration. Please correct syntax errors at or above this line: " + e.stack));
} else {
console.error(Utils.colors.error("WARNING! Could not load config file. Starting with default configuration. Error found: " + e));
}
@@ -263,6 +263,15 @@ var App = function() {
this.stop();
process.exit(0);
});
+
+ /* We also need to listen to SIGTERM signals so we stop everything when we are asked to stop by the OS.
+ */
+ process.on("SIGTERM", () => {
+ console.log("[SIGTERM] Received. Shutting down server...");
+ setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds
+ this.stop();
+ process.exit(0);
+ });
};
module.exports = new App();
diff --git a/js/main.js b/js/main.js
index 21a882f8..2330d3ee 100644
--- a/js/main.js
+++ b/js/main.js
@@ -39,9 +39,9 @@ var MM = (function() {
dom.opacity = 0;
wrapper.appendChild(dom);
- if (typeof module.data.header !== "undefined" && module.data.header !== "") {
+ if (typeof module.getHeader() !== "undefined" && module.getHeader() !== "") {
var moduleHeader = document.createElement("header");
- moduleHeader.innerHTML = module.data.header;
+ moduleHeader.innerHTML = module.getHeader();
moduleHeader.className = "module-header";
dom.appendChild(moduleHeader);
}
diff --git a/js/module.js b/js/module.js
index 907a7f61..3e39dd5c 100644
--- a/js/module.js
+++ b/js/module.js
@@ -212,7 +212,7 @@ var Module = Class.extend({
/* setData(data)
* Set the module data.
*
- * argument data obejct - Module data.
+ * argument data object - Module data.
*/
setData: function (data) {
this.data = data;
@@ -226,7 +226,7 @@ var Module = Class.extend({
/* setConfig(config)
* Set the module config and combine it with the module defaults.
*
- * argument config obejct - Module config.
+ * argument config object - Module config.
*/
setConfig: function (config) {
this.config = Object.assign({}, this.defaults, config);
diff --git a/modules/default/alert/README.md b/modules/default/alert/README.md
index c57ba793..4c6e4333 100644
--- a/modules/default/alert/README.md
+++ b/modules/default/alert/README.md
@@ -43,10 +43,11 @@ self.sendNotification("SHOW_ALERT", {});
```
### Notification params
-| Option | Description
-| --------- | -----------
-| `title` | The title of the notification.
**Possible values:** `text` or `html`
-| `message` | The message of the notification.
**Possible values:** `text` or `html`
+| Option | Description
+| ------------------ | -----------
+| `title` | The title of the notification.
**Possible values:** `text` or `html`
+| `message` | The message of the notification.
**Possible values:** `text` or `html`
+| `timer` (optional) | How long the notification should stay visible in ms.
If absent, the default `display_time` is used.
**Possible values:** `int` `float`
### Alert params
@@ -61,4 +62,4 @@ self.sendNotification("SHOW_ALERT", {});
## Open Source Licenses
### [NotificationStyles](https://github.com/codrops/NotificationStyles)
-See [ympanus.net](http://tympanus.net/codrops/licensing/) for license.
+See [tympanus.net](http://tympanus.net/codrops/licensing/) for license.
diff --git a/modules/default/alert/alert.js b/modules/default/alert/alert.js
index 9c0d91a7..0f47bc3f 100644
--- a/modules/default/alert/alert.js
+++ b/modules/default/alert/alert.js
@@ -51,7 +51,7 @@ Module.register("alert",{
message: msg,
layout: "growl",
effect: this.config.effect,
- ttl: this.config.display_time
+ ttl: message.timer !== undefined ? message.timer : this.config.display_time
}).show();
},
show_alert: function(params, sender) {
diff --git a/modules/default/alert/modernizr.custom.js b/modules/default/alert/modernizr.custom.js
index 3d33a8be..83c3d3f1 100644
--- a/modules/default/alert/modernizr.custom.js
+++ b/modules/default/alert/modernizr.custom.js
@@ -1,5 +1,3 @@
-/* Modernizr 2.8.3 (Custom Build) | MIT & BSD
- * Build: http://modernizr.com/download/#-cssanimations-shiv-cssclasses-prefixed-testprop-testallprops-domprefixes-load
- */
-// jscs:disable
-;window.Modernizr = function(a, b, c) {function x(a) {j.cssText = a;}function y(a, b) {return x(prefixes.join(a + ";") + (b || ""));}function z(a, b) {return typeof a === b;}function A(a, b) {return !!~("" + a).indexOf(b);}function B(a, b) {for (var d in a) {var e = a[d];if (!A(e,"-") && j[e] !== c)return b == "pfx" ? e : !0;}return !1;}function C(a, b, d) {for (var e in a) {var f = b[a[e]];if (f !== c)return d === !1 ? a[e] : z(f,"function") ? f.bind(d || b) : f;}return !1;}function D(a, b, c) {var d = a.charAt(0).toUpperCase() + a.slice(1),e = (a + " " + n.join(d + " ") + d).split(" ");return z(b,"string") || z(b,"undefined") ? B(e,b) : (e = (a + " " + o.join(d + " ") + d).split(" "),C(e,b,c));}var d = "2.8.3",e = {},f = !0,g = b.documentElement,h = "modernizr",i = b.createElement(h),j = i.style,k,l = {}.toString,m = "Webkit Moz O ms",n = m.split(" "),o = m.toLowerCase().split(" "),p = {},q = {},r = {},s = [],t = s.slice,u,v = {}.hasOwnProperty,w;!z(v,"undefined") && !z(v.call,"undefined") ? w = function(a, b) {return v.call(a,b);} : w = function(a, b) {return b in a && z(a.constructor.prototype[b],"undefined");},Function.prototype.bind || (Function.prototype.bind = function(b) {var c = this;if (typeof c != "function")throw new TypeError;var d = t.call(arguments,1),e = function() {if (this instanceof e) {var a = function() {};a.prototype = c.prototype;var f = new a,g = c.apply(f,d.concat(t.call(arguments)));return Object(g) === g ? g : f;}return c.apply(b,d.concat(t.call(arguments)));};return e;}),p.cssanimations = function() {return D("animationName");};for (var E in p)w(p,E) && (u = E.toLowerCase(),e[u] = p[E](),s.push((e[u] ? "" : "no-") + u));return e.addTest = function(a, b) {if (typeof a == "object")for (var d in a)w(a,d) && e.addTest(d,a[d]);else {a = a.toLowerCase();if (e[a] !== c)return e;b = typeof b == "function" ? b() : b,typeof f != "undefined" && f && (g.className += " " + (b ? "" : "no-") + a),e[a] = b;}return e;},x(""),i = k = null,function(a, b) {function l(a, b) {var c = a.createElement("p"),d = a.getElementsByTagName("head")[0] || a.documentElement;return c.innerHTML = "x",d.insertBefore(c.lastChild,d.firstChild);}function m() {var a = s.elements;return typeof a == "string" ? a.split(" ") : a;}function n(a) {var b = j[a[h]];return b || (b = {},i++,a[h] = i,j[i] = b),b;}function o(a, c, d) {c || (c = b);if (k)return c.createElement(a);d || (d = n(c));var g;return d.cache[a] ? g = d.cache[a].cloneNode() : f.test(a) ? g = (d.cache[a] = d.createElem(a)).cloneNode() : g = d.createElem(a),g.canHaveChildren && !e.test(a) && !g.tagUrn ? d.frag.appendChild(g) : g;}function p(a, c) {a || (a = b);if (k)return a.createDocumentFragment();c = c || n(a);var d = c.frag.cloneNode(),e = 0,f = m(),g = f.length;for (; e < g; e++)d.createElement(f[e]);return d;}function q(a, b) {b.cache || (b.cache = {},b.createElem = a.createElement,b.createFrag = a.createDocumentFragment,b.frag = b.createFrag()),a.createElement = function(c) {return s.shivMethods ? o(c,a,b) : b.createElem(c);},a.createDocumentFragment = Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&(" + m().join().replace(/[\w\-]+/g,function(a) {return b.createElem(a),b.frag.createElement(a),"c(\"" + a + "\")";}) + ");return n}")(s,b.frag);}function r(a) {a || (a = b);var c = n(a);return s.shivCSS && !g && !c.hasCSS && (c.hasCSS = !!l(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),k || q(a,c),a;}var c = "3.7.0",d = a.html5 || {},e = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,f = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g,h = "_html5shiv",i = 0,j = {},k;(function() {try {var a = b.createElement("a");a.innerHTML = "",g = "hidden"in a,k = a.childNodes.length == 1 || function() {b.createElement("a");var a = b.createDocumentFragment();return typeof a.cloneNode == "undefined" || typeof a.createDocumentFragment == "undefined" || typeof a.createElement == "undefined";}();}catch (c) {g = !0,k = !0;}})();var s = {elements: d.elements || "abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version: c,shivCSS: d.shivCSS !== !1,supportsUnknownElements: k,shivMethods: d.shivMethods !== !1,type: "default",shivDocument: r,createElement: o,createDocumentFragment: p};a.html5 = s,r(b);}(this,b),e._version = d,e._domPrefixes = o,e._cssomPrefixes = n,e.testProp = function(a) {return B([a]);},e.testAllProps = D,e.prefixed = function(a, b, c) {return b ? D(a,b,c) : D(a,"pfx");},g.className = g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2") + (f ? " js " + s.join(" ") : ""),e;}(this,this.document),function(a, b, c) {function d(a) {return "[object Function]" == o.call(a);}function e(a) {return "string" == typeof a;}function f() {}function g(a) {return !a || "loaded" == a || "complete" == a || "uninitialized" == a;}function h() {var a = p.shift();q = 1,a ? a.t ? m(function() {("c" == a.t ? B.injectCss : B.injectJs)(a.s,0,a.a,a.x,a.e,1);},0) : (a(),h()) : q = 0;}function i(a, c, d, e, f, i, j) {function k(b) {if (!o && g(l.readyState) && (u.r = o = 1,!q && h(),l.onload = l.onreadystatechange = null,b)) {"img" != a && m(function() {t.removeChild(l);},50);for (var d in y[c])y[c].hasOwnProperty(d) && y[c][d].onload();}}var j = j || B.errorTimeout,l = b.createElement(a),o = 0,r = 0,u = {t: d,s: c,e: f,a: i,x: j};1 === y[c] && (r = 1,y[c] = []),"object" == a ? l.data = c : (l.src = c,l.type = a),l.width = l.height = "0",l.onerror = l.onload = l.onreadystatechange = function() {k.call(this,r);},p.splice(e,0,u),"img" != a && (r || 2 === y[c] ? (t.insertBefore(l,s ? null : n),m(k,j)) : y[c].push(l));}function j(a, b, c, d, f) {return q = 0,b = b || "j",e(a) ? i("c" == b ? v : u,a,b,this.i++,c,d,f) : (p.splice(this.i++,0,a),1 == p.length && h()),this;}function k() {var a = B;return a.loader = {load: j,i: 0},a;}var l = b.documentElement,m = a.setTimeout,n = b.getElementsByTagName("script")[0],o = {}.toString,p = [],q = 0,r = "MozAppearance"in l.style,s = r && !!b.createRange().compareNode,t = s ? l : n.parentNode,l = a.opera && "[object Opera]" == o.call(a.opera),l = !!b.attachEvent && !l,u = r ? "object" : l ? "script" : "img",v = l ? "script" : u,w = Array.isArray || function(a) {return "[object Array]" == o.call(a);},x = [],y = {},z = {timeout: function(a, b) {return b.length && (a.timeout = b[0]),a;}},A,B;B = function(a) {function b(a) {var a = a.split("!"),b = x.length,c = a.pop(),d = a.length,c = {url: c,origUrl: c,prefixes: a},e,f,g;for (f = 0; f < d; f++)g = a[f].split("="),(e = z[g.shift()]) && (c = e(c,g));for (f = 0; f < b; f++)c = x[f](c);return c;}function g(a, e, f, g, h) {var i = b(a),j = i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass || (e && (e = d(e) ? e : e[a] || e[g] || e[a.split("/").pop().split("?")[0]]),i.instead ? i.instead(a,e,f,g,h) : (y[i.url] ? i.noexec = !0 : y[i.url] = 1,f.load(i.url,i.forceCSS || !i.forceJS && "css" == i.url.split(".").pop().split("?").shift() ? "c" : c,i.noexec,i.attrs,i.timeout),(d(e) || d(j)) && f.load(function() {k(),e && e(i.origUrl,h,g),j && j(i.origUrl,h,g),y[i.url] = 2;})));}function h(a, b) {function c(a, c) {if (a) {if (e(a))c || (j = function() {var a = [].slice.call(arguments);k.apply(this,a),l();}),g(a,j,b,0,h);else if (Object(a) === a)for (n in m = function() {var b = 0,c;for (c in a)a.hasOwnProperty(c) && b++;return b;}(),a)a.hasOwnProperty(n) && (!c && !--m && (d(j) ? j = function() {var a = [].slice.call(arguments);k.apply(this,a),l();} : j[n] = function(a) {return function() {var b = [].slice.call(arguments);a && a.apply(this,b),l();};}(k[n])),g(a[n],j,b,n,h));}else !c && l();}var h = !!a.test,i = a.load || a.both,j = a.callback || f,k = j,l = a.complete || f,m,n;c(h ? a.yep : a.nope,!!i),i && c(i);}var i,j,l = this.yepnope.loader;if (e(a))g(a,0,l,0);else if (w(a))for (i = 0; i < a.length; i++)j = a[i],e(j) ? g(j,0,l,0) : w(j) ? B(j) : Object(j) === j && h(j,l);else Object(a) === a && h(a,l);},B.addPrefix = function(a, b) {z[a] = b;},B.addFilter = function(a) {x.push(a);},B.errorTimeout = 1e4,null == b.readyState && b.addEventListener && (b.readyState = "loading",b.addEventListener("DOMContentLoaded",A = function() {b.removeEventListener("DOMContentLoaded",A,0),b.readyState = "complete";},0)),a.yepnope = k(),a.yepnope.executeStack = h,a.yepnope.injectJs = function(a, c, d, e, i, j) {var k = b.createElement("script"),l,o,e = e || B.errorTimeout;k.src = a;for (o in d)k.setAttribute(o,d[o]);c = j ? h : c || f,k.onreadystatechange = k.onload = function() {!l && g(k.readyState) && (l = 1,c(),k.onload = k.onreadystatechange = null);},m(function() {l || (l = 1,c(1));},e),i ? k.onload() : n.parentNode.insertBefore(k,n);},a.yepnope.injectCss = function(a, c, d, e, g, i) {var e = b.createElement("link"),j,c = i ? h : c || f;e.href = a,e.rel = "stylesheet",e.type = "text/css";for (j in d)e.setAttribute(j,d[j]);g || (n.parentNode.insertBefore(e,n),m(c,0));};}(this,document),Modernizr.load = function() {yepnope.apply(window,[].slice.call(arguments,0));};
+/*! modernizr 3.7.0 (Custom Build) | MIT *
+ * https://modernizr.com/download/?-cssanimations-domprefixes-prefixed-setclasses-shiv-testallprops-testprop !*/
+!function(e,t,n){function r(e,t){return typeof e===t}function o(e,t){return!!~(""+e).indexOf(t)}function i(){return"function"!=typeof t.createElement?t.createElement(arguments[0]):E?t.createElementNS.call(t,"http://www.w3.org/2000/svg",arguments[0]):t.createElement.apply(t,arguments)}function a(){var e=t.body;return e||(e=i(E?"svg":"body"),e.fake=!0),e}function s(e,n,r,o){var s,l,c,u,f="modernizr",d=i("div"),p=a();if(parseInt(r,10))for(;r--;)c=i("div"),c.id=o?o[r]:f+(r+1),d.appendChild(c);return s=i("style"),s.type="text/css",s.id="s"+f,(p.fake?p:d).appendChild(s),p.appendChild(d),s.styleSheet?s.styleSheet.cssText=e:s.appendChild(t.createTextNode(e)),d.id=f,p.fake&&(p.style.background="",p.style.overflow="hidden",u=S.style.overflow,S.style.overflow="hidden",S.appendChild(p)),l=n(d,e),p.fake?(p.parentNode.removeChild(p),S.style.overflow=u,S.offsetHeight):d.parentNode.removeChild(d),!!l}function l(e){return e.replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()}).replace(/^ms-/,"-ms-")}function c(t,n,r){var o;if("getComputedStyle"in e){o=getComputedStyle.call(e,t,n);var i=e.console;if(null!==o)r&&(o=o.getPropertyValue(r));else if(i){var a=i.error?"error":"log";i[a].call(i,"getComputedStyle returning null, its possible modernizr test results are inaccurate")}}else o=!n&&t.currentStyle&&t.currentStyle[r];return o}function u(t,r){var o=t.length;if("CSS"in e&&"supports"in e.CSS){for(;o--;)if(e.CSS.supports(l(t[o]),r))return!0;return!1}if("CSSSupportsRule"in e){for(var i=[];o--;)i.push("("+l(t[o])+":"+r+")");return i=i.join(" or "),s("@supports ("+i+") { #modernizr { position: absolute; } }",function(e){return"absolute"===c(e,null,"position")})}return n}function f(e){return e.replace(/([a-z])-([a-z])/g,function(e,t,n){return t+n.toUpperCase()}).replace(/^-/,"")}function d(e,t,a,s){function l(){d&&(delete N.style,delete N.modElem)}if(s=!r(s,"undefined")&&s,!r(a,"undefined")){var c=u(e,a);if(!r(c,"undefined"))return c}for(var d,p,m,h,v,g=["modernizr","tspan","samp"];!N.style&&g.length;)d=!0,N.modElem=i(g.shift()),N.style=N.modElem.style;for(m=e.length,p=0;p",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=y.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=y.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),y.elements=n+" "+e,c(t)}function i(e){var t=g[e[h]];return t||(t={},v++,e[h]=v,g[v]=t),t}function a(e,n,r){if(n||(n=t),f)return n.createElement(e);r||(r=i(n));var o;return o=r.cache[e]?r.cache[e].cloneNode():m.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!o.canHaveChildren||p.test(e)||o.tagUrn?o:r.frag.appendChild(o)}function s(e,n){if(e||(e=t),f)return e.createDocumentFragment();n=n||i(e);for(var o=n.frag.cloneNode(),a=0,s=r(),l=s.length;a",u="hidden"in e,f=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return void 0===e.cloneNode||void 0===e.createDocumentFragment||void 0===e.createElement}()}catch(e){u=!0,f=!0}}();var y={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:"3.7.3",shivCSS:!1!==d.shivCSS,supportsUnknownElements:f,shivMethods:!1!==d.shivMethods,type:"default",shivDocument:c,createElement:a,createDocumentFragment:s,addElements:o};e.html5=y,c(t),"object"==typeof module&&module.exports&&(module.exports=y)}(void 0!==e?e:this,t);var w=y._config.usePrefixes?x.split(" "):[];y._cssomPrefixes=w;var _={elem:i("modernizr")};Modernizr._q.push(function(){delete _.elem});var N={style:_.elem.style};Modernizr._q.unshift(function(){delete N.style}),y.testAllProps=h;var j=function(t){var r,o=prefixes.length,i=e.CSSRule;if(void 0===i)return n;if(!t)return!1;if(t=t.replace(/^@/,""),(r=t.replace(/-/g,"_").toUpperCase()+"_RULE")in i)return"@"+t;for(var a=0;a0&&(t+=" "+n+e.join(" "+n)),E?S.className.baseVal=t:S.className=t)}(C),delete y.addTest,delete y.addAsyncTest;for(var z=0;z
**Default value:** `365`
| `displaySymbol` | Display a symbol in front of an entry.
**Possible values:** `true` or `false`
**Default value:** `true`
| `defaultSymbol` | The default symbol.
**Possible values:** See [Font Awsome](http://fontawesome.io/icons/) website.
**Default value:** `calendar`
+| `showLocation` | Whether to show event locations.
**Possible values:** `true` or `false`
**Default value:** `false`
| `maxTitleLength` | The maximum title length.
**Possible values:** `10` - `50`
**Default value:** `25`
| `wrapEvents` | Wrap event titles to multiple lines. Breaks lines at the length defined by `maxTitleLength`.
**Possible values:** `true` or `false`
**Default value:** `false`
| `maxTitleLines` | The maximum number of lines a title will wrap vertically before being cut (Only enabled if `wrapEvents` is also enabled).
**Possible values:** `0` - `10`
**Default value:** `3`
@@ -53,7 +54,7 @@ The following properties can be configured:
| `hidePrivate` | Hides private calendar events.
**Possible values:** `true` or `false`
**Default value:** `false`
| `hideOngoing` | Hides calendar events that have already started.
**Possible values:** `true` or `false`
**Default value:** `false`
| `excludedEvents` | An array of words / phrases from event titles that will be excluded from being shown.
Additionally advanced filter objects can be passed in. Below is the configuration for the advance filtering object.
**Required**
`filterBy` - string used to determine if filter is applied.
**Optional**
`until` - Time before an event to display it Ex: [`'3 days'`, `'2 months'`, `'1 week'`]
`caseSensitive` - By default, excludedEvents are case insensitive, set this to true to enforce case sensitivity
`regex` - set to `true` if filterBy is a regex. For those not familiar with regex it is used for pattern matching, please see [here](https://regexr.com/) for more info.
**Example:** `['Birthday', 'Hide This Event', {filterBy: 'Payment', until: '6 days', caseSensitive: true}, {filterBy: '^[0-9]{1,}.*', regex: true}]`
**Default value:** `[]`
-| `sliceMultiDayEvents` | If this is set to true, events exceeding at least one midnight will be sliced into separate events including a counter like (1/2). This is especially helpful in "dateheaders" mode. Events will be sliced at midnight, end time for all events but the last will be 23:59 **Default value:** `true`
+| `sliceMultiDayEvents` | If this is set to true, events exceeding at least one midnight will be sliced into separate events including a counter like (1/2). This is especially helpful in "dateheaders" mode. Events will be sliced at midnight, end time for all events but the last will be 23:59 **Default value:** `false`
### Calendar configuration
@@ -90,6 +91,7 @@ config: {
| `repeatingCountTitle` | The count title for yearly repating events in this calendar.
**Example:** `'Birthday'`
| `maximumEntries` | The maximum number of events shown. Overrides global setting. **Possible values:** `0` - `100`
| `maximumNumberOfDays` | The maximum number of days in the future. Overrides global setting
+| `name` | The name of the calendar. Included in event broadcasts as `calendarName`.
| `auth` | The object containing options for authentication against the calendar.
| `symbolClass` | Add a class to the cell of symbol.
| `titleClass` | Add a class to the title's cell.
diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js
index a6eeb226..3aaed2ae 100755
--- a/modules/default/calendar/calendar.js
+++ b/modules/default/calendar/calendar.js
@@ -15,6 +15,7 @@ Module.register("calendar", {
maximumNumberOfDays: 365,
displaySymbol: true,
defaultSymbol: "calendar", // Fontawesome Symbol see http://fontawesome.io/cheatsheet/
+ showLocation: false,
displayRepeatingCountTitle: false,
defaultRepeatingCountTitle: "",
maxTitleLength: 25,
@@ -379,6 +380,31 @@ Module.register("calendar", {
currentFadeStep = e - startFade;
eventWrapper.style.opacity = 1 - (1 / fadeSteps * currentFadeStep);
}
+
+ if (this.config.showLocation) {
+ if (event.location !== false) {
+ var locationRow = document.createElement("tr");
+ locationRow.className = "normal xsmall light";
+
+ if (this.config.displaySymbol) {
+ var symbolCell = document.createElement("td");
+ locationRow.appendChild(symbolCell);
+ }
+
+ var descCell = document.createElement("td");
+ descCell.className = "location";
+ descCell.colSpan = "2";
+ descCell.innerHTML = event.location;
+ locationRow.appendChild(descCell);
+
+ wrapper.appendChild(locationRow);
+
+ if (e >= startFade) {
+ currentFadeStep = e - startFade;
+ locationRow.style.opacity = 1 - (1 / fadeSteps * currentFadeStep);
+ }
+ }
+ }
}
return wrapper;
@@ -436,10 +462,11 @@ Module.register("calendar", {
var events = [];
var today = moment().startOf("day");
var now = new Date();
+ var future = moment().startOf("day").add(this.config.maximumNumberOfDays, "days").toDate();
for (var c in this.calendarData) {
var calendar = this.calendarData[c];
for (var e in calendar) {
- var event = calendar[e];
+ var event = JSON.parse(JSON.stringify(calendar[e])); // clone object
if(this.config.hidePrivate) {
if(event.class === "PRIVATE") {
// do not add the current event, skip it
@@ -461,23 +488,30 @@ Module.register("calendar", {
* otherwise, esp. in dateheaders mode it is not clear how long these events are.
*/
if (this.config.sliceMultiDayEvents) {
- var midnight = moment(event.startDate, "x").clone().startOf("day").add(1, "day").format("x"); //next midnight
+ var splitEvents = [];
+ var midnight = moment(event.startDate, "x").clone().startOf("day").add(1, "day").format("x");
var count = 1;
- var maxCount = Math.ceil(((event.endDate - 1) - moment(event.startDate, "x").endOf("day").format("x"))/(1000*60*60*24)) + 1
- if (event.endDate > midnight) {
- while (event.endDate > midnight) {
- var nextEvent = JSON.parse(JSON.stringify(event)); //make a copy without reference to the original event
- nextEvent.startDate = midnight;
- event.endDate = midnight;
- event.title += " (" + count + "/" + maxCount + ")";
- events.push(event);
- event = nextEvent;
- count += 1;
- midnight = moment(midnight, "x").add(1, "day").format("x"); //move further one day for next split
- }
- event.title += " ("+count+"/"+maxCount+")";
- }
- events.push(event);
+ var maxCount = Math.ceil(((event.endDate - 1) - moment(event.startDate, "x").endOf("day").format("x"))/(1000*60*60*24)) + 1;
+ while (event.endDate > midnight) {
+ var thisEvent = JSON.parse(JSON.stringify(event)) // clone object
+ thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < (today + 24 * 60 * 60 * 1000);
+ thisEvent.endDate = midnight;
+ thisEvent.title += " (" + count + "/" + maxCount + ")";
+ splitEvents.push(thisEvent);
+
+ event.startDate = midnight;
+ count += 1;
+ midnight = moment(midnight, "x").add(1, "day").format("x"); // next day
+ }
+ // Last day
+ event.title += " ("+count+"/"+maxCount+")";
+ splitEvents.push(event);
+
+ for (event of splitEvents) {
+ if ((event.endDate > now) && (event.endDate <= future)) {
+ events.push(event);
+ }
+ }
} else {
events.push(event);
}
@@ -487,7 +521,6 @@ Module.register("calendar", {
events.sort(function (a, b) {
return a.startDate - b.startDate;
});
-
return events.slice(0, this.config.maximumEntries);
},
@@ -569,6 +602,17 @@ Module.register("calendar", {
return this.getCalendarProperty(url, "timeClass", "");
},
+ /* calendarNameForUrl(url)
+ * Retrieves the calendar name for a specific url.
+ *
+ * argument url string - Url to look for.
+ *
+ * return string - The name of the calendar
+ */
+ calendarNameForUrl: function (url) {
+ return this.getCalendarProperty(url, "name", "");
+ },
+
/* colorForUrl(url)
* Retrieves the color for a specific url.
*
@@ -709,6 +753,7 @@ Module.register("calendar", {
for (var e in calendar) {
var event = cloneObject(calendar[e]);
event.symbol = this.symbolsForUrl(url);
+ event.calendarName = this.calendarNameForUrl(url);
event.color = this.colorForUrl(url);
delete event.url;
eventList.push(event);
diff --git a/modules/default/calendar/calendarfetcher.js b/modules/default/calendar/calendarfetcher.js
index a1e4aa8d..0076a605 100644
--- a/modules/default/calendar/calendarfetcher.js
+++ b/modules/default/calendar/calendarfetcher.js
@@ -273,7 +273,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
/* isFullDayEvent(event)
* Checks if an event is a fullday event.
*
- * argument event obejct - The event object to check.
+ * argument event object - The event object to check.
*
* return bool - The event is a fullday event.
*/
diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js
index 03528bce..23b801d0 100644
--- a/modules/default/clock/clock.js
+++ b/modules/default/clock/clock.js
@@ -26,7 +26,6 @@ Module.register("clock",{
analogShowDate: "top", // options: false, 'top', or 'bottom'
secondsColor: "#888888",
timezone: null,
- autoTimezone: false
},
// Define required scripts.
getScripts: function() {
@@ -40,31 +39,16 @@ Module.register("clock",{
start: function() {
Log.info("Starting module: " + this.name);
- if (this.config.autoTimezone) {
- this.sendSocketNotification("AUTO_TIMEZONE");
- } else {
- // Schedule update interval.
- var self = this;
- setInterval(function() {
- self.updateDom();
- }, 1000);
- }
+ // Schedule update interval.
+ var self = this;
+ setInterval(function() {
+ self.updateDom();
+ }, 1000);
// Set locale.
moment.locale(config.language);
},
-
- socketNotificationReceived: function (notification, payload) {
- if (notification === "UPDATE_TIMEZONE") {
- var self = this;
- self.config.timezone = payload.timezone;
- setInterval(function() {
- self.updateDom();
- }, 1000);
- }
- },
-
// Override dom generator.
getDom: function() {
diff --git a/modules/default/clock/node_helper.js b/modules/default/clock/node_helper.js
deleted file mode 100644
index 68258b0a..00000000
--- a/modules/default/clock/node_helper.js
+++ /dev/null
@@ -1,29 +0,0 @@
-var http = require("http");
-var NodeHelper = require("node_helper");
-
-module.exports = NodeHelper.create({
- start: function () {
- },
-
- socketNotificationReceived: function (notification, payload) {
- var self = this;
-
- if (notification === "AUTO_TIMEZONE") {
- console.log("Loading timezone...");
- http.get("http://ip-api.com/json", function (req) {
- var data = "";
- req.on("data", function (d) {
- data += d;
- });
- req.on("end", function () {
- var body = JSON.parse(data);
- payload.timezone = body.timezone;
- self.sendSocketNotification("UPDATE_TIMEZONE", payload);
- });
- }).on("error", function () {
- payload.error = "Could not figure out the timezone.";
- self.sendSocketNotification("UPDATE_TIMEZONE", payload);
- });
- }
- }
-});
diff --git a/modules/default/currentweather/README.md b/modules/default/currentweather/README.md
index ac883a93..ce8cd19e 100644
--- a/modules/default/currentweather/README.md
+++ b/modules/default/currentweather/README.md
@@ -50,7 +50,7 @@ The following properties can be configured:
| `showIndoorTemperature` | If you have another module that emits the INDOOR_TEMPERATURE notification, the indoor temperature will be displayed
**Default value:** `false`
| `onlyTemp` | Show only current Temperature and weather icon without windspeed, sunset, sunrise time and feels like.
**Possible values:** `true` or `false`
**Default value:** `false`
| `showFeelsLike` | Shows the Feels like temperature weather.
**Possible values:**`true` or `false`
**Default value:** `true`
-| `useKMPHWind` | Uses KMPH as units for windspeed.
**Possible values:**`true` or `false`
**Default value:** `false`
+| `useKMPHwind` | Uses KMPH as units for windspeed.
**Possible values:**`true` or `false`
**Default value:** `false`
| `useBeaufort` | Pick between using the Beaufort scale for wind speed or using the default units.
**Possible values:** `true` or `false`
**Default value:** `true`
| `lang` | The language of the days.
**Possible values:** `en`, `nl`, `ru`, etc ...
**Default value:** uses value of _config.language_
| `decimalSymbol` | The decimal symbol to use.
**Possible values:** `.`, `,` or any other symbol.
**Default value:** `.`
diff --git a/modules/default/currentweather/currentweather.js b/modules/default/currentweather/currentweather.js
index 0472b7a1..2ccc23b7 100644
--- a/modules/default/currentweather/currentweather.js
+++ b/modules/default/currentweather/currentweather.js
@@ -11,7 +11,6 @@ Module.register("currentweather",{
// Default module config.
defaults: {
- autoLocation: false,
location: false,
locationID: false,
appid: "",
@@ -72,7 +71,7 @@ Module.register("currentweather",{
firstEvent: false,
// create a variable to hold the location name based on the API result.
- fetchedLocatioName: "",
+ fetchedLocationName: "",
// Define required scripts.
getScripts: function() {
@@ -110,19 +109,8 @@ Module.register("currentweather",{
this.weatherType = null;
this.feelsLike = null;
this.loaded = false;
+ this.scheduleUpdate(this.config.initialLoadDelay);
- if (this.config.autoLocation) {
- this.sendSocketNotification("AUTO_LOCATION");
- } else {
- this.scheduleUpdate(this.config.initialLoadDelay);
- }
- },
-
- socketNotificationReceived: function (notification, payload) {
- if (notification === "UPDATE_LOCATION") {
- this.config.location = payload.location;
- this.scheduleUpdate(this.config.initialLoadDelay);
- }
},
// add extra information of current weather
@@ -277,8 +265,8 @@ Module.register("currentweather",{
// Override getHeader method.
getHeader: function() {
- if (this.config.appendLocationNameToHeader) {
- return this.data.header + " " + this.fetchedLocatioName;
+ if (this.config.appendLocationNameToHeader && this.data.header !== undefined) {
+ return this.data.header + " " + this.fetchedLocationName;
}
return this.data.header;
diff --git a/modules/default/currentweather/node_helper.js b/modules/default/currentweather/node_helper.js
deleted file mode 100644
index 53956f62..00000000
--- a/modules/default/currentweather/node_helper.js
+++ /dev/null
@@ -1,29 +0,0 @@
-var http = require("http");
-var NodeHelper = require("node_helper");
-
-module.exports = NodeHelper.create({
- start: function () {
- },
-
- socketNotificationReceived: function (notification, payload) {
- var self = this;
-
- if (notification === "AUTO_LOCATION") {
- console.log("Loading timezone...");
- http.get("http://ip-api.com/json", function (req) {
- var data = "";
- req.on("data", function (d) {
- data += d;
- });
- req.on("end", function () {
- var body = JSON.parse(data);
- payload.location = body.city + ", " + body.regionName;
- self.sendSocketNotification("UPDATE_LOCATION", payload);
- });
- }).on("error", function () {
- payload.error = "Could not figure out the timezone.";
- self.sendSocketNotification("UPDATE_LOCATION", payload);
- });
- }
- }
-});
diff --git a/modules/default/newsfeed/README.md b/modules/default/newsfeed/README.md
index c06c3f07..b14a7ac6 100644
--- a/modules/default/newsfeed/README.md
+++ b/modules/default/newsfeed/README.md
@@ -46,6 +46,7 @@ MagicMirror's [notification mechanism](https://github.com/MichMich/MagicMirror/t
| `ARTICLE_MORE_DETAILS` | When received the _first time_, shows the corresponding description of the currently displayed news title.
The module expects that the module's configuration option `showDescription` is set to `false` (default value).
When received a _second consecutive time_, shows the full news article in an IFRAME.
This requires that the news page can be embedded in an IFRAME, e.g. doesn't have the HTTP response header [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) set to e.g. `DENY`.
When received the _next consecutive times_, reloads the page and scrolls down by `scrollLength` pixels to paginate through the article.
| `ARTICLE_LESS_DETAILS` | Hides the summary or full news article and only displays the news title of the currently viewed news item.
| `ARTICLE_TOGGLE_FULL` | Toogles article in fullscreen.
+| `ARTICLE_INFO_REQUEST` | Causes `newsfeed` to respond with the notification `ARTICLE_INFO_RESPONSE`, the payload of which provides the `title`, `source`, `date`, `desc` and `url` of the current news title.
Note the payload of the sent notification event is ignored.
diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js
index 212a6a0f..3bb38d0a 100644
--- a/modules/default/newsfeed/newsfeed.js
+++ b/modules/default/newsfeed/newsfeed.js
@@ -189,7 +189,7 @@ Module.register("newsfeed",{
fullArticle.style.top = "0";
fullArticle.style.left = "0";
fullArticle.style.border = "none";
- fullArticle.src = typeof this.newsItems[this.activeItem].url === "string" ? this.newsItems[this.activeItem].url : this.newsItems[this.activeItem].url.href;
+ fullArticle.src = this.getActiveItemURL()
fullArticle.style.zIndex = 1;
wrapper.appendChild(fullArticle);
}
@@ -210,6 +210,10 @@ Module.register("newsfeed",{
return wrapper;
},
+ getActiveItemURL: function() {
+ return typeof this.newsItems[this.activeItem].url === "string" ? this.newsItems[this.activeItem].url : this.newsItems[this.activeItem].url.href;
+ },
+
/* registerFeeds()
* registers the feeds to be used by the backend.
*/
@@ -387,6 +391,14 @@ Module.register("newsfeed",{
} else {
this.showFullArticle();
}
+ } else if (notification === "ARTICLE_INFO_REQUEST"){
+ this.sendNotification("ARTICLE_INFO_RESPONSE", {
+ title: this.newsItems[this.activeItem].title,
+ source: this.newsItems[this.activeItem].sourceTitle,
+ date: this.newsItems[this.activeItem].pubdate,
+ desc: this.newsItems[this.activeItem].description,
+ url: this.getActiveItemURL()
+ })
} else {
Log.info(this.name + " - unknown notification, ignoring: " + notification);
}
diff --git a/modules/default/weatherforecast/node_helper.js b/modules/default/weatherforecast/node_helper.js
deleted file mode 100644
index 53956f62..00000000
--- a/modules/default/weatherforecast/node_helper.js
+++ /dev/null
@@ -1,29 +0,0 @@
-var http = require("http");
-var NodeHelper = require("node_helper");
-
-module.exports = NodeHelper.create({
- start: function () {
- },
-
- socketNotificationReceived: function (notification, payload) {
- var self = this;
-
- if (notification === "AUTO_LOCATION") {
- console.log("Loading timezone...");
- http.get("http://ip-api.com/json", function (req) {
- var data = "";
- req.on("data", function (d) {
- data += d;
- });
- req.on("end", function () {
- var body = JSON.parse(data);
- payload.location = body.city + ", " + body.regionName;
- self.sendSocketNotification("UPDATE_LOCATION", payload);
- });
- }).on("error", function () {
- payload.error = "Could not figure out the timezone.";
- self.sendSocketNotification("UPDATE_LOCATION", payload);
- });
- }
- }
-});
diff --git a/modules/default/weatherforecast/weatherforecast.js b/modules/default/weatherforecast/weatherforecast.js
index c32821db..67193696 100644
--- a/modules/default/weatherforecast/weatherforecast.js
+++ b/modules/default/weatherforecast/weatherforecast.js
@@ -11,7 +11,6 @@ Module.register("weatherforecast",{
// Default module config.
defaults: {
- autoLocation: false,
location: false,
locationID: false,
appid: "",
@@ -96,20 +95,10 @@ Module.register("weatherforecast",{
this.forecast = [];
this.loaded = false;
+ this.scheduleUpdate(this.config.initialLoadDelay);
+
this.updateTimer = null;
- if (this.config.autoLocation) {
- this.sendSocketNotification("AUTO_LOCATION");
- } else {
- this.scheduleUpdate(this.config.initialLoadDelay);
- }
- },
-
- socketNotificationReceived: function (notification, payload) {
- if (notification === "UPDATE_LOCATION") {
- this.config.location = payload.location;
- this.scheduleUpdate(this.config.initialLoadDelay);
- }
},
// Override dom generator.
diff --git a/package-lock.json b/package-lock.json
index 124aa864..d87793e8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "magicmirror",
- "version": "2.7.0-develop",
+ "version": "2.8.0-develop",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1368,7 +1368,7 @@
"require-from-string": "^2.0.1",
"rfc6902": "^2.2.2",
"supports-hyperlinks": "^1.0.1",
- "vm2": "github:patriksimek/vm2#7e82f90ac705fc44fad044147cb0df09b4c79a57",
+ "vm2": "github:patriksimek/vm2#custom_files",
"voca": "^1.4.0"
},
"dependencies": {
@@ -1427,6 +1427,11 @@
"requires": {
"has-flag": "^2.0.0"
}
+ },
+ "vm2": {
+ "version": "github:patriksimek/vm2#468bc1e54e75e766b842830ea775669992a979e0",
+ "from": "github:patriksimek/vm2#custom_files",
+ "dev": true
}
}
},
@@ -2247,7 +2252,7 @@
},
"eventemitter2": {
"version": "0.4.14",
- "resolved": "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
"integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
"dev": true
},
@@ -2593,7 +2598,7 @@
},
"findup-sync": {
"version": "0.3.0",
- "resolved": "http://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
"integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
"dev": true,
"requires": {
@@ -2906,7 +2911,7 @@
},
"grunt-cli": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
"integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=",
"dev": true,
"requires": {
@@ -4667,9 +4672,9 @@
}
},
"moment": {
- "version": "2.23.0",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.23.0.tgz",
- "integrity": "sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA=="
+ "version": "2.24.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
+ "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"ms": {
"version": "2.0.0",
@@ -5813,7 +5818,7 @@
},
"require-uncached": {
"version": "1.0.3",
- "resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
"integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
"dev": true,
"requires": {
@@ -5823,7 +5828,7 @@
},
"resolve": {
"version": "1.1.7",
- "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
"dev": true
},
@@ -7219,11 +7224,6 @@
"unist-util-stringify-position": "^1.1.1"
}
},
- "vm2": {
- "version": "github:patriksimek/vm2#7e82f90ac705fc44fad044147cb0df09b4c79a57",
- "from": "vm2@github:patriksimek/vm2#7e82f90ac705fc44fad044147cb0df09b4c79a57",
- "dev": true
- },
"voca": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/voca/-/voca-1.4.0.tgz",
diff --git a/package.json b/package.json
index 3180f70d..37fc0a69 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "magicmirror",
- "version": "2.7.0-develop",
+ "version": "2.8.0-develop",
"description": "The open source modular smart mirror platform.",
"main": "js/electron.js",
"scripts": {
diff --git a/translations/fi.json b/translations/fi.json
index aa20759d..495439c1 100644
--- a/translations/fi.json
+++ b/translations/fi.json
@@ -7,6 +7,8 @@
"RUNNING": "Päättyy {timeUntilEnd} päästä",
"EMPTY": "Ei tulevia tapahtumia.",
+ "WEEK": "Viikko {weekNumber}",
+
"N": "P",
"NNE": "PPI",
"NE": "PI",
@@ -25,5 +27,7 @@
"NNW": "PPL",
"UPDATE_NOTIFICATION": "MagicMirror² päivitys saatavilla.",
- "UPDATE_NOTIFICATION_MODULE": "Päivitys saatavilla moduulille {MODULE_NAME}."
+ "UPDATE_NOTIFICATION_MODULE": "Päivitys saatavilla moduulille {MODULE_NAME}.",
+
+ "FEELS": "Tuntuu kuin"
}
diff --git a/translations/ru.json b/translations/ru.json
index cf2e5c5f..0512e14b 100644
--- a/translations/ru.json
+++ b/translations/ru.json
@@ -25,6 +25,7 @@
"WNW": "ЗСЗ",
"NW": "СЗ",
"NNW": "ССЗ",
+ "FEELS": "По ощущению",
"UPDATE_NOTIFICATION": "Есть обновление для MagicMirror².",
"UPDATE_NOTIFICATION_MODULE": "Есть обновление для {MODULE_NAME} модуля.",
diff --git a/translations/tlh.json b/translations/tlh.json
new file mode 100644
index 00000000..c13f4019
--- /dev/null
+++ b/translations/tlh.json
@@ -0,0 +1,35 @@
+{
+ "LOADING": "loS …",
+
+ "TODAY": "DaHjaj",
+ "TOMORROW": "wa'leS",
+ "DAYAFTERTOMORROW": "cha'leS",
+ "RUNNING": "Dor",
+ "EMPTY": "Sumbe' wanI'.",
+
+ "WEEK": "Hogh (terran) {weekNumber}",
+
+ "N": "N",
+ "NNE": "NNE",
+ "NE": "NE",
+ "ENE": "ENE",
+ "E": "chan",
+ "ESE": "ESE",
+ "SE": "SE",
+ "SSE": "SSE",
+ "S": "S",
+ "SSW": "SSW",
+ "SW": "tIng",
+ "WSW": "WSW",
+ "W": "W",
+ "WNW": "WNW",
+ "NW": "'ev",
+ "NNW": "NNW",
+
+ "UPDATE_NOTIFICATION": " De'chu' MagicMirror² lI'laH.",
+ "UPDATE_NOTIFICATION_MODULE": "bobcho' {MODULE_NAME} lI'laH De'chu.",
+ "UPDATE_INFO_SINGLE": "The current installation is {COMMIT_COUNT} commit behind on the {BRANCH_NAME} branch.",
+ "UPDATE_INFO_MULTIPLE": "The current installation is {COMMIT_COUNT} commits behind on the {BRANCH_NAME} branch.",
+
+ "FEELS": "jem"
+}
diff --git a/translations/translations.js b/translations/translations.js
index 39bf8d5b..3d719cc3 100644
--- a/translations/translations.js
+++ b/translations/translations.js
@@ -39,7 +39,8 @@ var translations = {
"bg" : "translations/bg.json", // Bulgarian
"cs" : "translations/cs.json", // Czech
"hr" : "translations/hr.json", // Croatian
- "sk" : "translations/sk.json" // Slovak
+ "sk" : "translations/sk.json", // Slovak
+ "tlh" : "translations/tlh.json" // Klingon
};
if (typeof module !== "undefined") {module.exports = translations;}
diff --git a/vendor/package-lock.json b/vendor/package-lock.json
index 9ad15ee5..3ce96fc2 100644
--- a/vendor/package-lock.json
+++ b/vendor/package-lock.json
@@ -193,11 +193,6 @@
"repeat-string": "^1.5.2"
}
},
- "font-awesome": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
- "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM="
- },
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -230,7 +225,8 @@
},
"ansi-regex": {
"version": "2.1.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -248,11 +244,13 @@
},
"balanced-match": {
"version": "1.0.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -265,15 +263,18 @@
},
"code-point-at": {
"version": "1.1.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -376,7 +377,8 @@
},
"inherits": {
"version": "2.0.3",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -386,6 +388,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -398,17 +401,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -425,6 +431,7 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -497,7 +504,8 @@
},
"number-is-nan": {
"version": "1.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -507,6 +515,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -582,7 +591,8 @@
},
"safe-buffer": {
"version": "5.1.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -612,6 +622,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -629,6 +640,7 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -667,11 +679,13 @@
},
"wrappy": {
"version": "1.0.2",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"yallist": {
"version": "3.0.2",
- "bundled": true
+ "bundled": true,
+ "optional": true
}
}
},
@@ -689,6 +703,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
"integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+ "optional": true,
"requires": {
"is-glob": "^2.0.0"
}
@@ -702,7 +717,8 @@
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "optional": true
},
"invert-kv": {
"version": "1.0.0",
@@ -721,7 +737,8 @@
"is-buffer": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
- "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
+ "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
+ "optional": true
},
"is-dotfile": {
"version": "1.0.3",
@@ -747,7 +764,8 @@
"is-extglob": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "optional": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
@@ -761,6 +779,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "optional": true,
"requires": {
"is-extglob": "^1.0.0"
}
@@ -789,7 +808,8 @@
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "optional": true
},
"isobject": {
"version": "2.1.0",
@@ -804,6 +824,7 @@
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "optional": true,
"requires": {
"is-buffer": "^1.1.5"
}
@@ -869,6 +890,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "optional": true,
"requires": {
"remove-trailing-separator": "^1.0.1"
}
@@ -1017,12 +1039,14 @@
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
- "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+ "optional": true
},
"repeat-element": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
- "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo="
+ "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+ "optional": true
},
"repeat-string": {
"version": "1.6.1",
@@ -1033,7 +1057,8 @@
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
- "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+ "optional": true
},
"set-immediate-shim": {
"version": "1.0.1",