Skip to content

Commit 19bd76a

Browse files
sdetweilrejas
andauthored
Fixcaldates2 fix calendar module date processing, using node-ical@0.20.1 (#3587)
here is an updated test version of the fixes for all kinds of calendar date problems. NOTE: the changed branch name NOTE: this used the node-cal@0.19.0 library UNCHANGED best to make a new folder and git clone there git clone https://github.com/sdetweil/MagicMirror cd MagicMirror git checkout fixcaldates2 // <------ note this is a changed branch name npm run install-mm copy your config.js and custom.css from the prior folder and the non-default modules you have installed… this ONLY changes the default calendar but DOES ship an updated node-ical library too if you need to fall back, just rename the folders around again so that your original is called MagicMirror all the testcases for node-ical and MagicMirror execute successfully. the ‘BIG’ change here is to get the local NON-TZ dates for the rrule.between() all the checking and conversion code is commented out or not used the node-ical fixes are for excluded dates (exdate) values being adjusted for DST/STD time… waiting to submit that PR one fix in calendar.js for checking if a past date was too far back, but it never checked to see IF the event date was in the past… (before today) so it chopped off too many and one change in calendarfetcher.js to put out a better diagnostic message of the parsed data… (exdate was excluded cause JSON stringify couldn’t convert the complex structure) I added the tests you all have documented please re-pull and checkout the new branch (I deleted the old branch) and npm run install-mm again --------- Co-authored-by: Veeck <github@veeck.de>
1 parent 291ae85 commit 19bd76a

33 files changed

Lines changed: 1182 additions & 113 deletions

CHANGELOG.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ _This release is scheduled to be released on 2025-01-01._
2121
- [linter] Re-add `eslint-plugin-import`now that it supports ESLint v9 (#3586)
2222
- [linter] Re-activate `eslint-plugin-package-json` to lint `package.json`
2323
- [core] Add export on animation names
24+
- [calendar] - added ability to display end date for full date events, where end is not same day (showEnd=true)
2425

2526
### Removed
2627

@@ -38,12 +39,16 @@ _This release is scheduled to be released on 2025-01-01._
3839

3940
- [updatenotification] Fix pm2 using detection when pm2 script is inside or outside MagicMirror root folder (#3576) (#3605) (#3626) (#3628)
4041
- [core] Fix loading node_helper of modules: avoid black screen, display errors and continue loading with next module (#3578)
41-
- [weather] Changed default value for weatherEndpoint of provider openweathermap to "/onecall" (#3574)
42-
- [tests] Fix electron tests with mock dates, the mock on server side was missing (#3597)
43-
- [tests] Fix test cases with hard coded Date.now (#3597)
42+
- [weather] changed default value for weatherEndpoint of provider openweathermap to "/onecall" (#3574)
43+
- [tests] fix electron tests with mock dates, the mock on server side was missing (#3597)
44+
- [tests] fix testcases with hard coded Date.now (#3597)
4445
- [core] Fix missing `basePath` where `location.host` is used (#3613)
4546
- [compliments] croner library changed filenames used in latest version (#3624)
4647
- [linter] Fix ESLint ignore pattern which caused that default modules not to be linted (#3632)
48+
- [calendar] - update to resolve issues #3098 #3144 #3351 #3422 #3443 #3467 #3537 related to timezone changes
49+
- [calendar] - fixes #3267 (styles array), also fixes event with both exdate AND recurrence(and testcase)
50+
- [calendar] - fix showEndsOnlyWithDuration not working, #3598, applies ONLY to full day events
51+
- [calendar] - fix showEnd for Full Day events #3602
4752
- [tests] Suppress "module is not defined" in e2e tests
4853

4954
## [2.29.0] - 2024-10-01

modules/default/calendar/calendar.js

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,17 @@ Module.register("calendar", {
168168

169169
this.selfUpdate();
170170
},
171+
notificationReceived (notification, payload, sender) {
171172

172-
// Override socket notification handler.
173-
socketNotificationReceived (notification, payload) {
174173
if (notification === "FETCH_CALENDAR") {
175-
this.sendSocketNotification(notification, { url: payload.url, id: this.identifier });
174+
if (this.hasCalendarURL(payload.url)) {
175+
this.sendSocketNotification(notification, { url: payload.url, id: this.identifier });
176+
}
176177
}
178+
},
179+
180+
// Override socket notification handler.
181+
socketNotificationReceived (notification, payload) {
177182

178183
if (this.identifier !== payload.id) {
179184
return;
@@ -417,18 +422,26 @@ Module.register("calendar", {
417422
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").format(this.config.dateFormat));
418423
// Add end time if showEnd
419424
if (this.config.showEnd) {
420-
if (this.config.showEndsOnlyWithDuration && event.startDate === event.endDate) {
421-
// no duration here, don't display end
422-
} else {
425+
// and has a duation
426+
if (event.startDate !== event.endDate) {
423427
timeWrapper.innerHTML += "-";
424428
timeWrapper.innerHTML += CalendarUtils.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat));
425429
}
426430
}
431+
427432
// For full day events we use the fullDayEventDateFormat
428433
if (event.fullDayEvent) {
429434
//subtract one second so that fullDayEvents end at 23:59:59, and not at 0:00:00 one the next day
430435
event.endDate -= ONE_SECOND;
431436
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat));
437+
// only show end if requested and allowed and the dates are different
438+
if (this.config.showEnd && !this.config.showEndsOnlyWithDuration && moment(event.startDate, "x").format("YYYYMMDD") !== moment(event.endDate, "x").format("YYYYMMDD")) {
439+
timeWrapper.innerHTML += "-";
440+
timeWrapper.innerHTML += CalendarUtils.capFirst(moment(event.endDate, "x").format(this.config.fullDayEventDateFormat));
441+
} else
442+
if ((moment(event.startDate, "x").format("YYYYMMDD") !== moment(event.endDate, "x").format("YYYYMMDD")) && (moment(event.startDate, "x") < moment(now, "x"))) {
443+
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(now, "x").format(this.config.fullDayEventDateFormat));
444+
}
432445
} else if (this.config.getRelative > 0 && event.startDate < now) {
433446
// Ongoing and getRelative is set
434447
timeWrapper.innerHTML = CalendarUtils.capFirst(
@@ -460,16 +473,18 @@ Module.register("calendar", {
460473
if (event.startDate >= now || (event.fullDayEvent && this.eventEndingWithinNextFullTimeUnit(event, ONE_DAY))) {
461474
// Use relative time
462475
if (!this.config.hideTime && !event.fullDayEvent) {
463-
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").calendar(null, { sameElse: this.config.dateFormat }));
476+
Log.debug("event not hidden and not fullday");
477+
timeWrapper.innerHTML = `${CalendarUtils.capFirst(moment(event.startDate, "x").calendar(null, { sameElse: this.config.dateFormat }))}`;
464478
} else {
465-
timeWrapper.innerHTML = CalendarUtils.capFirst(
479+
Log.debug("event full day or hidden");
480+
timeWrapper.innerHTML = `${CalendarUtils.capFirst(
466481
moment(event.startDate, "x").calendar(null, {
467482
sameDay: this.config.showTimeToday ? "LT" : `[${this.translate("TODAY")}]`,
468483
nextDay: `[${this.translate("TOMORROW")}]`,
469484
nextWeek: "dddd",
470485
sameElse: event.fullDayEvent ? this.config.fullDayEventDateFormat : this.config.dateFormat
471486
})
472-
);
487+
)}`;
473488
}
474489
if (event.fullDayEvent) {
475490
// Full days events within the next two days
@@ -488,9 +503,11 @@ Module.register("calendar", {
488503
timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("DAYAFTERTOMORROW"));
489504
}
490505
}
506+
Log.info("event fullday");
491507
} else if (event.startDate - now < this.config.getRelative * ONE_HOUR) {
508+
Log.info("not full day but within getrelative size");
492509
// If event is within getRelative hours, display 'in xxx' time format or moment.fromNow()
493-
timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").fromNow());
510+
timeWrapper.innerHTML = `${CalendarUtils.capFirst(moment(event.startDate, "x").fromNow())}`;
494511
}
495512
} else {
496513
// Ongoing event
@@ -603,6 +620,7 @@ Module.register("calendar", {
603620
const calendar = this.calendarData[calendarUrl];
604621
let remainingEntries = this.maximumEntriesForUrl(calendarUrl);
605622
let maxPastDaysCompare = now - this.maximumPastDaysForUrl(calendarUrl) * ONE_DAY;
623+
let by_url_calevents = [];
606624
for (const e in calendar) {
607625
const event = JSON.parse(JSON.stringify(calendar[e])); // clone object
608626

@@ -620,9 +638,6 @@ Module.register("calendar", {
620638
if (this.config.hideDuplicates && this.listContainsEvent(events, event)) {
621639
continue;
622640
}
623-
if (--remainingEntries < 0) {
624-
break;
625-
}
626641
}
627642

628643
event.url = calendarUrl;
@@ -667,15 +682,21 @@ Module.register("calendar", {
667682

668683
for (let splitEvent of splitEvents) {
669684
if (splitEvent.endDate > now && splitEvent.endDate <= future) {
670-
events.push(splitEvent);
685+
by_url_calevents.push(splitEvent);
671686
}
672687
}
673688
} else {
674-
events.push(event);
689+
by_url_calevents.push(event);
675690
}
676691
}
692+
by_url_calevents.sort(function (a, b) {
693+
return a.startDate - b.startDate;
694+
});
695+
Log.debug(`pushing ${by_url_calevents.length} events to total with room for ${remainingEntries}`);
696+
events = events.concat(by_url_calevents.slice(0, remainingEntries));
697+
Log.debug(`events for calendar=${events.length}`);
677698
}
678-
699+
Log.info(`sorting events count=${events.length}`);
679700
events.sort(function (a, b) {
680701
return a.startDate - b.startDate;
681702
});
@@ -715,7 +736,7 @@ Module.register("calendar", {
715736
}
716737
events = newEvents;
717738
}
718-
739+
Log.info(`slicing events total maxcount=${this.config.maximumEntries}`);
719740
return events.slice(0, this.config.maximumEntries);
720741
},
721742

modules/default/calendar/calendarfetcher.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn
5656

5757
try {
5858
data = ical.parseICS(responseData);
59-
Log.debug(`parsed data=${JSON.stringify(data)}`);
59+
Log.debug(`parsed data=${JSON.stringify(data, null, 2)}`);
6060
events = CalendarFetcherUtils.filterEvents(data, {
6161
excludedEvents,
6262
includePastEvents,

0 commit comments

Comments
 (0)