2023-07-01 21:17:31 +02:00
|
|
|
/**
|
|
|
|
|
* @external Moment
|
|
|
|
|
*/
|
2025-06-07 14:13:01 +02:00
|
|
|
const moment = require("moment-timezone");
|
Release 2.26.0 (#3319)
## [2.26.0] - 01-01-2024
Thanks to: @bnitkin, @bugsounet, @dependabot, @jkriegshauser,
@kaennchenstruggle, @KristjanESPERANTO and @Ybbet.
Special thanks to @khassel, @rejas and @sdetweil for taking over most
(if not all) of the work on this release as project collaborators. This
version would not be there without their effort. Thank you guys! You are
awesome!
This release also marks the latest release by Michael Teeuw. For more
info, please read the following post: [A New Chapter for MagicMirror:
The Community Takes the
Lead](https://forum.magicmirror.builders/topic/18329/a-new-chapter-for-magicmirror-the-community-takes-the-lead).
### Added
- Added update notification updater (for 3rd party modules)
- Added node 21 to the test matrix
- Added transform object to calendar:customEvents
- Added ESLint rules for jest (including jest/expect-expect and
jest/no-done-callback)
### Removed
- Removed Codecov workflow (not working anymore, other workflow
required) (#3107)
- Removed titleReplace from calendar, replaced + extended by
customEvents (backward compatibility included) (#3249)
- Removed failing unit test (#3254)
- Removed some unused variables
### Updated
- Update electron to v27 and update other dependencies as well as github
actions
- Update newsfeed: Use `html-to-text` instead of regex for transform
description
- Review ESLint config (#3269)
- Updated dependencies
- Clock module: optionally display current moon phase in addition to
rise/set times
- electron is now per default started without gpu, if needed it must be
enabled with new env var `ELECTRON_ENABLE_GPU=1` on startup (#3226)
- Replace prettier by stylistic in ESLint config to lint JavaScript (and
disable some rules for `config/config.js*` files)
- Update node-ical to v0.17.1 and fix tests
### Fixed
- Avoid fade out/in on updateDom when many calendars are used
- Fix the option eventClass on customEvents.
- Fix yr API version in locationforecast and sunrise call (#3227)
- Fix cloneObject() function to respect RegExp (#3237)
- Fix newsfeed module for feeds using "a10:updated" tag (#3238)
- Fix issue template (#3167)
- Fix #3256 filter out bad results from rrule.between
- Fix calendar events sometimes not respecting deleted events (#3250)
- Fix electron loadurl locally on Windows when address "0.0.0.0" (#2550)
- Fix updatanotification (update_helper.js): catch error if reponse is
not an JSON format (check PM2)
- Fix missing typeof in calendar module
- Fix style issues after prettier update
- Fix calendar test (#3291) by moving "Exdate check" from e2e to
electron to run on a Thursday
- Fix calendar config params `fetchInterval` and `excludedEvents` were
never used from single calendar config (#3297)
- Fix MM_PORT variable not used in electron and allow full path for
MM_CONFIG_FILE variable (#3302)
---------
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: dWoolridge <dwoolridge@charter.net>
Co-authored-by: Johan <jojjepersson@yahoo.se>
Co-authored-by: Dario Mratovich <dario_mratovich@hotmail.com>
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: buxxi <buxxi@omfilm.net>
Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com>
Co-authored-by: Dave Child <dave@addedbytes.com>
Co-authored-by: grenagit <46225780+grenagit@users.noreply.github.com>
Co-authored-by: Grena <grena@grenabox.fr>
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Co-authored-by: Patrick <psieg@users.noreply.github.com>
Co-authored-by: Piotr Rajnisz <56397164+rajniszp@users.noreply.github.com>
Co-authored-by: Suthep Yonphimai <tomzt@users.noreply.github.com>
Co-authored-by: CarJem Generations (Carter Wallace) <cwallacecs@gmail.com>
Co-authored-by: Nicholas Fogal <nfogal.misc@gmail.com>
Co-authored-by: JakeBinney <126349119+JakeBinney@users.noreply.github.com>
Co-authored-by: OWL4C <124401812+OWL4C@users.noreply.github.com>
Co-authored-by: Oscar Björkman <17575446+oscarb@users.noreply.github.com>
Co-authored-by: Ismar Slomic <ismar@slomic.no>
Co-authored-by: Jørgen Veum-Wahlberg <jorgen.wahlberg@amedia.no>
Co-authored-by: Eddie Hung <6740044+eddiehung@users.noreply.github.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Knapoc <Knapoc@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: NolanKingdon <27908974+NolanKingdon@users.noreply.github.com>
Co-authored-by: J. Kenzal Hunter <kenzal.hunter@gmail.com>
Co-authored-by: Teddy <teddy.payet@gmail.com>
Co-authored-by: TeddyStarinvest <teddy.payet@starinvest.com>
Co-authored-by: martingron <61826403+martingron@users.noreply.github.com>
Co-authored-by: dgoth <132394363+dgoth@users.noreply.github.com>
Co-authored-by: kaennchenstruggle <54073894+kaennchenstruggle@users.noreply.github.com>
Co-authored-by: jkriegshauser <jkriegshauser@gmail.com>
Co-authored-by: Ben Nitkin <ben@nitkin.net>
2024-01-01 15:38:08 +01:00
|
|
|
|
2025-09-09 08:09:45 +02:00
|
|
|
const Log = require("logger");
|
2023-07-01 21:17:31 +02:00
|
|
|
|
|
|
|
|
const CalendarFetcherUtils = {
|
Release 2.26.0 (#3319)
## [2.26.0] - 01-01-2024
Thanks to: @bnitkin, @bugsounet, @dependabot, @jkriegshauser,
@kaennchenstruggle, @KristjanESPERANTO and @Ybbet.
Special thanks to @khassel, @rejas and @sdetweil for taking over most
(if not all) of the work on this release as project collaborators. This
version would not be there without their effort. Thank you guys! You are
awesome!
This release also marks the latest release by Michael Teeuw. For more
info, please read the following post: [A New Chapter for MagicMirror:
The Community Takes the
Lead](https://forum.magicmirror.builders/topic/18329/a-new-chapter-for-magicmirror-the-community-takes-the-lead).
### Added
- Added update notification updater (for 3rd party modules)
- Added node 21 to the test matrix
- Added transform object to calendar:customEvents
- Added ESLint rules for jest (including jest/expect-expect and
jest/no-done-callback)
### Removed
- Removed Codecov workflow (not working anymore, other workflow
required) (#3107)
- Removed titleReplace from calendar, replaced + extended by
customEvents (backward compatibility included) (#3249)
- Removed failing unit test (#3254)
- Removed some unused variables
### Updated
- Update electron to v27 and update other dependencies as well as github
actions
- Update newsfeed: Use `html-to-text` instead of regex for transform
description
- Review ESLint config (#3269)
- Updated dependencies
- Clock module: optionally display current moon phase in addition to
rise/set times
- electron is now per default started without gpu, if needed it must be
enabled with new env var `ELECTRON_ENABLE_GPU=1` on startup (#3226)
- Replace prettier by stylistic in ESLint config to lint JavaScript (and
disable some rules for `config/config.js*` files)
- Update node-ical to v0.17.1 and fix tests
### Fixed
- Avoid fade out/in on updateDom when many calendars are used
- Fix the option eventClass on customEvents.
- Fix yr API version in locationforecast and sunrise call (#3227)
- Fix cloneObject() function to respect RegExp (#3237)
- Fix newsfeed module for feeds using "a10:updated" tag (#3238)
- Fix issue template (#3167)
- Fix #3256 filter out bad results from rrule.between
- Fix calendar events sometimes not respecting deleted events (#3250)
- Fix electron loadurl locally on Windows when address "0.0.0.0" (#2550)
- Fix updatanotification (update_helper.js): catch error if reponse is
not an JSON format (check PM2)
- Fix missing typeof in calendar module
- Fix style issues after prettier update
- Fix calendar test (#3291) by moving "Exdate check" from e2e to
electron to run on a Thursday
- Fix calendar config params `fetchInterval` and `excludedEvents` were
never used from single calendar config (#3297)
- Fix MM_PORT variable not used in electron and allow full path for
MM_CONFIG_FILE variable (#3302)
---------
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: dWoolridge <dwoolridge@charter.net>
Co-authored-by: Johan <jojjepersson@yahoo.se>
Co-authored-by: Dario Mratovich <dario_mratovich@hotmail.com>
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: buxxi <buxxi@omfilm.net>
Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com>
Co-authored-by: Dave Child <dave@addedbytes.com>
Co-authored-by: grenagit <46225780+grenagit@users.noreply.github.com>
Co-authored-by: Grena <grena@grenabox.fr>
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Co-authored-by: Patrick <psieg@users.noreply.github.com>
Co-authored-by: Piotr Rajnisz <56397164+rajniszp@users.noreply.github.com>
Co-authored-by: Suthep Yonphimai <tomzt@users.noreply.github.com>
Co-authored-by: CarJem Generations (Carter Wallace) <cwallacecs@gmail.com>
Co-authored-by: Nicholas Fogal <nfogal.misc@gmail.com>
Co-authored-by: JakeBinney <126349119+JakeBinney@users.noreply.github.com>
Co-authored-by: OWL4C <124401812+OWL4C@users.noreply.github.com>
Co-authored-by: Oscar Björkman <17575446+oscarb@users.noreply.github.com>
Co-authored-by: Ismar Slomic <ismar@slomic.no>
Co-authored-by: Jørgen Veum-Wahlberg <jorgen.wahlberg@amedia.no>
Co-authored-by: Eddie Hung <6740044+eddiehung@users.noreply.github.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Knapoc <Knapoc@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: NolanKingdon <27908974+NolanKingdon@users.noreply.github.com>
Co-authored-by: J. Kenzal Hunter <kenzal.hunter@gmail.com>
Co-authored-by: Teddy <teddy.payet@gmail.com>
Co-authored-by: TeddyStarinvest <teddy.payet@starinvest.com>
Co-authored-by: martingron <61826403+martingron@users.noreply.github.com>
Co-authored-by: dgoth <132394363+dgoth@users.noreply.github.com>
Co-authored-by: kaennchenstruggle <54073894+kaennchenstruggle@users.noreply.github.com>
Co-authored-by: jkriegshauser <jkriegshauser@gmail.com>
Co-authored-by: Ben Nitkin <ben@nitkin.net>
2024-01-01 15:38:08 +01:00
|
|
|
|
2023-07-01 21:17:31 +02:00
|
|
|
/**
|
2025-06-07 14:13:01 +02:00
|
|
|
* Determine based on the title of an event if it should be excluded from the list of events
|
|
|
|
|
* @param {object} config the global config
|
|
|
|
|
* @param {string} title the title of the event
|
|
|
|
|
* @returns {object} excluded: true if the event should be excluded, false otherwise
|
|
|
|
|
* until: the date until the event should be excluded.
|
2023-07-01 21:17:31 +02:00
|
|
|
*/
|
2025-06-07 14:13:01 +02:00
|
|
|
shouldEventBeExcluded (config, title) {
|
2025-12-08 10:07:04 +01:00
|
|
|
for (const filterConfig of config.excludedEvents) {
|
|
|
|
|
const match = CalendarFetcherUtils.checkEventAgainstFilter(title, filterConfig);
|
|
|
|
|
if (match) {
|
|
|
|
|
return {
|
|
|
|
|
excluded: !match.until,
|
|
|
|
|
until: match.until
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
2025-06-07 14:13:01 +02:00
|
|
|
excluded: false,
|
|
|
|
|
until: null
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get local timezone.
|
|
|
|
|
* This method makes it easier to test if different timezones cause problems by changing this implementation.
|
|
|
|
|
* @returns {string} timezone
|
|
|
|
|
*/
|
|
|
|
|
getLocalTimezone () {
|
|
|
|
|
return moment.tz.guess();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This function returns a list of moments for a recurring event.
|
|
|
|
|
* @param {object} event the current event which is a recurring event
|
|
|
|
|
* @param {moment.Moment} pastLocalMoment The past date to search for recurring events
|
|
|
|
|
* @param {moment.Moment} futureLocalMoment The future date to search for recurring events
|
|
|
|
|
* @param {number} durationInMs the duration of the event, this is used to take into account currently running events
|
|
|
|
|
* @returns {moment.Moment[]} All moments for the recurring event
|
|
|
|
|
*/
|
|
|
|
|
getMomentsFromRecurringEvent (event, pastLocalMoment, futureLocalMoment, durationInMs) {
|
|
|
|
|
const rule = event.rrule;
|
2025-12-08 10:07:04 +01:00
|
|
|
const isFullDayEvent = CalendarFetcherUtils.isFullDayEvent(event);
|
|
|
|
|
const eventTimezone = event.start.tz || CalendarFetcherUtils.getLocalTimezone();
|
2025-06-07 14:13:01 +02:00
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
// rrule.js interprets years < 1900 as offsets from 1900, causing issues with some birthday calendars
|
|
|
|
|
if (rule.origOptions?.dtstart?.getFullYear() < 1900) {
|
|
|
|
|
rule.origOptions.dtstart.setFullYear(1900);
|
2025-06-07 14:13:01 +02:00
|
|
|
}
|
2025-12-08 10:07:04 +01:00
|
|
|
if (rule.options?.dtstart?.getFullYear() < 1900) {
|
|
|
|
|
rule.options.dtstart.setFullYear(1900);
|
2025-06-07 14:13:01 +02:00
|
|
|
}
|
|
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
// Expand search window to include ongoing events
|
|
|
|
|
const oneDayInMs = 24 * 60 * 60 * 1000;
|
|
|
|
|
const searchFromDate = pastLocalMoment.clone().subtract(Math.max(durationInMs, oneDayInMs), "milliseconds").toDate();
|
|
|
|
|
const searchToDate = futureLocalMoment.clone().add(1, "days").toDate();
|
2025-06-07 14:13:01 +02:00
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
// For all-day events, extend "until" to end of day to include the final occurrence
|
|
|
|
|
if (isFullDayEvent && rule.options?.until) {
|
|
|
|
|
rule.options.until = moment(rule.options.until).endOf("day").toDate();
|
|
|
|
|
}
|
2025-06-07 14:13:01 +02:00
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
// Clear tzid to prevent rrule.js from double-adjusting times
|
|
|
|
|
if (rule.options) {
|
|
|
|
|
rule.options.tzid = null;
|
|
|
|
|
}
|
2025-06-07 14:13:01 +02:00
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
const dates = rule.between(searchFromDate, searchToDate, true) || [];
|
2025-06-07 14:13:01 +02:00
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
// Convert dates to moments in the appropriate timezone
|
|
|
|
|
// rrule.js returns UTC dates with tzid cleared, so we interpret them in the event's original timezone
|
|
|
|
|
return dates.map((date) => {
|
|
|
|
|
if (isFullDayEvent) {
|
|
|
|
|
// For all-day events, anchor to calendar day in event's timezone
|
|
|
|
|
return moment.tz(date, eventTimezone).startOf("day");
|
|
|
|
|
}
|
|
|
|
|
// For timed events, preserve the time in the event's original timezone
|
|
|
|
|
return moment.tz(date, "UTC").tz(eventTimezone, true);
|
|
|
|
|
});
|
2023-07-01 21:17:31 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Filter the events from ical according to the given config
|
|
|
|
|
* @param {object} data the calendar data from ical
|
|
|
|
|
* @param {object} config The configuration object
|
|
|
|
|
* @returns {string[]} the filtered events
|
|
|
|
|
*/
|
Release 2.26.0 (#3319)
## [2.26.0] - 01-01-2024
Thanks to: @bnitkin, @bugsounet, @dependabot, @jkriegshauser,
@kaennchenstruggle, @KristjanESPERANTO and @Ybbet.
Special thanks to @khassel, @rejas and @sdetweil for taking over most
(if not all) of the work on this release as project collaborators. This
version would not be there without their effort. Thank you guys! You are
awesome!
This release also marks the latest release by Michael Teeuw. For more
info, please read the following post: [A New Chapter for MagicMirror:
The Community Takes the
Lead](https://forum.magicmirror.builders/topic/18329/a-new-chapter-for-magicmirror-the-community-takes-the-lead).
### Added
- Added update notification updater (for 3rd party modules)
- Added node 21 to the test matrix
- Added transform object to calendar:customEvents
- Added ESLint rules for jest (including jest/expect-expect and
jest/no-done-callback)
### Removed
- Removed Codecov workflow (not working anymore, other workflow
required) (#3107)
- Removed titleReplace from calendar, replaced + extended by
customEvents (backward compatibility included) (#3249)
- Removed failing unit test (#3254)
- Removed some unused variables
### Updated
- Update electron to v27 and update other dependencies as well as github
actions
- Update newsfeed: Use `html-to-text` instead of regex for transform
description
- Review ESLint config (#3269)
- Updated dependencies
- Clock module: optionally display current moon phase in addition to
rise/set times
- electron is now per default started without gpu, if needed it must be
enabled with new env var `ELECTRON_ENABLE_GPU=1` on startup (#3226)
- Replace prettier by stylistic in ESLint config to lint JavaScript (and
disable some rules for `config/config.js*` files)
- Update node-ical to v0.17.1 and fix tests
### Fixed
- Avoid fade out/in on updateDom when many calendars are used
- Fix the option eventClass on customEvents.
- Fix yr API version in locationforecast and sunrise call (#3227)
- Fix cloneObject() function to respect RegExp (#3237)
- Fix newsfeed module for feeds using "a10:updated" tag (#3238)
- Fix issue template (#3167)
- Fix #3256 filter out bad results from rrule.between
- Fix calendar events sometimes not respecting deleted events (#3250)
- Fix electron loadurl locally on Windows when address "0.0.0.0" (#2550)
- Fix updatanotification (update_helper.js): catch error if reponse is
not an JSON format (check PM2)
- Fix missing typeof in calendar module
- Fix style issues after prettier update
- Fix calendar test (#3291) by moving "Exdate check" from e2e to
electron to run on a Thursday
- Fix calendar config params `fetchInterval` and `excludedEvents` were
never used from single calendar config (#3297)
- Fix MM_PORT variable not used in electron and allow full path for
MM_CONFIG_FILE variable (#3302)
---------
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: dWoolridge <dwoolridge@charter.net>
Co-authored-by: Johan <jojjepersson@yahoo.se>
Co-authored-by: Dario Mratovich <dario_mratovich@hotmail.com>
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: buxxi <buxxi@omfilm.net>
Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com>
Co-authored-by: Dave Child <dave@addedbytes.com>
Co-authored-by: grenagit <46225780+grenagit@users.noreply.github.com>
Co-authored-by: Grena <grena@grenabox.fr>
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Co-authored-by: Patrick <psieg@users.noreply.github.com>
Co-authored-by: Piotr Rajnisz <56397164+rajniszp@users.noreply.github.com>
Co-authored-by: Suthep Yonphimai <tomzt@users.noreply.github.com>
Co-authored-by: CarJem Generations (Carter Wallace) <cwallacecs@gmail.com>
Co-authored-by: Nicholas Fogal <nfogal.misc@gmail.com>
Co-authored-by: JakeBinney <126349119+JakeBinney@users.noreply.github.com>
Co-authored-by: OWL4C <124401812+OWL4C@users.noreply.github.com>
Co-authored-by: Oscar Björkman <17575446+oscarb@users.noreply.github.com>
Co-authored-by: Ismar Slomic <ismar@slomic.no>
Co-authored-by: Jørgen Veum-Wahlberg <jorgen.wahlberg@amedia.no>
Co-authored-by: Eddie Hung <6740044+eddiehung@users.noreply.github.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Knapoc <Knapoc@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: NolanKingdon <27908974+NolanKingdon@users.noreply.github.com>
Co-authored-by: J. Kenzal Hunter <kenzal.hunter@gmail.com>
Co-authored-by: Teddy <teddy.payet@gmail.com>
Co-authored-by: TeddyStarinvest <teddy.payet@starinvest.com>
Co-authored-by: martingron <61826403+martingron@users.noreply.github.com>
Co-authored-by: dgoth <132394363+dgoth@users.noreply.github.com>
Co-authored-by: kaennchenstruggle <54073894+kaennchenstruggle@users.noreply.github.com>
Co-authored-by: jkriegshauser <jkriegshauser@gmail.com>
Co-authored-by: Ben Nitkin <ben@nitkin.net>
2024-01-01 15:38:08 +01:00
|
|
|
filterEvents (data, config) {
|
2023-07-01 21:17:31 +02:00
|
|
|
const newEvents = [];
|
|
|
|
|
|
|
|
|
|
const eventDate = function (event, time) {
|
2025-06-07 14:13:01 +02:00
|
|
|
const startMoment = event[time].tz ? moment.tz(event[time], event[time].tz) : moment.tz(event[time], CalendarFetcherUtils.getLocalTimezone());
|
|
|
|
|
return CalendarFetcherUtils.isFullDayEvent(event) ? startMoment.startOf("day") : startMoment;
|
2023-07-01 21:17:31 +02:00
|
|
|
};
|
|
|
|
|
|
2025-10-22 22:50:31 +02:00
|
|
|
Log.debug(`There are ${Object.entries(data).length} calendar entries.`);
|
2024-01-26 22:56:54 -08:00
|
|
|
|
2025-06-07 14:13:01 +02:00
|
|
|
const now = moment();
|
|
|
|
|
const pastLocalMoment = config.includePastEvents ? now.clone().startOf("day").subtract(config.maximumNumberOfDays, "days") : now;
|
|
|
|
|
const futureLocalMoment
|
|
|
|
|
= now
|
|
|
|
|
.clone()
|
2024-01-26 22:56:54 -08:00
|
|
|
.startOf("day")
|
|
|
|
|
.add(config.maximumNumberOfDays, "days")
|
2025-06-07 14:13:01 +02:00
|
|
|
// Subtract 1 second so that events that start on the middle of the night will not repeat.
|
|
|
|
|
.subtract(1, "seconds");
|
2024-01-26 22:56:54 -08:00
|
|
|
|
2023-07-01 21:17:31 +02:00
|
|
|
Object.entries(data).forEach(([key, event]) => {
|
2025-10-22 22:50:31 +02:00
|
|
|
Log.debug("Processing entry...");
|
2023-07-01 21:17:31 +02:00
|
|
|
|
2025-06-07 14:13:01 +02:00
|
|
|
const title = CalendarFetcherUtils.getTitleFromEvent(event);
|
2025-10-22 22:50:31 +02:00
|
|
|
Log.debug(`title: ${title}`);
|
2025-06-07 14:13:01 +02:00
|
|
|
|
|
|
|
|
// Return quickly if event should be excluded.
|
|
|
|
|
let { excluded, eventFilterUntil } = this.shouldEventBeExcluded(config, title);
|
|
|
|
|
if (excluded) {
|
|
|
|
|
return;
|
2023-07-01 21:17:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: Ugly fix to solve the facebook birthday issue.
|
|
|
|
|
// Otherwise, the recurring events only show the birthday for next year.
|
|
|
|
|
let isFacebookBirthday = false;
|
|
|
|
|
if (typeof event.uid !== "undefined") {
|
|
|
|
|
if (event.uid.indexOf("@facebook.com") !== -1) {
|
|
|
|
|
isFacebookBirthday = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (event.type === "VEVENT") {
|
2025-10-22 22:50:31 +02:00
|
|
|
Log.debug(`Event:\n${JSON.stringify(event, null, 2)}`);
|
2025-06-07 14:13:01 +02:00
|
|
|
let eventStartMoment = eventDate(event, "start");
|
|
|
|
|
let eventEndMoment;
|
2023-07-01 21:17:31 +02:00
|
|
|
|
|
|
|
|
if (typeof event.end !== "undefined") {
|
2025-06-07 14:13:01 +02:00
|
|
|
eventEndMoment = eventDate(event, "end");
|
2023-07-01 21:17:31 +02:00
|
|
|
} else if (typeof event.duration !== "undefined") {
|
2025-06-07 14:13:01 +02:00
|
|
|
eventEndMoment = eventStartMoment.clone().add(moment.duration(event.duration));
|
2023-07-01 21:17:31 +02:00
|
|
|
} else {
|
|
|
|
|
if (!isFacebookBirthday) {
|
|
|
|
|
// make copy of start date, separate storage area
|
2025-06-07 14:13:01 +02:00
|
|
|
eventEndMoment = eventStartMoment.clone();
|
2023-07-01 21:17:31 +02:00
|
|
|
} else {
|
2025-06-07 14:13:01 +02:00
|
|
|
eventEndMoment = eventStartMoment.clone().add(1, "days");
|
2023-07-01 21:17:31 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-22 22:50:31 +02:00
|
|
|
Log.debug(`start: ${eventStartMoment.toDate()}`);
|
|
|
|
|
Log.debug(`end: ${eventEndMoment.toDate()}`);
|
2023-07-01 21:17:31 +02:00
|
|
|
|
|
|
|
|
// Calculate the duration of the event for use with recurring events.
|
2025-06-07 14:13:01 +02:00
|
|
|
const durationMs = eventEndMoment.valueOf() - eventStartMoment.valueOf();
|
2025-10-22 22:50:31 +02:00
|
|
|
Log.debug(`duration: ${durationMs}`);
|
2023-07-01 21:17:31 +02:00
|
|
|
|
|
|
|
|
const location = event.location || false;
|
|
|
|
|
const geo = event.geo || false;
|
|
|
|
|
const description = event.description || false;
|
|
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
let instances = [];
|
2024-01-26 22:56:54 -08:00
|
|
|
if (event.rrule && typeof event.rrule !== "undefined" && !isFacebookBirthday) {
|
2025-12-08 10:07:04 +01:00
|
|
|
instances = CalendarFetcherUtils.expandRecurringEvent(event, pastLocalMoment, futureLocalMoment, durationMs);
|
2023-07-01 21:17:31 +02:00
|
|
|
} else {
|
|
|
|
|
const fullDayEvent = isFacebookBirthday ? true : CalendarFetcherUtils.isFullDayEvent(event);
|
2025-12-08 10:07:04 +01:00
|
|
|
let end = eventEndMoment;
|
|
|
|
|
if (fullDayEvent && eventStartMoment.valueOf() === end.valueOf()) {
|
|
|
|
|
end = end.endOf("day");
|
2023-07-01 21:17:31 +02:00
|
|
|
}
|
|
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
instances.push({
|
|
|
|
|
event: event,
|
|
|
|
|
startMoment: eventStartMoment,
|
|
|
|
|
endMoment: end,
|
|
|
|
|
isRecurring: false
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const instance of instances) {
|
|
|
|
|
const { event: instanceEvent, startMoment, endMoment, isRecurring } = instance;
|
2023-07-01 21:17:31 +02:00
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
// Filter logic
|
|
|
|
|
if (endMoment.isBefore(pastLocalMoment) || startMoment.isAfter(futureLocalMoment)) {
|
|
|
|
|
continue;
|
2023-07-01 21:17:31 +02:00
|
|
|
}
|
|
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
if (CalendarFetcherUtils.timeFilterApplies(now, endMoment, eventFilterUntil)) {
|
|
|
|
|
continue;
|
2023-07-01 21:17:31 +02:00
|
|
|
}
|
|
|
|
|
|
2025-12-08 10:07:04 +01:00
|
|
|
const title = CalendarFetcherUtils.getTitleFromEvent(instanceEvent);
|
|
|
|
|
const fullDay = isFacebookBirthday ? true : CalendarFetcherUtils.isFullDayEvent(event);
|
|
|
|
|
|
|
|
|
|
Log.debug(`saving event: ${title}`);
|
2023-07-01 21:17:31 +02:00
|
|
|
newEvents.push({
|
|
|
|
|
title: title,
|
2025-12-08 10:07:04 +01:00
|
|
|
startDate: startMoment.format("x"),
|
|
|
|
|
endDate: endMoment.format("x"),
|
|
|
|
|
fullDayEvent: fullDay,
|
|
|
|
|
recurringEvent: isRecurring,
|
2023-07-01 21:17:31 +02:00
|
|
|
class: event.class,
|
2024-12-07 02:51:11 -06:00
|
|
|
firstYear: event.start.getFullYear(),
|
2025-12-08 10:07:04 +01:00
|
|
|
location: instanceEvent.location || location,
|
|
|
|
|
geo: instanceEvent.geo || geo,
|
|
|
|
|
description: instanceEvent.description || description
|
2023-07-01 21:17:31 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
newEvents.sort(function (a, b) {
|
|
|
|
|
return a.startDate - b.startDate;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return newEvents;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets the title from the event.
|
|
|
|
|
* @param {object} event The event object to check.
|
|
|
|
|
* @returns {string} The title of the event, or "Event" if no title is found.
|
|
|
|
|
*/
|
Release 2.26.0 (#3319)
## [2.26.0] - 01-01-2024
Thanks to: @bnitkin, @bugsounet, @dependabot, @jkriegshauser,
@kaennchenstruggle, @KristjanESPERANTO and @Ybbet.
Special thanks to @khassel, @rejas and @sdetweil for taking over most
(if not all) of the work on this release as project collaborators. This
version would not be there without their effort. Thank you guys! You are
awesome!
This release also marks the latest release by Michael Teeuw. For more
info, please read the following post: [A New Chapter for MagicMirror:
The Community Takes the
Lead](https://forum.magicmirror.builders/topic/18329/a-new-chapter-for-magicmirror-the-community-takes-the-lead).
### Added
- Added update notification updater (for 3rd party modules)
- Added node 21 to the test matrix
- Added transform object to calendar:customEvents
- Added ESLint rules for jest (including jest/expect-expect and
jest/no-done-callback)
### Removed
- Removed Codecov workflow (not working anymore, other workflow
required) (#3107)
- Removed titleReplace from calendar, replaced + extended by
customEvents (backward compatibility included) (#3249)
- Removed failing unit test (#3254)
- Removed some unused variables
### Updated
- Update electron to v27 and update other dependencies as well as github
actions
- Update newsfeed: Use `html-to-text` instead of regex for transform
description
- Review ESLint config (#3269)
- Updated dependencies
- Clock module: optionally display current moon phase in addition to
rise/set times
- electron is now per default started without gpu, if needed it must be
enabled with new env var `ELECTRON_ENABLE_GPU=1` on startup (#3226)
- Replace prettier by stylistic in ESLint config to lint JavaScript (and
disable some rules for `config/config.js*` files)
- Update node-ical to v0.17.1 and fix tests
### Fixed
- Avoid fade out/in on updateDom when many calendars are used
- Fix the option eventClass on customEvents.
- Fix yr API version in locationforecast and sunrise call (#3227)
- Fix cloneObject() function to respect RegExp (#3237)
- Fix newsfeed module for feeds using "a10:updated" tag (#3238)
- Fix issue template (#3167)
- Fix #3256 filter out bad results from rrule.between
- Fix calendar events sometimes not respecting deleted events (#3250)
- Fix electron loadurl locally on Windows when address "0.0.0.0" (#2550)
- Fix updatanotification (update_helper.js): catch error if reponse is
not an JSON format (check PM2)
- Fix missing typeof in calendar module
- Fix style issues after prettier update
- Fix calendar test (#3291) by moving "Exdate check" from e2e to
electron to run on a Thursday
- Fix calendar config params `fetchInterval` and `excludedEvents` were
never used from single calendar config (#3297)
- Fix MM_PORT variable not used in electron and allow full path for
MM_CONFIG_FILE variable (#3302)
---------
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: dWoolridge <dwoolridge@charter.net>
Co-authored-by: Johan <jojjepersson@yahoo.se>
Co-authored-by: Dario Mratovich <dario_mratovich@hotmail.com>
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: buxxi <buxxi@omfilm.net>
Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com>
Co-authored-by: Dave Child <dave@addedbytes.com>
Co-authored-by: grenagit <46225780+grenagit@users.noreply.github.com>
Co-authored-by: Grena <grena@grenabox.fr>
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Co-authored-by: Patrick <psieg@users.noreply.github.com>
Co-authored-by: Piotr Rajnisz <56397164+rajniszp@users.noreply.github.com>
Co-authored-by: Suthep Yonphimai <tomzt@users.noreply.github.com>
Co-authored-by: CarJem Generations (Carter Wallace) <cwallacecs@gmail.com>
Co-authored-by: Nicholas Fogal <nfogal.misc@gmail.com>
Co-authored-by: JakeBinney <126349119+JakeBinney@users.noreply.github.com>
Co-authored-by: OWL4C <124401812+OWL4C@users.noreply.github.com>
Co-authored-by: Oscar Björkman <17575446+oscarb@users.noreply.github.com>
Co-authored-by: Ismar Slomic <ismar@slomic.no>
Co-authored-by: Jørgen Veum-Wahlberg <jorgen.wahlberg@amedia.no>
Co-authored-by: Eddie Hung <6740044+eddiehung@users.noreply.github.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Knapoc <Knapoc@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: NolanKingdon <27908974+NolanKingdon@users.noreply.github.com>
Co-authored-by: J. Kenzal Hunter <kenzal.hunter@gmail.com>
Co-authored-by: Teddy <teddy.payet@gmail.com>
Co-authored-by: TeddyStarinvest <teddy.payet@starinvest.com>
Co-authored-by: martingron <61826403+martingron@users.noreply.github.com>
Co-authored-by: dgoth <132394363+dgoth@users.noreply.github.com>
Co-authored-by: kaennchenstruggle <54073894+kaennchenstruggle@users.noreply.github.com>
Co-authored-by: jkriegshauser <jkriegshauser@gmail.com>
Co-authored-by: Ben Nitkin <ben@nitkin.net>
2024-01-01 15:38:08 +01:00
|
|
|
getTitleFromEvent (event) {
|
2023-07-01 21:17:31 +02:00
|
|
|
let title = "Event";
|
|
|
|
|
if (event.summary) {
|
|
|
|
|
title = typeof event.summary.val !== "undefined" ? event.summary.val : event.summary;
|
|
|
|
|
} else if (event.description) {
|
|
|
|
|
title = event.description;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return title;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Checks if an event is a fullday event.
|
|
|
|
|
* @param {object} event The event object to check.
|
|
|
|
|
* @returns {boolean} True if the event is a fullday event, false otherwise
|
|
|
|
|
*/
|
Release 2.26.0 (#3319)
## [2.26.0] - 01-01-2024
Thanks to: @bnitkin, @bugsounet, @dependabot, @jkriegshauser,
@kaennchenstruggle, @KristjanESPERANTO and @Ybbet.
Special thanks to @khassel, @rejas and @sdetweil for taking over most
(if not all) of the work on this release as project collaborators. This
version would not be there without their effort. Thank you guys! You are
awesome!
This release also marks the latest release by Michael Teeuw. For more
info, please read the following post: [A New Chapter for MagicMirror:
The Community Takes the
Lead](https://forum.magicmirror.builders/topic/18329/a-new-chapter-for-magicmirror-the-community-takes-the-lead).
### Added
- Added update notification updater (for 3rd party modules)
- Added node 21 to the test matrix
- Added transform object to calendar:customEvents
- Added ESLint rules for jest (including jest/expect-expect and
jest/no-done-callback)
### Removed
- Removed Codecov workflow (not working anymore, other workflow
required) (#3107)
- Removed titleReplace from calendar, replaced + extended by
customEvents (backward compatibility included) (#3249)
- Removed failing unit test (#3254)
- Removed some unused variables
### Updated
- Update electron to v27 and update other dependencies as well as github
actions
- Update newsfeed: Use `html-to-text` instead of regex for transform
description
- Review ESLint config (#3269)
- Updated dependencies
- Clock module: optionally display current moon phase in addition to
rise/set times
- electron is now per default started without gpu, if needed it must be
enabled with new env var `ELECTRON_ENABLE_GPU=1` on startup (#3226)
- Replace prettier by stylistic in ESLint config to lint JavaScript (and
disable some rules for `config/config.js*` files)
- Update node-ical to v0.17.1 and fix tests
### Fixed
- Avoid fade out/in on updateDom when many calendars are used
- Fix the option eventClass on customEvents.
- Fix yr API version in locationforecast and sunrise call (#3227)
- Fix cloneObject() function to respect RegExp (#3237)
- Fix newsfeed module for feeds using "a10:updated" tag (#3238)
- Fix issue template (#3167)
- Fix #3256 filter out bad results from rrule.between
- Fix calendar events sometimes not respecting deleted events (#3250)
- Fix electron loadurl locally on Windows when address "0.0.0.0" (#2550)
- Fix updatanotification (update_helper.js): catch error if reponse is
not an JSON format (check PM2)
- Fix missing typeof in calendar module
- Fix style issues after prettier update
- Fix calendar test (#3291) by moving "Exdate check" from e2e to
electron to run on a Thursday
- Fix calendar config params `fetchInterval` and `excludedEvents` were
never used from single calendar config (#3297)
- Fix MM_PORT variable not used in electron and allow full path for
MM_CONFIG_FILE variable (#3302)
---------
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: dWoolridge <dwoolridge@charter.net>
Co-authored-by: Johan <jojjepersson@yahoo.se>
Co-authored-by: Dario Mratovich <dario_mratovich@hotmail.com>
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: buxxi <buxxi@omfilm.net>
Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com>
Co-authored-by: Dave Child <dave@addedbytes.com>
Co-authored-by: grenagit <46225780+grenagit@users.noreply.github.com>
Co-authored-by: Grena <grena@grenabox.fr>
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Co-authored-by: Patrick <psieg@users.noreply.github.com>
Co-authored-by: Piotr Rajnisz <56397164+rajniszp@users.noreply.github.com>
Co-authored-by: Suthep Yonphimai <tomzt@users.noreply.github.com>
Co-authored-by: CarJem Generations (Carter Wallace) <cwallacecs@gmail.com>
Co-authored-by: Nicholas Fogal <nfogal.misc@gmail.com>
Co-authored-by: JakeBinney <126349119+JakeBinney@users.noreply.github.com>
Co-authored-by: OWL4C <124401812+OWL4C@users.noreply.github.com>
Co-authored-by: Oscar Björkman <17575446+oscarb@users.noreply.github.com>
Co-authored-by: Ismar Slomic <ismar@slomic.no>
Co-authored-by: Jørgen Veum-Wahlberg <jorgen.wahlberg@amedia.no>
Co-authored-by: Eddie Hung <6740044+eddiehung@users.noreply.github.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Knapoc <Knapoc@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: NolanKingdon <27908974+NolanKingdon@users.noreply.github.com>
Co-authored-by: J. Kenzal Hunter <kenzal.hunter@gmail.com>
Co-authored-by: Teddy <teddy.payet@gmail.com>
Co-authored-by: TeddyStarinvest <teddy.payet@starinvest.com>
Co-authored-by: martingron <61826403+martingron@users.noreply.github.com>
Co-authored-by: dgoth <132394363+dgoth@users.noreply.github.com>
Co-authored-by: kaennchenstruggle <54073894+kaennchenstruggle@users.noreply.github.com>
Co-authored-by: jkriegshauser <jkriegshauser@gmail.com>
Co-authored-by: Ben Nitkin <ben@nitkin.net>
2024-01-01 15:38:08 +01:00
|
|
|
isFullDayEvent (event) {
|
2023-07-01 21:17:31 +02:00
|
|
|
if (event.start.length === 8 || event.start.dateOnly || event.datetype === "date") {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const start = event.start || 0;
|
|
|
|
|
const startDate = new Date(start);
|
|
|
|
|
const end = event.end || 0;
|
|
|
|
|
if ((end - start) % (24 * 60 * 60 * 1000) === 0 && startDate.getHours() === 0 && startDate.getMinutes() === 0) {
|
|
|
|
|
// Is 24 hours, and starts on the middle of the night.
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Determines if the user defined time filter should apply
|
2025-06-07 14:13:01 +02:00
|
|
|
* @param {moment.Moment} now Date object using previously created object for consistency
|
|
|
|
|
* @param {moment.Moment} endDate Moment object representing the event end date
|
2023-07-01 21:17:31 +02:00
|
|
|
* @param {string} filter The time to subtract from the end date to determine if an event should be shown
|
|
|
|
|
* @returns {boolean} True if the event should be filtered out, false otherwise
|
|
|
|
|
*/
|
Release 2.26.0 (#3319)
## [2.26.0] - 01-01-2024
Thanks to: @bnitkin, @bugsounet, @dependabot, @jkriegshauser,
@kaennchenstruggle, @KristjanESPERANTO and @Ybbet.
Special thanks to @khassel, @rejas and @sdetweil for taking over most
(if not all) of the work on this release as project collaborators. This
version would not be there without their effort. Thank you guys! You are
awesome!
This release also marks the latest release by Michael Teeuw. For more
info, please read the following post: [A New Chapter for MagicMirror:
The Community Takes the
Lead](https://forum.magicmirror.builders/topic/18329/a-new-chapter-for-magicmirror-the-community-takes-the-lead).
### Added
- Added update notification updater (for 3rd party modules)
- Added node 21 to the test matrix
- Added transform object to calendar:customEvents
- Added ESLint rules for jest (including jest/expect-expect and
jest/no-done-callback)
### Removed
- Removed Codecov workflow (not working anymore, other workflow
required) (#3107)
- Removed titleReplace from calendar, replaced + extended by
customEvents (backward compatibility included) (#3249)
- Removed failing unit test (#3254)
- Removed some unused variables
### Updated
- Update electron to v27 and update other dependencies as well as github
actions
- Update newsfeed: Use `html-to-text` instead of regex for transform
description
- Review ESLint config (#3269)
- Updated dependencies
- Clock module: optionally display current moon phase in addition to
rise/set times
- electron is now per default started without gpu, if needed it must be
enabled with new env var `ELECTRON_ENABLE_GPU=1` on startup (#3226)
- Replace prettier by stylistic in ESLint config to lint JavaScript (and
disable some rules for `config/config.js*` files)
- Update node-ical to v0.17.1 and fix tests
### Fixed
- Avoid fade out/in on updateDom when many calendars are used
- Fix the option eventClass on customEvents.
- Fix yr API version in locationforecast and sunrise call (#3227)
- Fix cloneObject() function to respect RegExp (#3237)
- Fix newsfeed module for feeds using "a10:updated" tag (#3238)
- Fix issue template (#3167)
- Fix #3256 filter out bad results from rrule.between
- Fix calendar events sometimes not respecting deleted events (#3250)
- Fix electron loadurl locally on Windows when address "0.0.0.0" (#2550)
- Fix updatanotification (update_helper.js): catch error if reponse is
not an JSON format (check PM2)
- Fix missing typeof in calendar module
- Fix style issues after prettier update
- Fix calendar test (#3291) by moving "Exdate check" from e2e to
electron to run on a Thursday
- Fix calendar config params `fetchInterval` and `excludedEvents` were
never used from single calendar config (#3297)
- Fix MM_PORT variable not used in electron and allow full path for
MM_CONFIG_FILE variable (#3302)
---------
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: dWoolridge <dwoolridge@charter.net>
Co-authored-by: Johan <jojjepersson@yahoo.se>
Co-authored-by: Dario Mratovich <dario_mratovich@hotmail.com>
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: buxxi <buxxi@omfilm.net>
Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com>
Co-authored-by: Dave Child <dave@addedbytes.com>
Co-authored-by: grenagit <46225780+grenagit@users.noreply.github.com>
Co-authored-by: Grena <grena@grenabox.fr>
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Co-authored-by: Patrick <psieg@users.noreply.github.com>
Co-authored-by: Piotr Rajnisz <56397164+rajniszp@users.noreply.github.com>
Co-authored-by: Suthep Yonphimai <tomzt@users.noreply.github.com>
Co-authored-by: CarJem Generations (Carter Wallace) <cwallacecs@gmail.com>
Co-authored-by: Nicholas Fogal <nfogal.misc@gmail.com>
Co-authored-by: JakeBinney <126349119+JakeBinney@users.noreply.github.com>
Co-authored-by: OWL4C <124401812+OWL4C@users.noreply.github.com>
Co-authored-by: Oscar Björkman <17575446+oscarb@users.noreply.github.com>
Co-authored-by: Ismar Slomic <ismar@slomic.no>
Co-authored-by: Jørgen Veum-Wahlberg <jorgen.wahlberg@amedia.no>
Co-authored-by: Eddie Hung <6740044+eddiehung@users.noreply.github.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Knapoc <Knapoc@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: NolanKingdon <27908974+NolanKingdon@users.noreply.github.com>
Co-authored-by: J. Kenzal Hunter <kenzal.hunter@gmail.com>
Co-authored-by: Teddy <teddy.payet@gmail.com>
Co-authored-by: TeddyStarinvest <teddy.payet@starinvest.com>
Co-authored-by: martingron <61826403+martingron@users.noreply.github.com>
Co-authored-by: dgoth <132394363+dgoth@users.noreply.github.com>
Co-authored-by: kaennchenstruggle <54073894+kaennchenstruggle@users.noreply.github.com>
Co-authored-by: jkriegshauser <jkriegshauser@gmail.com>
Co-authored-by: Ben Nitkin <ben@nitkin.net>
2024-01-01 15:38:08 +01:00
|
|
|
timeFilterApplies (now, endDate, filter) {
|
2023-07-01 21:17:31 +02:00
|
|
|
if (filter) {
|
|
|
|
|
const until = filter.split(" "),
|
|
|
|
|
value = parseInt(until[0]),
|
|
|
|
|
increment = until[1].slice(-1) === "s" ? until[1] : `${until[1]}s`, // Massage the data for moment js
|
|
|
|
|
filterUntil = moment(endDate.format()).subtract(value, increment);
|
|
|
|
|
|
2025-06-07 14:13:01 +02:00
|
|
|
return now < filterUntil;
|
2023-07-01 21:17:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Determines if the user defined title filter should apply
|
|
|
|
|
* @param {string} title the title of the event
|
|
|
|
|
* @param {string} filter the string to look for, can be a regex also
|
|
|
|
|
* @param {boolean} useRegex true if a regex should be used, otherwise it just looks for the filter as a string
|
|
|
|
|
* @param {string} regexFlags flags that should be applied to the regex
|
|
|
|
|
* @returns {boolean} True if the title should be filtered out, false otherwise
|
|
|
|
|
*/
|
Release 2.26.0 (#3319)
## [2.26.0] - 01-01-2024
Thanks to: @bnitkin, @bugsounet, @dependabot, @jkriegshauser,
@kaennchenstruggle, @KristjanESPERANTO and @Ybbet.
Special thanks to @khassel, @rejas and @sdetweil for taking over most
(if not all) of the work on this release as project collaborators. This
version would not be there without their effort. Thank you guys! You are
awesome!
This release also marks the latest release by Michael Teeuw. For more
info, please read the following post: [A New Chapter for MagicMirror:
The Community Takes the
Lead](https://forum.magicmirror.builders/topic/18329/a-new-chapter-for-magicmirror-the-community-takes-the-lead).
### Added
- Added update notification updater (for 3rd party modules)
- Added node 21 to the test matrix
- Added transform object to calendar:customEvents
- Added ESLint rules for jest (including jest/expect-expect and
jest/no-done-callback)
### Removed
- Removed Codecov workflow (not working anymore, other workflow
required) (#3107)
- Removed titleReplace from calendar, replaced + extended by
customEvents (backward compatibility included) (#3249)
- Removed failing unit test (#3254)
- Removed some unused variables
### Updated
- Update electron to v27 and update other dependencies as well as github
actions
- Update newsfeed: Use `html-to-text` instead of regex for transform
description
- Review ESLint config (#3269)
- Updated dependencies
- Clock module: optionally display current moon phase in addition to
rise/set times
- electron is now per default started without gpu, if needed it must be
enabled with new env var `ELECTRON_ENABLE_GPU=1` on startup (#3226)
- Replace prettier by stylistic in ESLint config to lint JavaScript (and
disable some rules for `config/config.js*` files)
- Update node-ical to v0.17.1 and fix tests
### Fixed
- Avoid fade out/in on updateDom when many calendars are used
- Fix the option eventClass on customEvents.
- Fix yr API version in locationforecast and sunrise call (#3227)
- Fix cloneObject() function to respect RegExp (#3237)
- Fix newsfeed module for feeds using "a10:updated" tag (#3238)
- Fix issue template (#3167)
- Fix #3256 filter out bad results from rrule.between
- Fix calendar events sometimes not respecting deleted events (#3250)
- Fix electron loadurl locally on Windows when address "0.0.0.0" (#2550)
- Fix updatanotification (update_helper.js): catch error if reponse is
not an JSON format (check PM2)
- Fix missing typeof in calendar module
- Fix style issues after prettier update
- Fix calendar test (#3291) by moving "Exdate check" from e2e to
electron to run on a Thursday
- Fix calendar config params `fetchInterval` and `excludedEvents` were
never used from single calendar config (#3297)
- Fix MM_PORT variable not used in electron and allow full path for
MM_CONFIG_FILE variable (#3302)
---------
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: dWoolridge <dwoolridge@charter.net>
Co-authored-by: Johan <jojjepersson@yahoo.se>
Co-authored-by: Dario Mratovich <dario_mratovich@hotmail.com>
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: buxxi <buxxi@omfilm.net>
Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com>
Co-authored-by: Dave Child <dave@addedbytes.com>
Co-authored-by: grenagit <46225780+grenagit@users.noreply.github.com>
Co-authored-by: Grena <grena@grenabox.fr>
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Co-authored-by: Patrick <psieg@users.noreply.github.com>
Co-authored-by: Piotr Rajnisz <56397164+rajniszp@users.noreply.github.com>
Co-authored-by: Suthep Yonphimai <tomzt@users.noreply.github.com>
Co-authored-by: CarJem Generations (Carter Wallace) <cwallacecs@gmail.com>
Co-authored-by: Nicholas Fogal <nfogal.misc@gmail.com>
Co-authored-by: JakeBinney <126349119+JakeBinney@users.noreply.github.com>
Co-authored-by: OWL4C <124401812+OWL4C@users.noreply.github.com>
Co-authored-by: Oscar Björkman <17575446+oscarb@users.noreply.github.com>
Co-authored-by: Ismar Slomic <ismar@slomic.no>
Co-authored-by: Jørgen Veum-Wahlberg <jorgen.wahlberg@amedia.no>
Co-authored-by: Eddie Hung <6740044+eddiehung@users.noreply.github.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Knapoc <Knapoc@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: NolanKingdon <27908974+NolanKingdon@users.noreply.github.com>
Co-authored-by: J. Kenzal Hunter <kenzal.hunter@gmail.com>
Co-authored-by: Teddy <teddy.payet@gmail.com>
Co-authored-by: TeddyStarinvest <teddy.payet@starinvest.com>
Co-authored-by: martingron <61826403+martingron@users.noreply.github.com>
Co-authored-by: dgoth <132394363+dgoth@users.noreply.github.com>
Co-authored-by: kaennchenstruggle <54073894+kaennchenstruggle@users.noreply.github.com>
Co-authored-by: jkriegshauser <jkriegshauser@gmail.com>
Co-authored-by: Ben Nitkin <ben@nitkin.net>
2024-01-01 15:38:08 +01:00
|
|
|
titleFilterApplies (title, filter, useRegex, regexFlags) {
|
2023-07-01 21:17:31 +02:00
|
|
|
if (useRegex) {
|
|
|
|
|
let regexFilter = filter;
|
|
|
|
|
// Assume if leading slash, there is also trailing slash
|
|
|
|
|
if (filter[0] === "/") {
|
|
|
|
|
// Strip leading and trailing slashes
|
|
|
|
|
regexFilter = filter.substr(1).slice(0, -1);
|
|
|
|
|
}
|
|
|
|
|
return new RegExp(regexFilter, regexFlags).test(title);
|
|
|
|
|
} else {
|
|
|
|
|
return title.includes(filter);
|
|
|
|
|
}
|
2025-12-08 10:07:04 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Expands a recurring event into individual event instances.
|
|
|
|
|
* @param {object} event The recurring event object
|
|
|
|
|
* @param {moment.Moment} pastLocalMoment The past date limit
|
|
|
|
|
* @param {moment.Moment} futureLocalMoment The future date limit
|
|
|
|
|
* @param {number} durationMs The duration of the event in milliseconds
|
|
|
|
|
* @returns {object[]} Array of event instances
|
|
|
|
|
*/
|
|
|
|
|
expandRecurringEvent (event, pastLocalMoment, futureLocalMoment, durationMs) {
|
|
|
|
|
const moments = CalendarFetcherUtils.getMomentsFromRecurringEvent(event, pastLocalMoment, futureLocalMoment, durationMs);
|
|
|
|
|
const instances = [];
|
|
|
|
|
|
|
|
|
|
for (const startMoment of moments) {
|
|
|
|
|
let curEvent = event;
|
|
|
|
|
let showRecurrence = true;
|
|
|
|
|
let recurringEventStartMoment = startMoment.clone().tz(CalendarFetcherUtils.getLocalTimezone());
|
|
|
|
|
let recurringEventEndMoment = recurringEventStartMoment.clone().add(durationMs, "ms");
|
|
|
|
|
|
|
|
|
|
const dateKey = recurringEventStartMoment.tz("UTC").format("YYYY-MM-DD");
|
|
|
|
|
|
|
|
|
|
// Check for overrides
|
|
|
|
|
if (curEvent.recurrences !== undefined) {
|
|
|
|
|
if (curEvent.recurrences[dateKey] !== undefined) {
|
|
|
|
|
curEvent = curEvent.recurrences[dateKey];
|
|
|
|
|
// Re-calculate start/end based on override
|
|
|
|
|
const start = curEvent.start;
|
|
|
|
|
const end = curEvent.end;
|
|
|
|
|
const localTimezone = CalendarFetcherUtils.getLocalTimezone();
|
|
|
|
|
|
|
|
|
|
recurringEventStartMoment = (start.tz ? moment(start).tz(start.tz) : moment(start)).tz(localTimezone);
|
|
|
|
|
recurringEventEndMoment = (end.tz ? moment(end).tz(end.tz) : moment(end)).tz(localTimezone);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for exceptions
|
|
|
|
|
if (curEvent.exdate !== undefined) {
|
|
|
|
|
if (curEvent.exdate[dateKey] !== undefined) {
|
|
|
|
|
showRecurrence = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (recurringEventStartMoment.valueOf() === recurringEventEndMoment.valueOf()) {
|
|
|
|
|
recurringEventEndMoment = recurringEventEndMoment.endOf("day");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (showRecurrence) {
|
|
|
|
|
instances.push({
|
|
|
|
|
event: curEvent,
|
|
|
|
|
startMoment: recurringEventStartMoment,
|
|
|
|
|
endMoment: recurringEventEndMoment,
|
|
|
|
|
isRecurring: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return instances;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Checks if an event title matches a specific filter configuration.
|
|
|
|
|
* @param {string} title The event title to check
|
|
|
|
|
* @param {string|object} filterConfig The filter configuration (string or object)
|
|
|
|
|
* @returns {object|null} Object with {until: string|null} if matched, null otherwise
|
|
|
|
|
*/
|
|
|
|
|
checkEventAgainstFilter (title, filterConfig) {
|
|
|
|
|
let filter = filterConfig;
|
|
|
|
|
let testTitle = title.toLowerCase();
|
|
|
|
|
let until = null;
|
|
|
|
|
let useRegex = false;
|
|
|
|
|
let regexFlags = "g";
|
|
|
|
|
|
|
|
|
|
if (filter instanceof Object) {
|
|
|
|
|
if (typeof filter.until !== "undefined") {
|
|
|
|
|
until = filter.until;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeof filter.regex !== "undefined") {
|
|
|
|
|
useRegex = filter.regex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (filter.caseSensitive) {
|
|
|
|
|
filter = filter.filterBy;
|
|
|
|
|
testTitle = title;
|
|
|
|
|
} else if (useRegex) {
|
|
|
|
|
filter = filter.filterBy;
|
|
|
|
|
testTitle = title;
|
|
|
|
|
regexFlags += "i";
|
|
|
|
|
} else {
|
|
|
|
|
filter = filter.filterBy.toLowerCase();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
filter = filter.toLowerCase();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (CalendarFetcherUtils.titleFilterApplies(testTitle, filter, useRegex, regexFlags)) {
|
|
|
|
|
return { until };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
2023-07-01 21:17:31 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (typeof module !== "undefined") {
|
|
|
|
|
module.exports = CalendarFetcherUtils;
|
|
|
|
|
}
|