diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e3413bb..efdd1aac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Module API: Add Visibility locking to module system. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#visibility-locking) for more information.
- Module API: Method to overwrite the module's header. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#getheader) for more information.
- Module API: Option to define the minimumn MagicMirror version to run a module. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#requiresversion) for more information.
+- Calendar module now broadcasts the event list to all other modules using the notification system. [See documentation](https://github.com/MichMich/MagicMirror/tree/master/modules/default/calendar) for more information.
### Updated
- Modified translations for Frysk.
diff --git a/js/class.js b/js/class.js
index 2b011b29..01a92603 100644
--- a/js/class.js
+++ b/js/class.js
@@ -11,24 +11,6 @@
// The base Class implementation (does nothing)
this.Class = function() {};
- //Define the clone method for later use.
- function cloneObject(obj) {
- if (obj === null || typeof obj !== "object") {
- return obj;
- }
-
- var temp = obj.constructor(); // give temp the original obj's constructor
- for (var key in obj) {
- temp[key] = cloneObject(obj[key]);
-
- if (key === "lockStrings") {
- Log.log(key);
- }
- }
-
- return temp;
- }
-
// Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;
@@ -87,5 +69,24 @@
};
})();
+//Define the clone method for later use.
+//Helper Method
+function cloneObject(obj) {
+ if (obj === null || typeof obj !== "object") {
+ return obj;
+ }
+
+ var temp = obj.constructor(); // give temp the original obj's constructor
+ for (var key in obj) {
+ temp[key] = cloneObject(obj[key]);
+
+ if (key === "lockStrings") {
+ Log.log(key);
+ }
+ }
+
+ return temp;
+}
+
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = Class;}
diff --git a/js/module.js b/js/module.js
index 17ca9595..397d4799 100644
--- a/js/module.js
+++ b/js/module.js
@@ -371,20 +371,6 @@ Module.create = function (name) {
return;
}
- //Define the clone method for later use.
- function cloneObject(obj) {
- if (obj === null || typeof obj !== "object") {
- return obj;
- }
-
- var temp = obj.constructor(); // give temp the original obj's constructor
- for (var key in obj) {
- temp[key] = cloneObject(obj[key]);
- }
-
- return temp;
- }
-
var moduleDefinition = Module.definitions[name];
var clonedDefinition = cloneObject(moduleDefinition);
diff --git a/modules/default/calendar/README.md b/modules/default/calendar/README.md
index fc553095..54d318ce 100644
--- a/modules/default/calendar/README.md
+++ b/modules/default/calendar/README.md
@@ -106,7 +106,6 @@ The following properties can be configured:
titleReplace |
An object of textual replacements applied to the tile of the event. This allow to remove or replace certains words in the title.
Example:
-
titleReplace: {'Birthday of ' : '', 'foo':'bar'}
@@ -141,6 +140,13 @@ The following properties can be configured:
Default value: 0 (disabled)
|
+
+ broadcastEvents |
+ If this property is set to true, the calendar will broadcast all the events to all other modules with the notification message: CALENDAR_EVENTS . The event objects are stored in an array and contain the following fields: title , startDate , endDate , fullDayEvent , location and geo .
+ Possible values: true , false
+ Default value: true
+ |
+
diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js
index c2a2c851..39ea6b58 100644
--- a/modules/default/calendar/calendar.js
+++ b/modules/default/calendar/calendar.js
@@ -7,7 +7,7 @@
* MIT Licensed.
*/
-Module.register("calendar",{
+Module.register("calendar", {
// Define module defaults
defaults: {
@@ -16,7 +16,7 @@ Module.register("calendar",{
displaySymbol: true,
defaultSymbol: "calendar", // Fontawesome Symbol see http://fontawesome.io/cheatsheet/
displayRepeatingCountTitle: false,
- defaultRepeatingCountTitle: '',
+ defaultRepeatingCountTitle: "",
maxTitleLength: 25,
fetchInterval: 5 * 60 * 1000, // Update every 5 minutes.
animationSpeed: 2000,
@@ -35,20 +35,21 @@ Module.register("calendar",{
"De verjaardag van ": "",
"'s birthday": ""
},
+ broadcastEvents: true
},
// Define required scripts.
- getStyles: function() {
+ getStyles: function () {
return ["calendar.css", "font-awesome.css"];
},
// Define required scripts.
- getScripts: function() {
+ getScripts: function () {
return ["moment.js"];
},
// Define required translations.
- getTranslations: function() {
+ getTranslations: function () {
// The translations for the defaut modules are defined in the core translation files.
// Therefor we can just return false. Otherwise we should have returned a dictionairy.
// If you're trying to build your own module including translations, check out the documentation.
@@ -56,7 +57,7 @@ Module.register("calendar",{
},
// Override start method.
- start: function() {
+ start: function () {
Log.log("Starting module: " + this.name);
// Set locale.
@@ -73,11 +74,15 @@ Module.register("calendar",{
},
// Override socket notification handler.
- socketNotificationReceived: function(notification, payload) {
+ socketNotificationReceived: function (notification, payload) {
if (notification === "CALENDAR_EVENTS") {
if (this.hasCalendarURL(payload.url)) {
this.calendarData[payload.url] = payload.events;
this.loaded = true;
+
+ if (this.config.broadcastEvents) {
+ this.broadcastEvents();
+ }
}
} else if (notification === "FETCH_ERROR") {
Log.error("Calendar Error. Could not fetch calendar: " + payload.url);
@@ -91,7 +96,7 @@ Module.register("calendar",{
},
// Override dom generator.
- getDom: function() {
+ getDom: function () {
var events = this.createEventList();
var wrapper = document.createElement("table");
@@ -110,27 +115,27 @@ Module.register("calendar",{
eventWrapper.className = "normal";
if (this.config.displaySymbol) {
- var symbolWrapper = document.createElement("td");
+ var symbolWrapper = document.createElement("td");
symbolWrapper.className = "symbol";
- var symbol = document.createElement("span");
+ var symbol = document.createElement("span");
symbol.className = "fa fa-" + this.symbolForUrl(event.url);
symbolWrapper.appendChild(symbol);
eventWrapper.appendChild(symbolWrapper);
}
var titleWrapper = document.createElement("td"),
- repeatingCountTitle = '';
+ repeatingCountTitle = "";
if (this.config.displayRepeatingCountTitle) {
repeatingCountTitle = this.countTitleForUrl(event.url);
- if(repeatingCountTitle !== '') {
+ if (repeatingCountTitle !== "") {
var thisYear = new Date().getFullYear(),
yearDiff = thisYear - event.firstYear;
- repeatingCountTitle = ', '+ yearDiff + '. ' + repeatingCountTitle;
+ repeatingCountTitle = ", " + yearDiff + ". " + repeatingCountTitle;
}
}
@@ -138,24 +143,24 @@ Module.register("calendar",{
titleWrapper.className = "title bright";
eventWrapper.appendChild(titleWrapper);
- var timeWrapper = document.createElement("td");
+ var timeWrapper = document.createElement("td");
//console.log(event.today);
var now = new Date();
// Define second, minute, hour, and day variables
- var one_second = 1000; // 1,000 milliseconds
- var one_minute = one_second * 60;
- var one_hour = one_minute * 60;
- var one_day = one_hour * 24;
+ var oneSecond = 1000; // 1,000 milliseconds
+ var oneMinute = oneSecond * 60;
+ var oneHour = oneMinute * 60;
+ var oneDay = oneHour * 24;
if (event.fullDayEvent) {
if (event.today) {
timeWrapper.innerHTML = this.capFirst(this.translate("TODAY"));
- } else if (event.startDate - now < one_day && event.startDate - now > 0) {
+ } else if (event.startDate - now < oneDay && event.startDate - now > 0) {
timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW"));
- } else if (event.startDate - now < 2*one_day && event.startDate - now > 0) {
- if (this.translate('DAYAFTERTOMORROW') !== 'DAYAFTERTOMORROW') {
- timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW"));
+ } else if (event.startDate - now < 2 * oneDay && event.startDate - now > 0) {
+ if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") {
+ timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW"));
} else {
- timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
+ timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
}
} else {
/* Check to see if the user displays absolute or relative dates with their events
@@ -166,21 +171,21 @@ Module.register("calendar",{
* Note: this needs to be put in its own function, as the whole thing repeats again verbatim
*/
if (this.config.timeFormat === "absolute") {
- if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * one_day))) {
+ if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) {
// This event falls within the config.urgency period that the user has set
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
} else {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format("MMM Do"));
}
} else {
- timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
+ timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
}
}
} else {
if (event.startDate >= new Date()) {
- if (event.startDate - now < 2 * one_day) {
+ if (event.startDate - now < 2 * oneDay) {
// This event is within the next 48 hours (2 days)
- if (event.startDate - now < this.config.getRelative * one_hour) {
+ if (event.startDate - now < this.config.getRelative * oneHour) {
// If event is within 6 hour, display 'in xxx' time format or moment.fromNow()
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
} else {
@@ -196,7 +201,7 @@ Module.register("calendar",{
* Note: this needs to be put in its own function, as the whole thing repeats again verbatim
*/
if (this.config.timeFormat === "absolute") {
- if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * one_day))) {
+ if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) {
// This event falls within the config.urgency period that the user has set
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
} else {
@@ -207,7 +212,7 @@ Module.register("calendar",{
}
}
} else {
- timeWrapper.innerHTML = this.capFirst(this.translate("RUNNING")) + ' ' + moment(event.endDate,"x").fromNow(true);
+ timeWrapper.innerHTML = this.capFirst(this.translate("RUNNING")) + " " + moment(event.endDate, "x").fromNow(true);
}
}
//timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll');
@@ -241,7 +246,7 @@ Module.register("calendar",{
*
* return bool - Has calendar url
*/
- hasCalendarURL: function(url) {
+ hasCalendarURL: function (url) {
for (var c in this.config.calendars) {
var calendar = this.config.calendars[c];
if (calendar.url === url) {
@@ -257,7 +262,7 @@ Module.register("calendar",{
*
* return array - Array with events.
*/
- createEventList: function() {
+ createEventList: function () {
var events = [];
var today = moment().startOf("day");
for (var c in this.calendarData) {
@@ -270,7 +275,7 @@ Module.register("calendar",{
}
}
- events.sort(function(a, b) {
+ events.sort(function (a, b) {
return a.startDate - b.startDate;
});
@@ -282,7 +287,7 @@ Module.register("calendar",{
*
* argument url sting - Url to add.
*/
- addCalendar: function(url, user, pass) {
+ addCalendar: function (url, user, pass) {
this.sendSocketNotification("ADD_CALENDAR", {
url: url,
maximumEntries: this.config.maximumEntries,
@@ -300,10 +305,10 @@ Module.register("calendar",{
*
* return string - The Symbol
*/
- symbolForUrl: function(url) {
+ symbolForUrl: function (url) {
for (var c in this.config.calendars) {
var calendar = this.config.calendars[c];
- if (calendar.url === url && typeof calendar.symbol === "string") {
+ if (calendar.url === url && typeof calendar.symbol === "string") {
return calendar.symbol;
}
}
@@ -317,10 +322,10 @@ Module.register("calendar",{
*
* return string - The Symbol
*/
- countTitleForUrl: function(url) {
+ countTitleForUrl: function (url) {
for (var c in this.config.calendars) {
var calendar = this.config.calendars[c];
- if (calendar.url === url && typeof calendar.repeatingCountTitle === "string") {
+ if (calendar.url === url && typeof calendar.repeatingCountTitle === "string") {
return calendar.repeatingCountTitle;
}
}
@@ -337,9 +342,9 @@ Module.register("calendar",{
*
* return string - The shortened string.
*/
- shorten: function(string, maxLength) {
+ shorten: function (string, maxLength) {
if (string.length > maxLength) {
- return string.slice(0,maxLength) + "…";
+ return string.slice(0, maxLength) + "…";
}
return string;
@@ -349,8 +354,8 @@ Module.register("calendar",{
* Capitalize the first letter of a string
* Eeturn capitalized string
*/
-
- capFirst: function(string) {
+
+ capFirst: function (string) {
return string.charAt(0).toUpperCase() + string.slice(1);
},
@@ -363,7 +368,7 @@ Module.register("calendar",{
*
* return string - The transformed title.
*/
- titleTransform: function(title) {
+ titleTransform: function (title) {
for (var needle in this.config.titleReplace) {
var replacement = this.config.titleReplace[needle];
title = title.replace(needle, replacement);
@@ -371,5 +376,28 @@ Module.register("calendar",{
title = this.shorten(title, this.config.maxTitleLength);
return title;
+ },
+
+ /* broadcastEvents()
+ * Broadcasts the events to all other modules for reuse.
+ * The all events available in one array, sorted on startdate.
+ */
+ broadcastEvents: function () {
+ var eventList = [];
+ for (url in this.calendarData) {
+ var calendar = this.calendarData[url];
+ for (e in calendar) {
+ var event = cloneObject(calendar[e]);
+ delete event.url;
+ eventList.push(event);
+ }
+ }
+
+ eventList.sort(function(a,b) {
+ return a.startDate - b.startDate;
+ });
+
+ this.sendNotification("CALENDAR_EVENTS", eventList);
+
}
});
diff --git a/modules/default/calendar/calendarfetcher.js b/modules/default/calendar/calendarfetcher.js
index 214e2e5a..7f142546 100644
--- a/modules/default/calendar/calendarfetcher.js
+++ b/modules/default/calendar/calendarfetcher.js
@@ -27,7 +27,7 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
var opts = {
headers: {
- 'User-Agent': 'Mozilla/5.0 (Node.js 6.0.0) MagicMirror/v2 (https://github.com/MichMich/MagicMirror/)'
+ "User-Agent": "Mozilla/5.0 (Node.js 6.0.0) MagicMirror/v2 (https://github.com/MichMich/MagicMirror/)"
}
};
@@ -77,7 +77,7 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
if (!isFacebookBirthday) {
endDate = startDate;
} else {
- endDate = moment(startDate).add(1, 'days');
+ endDate = moment(startDate).add(1, "days");
}
}
@@ -101,7 +101,7 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
for (var d in dates) {
startDate = moment(new Date(dates[d]));
- endDate = moment(parseInt(startDate.format("x")) + duration, 'x');
+ endDate = moment(parseInt(startDate.format("x")) + duration, "x");
if (endDate.format("x") > now) {
newEvents.push({
title: title,
@@ -132,12 +132,19 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
continue;
}
- // Every thing is good. Add it to the list.
+
+ var location = event.location || false;
+ var geo = event.geo || false;
+
+ // Every thing is good. Add it to the list.
+
newEvents.push({
title: title,
startDate: startDate.format("x"),
endDate: endDate.format("x"),
- fullDayEvent: fullDayEvent
+ fullDayEvent: fullDayEvent,
+ location: location,
+ geo: geo
});
}