mirror of
				https://github.com/MichMich/MagicMirror.git
				synced 2025-11-04 05:15:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			159 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* 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("node-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 });
 | 
						|
		}
 | 
						|
 | 
						|
		fetcher
 | 
						|
			.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;
 |