mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-07-10 17:24:44 +00:00
Install latest ical version and use it
This commit is contained in:
parent
6d3308621f
commit
6d60baa2d6
@ -5,7 +5,8 @@
|
|||||||
* MIT Licensed.
|
* MIT Licensed.
|
||||||
*/
|
*/
|
||||||
const Log = require("../../../js/logger.js");
|
const Log = require("../../../js/logger.js");
|
||||||
const ical = require("./vendor/ical.js");
|
const fetch = require("node-fetch");
|
||||||
|
const ical = require("ical");
|
||||||
const moment = require("moment");
|
const moment = require("moment");
|
||||||
|
|
||||||
var CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, includePastEvents) {
|
var CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, includePastEvents) {
|
||||||
@ -20,318 +21,316 @@ var CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEntr
|
|||||||
/* fetchCalendar()
|
/* fetchCalendar()
|
||||||
* Initiates calendar fetch.
|
* Initiates calendar fetch.
|
||||||
*/
|
*/
|
||||||
var fetchCalendar = function () {
|
const fetchCalendar = function () {
|
||||||
clearTimeout(reloadTimer);
|
clearTimeout(reloadTimer);
|
||||||
reloadTimer = null;
|
reloadTimer = null;
|
||||||
|
|
||||||
var nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
|
const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
|
||||||
var opts = {
|
const opts = {
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)"
|
"User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)"
|
||||||
},
|
},
|
||||||
gzip: true
|
compress: true
|
||||||
};
|
};
|
||||||
|
|
||||||
if (auth) {
|
if (auth) {
|
||||||
if (auth.method === "bearer") {
|
if (auth.method === "bearer") {
|
||||||
opts.auth = {
|
opts.headers.Authorization = `Bearer ${auth.pass}`;
|
||||||
bearer: auth.pass
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
opts.auth = {
|
let base64data = Buffer.from(`${auth.user}:${auth.pass}`).toString("base64");
|
||||||
user: auth.user,
|
opts.headers.Authorization = `Basic ${base64data}`;
|
||||||
pass: auth.pass
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// TODO
|
||||||
if (auth.method === "digest") {
|
if (auth.method === "digest") {
|
||||||
opts.auth.sendImmediately = false;
|
//opts.auth.sendImmediately = false;
|
||||||
} else {
|
|
||||||
opts.auth.sendImmediately = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ical.fromURL(url, opts, function (err, data) {
|
fetch(url, opts)
|
||||||
if (err) {
|
.then((response) => response.text())
|
||||||
fetchFailedCallback(self, err);
|
.then((rawData) => {
|
||||||
scheduleTimer();
|
const data = ical.parseICS(rawData);
|
||||||
return;
|
const newEvents = [];
|
||||||
}
|
|
||||||
|
|
||||||
var newEvents = [];
|
// limitFunction doesn't do much limiting, see comment re: the dates array in rrule section below as to why we need to do the filtering ourselves
|
||||||
|
const limitFunction = function (date, i) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
// limitFunction doesn't do much limiting, see comment re: the dates array in rrule section below as to why we need to do the filtering ourselves
|
const eventDate = function (event, time) {
|
||||||
var limitFunction = function (date, i) {
|
return event[time].length === 8 ? moment(event[time], "YYYYMMDD") : moment(new Date(event[time]));
|
||||||
return true;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
var eventDate = function (event, time) {
|
for (let k in data) {
|
||||||
return event[time].length === 8 ? moment(event[time], "YYYYMMDD") : moment(new Date(event[time]));
|
if (data.hasOwnProperty(k)) {
|
||||||
};
|
var event = data[k];
|
||||||
|
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;
|
||||||
|
|
||||||
for (var e in data) {
|
if (includePastEvents) {
|
||||||
var event = data[e];
|
past = moment().startOf("day").subtract(maximumNumberOfDays, "days").toDate();
|
||||||
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.
|
|
||||||
// Otherwise, the recurring events only show the birthday for next year.
|
|
||||||
var isFacebookBirthday = false;
|
|
||||||
if (typeof event.uid !== "undefined") {
|
|
||||||
if (event.uid.indexOf("@facebook.com") !== -1) {
|
|
||||||
isFacebookBirthday = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type === "VEVENT") {
|
|
||||||
var startDate = eventDate(event, "start");
|
|
||||||
var endDate;
|
|
||||||
if (typeof event.end !== "undefined") {
|
|
||||||
endDate = eventDate(event, "end");
|
|
||||||
} else if (typeof event.duration !== "undefined") {
|
|
||||||
var dur = moment.duration(event.duration);
|
|
||||||
endDate = startDate.clone().add(dur);
|
|
||||||
} else {
|
|
||||||
if (!isFacebookBirthday) {
|
|
||||||
endDate = startDate;
|
|
||||||
} else {
|
|
||||||
endDate = moment(startDate).add(1, "days");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// calculate the duration f the event for use with recurring events.
|
// FIXME: Ugly fix to solve the facebook birthday issue.
|
||||||
var duration = parseInt(endDate.format("x")) - parseInt(startDate.format("x"));
|
// Otherwise, the recurring events only show the birthday for next year.
|
||||||
|
var isFacebookBirthday = false;
|
||||||
if (event.start.length === 8) {
|
if (typeof event.uid !== "undefined") {
|
||||||
startDate = startDate.startOf("day");
|
if (event.uid.indexOf("@facebook.com") !== -1) {
|
||||||
}
|
isFacebookBirthday = true;
|
||||||
|
|
||||||
var title = getTitleFromEvent(event);
|
|
||||||
|
|
||||||
var excluded = false,
|
|
||||||
dateFilter = null;
|
|
||||||
|
|
||||||
for (var f in excludedEvents) {
|
|
||||||
var filter = excludedEvents[f],
|
|
||||||
testTitle = title.toLowerCase(),
|
|
||||||
until = null,
|
|
||||||
useRegex = false,
|
|
||||||
regexFlags = "g";
|
|
||||||
|
|
||||||
if (filter instanceof Object) {
|
|
||||||
if (typeof filter.until !== "undefined") {
|
|
||||||
until = filter.until;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof filter.regex !== "undefined") {
|
if (event.type === "VEVENT") {
|
||||||
useRegex = filter.regex;
|
var startDate = eventDate(event, "start");
|
||||||
}
|
var endDate;
|
||||||
|
if (typeof event.end !== "undefined") {
|
||||||
// If additional advanced filtering is added in, this section
|
endDate = eventDate(event, "end");
|
||||||
// must remain last as we overwrite the filter object with the
|
} else if (typeof event.duration !== "undefined") {
|
||||||
// filterBy string
|
var dur = moment.duration(event.duration);
|
||||||
if (filter.caseSensitive) {
|
endDate = startDate.clone().add(dur);
|
||||||
filter = filter.filterBy;
|
|
||||||
testTitle = title;
|
|
||||||
} else if (useRegex) {
|
|
||||||
filter = filter.filterBy;
|
|
||||||
testTitle = title;
|
|
||||||
regexFlags += "i";
|
|
||||||
} else {
|
} else {
|
||||||
filter = filter.filterBy.toLowerCase();
|
if (!isFacebookBirthday) {
|
||||||
}
|
endDate = startDate;
|
||||||
} else {
|
} else {
|
||||||
filter = filter.toLowerCase();
|
endDate = moment(startDate).add(1, "days");
|
||||||
}
|
|
||||||
|
|
||||||
if (testTitleByFilter(testTitle, filter, useRegex, regexFlags)) {
|
|
||||||
if (until) {
|
|
||||||
dateFilter = until;
|
|
||||||
} else {
|
|
||||||
excluded = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (excluded) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var location = event.location || false;
|
|
||||||
var geo = event.geo || false;
|
|
||||||
var description = event.description || false;
|
|
||||||
|
|
||||||
if (typeof event.rrule !== "undefined" && event.rrule !== null && !isFacebookBirthday) {
|
|
||||||
var rule = event.rrule;
|
|
||||||
var addedEvents = 0;
|
|
||||||
|
|
||||||
// can cause problems with e.g. birthdays before 1900
|
|
||||||
if ((rule.options && rule.origOptions && rule.origOptions.dtstart && rule.origOptions.dtstart.getFullYear() < 1900) || (rule.options && rule.options.dtstart && rule.options.dtstart.getFullYear() < 1900)) {
|
|
||||||
rule.origOptions.dtstart.setYear(1900);
|
|
||||||
rule.options.dtstart.setYear(1900);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For recurring events, get the set of start dates that fall within the range
|
|
||||||
// of dates we"re looking for.
|
|
||||||
// kblankenship1989 - to fix issue #1798, converting all dates to locale time first, then converting back to UTC time
|
|
||||||
var pastLocal = moment(past).subtract(past.getTimezoneOffset(), "minutes").toDate();
|
|
||||||
var futureLocal = moment(future).subtract(future.getTimezoneOffset(), "minutes").toDate();
|
|
||||||
var datesLocal = rule.between(pastLocal, futureLocal, true, limitFunction);
|
|
||||||
var dates = datesLocal.map(function (dateLocal) {
|
|
||||||
var date = moment(dateLocal).add(dateLocal.getTimezoneOffset(), "minutes").toDate();
|
|
||||||
return date;
|
|
||||||
});
|
|
||||||
|
|
||||||
// The "dates" array contains the set of dates within our desired date range range that are valid
|
|
||||||
// for the recurrence rule. *However*, it"s possible for us to have a specific recurrence that
|
|
||||||
// had its date changed from outside the range to inside the range. For the time being,
|
|
||||||
// we"ll handle this by adding *all* recurrence entries into the set of dates that we check,
|
|
||||||
// because the logic below will filter out any recurrences that don"t actually belong within
|
|
||||||
// our display range.
|
|
||||||
// Would be great if there was a better way to handle this.
|
|
||||||
if (event.recurrences !== undefined) {
|
|
||||||
var pastMoment = moment(past);
|
|
||||||
var futureMoment = moment(future);
|
|
||||||
|
|
||||||
for (var r in event.recurrences) {
|
|
||||||
// Only add dates that weren't already in the range we added from the rrule so that
|
|
||||||
// we don"t double-add those events.
|
|
||||||
if (moment(new Date(r)).isBetween(pastMoment, futureMoment) !== true) {
|
|
||||||
dates.push(new Date(r));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through the set of date entries to see which recurrences should be added to our event list.
|
// calculate the duration f the event for use with recurring events.
|
||||||
for (var d in dates) {
|
var duration = parseInt(endDate.format("x")) - parseInt(startDate.format("x"));
|
||||||
var date = dates[d];
|
|
||||||
// ical.js started returning recurrences and exdates as ISOStrings without time information.
|
|
||||||
// .toISOString().substring(0,10) is the method they use to calculate keys, so we'll do the same
|
|
||||||
// (see https://github.com/peterbraden/ical.js/pull/84 )
|
|
||||||
var dateKey = date.toISOString().substring(0, 10);
|
|
||||||
var curEvent = event;
|
|
||||||
var showRecurrence = true;
|
|
||||||
|
|
||||||
// Stop parsing this event's recurrences if we've already found maximumEntries worth of recurrences.
|
if (event.start.length === 8) {
|
||||||
// (The logic below would still filter the extras, but the check is simple since we're already tracking the count)
|
startDate = startDate.startOf("day");
|
||||||
if (addedEvents >= maximumEntries) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startDate = moment(date);
|
var title = getTitleFromEvent(event);
|
||||||
|
|
||||||
// For each date that we"re checking, it"s possible that there is a recurrence override for that one day.
|
var excluded = false,
|
||||||
if (curEvent.recurrences !== undefined && curEvent.recurrences[dateKey] !== undefined) {
|
dateFilter = null;
|
||||||
// We found an override, so for this recurrence, use a potentially different title, start date, and duration.
|
|
||||||
curEvent = curEvent.recurrences[dateKey];
|
for (var f in excludedEvents) {
|
||||||
startDate = moment(curEvent.start);
|
var filter = excludedEvents[f],
|
||||||
duration = parseInt(moment(curEvent.end).format("x")) - parseInt(startDate.format("x"));
|
testTitle = title.toLowerCase(),
|
||||||
}
|
until = null,
|
||||||
// If there"s no recurrence override, check for an exception date. Exception dates represent exceptions to the rule.
|
useRegex = false,
|
||||||
else if (curEvent.exdate !== undefined && curEvent.exdate[dateKey] !== undefined) {
|
regexFlags = "g";
|
||||||
// This date is an exception date, which means we should skip it in the recurrence pattern.
|
|
||||||
showRecurrence = false;
|
if (filter instanceof Object) {
|
||||||
|
if (typeof filter.until !== "undefined") {
|
||||||
|
until = filter.until;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof filter.regex !== "undefined") {
|
||||||
|
useRegex = filter.regex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If additional advanced filtering is added in, this section
|
||||||
|
// must remain last as we overwrite the filter object with the
|
||||||
|
// filterBy string
|
||||||
|
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 (testTitleByFilter(testTitle, filter, useRegex, regexFlags)) {
|
||||||
|
if (until) {
|
||||||
|
dateFilter = until;
|
||||||
|
} else {
|
||||||
|
excluded = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
endDate = moment(parseInt(startDate.format("x")) + duration, "x");
|
if (excluded) {
|
||||||
if (startDate.format("x") === endDate.format("x")) {
|
continue;
|
||||||
endDate = endDate.endOf("day");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var recurrenceTitle = getTitleFromEvent(curEvent);
|
var location = event.location || false;
|
||||||
|
var geo = event.geo || false;
|
||||||
|
var description = event.description || false;
|
||||||
|
|
||||||
// If this recurrence ends before the start of the date range, or starts after the end of the date range, don"t add
|
if (typeof event.rrule !== "undefined" && event.rrule !== null && !isFacebookBirthday) {
|
||||||
// it to the event list.
|
var rule = event.rrule;
|
||||||
if (endDate.isBefore(past) || startDate.isAfter(future)) {
|
var addedEvents = 0;
|
||||||
showRecurrence = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeFilterApplies(now, endDate, dateFilter)) {
|
// can cause problems with e.g. birthdays before 1900
|
||||||
showRecurrence = false;
|
if ((rule.options && rule.origOptions && rule.origOptions.dtstart && rule.origOptions.dtstart.getFullYear() < 1900) || (rule.options && rule.options.dtstart && rule.options.dtstart.getFullYear() < 1900)) {
|
||||||
}
|
rule.origOptions.dtstart.setYear(1900);
|
||||||
|
rule.options.dtstart.setYear(1900);
|
||||||
|
}
|
||||||
|
|
||||||
if (showRecurrence === true && addedEvents < maximumEntries) {
|
// For recurring events, get the set of start dates that fall within the range
|
||||||
addedEvents++;
|
// of dates we"re looking for.
|
||||||
|
// kblankenship1989 - to fix issue #1798, converting all dates to locale time first, then converting back to UTC time
|
||||||
|
var pastLocal = moment(past).subtract(past.getTimezoneOffset(), "minutes").toDate();
|
||||||
|
var futureLocal = moment(future).subtract(future.getTimezoneOffset(), "minutes").toDate();
|
||||||
|
var datesLocal = rule.between(pastLocal, futureLocal, true, limitFunction);
|
||||||
|
var dates = datesLocal.map(function (dateLocal) {
|
||||||
|
var date = moment(dateLocal).add(dateLocal.getTimezoneOffset(), "minutes").toDate();
|
||||||
|
return date;
|
||||||
|
});
|
||||||
|
|
||||||
|
// The "dates" array contains the set of dates within our desired date range range that are valid
|
||||||
|
// for the recurrence rule. *However*, it"s possible for us to have a specific recurrence that
|
||||||
|
// had its date changed from outside the range to inside the range. For the time being,
|
||||||
|
// we"ll handle this by adding *all* recurrence entries into the set of dates that we check,
|
||||||
|
// because the logic below will filter out any recurrences that don"t actually belong within
|
||||||
|
// our display range.
|
||||||
|
// Would be great if there was a better way to handle this.
|
||||||
|
if (event.recurrences !== undefined) {
|
||||||
|
var pastMoment = moment(past);
|
||||||
|
var futureMoment = moment(future);
|
||||||
|
|
||||||
|
for (var r in event.recurrences) {
|
||||||
|
// Only add dates that weren't already in the range we added from the rrule so that
|
||||||
|
// we don"t double-add those events.
|
||||||
|
if (moment(new Date(r)).isBetween(pastMoment, futureMoment) !== true) {
|
||||||
|
dates.push(new Date(r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through the set of date entries to see which recurrences should be added to our event list.
|
||||||
|
for (var d in dates) {
|
||||||
|
var date = dates[d];
|
||||||
|
// ical.js started returning recurrences and exdates as ISOStrings without time information.
|
||||||
|
// .toISOString().substring(0,10) is the method they use to calculate keys, so we'll do the same
|
||||||
|
// (see https://github.com/peterbraden/ical.js/pull/84 )
|
||||||
|
var dateKey = date.toISOString().substring(0, 10);
|
||||||
|
var curEvent = event;
|
||||||
|
var showRecurrence = true;
|
||||||
|
|
||||||
|
// Stop parsing this event's recurrences if we've already found maximumEntries worth of recurrences.
|
||||||
|
// (The logic below would still filter the extras, but the check is simple since we're already tracking the count)
|
||||||
|
if (addedEvents >= maximumEntries) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
startDate = moment(date);
|
||||||
|
|
||||||
|
// For each date that we"re checking, it"s possible that there is a recurrence override for that one day.
|
||||||
|
if (curEvent.recurrences !== undefined && curEvent.recurrences[dateKey] !== undefined) {
|
||||||
|
// We found an override, so for this recurrence, use a potentially different title, start date, and duration.
|
||||||
|
curEvent = curEvent.recurrences[dateKey];
|
||||||
|
startDate = moment(curEvent.start);
|
||||||
|
duration = parseInt(moment(curEvent.end).format("x")) - parseInt(startDate.format("x"));
|
||||||
|
}
|
||||||
|
// If there"s no recurrence override, check for an exception date. Exception dates represent exceptions to the rule.
|
||||||
|
else if (curEvent.exdate !== undefined && curEvent.exdate[dateKey] !== undefined) {
|
||||||
|
// This date is an exception date, which means we should skip it in the recurrence pattern.
|
||||||
|
showRecurrence = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
endDate = moment(parseInt(startDate.format("x")) + duration, "x");
|
||||||
|
if (startDate.format("x") === endDate.format("x")) {
|
||||||
|
endDate = endDate.endOf("day");
|
||||||
|
}
|
||||||
|
|
||||||
|
var recurrenceTitle = getTitleFromEvent(curEvent);
|
||||||
|
|
||||||
|
// If this recurrence ends before the start of the date range, or starts after the end of the date range, don"t add
|
||||||
|
// it to the event list.
|
||||||
|
if (endDate.isBefore(past) || startDate.isAfter(future)) {
|
||||||
|
showRecurrence = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeFilterApplies(now, endDate, dateFilter)) {
|
||||||
|
showRecurrence = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showRecurrence === true && addedEvents < maximumEntries) {
|
||||||
|
addedEvents++;
|
||||||
|
newEvents.push({
|
||||||
|
title: recurrenceTitle,
|
||||||
|
startDate: startDate.format("x"),
|
||||||
|
endDate: endDate.format("x"),
|
||||||
|
fullDayEvent: isFullDayEvent(event),
|
||||||
|
class: event.class,
|
||||||
|
firstYear: event.start.getFullYear(),
|
||||||
|
location: location,
|
||||||
|
geo: geo,
|
||||||
|
description: description
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end recurring event parsing
|
||||||
|
} else {
|
||||||
|
// Single event.
|
||||||
|
var fullDayEvent = isFacebookBirthday ? true : isFullDayEvent(event);
|
||||||
|
|
||||||
|
if (includePastEvents) {
|
||||||
|
// Past event is too far in the past, so skip.
|
||||||
|
if (endDate < past) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// It's not a fullday event, and it is in the past, so skip.
|
||||||
|
if (!fullDayEvent && endDate < new Date()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's a fullday event, and it is before today, So skip.
|
||||||
|
if (fullDayEvent && endDate <= today) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// It exceeds the maximumNumberOfDays limit, so skip.
|
||||||
|
if (startDate > future) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeFilterApplies(now, endDate, dateFilter)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust start date so multiple day events will be displayed as happening today even though they started some days ago already
|
||||||
|
if (fullDayEvent && startDate <= today) {
|
||||||
|
startDate = moment(today);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Every thing is good. Add it to the list.
|
||||||
newEvents.push({
|
newEvents.push({
|
||||||
title: recurrenceTitle,
|
title: title,
|
||||||
startDate: startDate.format("x"),
|
startDate: startDate.format("x"),
|
||||||
endDate: endDate.format("x"),
|
endDate: endDate.format("x"),
|
||||||
fullDayEvent: isFullDayEvent(event),
|
fullDayEvent: fullDayEvent,
|
||||||
class: event.class,
|
class: event.class,
|
||||||
firstYear: event.start.getFullYear(),
|
|
||||||
location: location,
|
location: location,
|
||||||
geo: geo,
|
geo: geo,
|
||||||
description: description
|
description: description
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// end recurring event parsing
|
|
||||||
} else {
|
|
||||||
// Single event.
|
|
||||||
var fullDayEvent = isFacebookBirthday ? true : isFullDayEvent(event);
|
|
||||||
|
|
||||||
if (includePastEvents) {
|
|
||||||
// Past event is too far in the past, so skip.
|
|
||||||
if (endDate < past) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// It's not a fullday event, and it is in the past, so skip.
|
|
||||||
if (!fullDayEvent && endDate < new Date()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// It's a fullday event, and it is before today, So skip.
|
|
||||||
if (fullDayEvent && endDate <= today) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// It exceeds the maximumNumberOfDays limit, so skip.
|
|
||||||
if (startDate > future) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeFilterApplies(now, endDate, dateFilter)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust start date so multiple day events will be displayed as happening today even though they started some days ago already
|
|
||||||
if (fullDayEvent && startDate <= today) {
|
|
||||||
startDate = moment(today);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Every thing is good. Add it to the list.
|
|
||||||
newEvents.push({
|
|
||||||
title: title,
|
|
||||||
startDate: startDate.format("x"),
|
|
||||||
endDate: endDate.format("x"),
|
|
||||||
fullDayEvent: fullDayEvent,
|
|
||||||
class: event.class,
|
|
||||||
location: location,
|
|
||||||
geo: geo,
|
|
||||||
description: description
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
newEvents.sort(function (a, b) {
|
newEvents.sort(function (a, b) {
|
||||||
return a.startDate - b.startDate;
|
return a.startDate - b.startDate;
|
||||||
|
});
|
||||||
|
|
||||||
|
events = newEvents.slice(0, maximumEntries);
|
||||||
|
|
||||||
|
self.broadcastEvents();
|
||||||
|
scheduleTimer();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
fetchFailedCallback(self, err);
|
||||||
|
scheduleTimer();
|
||||||
});
|
});
|
||||||
|
|
||||||
events = newEvents.slice(0, maximumEntries);
|
|
||||||
|
|
||||||
self.broadcastEvents();
|
|
||||||
scheduleTimer();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* scheduleTimer()
|
/* scheduleTimer()
|
||||||
|
21
package-lock.json
generated
21
package-lock.json
generated
@ -3235,6 +3235,24 @@
|
|||||||
"integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==",
|
"integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ical": {
|
||||||
|
"version": "0.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ical/-/ical-0.8.0.tgz",
|
||||||
|
"integrity": "sha512-/viUSb/RGLLnlgm0lWRlPBtVeQguQRErSPYl3ugnUaKUnzQswKqOG3M8/P1v1AB5NJwlHTuvTq1cs4mpeG2rCg==",
|
||||||
|
"requires": {
|
||||||
|
"rrule": "2.4.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"rrule": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/rrule/-/rrule-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-+NcvhETefswZq13T8nkuEnnQ6YgUeZaqMqVbp+ZiFDPCbp3AVgQIwUvNVDdMNrP05bKZG9ddDULFp0qZZYDrxg==",
|
||||||
|
"requires": {
|
||||||
|
"luxon": "^1.3.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.1.tgz",
|
||||||
@ -4714,8 +4732,7 @@
|
|||||||
"node-fetch": {
|
"node-fetch": {
|
||||||
"version": "2.6.0",
|
"version": "2.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
|
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node-releases": {
|
"node-releases": {
|
||||||
"version": "1.1.53",
|
"version": "1.1.53",
|
||||||
|
@ -72,10 +72,12 @@
|
|||||||
"express-ipfilter": "^1.0.1",
|
"express-ipfilter": "^1.0.1",
|
||||||
"feedme": "latest",
|
"feedme": "latest",
|
||||||
"helmet": "^3.21.2",
|
"helmet": "^3.21.2",
|
||||||
|
"ical": "^0.8.0",
|
||||||
"iconv-lite": "latest",
|
"iconv-lite": "latest",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"module-alias": "^2.2.2",
|
"module-alias": "^2.2.2",
|
||||||
"moment": "latest",
|
"moment": "latest",
|
||||||
|
"node-fetch": "^2.6.0",
|
||||||
"request": "^2.88.0",
|
"request": "^2.88.0",
|
||||||
"rrule": "^2.6.2",
|
"rrule": "^2.6.2",
|
||||||
"rrule-alt": "^2.2.8",
|
"rrule-alt": "^2.2.8",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user