From 806be39a6d549e17c663e906b8dd3349612bfc8e Mon Sep 17 00:00:00 2001 From: Jon Kolb Date: Mon, 1 Apr 2019 15:39:25 -0400 Subject: [PATCH 1/2] Add includePastEvents global and calendar-specific settings --- CHANGELOG.md | 1 + modules/default/calendar/README.md | 2 ++ modules/default/calendar/calendar.js | 12 ++++++-- modules/default/calendar/calendarfetcher.js | 32 ++++++++++++++------- modules/default/calendar/debug.js | 1 + modules/default/calendar/node_helper.js | 6 ++-- 6 files changed, 38 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e0f65f3..333be48f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Fixed `package.json` version number. - 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 +- Add `includePastEvents` config option for calendars to include events from the past `maximumNumberOfDays` in 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) diff --git a/modules/default/calendar/README.md b/modules/default/calendar/README.md index 65362a81..8f8a6d12 100755 --- a/modules/default/calendar/README.md +++ b/modules/default/calendar/README.md @@ -55,6 +55,7 @@ The following properties can be configured: | `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:** `false` +| `includePastEvents` | If this is set to true, events from the past `maximumNumberOfDays` will be included in event broadcasts
**Default value:** `false` ### Calendar configuration @@ -96,6 +97,7 @@ config: { | `symbolClass` | Add a class to the cell of symbol. | `titleClass` | Add a class to the title's cell. | `timeClass` | Add a class to the time's cell. +| `includePastEvents` | Whether to include past events from this calendar. Overrides global setting #### Calendar authentication options: diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index 3aaed2ae..ee342153 100755 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -49,7 +49,8 @@ Module.register("calendar", { }, broadcastEvents: true, excludedEvents: [], - sliceMultiDayEvents: false + sliceMultiDayEvents: false, + includePastEvents: false, }, // Define required scripts. @@ -83,7 +84,8 @@ Module.register("calendar", { var calendarConfig = { maximumEntries: calendar.maximumEntries, - maximumNumberOfDays: calendar.maximumNumberOfDays + maximumNumberOfDays: calendar.maximumNumberOfDays, + includePastEvents: calendar.includePastEvents, }; if (calendar.symbolClass === "undefined" || calendar.symbolClass === null) { calendarConfig.symbolClass = ""; @@ -467,6 +469,9 @@ Module.register("calendar", { var calendar = this.calendarData[c]; for (var e in calendar) { var event = JSON.parse(JSON.stringify(calendar[e])); // clone object + if(event.endDate < now) { + continue; + } if(this.config.hidePrivate) { if(event.class === "PRIVATE") { // do not add the current event, skip it @@ -550,7 +555,8 @@ Module.register("calendar", { symbolClass: calendarConfig.symbolClass, titleClass: calendarConfig.titleClass, timeClass: calendarConfig.timeClass, - auth: auth + auth: auth, + includePastEvents: calendarConfig.includePastEvents || this.config.includePastEvents, }); }, diff --git a/modules/default/calendar/calendarfetcher.js b/modules/default/calendar/calendarfetcher.js index 0076a605..3a30aea2 100644 --- a/modules/default/calendar/calendarfetcher.js +++ b/modules/default/calendar/calendarfetcher.js @@ -8,7 +8,7 @@ var ical = require("./vendor/ical.js"); var moment = require("moment"); -var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth) { +var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, includePastEvents) { var self = this; var reloadTimer = null; @@ -74,6 +74,11 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri var now = new Date(); var today = moment().startOf("day").toDate(); var future = moment().startOf("day").add(maximumNumberOfDays, "days").subtract(1,"seconds").toDate(); // Subtract 1 second so that events that start on the middle of the night will not repeat. + var past = today; + + if (includePastEvents) { + past = moment().startOf("day").subtract(maximumNumberOfDays, "days").toDate(); + } // FIXME: // Ugly fix to solve the facebook birthday issue. @@ -181,7 +186,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri rule.options.dtstart.setYear(1900); } - var dates = rule.between(today, future, true, limitFunction); + var dates = rule.between(past, future, true, limitFunction); for (var d in dates) { startDate = moment(new Date(dates[d])); @@ -191,7 +196,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri continue; } - if (endDate.format("x") > now) { + if (includePastEvents || endDate.format("x") > now) { newEvents.push({ title: title, startDate: startDate.format("x"), @@ -210,14 +215,21 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri // Single event. var fullDayEvent = (isFacebookBirthday) ? true : isFullDayEvent(event); - if (!fullDayEvent && endDate < new Date()) { - //console.log("It's not a fullday event, and it is in the past. So skip: " + title); - continue; - } + if (includePastEvents) { + if (endDate < past) { + //console.log("Past event is too far in the past. So skip: " + title); + continue; + } + } else { + if (!fullDayEvent && endDate < new Date()) { + //console.log("It's not a fullday event, and it is in the past. So skip: " + title); + continue; + } - if (fullDayEvent && endDate <= today) { - //console.log("It's a fullday event, and it is before today. So skip: " + title); - continue; + if (fullDayEvent && endDate <= today) { + //console.log("It's a fullday event, and it is before today. So skip: " + title); + continue; + } } if (startDate > future) { diff --git a/modules/default/calendar/debug.js b/modules/default/calendar/debug.js index ddf0fb42..b8295d66 100644 --- a/modules/default/calendar/debug.js +++ b/modules/default/calendar/debug.js @@ -15,6 +15,7 @@ var maximumEntries = 10; var maximumNumberOfDays = 365; var user = "magicmirror"; var pass = "MyStrongPass"; +var includePastEvents = false; var auth = { user: user, diff --git a/modules/default/calendar/node_helper.js b/modules/default/calendar/node_helper.js index 25e7f1f7..30c28e9d 100644 --- a/modules/default/calendar/node_helper.js +++ b/modules/default/calendar/node_helper.js @@ -24,7 +24,7 @@ module.exports = NodeHelper.create({ socketNotificationReceived: function(notification, payload) { if (notification === "ADD_CALENDAR") { //console.log('ADD_CALENDAR: '); - this.createFetcher(payload.url, payload.fetchInterval, payload.excludedEvents, payload.maximumEntries, payload.maximumNumberOfDays, payload.auth); + this.createFetcher(payload.url, payload.fetchInterval, payload.excludedEvents, payload.maximumEntries, payload.maximumNumberOfDays, payload.auth, payload.includePastEvents); } }, @@ -36,7 +36,7 @@ module.exports = NodeHelper.create({ * attribute reloadInterval number - Reload interval in milliseconds. */ - createFetcher: function(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth) { + createFetcher: function(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, includePastEvents) { var self = this; if (!validUrl.isUri(url)) { @@ -47,7 +47,7 @@ module.exports = NodeHelper.create({ var fetcher; if (typeof self.fetchers[url] === "undefined") { console.log("Create new calendar fetcher for url: " + url + " - Interval: " + fetchInterval); - fetcher = new CalendarFetcher(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth); + fetcher = new CalendarFetcher(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, includePastEvents); fetcher.onReceive(function(fetcher) { //console.log('Broadcast events.'); From c61f0409fb8d65f71fca9ca29015ffd864a802e3 Mon Sep 17 00:00:00 2001 From: Jon Kolb Date: Wed, 10 Apr 2019 16:50:18 -0400 Subject: [PATCH 2/2] Rename includePastEvents calendar config option to broadcastPastEvents --- CHANGELOG.md | 3 ++- modules/default/calendar/README.md | 4 ++-- modules/default/calendar/calendar.js | 6 +++--- modules/default/calendar/debug.js | 2 +- modules/default/calendar/node_helper.js | 6 +++--- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 333be48f..056f23b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Russian translation for “Feels” +- Add `broadcastPastEvents` config option for calendars to include events from the past `maximumNumberOfDays` in event broadcasts + ### Updated ### Fixed @@ -44,7 +46,6 @@ Fixed `package.json` version number. - 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 -- Add `includePastEvents` config option for calendars to include events from the past `maximumNumberOfDays` in 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) diff --git a/modules/default/calendar/README.md b/modules/default/calendar/README.md index 8f8a6d12..786f7362 100755 --- a/modules/default/calendar/README.md +++ b/modules/default/calendar/README.md @@ -55,7 +55,7 @@ The following properties can be configured: | `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:** `false` -| `includePastEvents` | If this is set to true, events from the past `maximumNumberOfDays` will be included in event broadcasts
**Default value:** `false` +| `broadcastPastEvents` | If this is set to true, events from the past `maximumNumberOfDays` will be included in event broadcasts
**Default value:** `false` ### Calendar configuration @@ -97,7 +97,7 @@ config: { | `symbolClass` | Add a class to the cell of symbol. | `titleClass` | Add a class to the title's cell. | `timeClass` | Add a class to the time's cell. -| `includePastEvents` | Whether to include past events from this calendar. Overrides global setting +| `broadcastPastEvents` | Whether to include past events from this calendar. Overrides global setting #### Calendar authentication options: diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index ee342153..45009934 100755 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -50,7 +50,7 @@ Module.register("calendar", { broadcastEvents: true, excludedEvents: [], sliceMultiDayEvents: false, - includePastEvents: false, + broadcastPastEvents: false, }, // Define required scripts. @@ -85,7 +85,7 @@ Module.register("calendar", { var calendarConfig = { maximumEntries: calendar.maximumEntries, maximumNumberOfDays: calendar.maximumNumberOfDays, - includePastEvents: calendar.includePastEvents, + broadcastPastEvents: calendar.broadcastPastEvents, }; if (calendar.symbolClass === "undefined" || calendar.symbolClass === null) { calendarConfig.symbolClass = ""; @@ -556,7 +556,7 @@ Module.register("calendar", { titleClass: calendarConfig.titleClass, timeClass: calendarConfig.timeClass, auth: auth, - includePastEvents: calendarConfig.includePastEvents || this.config.includePastEvents, + broadcastPastEvents: calendarConfig.broadcastPastEvents || this.config.broadcastPastEvents, }); }, diff --git a/modules/default/calendar/debug.js b/modules/default/calendar/debug.js index b8295d66..a568e1cd 100644 --- a/modules/default/calendar/debug.js +++ b/modules/default/calendar/debug.js @@ -15,7 +15,7 @@ var maximumEntries = 10; var maximumNumberOfDays = 365; var user = "magicmirror"; var pass = "MyStrongPass"; -var includePastEvents = false; +var broadcastPastEvents = false; var auth = { user: user, diff --git a/modules/default/calendar/node_helper.js b/modules/default/calendar/node_helper.js index 30c28e9d..9c6e4979 100644 --- a/modules/default/calendar/node_helper.js +++ b/modules/default/calendar/node_helper.js @@ -24,7 +24,7 @@ module.exports = NodeHelper.create({ socketNotificationReceived: function(notification, payload) { if (notification === "ADD_CALENDAR") { //console.log('ADD_CALENDAR: '); - this.createFetcher(payload.url, payload.fetchInterval, payload.excludedEvents, payload.maximumEntries, payload.maximumNumberOfDays, payload.auth, payload.includePastEvents); + this.createFetcher(payload.url, payload.fetchInterval, payload.excludedEvents, payload.maximumEntries, payload.maximumNumberOfDays, payload.auth, payload.broadcastPastEvents); } }, @@ -36,7 +36,7 @@ module.exports = NodeHelper.create({ * attribute reloadInterval number - Reload interval in milliseconds. */ - createFetcher: function(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, includePastEvents) { + createFetcher: function(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, broadcastPastEvents) { var self = this; if (!validUrl.isUri(url)) { @@ -47,7 +47,7 @@ module.exports = NodeHelper.create({ var fetcher; if (typeof self.fetchers[url] === "undefined") { console.log("Create new calendar fetcher for url: " + url + " - Interval: " + fetchInterval); - fetcher = new CalendarFetcher(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, includePastEvents); + fetcher = new CalendarFetcher(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, broadcastPastEvents); fetcher.onReceive(function(fetcher) { //console.log('Broadcast events.');