jclarke0000 / MMM-MyCalendar

Alternative calendar module for MagicMirror.
57 stars 17 forks source link

Release 2.25.0 of MagicMirror breaks the module #40

Open el97 opened 9 months ago

el97 commented 9 months ago

The latest version of MagicMirror breaks the module. I fixed it on my own by removing a few lines in calendarfetcher.js. I'm not sure if this is the right way and therefore I won't make a PR. Feel free to try this at your own risk. The following lines I removed is

const fetch = require("fetch");
const digest = require("digest-fetch");
let fetcher = null;
            } else if (auth.method === "digest") {
                fetcher = new digest(auth.user, auth.pass).fetch(url, { headers: headers, agent: httpsAgent });
        if (fetcher === null) {
            fetcher = fetch(url, { headers: headers, agent: httpsAgent });
        }
DrSpaldo commented 9 months ago

I am also getting the same error and can't start MM

@el97 did you remove all of those lines?

el97 commented 9 months ago

@DrSpaldo You can start by marking them out with comments. Write / at the beginning of the line and then /at the end like this

/*const fetch = require("fetch");*/
/*const digest = require("digest-fetch");*/

You can also do it this way if the lines come after each other.

/*const fetch = require("fetch");
const digest = require("digest-fetch");*/

This is what my file looks like

/* MagicMirror²
 * Node Helper: Calendar - CalendarFetcher
 *
 * By Michael Teeuw https://michaelteeuw.nl
 * MIT Licensed.
 */
const CalendarUtils = require("./calendarutils");
const Log = require("logger");
const NodeHelper = require("node_helper");
const ical = require("node-ical");
/*const fetch = require("fetch");*/
/*const digest = require("digest-fetch");*/
const https = require("https");

/**
 *
 * @param {string} url The url of the calendar to fetch
 * @param {number} reloadInterval Time in ms the calendar is fetched again
 * @param {string[]} excludedEvents An array of words / phrases from event titles that will be excluded from being shown.
 * @param {number} maximumEntries The maximum number of events fetched.
 * @param {number} maximumNumberOfDays The maximum number of days an event should be in the future.
 * @param {object} auth The object containing options for authentication against the calendar.
 * @param {boolean} includePastEvents If true events from the past maximumNumberOfDays will be fetched too
 * @param {boolean} selfSignedCert If true, the server certificate is not verified against the list of supplied CAs.
 * @class
 */
const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, includePastEvents, selfSignedCert) {
    let reloadTimer = null;
    let events = [];

    let fetchFailedCallback = function () {};
    let eventsReceivedCallback = function () {};

    /**
     * Initiates calendar fetch.
     */
    const fetchCalendar = () => {
        clearTimeout(reloadTimer);
        reloadTimer = null;
        const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
/*      let fetcher = null;*/
        let httpsAgent = null;
        let headers = {
            "User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version
        };

        if (selfSignedCert) {
            httpsAgent = new https.Agent({
                rejectUnauthorized: false
            });
        }
        if (auth) {
            if (auth.method === "bearer") {
                headers.Authorization = "Bearer " + auth.pass;
/*          } else if (auth.method === "digest") {
                fetcher = new digest(auth.user, auth.pass).fetch(url, { headers: headers, agent: httpsAgent });*/
            } else {
                headers.Authorization = "Basic " + Buffer.from(auth.user + ":" + auth.pass).toString("base64");
            }
        }
/*      if (fetcher === null) {
            fetcher = fetch(url, { headers: headers, agent: httpsAgent });
        }*/

        fetch(url, { headers: headers, agent: httpsAgent })
            .then(NodeHelper.checkFetchStatus)
            .then((response) => response.text())
            .then((responseData) => {
                let data = [];

                try {
                    data = ical.parseICS(responseData);
                    Log.debug("parsed data=" + JSON.stringify(data));
                    events = CalendarUtils.filterEvents(data, {
                        excludedEvents,
                        includePastEvents,
                        maximumEntries,
                        maximumNumberOfDays
                    });
                } catch (error) {
                    fetchFailedCallback(this, error);
                    scheduleTimer();
                    return;
                }
                this.broadcastEvents();
                scheduleTimer();
            })
            .catch((error) => {
                fetchFailedCallback(this, error);
                scheduleTimer();
            });
    };

    /**
     * Schedule the timer for the next update.
     */
    const scheduleTimer = function () {
        clearTimeout(reloadTimer);
        reloadTimer = setTimeout(function () {
            fetchCalendar();
        }, reloadInterval);
    };

    /* public methods */

    /**
     * Initiate fetchCalendar();
     */
    this.startFetch = function () {
        fetchCalendar();
    };

    /**
     * Broadcast the existing events.
     */
    this.broadcastEvents = function () {
        Log.info("Calendar-Fetcher: Broadcasting " + events.length + " events.");
        eventsReceivedCallback(this);
    };

    /**
     * Sets the on success callback
     *
     * @param {Function} callback The on success callback.
     */
    this.onReceive = function (callback) {
        eventsReceivedCallback = callback;
    };

    /**
     * Sets the on error callback
     *
     * @param {Function} callback The on error callback.
     */
    this.onError = function (callback) {
        fetchFailedCallback = callback;
    };

    /**
     * Returns the url of this fetcher.
     *
     * @returns {string} The url of this fetcher.
     */
    this.url = function () {
        return url;
    };

    /**
     * Returns current available events for this fetcher.
     *
     * @returns {object[]} The current available events for this fetcher.
     */
    this.events = function () {
        return events;
    };
};

module.exports = CalendarFetcher;
DrSpaldo commented 9 months ago

Looks like that is working for me as well so far @el97

Hopefully the author @jclarke0000 can have a look at this and see if any other changes need to be made, I am guessing it may relate to the updated Node version required?

el97 commented 9 months ago

Looks like that is working for me as well so far @el97

Hopefully the author @jclarke0000 can have a look at this and see if any other changes need to be made, I am guessing it may relate to the updated Node version required?

I wouldn't be too hopeful since his latest activity was in April 2022.

DrSpaldo commented 9 months ago

I wouldn't be too hopeful since his latest activity was in April 2022.

Ah, yes, you are right. Maybe it will be all up to you from now on!

AnduriI commented 9 months ago

Well I have the same problem, but your intended solution doesn't work for me. It will start MM again with your modification, but show no events. Maybe it depends on the calendar provider. What dou you use? I have all my calendars on google...

usafle commented 9 months ago

I didn't have an issue with this module after updating MM to the latest version. However, my default clock module was showing some incorrect time zone. I fixed this by adding my time zone into the config.js and into clock.js

However, this module still is pulling the same time from whatever time zone MM was pulling from. In other words, all my events are showing incorrect start times - it doesn't match up with my GCalender any longer. Everything is hours ahead of when it's supposed to actually start.

Any ideas?

AnduriI commented 9 months ago

It will start MM again with your modification, but show no events.

well that problem is gone now. For some reason all my events suddenly showed up. So your fix is working.

el97 commented 9 months ago

I didn't have an issue with this module after updating MM to the latest version. However, my default clock module was showing some incorrect time zone. I fixed this by adding my time zone into the config.js and into clock.js

However, this module still is pulling the same time from whatever time zone MM was pulling from. In other words, all my events are showing incorrect start times - it doesn't match up with my GCalender any longer. Everything is hours ahead of when it's supposed to actually start.

Any ideas?

@usafle I'm guessing that MM takes the time from the computer it's running at. If you use a Raspberry Pi, make sure that you have put in the right settings in raspi-config.

usafle commented 9 months ago

@el97 I've checked, re-checked and double-checked my RPI time settings everywhere on the machine, and they all are reporting the correct time. Only after updating to the most recent MM OS did this start occurring.

el97 commented 9 months ago

@usafle I'm using Raspbian bullseye so I'm not sure what to do exactly. I would take a backup and then start from the beginning.

usafle commented 8 months ago

@el97 I was just about to do just that and looked at my MM this morning and now all the times are correct. So, like some others on here this module just "fixed itself".

el97 commented 8 months ago

@el97 I was just about to do just that and looked at my MM this morning and now all the times are correct. So, like some others on here this module just "fixed itself".

@usafle oooh... Those kinds of fixes are scary. An issue that fixes itself is still an issue because you don't know the solution to it. Oh well... If it works it works I guess.

usafle commented 8 months ago

Well the mysterious time pull is back once again. This is frustrating.

@usafle oooh... Those kinds of fixes are scary. An issue that fixes itself is still an issue because you don't know the solution to it. Oh well... If it works it works I guess.

dbeltjr commented 7 months ago

I just upgraded MM as well to the 2.25.0 version and the MyCalendar module broke mine. I commented out the lines in calendarfetcher.js stated above and my MM was able to load, but the modules sits in a permanent "Loading..." status. I was reading and fetch is now incorporated into Node.js, so it may be why this broke. I'm not a programmer, so I couldn't even start to figure out how to fix that, but that seems to be the issue.

dbeltjr commented 7 months ago

After some tinkering, I figured out what code could be copied from the default calendar file to make it work properly. I created 2 new pull requests for calendarfetcher.js and node-helper.js.