mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-12-01 02:21:39 +00:00
[logger] Add prefixes to most Log messages (#3923)
Co-authored-by: veeck <gitkraken@veeck.de>
This commit is contained in:
@@ -29,6 +29,7 @@ planned for 2026-01-01
|
||||
### Updated
|
||||
|
||||
- [core] Update dependencies (#3909, #3916, #3921, #3925)
|
||||
- [logger] Add prefixes to most Log messages (#3923)
|
||||
|
||||
## [2.33.0] - 2025-10-01
|
||||
|
||||
@@ -358,7 +359,7 @@ For more info, please read the following post: [A New Chapter for MagicMirror: T
|
||||
### Fixed
|
||||
|
||||
- [weather] Correct apiBase of weathergov weatherProvider to match documentation (#2926)
|
||||
- Worked around several issues in the RRULE library that were causing deleted calender events to still show, some
|
||||
- Worked around several issues in the RRULE library that were causing deleted calendar events to still show, some
|
||||
initial and recurring events to not show, and some event times to be off an hour. (#3291)
|
||||
- Skip changelog requirement when running tests for dependency updates (#3320)
|
||||
- Display precipitation probability when it is 0% instead of blank/empty (#3345)
|
||||
|
||||
@@ -132,7 +132,7 @@ function addAnimateCSS (element, animation, animationTime) {
|
||||
const node = document.getElementById(element);
|
||||
if (!node) {
|
||||
// don't execute animate: we don't find div
|
||||
Log.warn("addAnimateCSS: node not found for", element);
|
||||
Log.warn("[animateCSS] node not found for adding", element);
|
||||
return;
|
||||
}
|
||||
node.style.setProperty("--animate-duration", `${animationTime}s`);
|
||||
@@ -149,7 +149,7 @@ function removeAnimateCSS (element, animation) {
|
||||
const node = document.getElementById(element);
|
||||
if (!node) {
|
||||
// don't execute animate: we don't find div
|
||||
Log.warn("removeAnimateCSS: node not found for", element);
|
||||
Log.warn("[animateCSS] node not found for removing", element);
|
||||
return;
|
||||
}
|
||||
node.classList.remove("animate__animated", animationName);
|
||||
|
||||
@@ -44,7 +44,7 @@ function checkConfigFile () {
|
||||
}
|
||||
|
||||
// Validate syntax of the configuration file.
|
||||
Log.info(`Checking config file ${configFileName} ...`);
|
||||
Log.info(`[checkconfig] Checking config file ${configFileName} ...`);
|
||||
|
||||
// I'm not sure if all ever is utf-8
|
||||
const configFile = fs.readFileSync(configFileName, "utf-8");
|
||||
@@ -67,7 +67,7 @@ function checkConfigFile () {
|
||||
);
|
||||
|
||||
if (errors.length === 0) {
|
||||
Log.info(styleText("green", "Your configuration file doesn't contain syntax errors :)"));
|
||||
Log.info(styleText("green", "[checkconfig] Your configuration file doesn't contain syntax errors :)"));
|
||||
validateModulePositions(configFileName);
|
||||
} else {
|
||||
let errorMessage = "Your configuration file contains syntax errors :(";
|
||||
@@ -84,7 +84,7 @@ function checkConfigFile () {
|
||||
* @param {string} configFileName - The path and filename of the configuration file to validate.
|
||||
*/
|
||||
function validateModulePositions (configFileName) {
|
||||
Log.info("Checking modules structure configuration ...");
|
||||
Log.info("[checkconfig] Checking modules structure configuration ...");
|
||||
|
||||
const positionList = Utils.getModulePositions();
|
||||
|
||||
@@ -118,7 +118,7 @@ function validateModulePositions (configFileName) {
|
||||
|
||||
const valid = validate(data);
|
||||
if (valid) {
|
||||
Log.info(styleText("green", "Your modules structure configuration doesn't contain errors :)"));
|
||||
Log.info(styleText("green", "[checkconfig] Your modules structure configuration doesn't contain errors :)"));
|
||||
} else {
|
||||
const module = validate.errors[0].instancePath.split("/")[2];
|
||||
const position = validate.errors[0].instancePath.split("/")[3];
|
||||
@@ -130,13 +130,13 @@ function validateModulePositions (configFileName) {
|
||||
} else {
|
||||
errorMessage += validate.errors[0].message;
|
||||
}
|
||||
Log.error(errorMessage);
|
||||
Log.error("[checkconfig]", errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
checkConfigFile();
|
||||
} catch (error) {
|
||||
Log.error(error.message);
|
||||
Log.error("[checkconfig]", error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ function createWindow () {
|
||||
try {
|
||||
electronSize = electron.screen.getPrimaryDisplay().workAreaSize;
|
||||
} catch {
|
||||
Log.warn("Could not get display size, using defaults ...");
|
||||
Log.warn("[electron] Could not get display size, using defaults ...");
|
||||
}
|
||||
|
||||
let electronSwitchesDefaults = ["autoplay-policy", "no-user-gesture-required"];
|
||||
@@ -196,7 +196,7 @@ app.on("activate", function () {
|
||||
* core.stop() is called by process.on("SIGINT"... in `app.js`
|
||||
*/
|
||||
app.on("before-quit", async (event) => {
|
||||
Log.log("Shutting down server...");
|
||||
Log.log("[electron] Shutting down server...");
|
||||
event.preventDefault();
|
||||
setTimeout(() => {
|
||||
process.exit(0);
|
||||
@@ -215,7 +215,7 @@ app.on("certificate-error", (event, webContents, url, error, certificate, callba
|
||||
|
||||
if (process.env.clientonly) {
|
||||
app.whenReady().then(() => {
|
||||
Log.log("Launching client viewer application.");
|
||||
Log.log("[electron] Launching client viewer application.");
|
||||
createWindow();
|
||||
});
|
||||
}
|
||||
@@ -228,7 +228,7 @@ if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].includes(co
|
||||
core.start().then((c) => {
|
||||
config = c;
|
||||
app.whenReady().then(() => {
|
||||
Log.log("Launching application.");
|
||||
Log.log("[electron] Launching application.");
|
||||
createWindow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -268,7 +268,6 @@ const MM = (function () {
|
||||
const hideModule = function (module, speed, callback, options = {}) {
|
||||
// set lockString if set in options.
|
||||
if (options.lockString) {
|
||||
// Log.log("Has lockstring: " + options.lockString);
|
||||
if (module.lockStrings.indexOf(options.lockString) === -1) {
|
||||
module.lockStrings.push(options.lockString);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ const Module = Class.extend({
|
||||
* Called when the module is instantiated.
|
||||
*/
|
||||
init () {
|
||||
//Log.log(this.defaults);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -145,9 +144,9 @@ const Module = Class.extend({
|
||||
*/
|
||||
notificationReceived (notification, payload, sender) {
|
||||
if (sender) {
|
||||
// Log.log(this.name + " received a module notification: " + notification + " from sender: " + sender.name);
|
||||
Log.debug(`${this.name} received a module notification: ${notification} from sender: ${sender.name}`);
|
||||
} else {
|
||||
// Log.log(this.name + " received a system notification: " + notification);
|
||||
Log.debug(`${this.name} received a system notification: ${notification}`);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -4,15 +4,15 @@ const Class = require("./class");
|
||||
|
||||
const NodeHelper = Class.extend({
|
||||
init () {
|
||||
Log.log("Initializing new module helper ...");
|
||||
Log.log("[nodehelper] Initializing new module helper ...");
|
||||
},
|
||||
|
||||
loaded () {
|
||||
Log.log(`Module helper loaded: ${this.name}`);
|
||||
Log.log(`[nodehelper] Module helper loaded: ${this.name}`);
|
||||
},
|
||||
|
||||
start () {
|
||||
Log.log(`Starting module helper: ${this.name}`);
|
||||
Log.log(`[nodehelper] Starting module helper: ${this.name}`);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -21,7 +21,7 @@ const NodeHelper = Class.extend({
|
||||
* gracefully exit the module.
|
||||
*/
|
||||
stop () {
|
||||
Log.log(`Stopping module helper: ${this.name}`);
|
||||
Log.log(`[nodehelper] Stopping module helper: ${this.name}`);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -30,7 +30,7 @@ const NodeHelper = Class.extend({
|
||||
* @param {object} payload The payload of the notification.
|
||||
*/
|
||||
socketNotificationReceived (notification, payload) {
|
||||
Log.log(`${this.name} received a socket notification: ${notification} - Payload: ${payload}`);
|
||||
Log.log(`[nodehelper] ${this.name} received a socket notification: ${notification} - Payload: ${payload}`);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -83,7 +83,7 @@ const NodeHelper = Class.extend({
|
||||
setSocketIO (io) {
|
||||
this.io = io;
|
||||
|
||||
Log.log(`Connecting socket for: ${this.name}`);
|
||||
Log.log(`[nodehelper] Connecting socket for: ${this.name}`);
|
||||
|
||||
io.of(this.name).on("connection", (socket) => {
|
||||
// register catch all.
|
||||
|
||||
@@ -20,7 +20,7 @@ const Translator = (function () {
|
||||
fileInfo = JSON.parse(xhr.responseText);
|
||||
} catch (exception) {
|
||||
// nothing here, but don't die
|
||||
Log.error(` loading json file =${file} failed`);
|
||||
Log.error(`[translator] loading json file =${file} failed`);
|
||||
}
|
||||
resolve(fileInfo);
|
||||
}
|
||||
@@ -67,22 +67,18 @@ const Translator = (function () {
|
||||
}
|
||||
|
||||
if (this.translations[module.name] && key in this.translations[module.name]) {
|
||||
// Log.log("Got translation for " + key + " from module translation: ");
|
||||
return createStringFromTemplate(this.translations[module.name][key], variables);
|
||||
}
|
||||
|
||||
if (key in this.coreTranslations) {
|
||||
// Log.log("Got translation for " + key + " from core translation.");
|
||||
return createStringFromTemplate(this.coreTranslations[key], variables);
|
||||
}
|
||||
|
||||
if (this.translationsFallback[module.name] && key in this.translationsFallback[module.name]) {
|
||||
// Log.log("Got translation for " + key + " from module translation fallback.");
|
||||
return createStringFromTemplate(this.translationsFallback[module.name][key], variables);
|
||||
}
|
||||
|
||||
if (key in this.coreTranslationsFallback) {
|
||||
// Log.log("Got translation for " + key + " from core translation fallback.");
|
||||
return createStringFromTemplate(this.coreTranslationsFallback[key], variables);
|
||||
}
|
||||
|
||||
@@ -96,7 +92,7 @@ const Translator = (function () {
|
||||
* @param {boolean} isFallback Flag to indicate fallback translations.
|
||||
*/
|
||||
async load (module, file, isFallback) {
|
||||
Log.log(`${module.name} - Load translation${isFallback ? " fallback" : ""}: ${file}`);
|
||||
Log.log(`[translator] ${module.name} - Load translation${isFallback ? " fallback" : ""}: ${file}`);
|
||||
|
||||
if (this.translationsFallback[module.name]) {
|
||||
return;
|
||||
@@ -113,10 +109,10 @@ const Translator = (function () {
|
||||
*/
|
||||
async loadCoreTranslations (lang) {
|
||||
if (lang in translations) {
|
||||
Log.log(`Loading core translation file: ${translations[lang]}`);
|
||||
Log.log(`[translator] Loading core translation file: ${translations[lang]}`);
|
||||
this.coreTranslations = await loadJSON(translations[lang]);
|
||||
} else {
|
||||
Log.log("Configured language not found in core translations.");
|
||||
Log.log("[translator] Configured language not found in core translations.");
|
||||
}
|
||||
|
||||
await this.loadCoreTranslationsFallback();
|
||||
@@ -129,7 +125,7 @@ const Translator = (function () {
|
||||
async loadCoreTranslationsFallback () {
|
||||
let first = Object.keys(translations)[0];
|
||||
if (first) {
|
||||
Log.log(`Loading core translation fallback file: ${translations[first]}`);
|
||||
Log.log(`[translator] Loading core translation fallback file: ${translations[first]}`);
|
||||
this.coreTranslationsFallback = await loadJSON(translations[first]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ Module.register("alert", {
|
||||
return new Promise((resolve) => {
|
||||
this.nunjucksEnvironment().render(this.getTemplate(type), data, function (err, res) {
|
||||
if (err) {
|
||||
Log.error("Failed to render alert", err);
|
||||
Log.error("[alert] Failed to render alert", err);
|
||||
}
|
||||
|
||||
resolve(res);
|
||||
|
||||
@@ -96,12 +96,12 @@ Module.register("calendar", {
|
||||
Log.info(`Starting module: ${this.name}`);
|
||||
|
||||
if (this.config.colored) {
|
||||
Log.warn("Your are using the deprecated config values 'colored'. Please switch to 'coloredSymbol' & 'coloredText'!");
|
||||
Log.warn("[calendar] Your are using the deprecated config values 'colored'. Please switch to 'coloredSymbol' & 'coloredText'!");
|
||||
this.config.coloredText = true;
|
||||
this.config.coloredSymbol = true;
|
||||
}
|
||||
if (this.config.coloredSymbolOnly) {
|
||||
Log.warn("Your are using the deprecated config values 'coloredSymbolOnly'. Please switch to 'coloredSymbol' & 'coloredText'!");
|
||||
Log.warn("[calendar] Your are using the deprecated config values 'coloredSymbolOnly'. Please switch to 'coloredSymbol' & 'coloredText'!");
|
||||
this.config.coloredText = false;
|
||||
this.config.coloredSymbol = true;
|
||||
}
|
||||
@@ -143,7 +143,7 @@ Module.register("calendar", {
|
||||
|
||||
// we check user and password here for backwards compatibility with old configs
|
||||
if (calendar.user && calendar.pass) {
|
||||
Log.warn("Deprecation warning: Please update your calendar authentication configuration.");
|
||||
Log.warn("[calendar] Deprecation warning: Please update your calendar authentication configuration.");
|
||||
Log.warn("https://docs.magicmirror.builders/modules/calendar.html#configuration-options");
|
||||
calendar.auth = {
|
||||
user: calendar.user,
|
||||
@@ -160,7 +160,7 @@ Module.register("calendar", {
|
||||
|
||||
// for backward compatibility titleReplace
|
||||
if (typeof this.config.titleReplace !== "undefined") {
|
||||
Log.warn("Deprecation warning: Please consider upgrading your calendar titleReplace configuration to customEvents.");
|
||||
Log.warn("[calendar] Deprecation warning: Please consider upgrading your calendar titleReplace configuration to customEvents.");
|
||||
for (const [titlesearchstr, titlereplacestr] of Object.entries(this.config.titleReplace)) {
|
||||
this.config.customEvents.push({ keyword: ".*", transform: { search: titlesearchstr, replace: titlereplacestr } });
|
||||
}
|
||||
@@ -201,7 +201,7 @@ Module.register("calendar", {
|
||||
// set this calendar as displayed
|
||||
this.calendarDisplayer[payload.url] = true;
|
||||
} else {
|
||||
Log.debug("[Calendar] DOM not updated waiting self update()");
|
||||
Log.debug("[calendar] DOM not updated waiting self update()");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -461,10 +461,10 @@ Module.register("calendar", {
|
||||
if (eventStartDateMoment.isSameOrAfter(now) || (event.fullDayEvent && eventEndDateMoment.diff(now, "days") === 0)) {
|
||||
// Use relative time
|
||||
if (!this.config.hideTime && !event.fullDayEvent) {
|
||||
Log.debug("event not hidden and not fullday");
|
||||
Log.debug("[calendar] event not hidden and not fullday");
|
||||
timeWrapper.innerHTML = `${CalendarUtils.capFirst(eventStartDateMoment.calendar(null, { sameElse: this.config.dateFormat }))}`;
|
||||
} else {
|
||||
Log.debug("event full day or hidden");
|
||||
Log.debug("[calendar] event full day or hidden");
|
||||
timeWrapper.innerHTML = `${CalendarUtils.capFirst(
|
||||
eventStartDateMoment.calendar(null, {
|
||||
sameDay: this.config.showTimeToday ? "LT" : `[${this.translate("TODAY")}]`,
|
||||
@@ -491,9 +491,9 @@ Module.register("calendar", {
|
||||
timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("DAYAFTERTOMORROW"));
|
||||
}
|
||||
}
|
||||
Log.info("event fullday");
|
||||
Log.info("[calendar] event fullday");
|
||||
} else if (eventStartDateMoment.diff(now, "h") < this.config.getRelative) {
|
||||
Log.info("not full day but within getrelative size");
|
||||
Log.info("[calendar] not full day but within getrelative size");
|
||||
// If event is within getRelative hours, display 'in xxx' time format or moment.fromNow()
|
||||
timeWrapper.innerHTML = `${CalendarUtils.capFirst(eventStartDateMoment.fromNow())}`;
|
||||
}
|
||||
@@ -680,14 +680,14 @@ Module.register("calendar", {
|
||||
by_url_calevents.sort(function (a, b) {
|
||||
return a.startDate - b.startDate;
|
||||
});
|
||||
Log.debug(`pushing ${by_url_calevents.length} events to total with room for ${remainingEntries}`);
|
||||
Log.debug(`[calendar] pushing ${by_url_calevents.length} events to total with room for ${remainingEntries}`);
|
||||
events = events.concat(by_url_calevents.slice(0, remainingEntries));
|
||||
Log.debug(`events for calendar=${events.length}`);
|
||||
Log.debug(`[calendar] events for calendar=${events.length}`);
|
||||
} else {
|
||||
events = events.concat(by_url_calevents);
|
||||
}
|
||||
}
|
||||
Log.info(`sorting events count=${events.length}`);
|
||||
Log.info(`[calendar] sorting events count=${events.length}`);
|
||||
events.sort(function (a, b) {
|
||||
return a.startDate - b.startDate;
|
||||
});
|
||||
@@ -721,7 +721,7 @@ Module.register("calendar", {
|
||||
}
|
||||
events = newEvents;
|
||||
}
|
||||
Log.info(`slicing events total maxcount=${this.config.maximumEntries}`);
|
||||
Log.info(`[calendar] slicing events total maxcount=${this.config.maximumEntries}`);
|
||||
return events.slice(0, this.config.maximumEntries);
|
||||
},
|
||||
|
||||
@@ -936,7 +936,7 @@ Module.register("calendar", {
|
||||
setTimeout(
|
||||
() => {
|
||||
setInterval(() => {
|
||||
Log.debug("[Calendar] self update");
|
||||
Log.debug("[calendar] self update");
|
||||
if (this.config.updateOnFetch) {
|
||||
this.updateDom(1);
|
||||
} else {
|
||||
|
||||
@@ -57,7 +57,7 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn
|
||||
|
||||
try {
|
||||
data = ical.parseICS(responseData);
|
||||
Log.debug(`parsed data=${JSON.stringify(data, null, 2)}`);
|
||||
Log.debug(`[calendar] parsed data=${JSON.stringify(data, null, 2)}`);
|
||||
events = CalendarFetcherUtils.filterEvents(data, {
|
||||
excludedEvents,
|
||||
includePastEvents,
|
||||
@@ -91,7 +91,7 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn
|
||||
* Broadcast the existing events.
|
||||
*/
|
||||
this.broadcastEvents = function () {
|
||||
Log.info(`Calendar-Fetcher: Broadcasting ${events.length} events from ${url}.`);
|
||||
Log.info(`[calendar] Fetcher: Broadcasting ${events.length} events from ${url}.`);
|
||||
eventsReceivedCallback(this);
|
||||
};
|
||||
|
||||
|
||||
@@ -95,27 +95,26 @@ const CalendarFetcherUtils = {
|
||||
const oneDayInMs = 24 * 60 * 60000;
|
||||
let searchFromDate = pastLocalMoment.clone().subtract(Math.max(durationInMs, oneDayInMs), "milliseconds").toDate();
|
||||
let searchToDate = futureLocalMoment.clone().add(1, "days").toDate();
|
||||
Log.debug(`Search for recurring events between: ${searchFromDate} and ${searchToDate}`);
|
||||
Log.debug(`[calendar] Search for recurring events between: ${searchFromDate} and ${searchToDate}`);
|
||||
|
||||
// if until is set, and its a full day event, force the time to midnight. rrule gets confused with non-00 offset
|
||||
// looks like MS Outlook sets the until time incorrectly for fullday events
|
||||
if ((rule.options.until !== undefined) && CalendarFetcherUtils.isFullDayEvent(event)) {
|
||||
Log.debug("fixup rrule until");
|
||||
Log.debug("[calendar] fixup rrule until");
|
||||
rule.options.until = moment(rule.options.until).clone().startOf("day").add(1, "day")
|
||||
.toDate();
|
||||
}
|
||||
|
||||
Log.debug("fix rrule start=", rule.options.dtstart);
|
||||
Log.debug("event before rrule.between=", JSON.stringify(event, null, 2), "exdates=", event.exdate);
|
||||
|
||||
Log.debug(`RRule: ${rule.toString()}`);
|
||||
Log.debug("[calendar] fix rrule start=", rule.options.dtstart);
|
||||
Log.debug("[calendar] event before rrule.between=", JSON.stringify(event, null, 2), "exdates=", event.exdate);
|
||||
Log.debug(`[calendar] RRule: ${rule.toString()}`);
|
||||
rule.options.tzid = null; // RRule gets *very* confused with timezones
|
||||
|
||||
let dates = rule.between(searchFromDate, searchToDate, true, () => {
|
||||
return true;
|
||||
});
|
||||
|
||||
Log.debug(`Title: ${event.summary}, with dates: \n\n${JSON.stringify(dates)}\n`);
|
||||
Log.debug(`[calendar] Title: ${event.summary}, with dates: \n\n${JSON.stringify(dates)}\n`);
|
||||
|
||||
// shouldn't need this anymore, as RRULE not passed junk
|
||||
dates = dates.filter((d) => {
|
||||
@@ -141,7 +140,7 @@ const CalendarFetcherUtils = {
|
||||
return CalendarFetcherUtils.isFullDayEvent(event) ? startMoment.startOf("day") : startMoment;
|
||||
};
|
||||
|
||||
Log.debug(`There are ${Object.entries(data).length} calendar entries.`);
|
||||
Log.debug(`[calendar] There are ${Object.entries(data).length} calendar entries.`);
|
||||
|
||||
const now = moment();
|
||||
const pastLocalMoment = config.includePastEvents ? now.clone().startOf("day").subtract(config.maximumNumberOfDays, "days") : now;
|
||||
@@ -154,10 +153,10 @@ const CalendarFetcherUtils = {
|
||||
.subtract(1, "seconds");
|
||||
|
||||
Object.entries(data).forEach(([key, event]) => {
|
||||
Log.debug("Processing entry...");
|
||||
Log.debug("[calendar] Processing entry...");
|
||||
|
||||
const title = CalendarFetcherUtils.getTitleFromEvent(event);
|
||||
Log.debug(`title: ${title}`);
|
||||
Log.debug(`[calendar] title: ${title}`);
|
||||
|
||||
// Return quickly if event should be excluded.
|
||||
let { excluded, eventFilterUntil } = this.shouldEventBeExcluded(config, title);
|
||||
@@ -175,7 +174,7 @@ const CalendarFetcherUtils = {
|
||||
}
|
||||
|
||||
if (event.type === "VEVENT") {
|
||||
Log.debug(`Event:\n${JSON.stringify(event, null, 2)}`);
|
||||
Log.debug(`[calendar] Event:\n${JSON.stringify(event, null, 2)}`);
|
||||
let eventStartMoment = eventDate(event, "start");
|
||||
let eventEndMoment;
|
||||
|
||||
@@ -192,12 +191,12 @@ const CalendarFetcherUtils = {
|
||||
}
|
||||
}
|
||||
|
||||
Log.debug(`start: ${eventStartMoment.toDate()}`);
|
||||
Log.debug(`end:: ${eventEndMoment.toDate()}`);
|
||||
Log.debug(`[calendar] start: ${eventStartMoment.toDate()}`);
|
||||
Log.debug(`[calendar] end: ${eventEndMoment.toDate()}`);
|
||||
|
||||
// Calculate the duration of the event for use with recurring events.
|
||||
const durationMs = eventEndMoment.valueOf() - eventStartMoment.valueOf();
|
||||
Log.debug(`duration: ${durationMs}`);
|
||||
Log.debug(`[calendar] duration: ${durationMs}`);
|
||||
|
||||
const location = event.location || false;
|
||||
const geo = event.geo || false;
|
||||
@@ -218,12 +217,12 @@ const CalendarFetcherUtils = {
|
||||
|
||||
let dateKey = recurringEventStartMoment.tz("UTC").format("YYYY-MM-DD");
|
||||
|
||||
Log.debug("event date dateKey=", dateKey);
|
||||
Log.debug("[calendar] event date dateKey=", dateKey);
|
||||
// For each date that we're checking, it's possible that there is a recurrence override for that one day.
|
||||
if (curEvent.recurrences !== undefined) {
|
||||
Log.debug("have recurrences=", curEvent.recurrences);
|
||||
Log.debug("[calendar] have recurrences=", curEvent.recurrences);
|
||||
if (curEvent.recurrences[dateKey] !== undefined) {
|
||||
Log.debug("have a recurrence match for dateKey=", dateKey);
|
||||
Log.debug("[calendar] have a recurrence match for dateKey=", dateKey);
|
||||
// We found an override, so for this recurrence, use a potentially different title, start date, and duration.
|
||||
curEvent = curEvent.recurrences[dateKey];
|
||||
// Some event start/end dates don't have timezones
|
||||
@@ -238,12 +237,12 @@ const CalendarFetcherUtils = {
|
||||
recurringEventEndMoment = moment(curEvent.end).tz(CalendarFetcherUtils.getLocalTimezone());
|
||||
}
|
||||
} else {
|
||||
Log.debug("recurrence key ", dateKey, " doesn't match");
|
||||
Log.debug("[calendar] recurrence key ", dateKey, " doesn't match");
|
||||
}
|
||||
}
|
||||
// If there's no recurrence override, check for an exception date. Exception dates represent exceptions to the rule.
|
||||
if (curEvent.exdate !== undefined) {
|
||||
Log.debug("have datekey=", dateKey, " exdates=", curEvent.exdate);
|
||||
Log.debug("[calendar] have datekey=", dateKey, " exdates=", curEvent.exdate);
|
||||
if (curEvent.exdate[dateKey] !== undefined) {
|
||||
// This date is an exception date, which means we should skip it in the recurrence pattern.
|
||||
showRecurrence = false;
|
||||
@@ -267,7 +266,7 @@ const CalendarFetcherUtils = {
|
||||
}
|
||||
|
||||
if (showRecurrence === true) {
|
||||
Log.debug(`saving event: ${recurrenceTitle}`);
|
||||
Log.debug(`[calendar] saving event: ${recurrenceTitle}`);
|
||||
newEvents.push({
|
||||
title: recurrenceTitle,
|
||||
startDate: recurringEventStartMoment.format("x"),
|
||||
@@ -281,15 +280,13 @@ const CalendarFetcherUtils = {
|
||||
description: description
|
||||
});
|
||||
} else {
|
||||
Log.debug("not saving event ", recurrenceTitle, eventStartMoment);
|
||||
Log.debug("[calendar] not saving event ", recurrenceTitle, eventStartMoment);
|
||||
}
|
||||
Log.debug(" ");
|
||||
}
|
||||
// End recurring event parsing.
|
||||
} else {
|
||||
// Single event.
|
||||
const fullDayEvent = isFacebookBirthday ? true : CalendarFetcherUtils.isFullDayEvent(event);
|
||||
// Log.debug("full day event")
|
||||
|
||||
// if the start and end are the same, then make end the 'end of day' value (start is at 00:00:00)
|
||||
if (fullDayEvent && eventStartMoment.valueOf() === eventEndMoment.valueOf()) {
|
||||
|
||||
@@ -21,22 +21,20 @@ const auth = {
|
||||
pass: pass
|
||||
};
|
||||
|
||||
Log.log("Create fetcher ...");
|
||||
Log.log("[calendar] Create fetcher ...");
|
||||
|
||||
const fetcher = new CalendarFetcher(url, fetchInterval, [], maximumEntries, maximumNumberOfDays, auth);
|
||||
|
||||
fetcher.onReceive(function (fetcher) {
|
||||
Log.log(fetcher.events());
|
||||
Log.log("------------------------------------------------------------");
|
||||
Log.log("[calendar] ", fetcher.events());
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
fetcher.onError(function (fetcher, error) {
|
||||
Log.log("Fetcher error:");
|
||||
Log.log(error);
|
||||
Log.log("[calendar] Fetcher error:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
fetcher.startFetch();
|
||||
|
||||
Log.log("Create fetcher done! ");
|
||||
Log.log("[calendar] Create fetcher done! ");
|
||||
|
||||
@@ -5,7 +5,7 @@ const CalendarFetcher = require("./calendarfetcher");
|
||||
module.exports = NodeHelper.create({
|
||||
// Override start method.
|
||||
start () {
|
||||
Log.log(`Starting node helper for: ${this.name}`);
|
||||
Log.log(`[calendar] Starting node helper for: ${this.name}`);
|
||||
this.fetchers = [];
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@ module.exports = NodeHelper.create({
|
||||
} else if (notification === "FETCH_CALENDAR") {
|
||||
const key = payload.id + payload.url;
|
||||
if (typeof this.fetchers[key] === "undefined") {
|
||||
Log.error("Calendar Error. No fetcher exists with key: ", key);
|
||||
Log.error("[calendar] No fetcher exists with key: ", key);
|
||||
this.sendSocketNotification("CALENDAR_ERROR", { error_type: "MODULE_ERROR_UNSPECIFIED" });
|
||||
return;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ module.exports = NodeHelper.create({
|
||||
try {
|
||||
new URL(url);
|
||||
} catch (error) {
|
||||
Log.error("Calendar Error. Malformed calendar url: ", url, error);
|
||||
Log.error("[calendar] Malformed calendar url: ", url, error);
|
||||
this.sendSocketNotification("CALENDAR_ERROR", { error_type: "MODULE_ERROR_MALFORMED_URL" });
|
||||
return;
|
||||
}
|
||||
@@ -50,10 +50,10 @@ module.exports = NodeHelper.create({
|
||||
let fetchIntervalCorrected;
|
||||
if (typeof this.fetchers[identifier + url] === "undefined") {
|
||||
if (fetchInterval < 60000) {
|
||||
Log.warn(`fetchInterval for url ${url} must be >= 60000`);
|
||||
Log.warn(`[calendar] fetchInterval for url ${url} must be >= 60000`);
|
||||
fetchIntervalCorrected = 60000;
|
||||
}
|
||||
Log.log(`Create new calendarfetcher for url: ${url} - Interval: ${fetchIntervalCorrected || fetchInterval}`);
|
||||
Log.log(`[calendar] Create new calendarfetcher for url: ${url} - Interval: ${fetchIntervalCorrected || fetchInterval}`);
|
||||
fetcher = new CalendarFetcher(url, fetchIntervalCorrected || fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, broadcastPastEvents, selfSignedCert);
|
||||
|
||||
fetcher.onReceive((fetcher) => {
|
||||
@@ -61,7 +61,7 @@ module.exports = NodeHelper.create({
|
||||
});
|
||||
|
||||
fetcher.onError((fetcher, error) => {
|
||||
Log.error("Calendar Error. Could not fetch calendar: ", fetcher.url(), error);
|
||||
Log.error("[calendar] Calendar Error. Could not fetch calendar: ", fetcher.url(), error);
|
||||
let error_type = NodeHelper.checkFetchError(error);
|
||||
this.sendSocketNotification("CALENDAR_ERROR", {
|
||||
id: identifier,
|
||||
@@ -71,7 +71,7 @@ module.exports = NodeHelper.create({
|
||||
|
||||
this.fetchers[identifier + url] = fetcher;
|
||||
} else {
|
||||
Log.log(`Use existing calendarfetcher for url: ${url}`);
|
||||
Log.log(`[calendar] Use existing calendarfetcher for url: ${url}`);
|
||||
fetcher = this.fetchers[identifier + url];
|
||||
fetcher.broadcastEvents();
|
||||
}
|
||||
|
||||
@@ -53,12 +53,12 @@ Module.register("compliments", {
|
||||
this.compliments_new = JSON.parse(response);
|
||||
}
|
||||
else {
|
||||
Log.error(`${this.name} remoteFile refresh failed`);
|
||||
Log.error(`[compliments] ${this.name} remoteFile refresh failed`);
|
||||
}
|
||||
},
|
||||
this.config.remoteFileRefreshInterval);
|
||||
} else {
|
||||
Log.error(`${this.name} remoteFileRefreshInterval less than minimum`);
|
||||
Log.error(`[compliments] ${this.name} remoteFileRefreshInterval less than minimum`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,7 +183,7 @@ Module.register("compliments", {
|
||||
// if so, use its notice entries
|
||||
Array.prototype.push.apply(date_compliments, this.config.compliments[entry]);
|
||||
}
|
||||
} else Log.error(`compliments cron syntax invalid=${JSON.stringify(entry)}`);
|
||||
} else Log.error(`[compliments] cron syntax invalid=${JSON.stringify(entry)}`);
|
||||
} else if (new RegExp(entry).test(date)) {
|
||||
Array.prototype.push.apply(date_compliments, this.config.compliments[entry]);
|
||||
}
|
||||
@@ -220,7 +220,7 @@ Module.register("compliments", {
|
||||
const response = await fetch(url + this.urlSuffix);
|
||||
return await response.text();
|
||||
} catch (error) {
|
||||
Log.info(`${this.name} fetch failed error=`, error);
|
||||
Log.info(`[compliments] ${this.name} fetch failed error=`, error);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -375,7 +375,7 @@ Module.register("newsfeed", {
|
||||
this.activeItem = 0;
|
||||
}
|
||||
this.resetDescrOrFullArticleAndTimer();
|
||||
Log.debug(`${this.name} - going from article #${before} to #${this.activeItem} (of ${this.newsItems.length})`);
|
||||
Log.debug(`[newsfeed] going from article #${before} to #${this.activeItem} (of ${this.newsItems.length})`);
|
||||
this.updateDom(100);
|
||||
} else if (notification === "ARTICLE_PREVIOUS") {
|
||||
this.activeItem--;
|
||||
@@ -383,7 +383,7 @@ Module.register("newsfeed", {
|
||||
this.activeItem = this.newsItems.length - 1;
|
||||
}
|
||||
this.resetDescrOrFullArticleAndTimer();
|
||||
Log.debug(`${this.name} - going from article #${before} to #${this.activeItem} (of ${this.newsItems.length})`);
|
||||
Log.debug(`[newsfeed] going from article #${before} to #${this.activeItem} (of ${this.newsItems.length})`);
|
||||
this.updateDom(100);
|
||||
}
|
||||
// if "more details" is received the first time: show article summary, on second time show full article
|
||||
@@ -392,8 +392,8 @@ Module.register("newsfeed", {
|
||||
if (this.config.showFullArticle === true) {
|
||||
this.scrollPosition += this.config.scrollLength;
|
||||
window.scrollTo(0, this.scrollPosition);
|
||||
Log.debug(`${this.name} - scrolling down`);
|
||||
Log.debug(`${this.name} - ARTICLE_MORE_DETAILS, scroll position: ${this.config.scrollLength}`);
|
||||
Log.debug("[newsfeed] scrolling down");
|
||||
Log.debug(`[newsfeed] ARTICLE_MORE_DETAILS, scroll position: ${this.config.scrollLength}`);
|
||||
} else {
|
||||
this.showFullArticle();
|
||||
}
|
||||
@@ -401,12 +401,12 @@ Module.register("newsfeed", {
|
||||
if (this.config.showFullArticle === true) {
|
||||
this.scrollPosition -= this.config.scrollLength;
|
||||
window.scrollTo(0, this.scrollPosition);
|
||||
Log.debug(`${this.name} - scrolling up`);
|
||||
Log.debug(`${this.name} - ARTICLE_SCROLL_UP, scroll position: ${this.config.scrollLength}`);
|
||||
Log.debug("[newsfeed] scrolling up");
|
||||
Log.debug(`[newsfeed] ARTICLE_SCROLL_UP, scroll position: ${this.config.scrollLength}`);
|
||||
}
|
||||
} else if (notification === "ARTICLE_LESS_DETAILS") {
|
||||
this.resetDescrOrFullArticleAndTimer();
|
||||
Log.debug(`${this.name} - showing only article titles again`);
|
||||
Log.debug("[newsfeed] showing only article titles again");
|
||||
this.updateDom(100);
|
||||
} else if (notification === "ARTICLE_TOGGLE_FULL") {
|
||||
if (this.config.showFullArticle) {
|
||||
@@ -435,7 +435,7 @@ Module.register("newsfeed", {
|
||||
}
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
Log.debug(`${this.name} - showing ${this.isShowingDescription ? "article description" : "full article"}`);
|
||||
Log.debug(`[newsfeed] showing ${this.isShowingDescription ? "article description" : "full article"}`);
|
||||
this.updateDom(100);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -67,11 +67,10 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings
|
||||
hash: crypto.createHash("sha256").update(`${pubdate} :: ${title} :: ${url}`).digest("hex")
|
||||
});
|
||||
} else if (logFeedWarnings) {
|
||||
Log.warn("Can't parse feed item:");
|
||||
Log.warn(item);
|
||||
Log.warn(`Title: ${title}`);
|
||||
Log.warn(`Description: ${description}`);
|
||||
Log.warn(`Pubdate: ${pubdate}`);
|
||||
Log.warn("[newsfeed] Can't parse feed item:", item);
|
||||
Log.warn(`[newsfeed] Title: ${title}`);
|
||||
Log.warn(`[newsfeed] Description: ${description}`);
|
||||
Log.warn(`[newsfeed] Pubdate: ${pubdate}`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -95,10 +94,10 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings
|
||||
const ttlms = Math.min(minutes * 60 * 1000, 86400000);
|
||||
if (ttlms > reloadIntervalMS) {
|
||||
reloadIntervalMS = ttlms;
|
||||
Log.info(`Newsfeed-Fetcher: reloadInterval set to ttl=${reloadIntervalMS} for url ${url}`);
|
||||
Log.info(`[newsfeed] reloadInterval set to ttl=${reloadIntervalMS} for url ${url}`);
|
||||
}
|
||||
} catch (error) {
|
||||
Log.warn(`Newsfeed-Fetcher: feed ttl is no valid integer=${minutes} for url ${url}`);
|
||||
Log.warn(`[newsfeed] feed ttl is no valid integer=${minutes} for url ${url}`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -149,10 +148,10 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings
|
||||
*/
|
||||
this.broadcastItems = function () {
|
||||
if (items.length <= 0) {
|
||||
Log.info("Newsfeed-Fetcher: No items to broadcast yet.");
|
||||
Log.info("[newsfeed] No items to broadcast yet.");
|
||||
return;
|
||||
}
|
||||
Log.info(`Newsfeed-Fetcher: Broadcasting ${items.length} items.`);
|
||||
Log.info(`[newsfeed] Broadcasting ${items.length} items.`);
|
||||
itemsReceivedCallback(this);
|
||||
};
|
||||
|
||||
|
||||
@@ -32,14 +32,14 @@ module.exports = NodeHelper.create({
|
||||
try {
|
||||
new URL(url);
|
||||
} catch (error) {
|
||||
Log.error("Newsfeed Error. Malformed newsfeed url: ", url, error);
|
||||
Log.error("[newsfeed] Error: Malformed newsfeed url: ", url, error);
|
||||
this.sendSocketNotification("NEWSFEED_ERROR", { error_type: "MODULE_ERROR_MALFORMED_URL" });
|
||||
return;
|
||||
}
|
||||
|
||||
let fetcher;
|
||||
if (typeof this.fetchers[url] === "undefined") {
|
||||
Log.log(`Create new newsfetcher for url: ${url} - Interval: ${reloadInterval}`);
|
||||
Log.log(`[newsfeed] Create new newsfetcher for url: ${url} - Interval: ${reloadInterval}`);
|
||||
fetcher = new NewsfeedFetcher(url, reloadInterval, encoding, config.logFeedWarnings, useCorsProxy);
|
||||
|
||||
fetcher.onReceive(() => {
|
||||
@@ -47,7 +47,7 @@ module.exports = NodeHelper.create({
|
||||
});
|
||||
|
||||
fetcher.onError((fetcher, error) => {
|
||||
Log.error("Newsfeed Error. Could not fetch newsfeed: ", url, error);
|
||||
Log.error("[newsfeed] Error: Could not fetch newsfeed: ", url, error);
|
||||
let error_type = NodeHelper.checkFetchError(error);
|
||||
this.sendSocketNotification("NEWSFEED_ERROR", {
|
||||
error_type
|
||||
@@ -56,7 +56,7 @@ module.exports = NodeHelper.create({
|
||||
|
||||
this.fetchers[url] = fetcher;
|
||||
} else {
|
||||
Log.log(`Use existing newsfetcher for url: ${url}`);
|
||||
Log.log(`[newsfeed] Use existing newsfetcher for url: ${url}`);
|
||||
fetcher = this.fetchers[url];
|
||||
fetcher.setReloadInterval(reloadInterval);
|
||||
fetcher.broadcastItems();
|
||||
|
||||
@@ -24,7 +24,7 @@ class GitHelper {
|
||||
const { stderr } = await this.execShell(`cd ${moduleFolder} && git remote -v`);
|
||||
|
||||
if (stderr) {
|
||||
Log.error(`Failed to fetch git data for ${moduleFolder}: ${stderr}`);
|
||||
Log.error(`[updatenotification] Failed to fetch git data for ${moduleFolder}: ${stderr}`);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class GitHelper {
|
||||
}
|
||||
|
||||
try {
|
||||
Log.info(`Checking git for module: ${moduleName}`);
|
||||
Log.info(`[updatenotification] Checking git for module: ${moduleName}`);
|
||||
// Throws error if file doesn't exist
|
||||
fs.statSync(path.join(moduleFolder, ".git"));
|
||||
|
||||
@@ -72,7 +72,7 @@ class GitHelper {
|
||||
const { stderr, stdout } = await this.execShell(`cd ${repo.folder} && git rev-parse HEAD`);
|
||||
|
||||
if (stderr) {
|
||||
Log.error(`Failed to get current commit hash for ${repo.module}: ${stderr}`);
|
||||
Log.error(`[updatenotification] Failed to get current commit hash for ${repo.module}: ${stderr}`);
|
||||
}
|
||||
|
||||
gitInfo.hash = stdout;
|
||||
@@ -81,7 +81,7 @@ class GitHelper {
|
||||
const { stderr, stdout } = await this.execShell(`cd ${repo.folder} && git status -sb`);
|
||||
|
||||
if (stderr) {
|
||||
Log.error(`Failed to get git status for ${repo.module}: ${stderr}`);
|
||||
Log.error(`[updatenotification] Failed to get git status for ${repo.module}: ${stderr}`);
|
||||
// exit without git status info
|
||||
return;
|
||||
}
|
||||
@@ -151,7 +151,7 @@ class GitHelper {
|
||||
const { stdout } = await this.execShell(`cd ${repo.folder} && git ls-remote -q --tags --refs`);
|
||||
tagList = stdout.trim();
|
||||
} catch (err) {
|
||||
Log.error(`Failed to get tag list for ${repo.module}: ${err}`);
|
||||
Log.error(`[updatenotification] Failed to get tag list for ${repo.module}: ${err}`);
|
||||
}
|
||||
// check if tag is between commits and only report behind > 0 if so
|
||||
try {
|
||||
@@ -162,13 +162,13 @@ class GitHelper {
|
||||
}
|
||||
if (cnt === 0) gitInfo.behind = 0;
|
||||
} catch (err) {
|
||||
Log.error(`Failed to get git revisions for ${repo.module}: ${err}`);
|
||||
Log.error(`[updatenotification] Failed to get git revisions for ${repo.module}: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
return gitInfo;
|
||||
} catch (err) {
|
||||
Log.error(`Failed to get git revisions for ${repo.module}: ${err}`);
|
||||
Log.error(`[updatenotification] Failed to get git revisions for ${repo.module}: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ class GitHelper {
|
||||
this.gitResultList.push(gitInfo);
|
||||
}
|
||||
} catch (e) {
|
||||
Log.error(`Failed to retrieve repo info for ${repo.module}: ${e}`);
|
||||
Log.error(`[updatenotification] Failed to retrieve repo info for ${repo.module}: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ class GitHelper {
|
||||
const allRepos = await this.gitResultList.map((module) => {
|
||||
return new Promise((resolve) => {
|
||||
if (module.behind > 0 && module.module !== "MagicMirror") {
|
||||
Log.info(`Update found for module: ${module.module}`);
|
||||
Log.info(`[updatenotification] Update found for module: ${module.module}`);
|
||||
updates.push(module);
|
||||
}
|
||||
resolve(module);
|
||||
|
||||
@@ -51,7 +51,7 @@ class Updater {
|
||||
this.PM2Id = null; // pm2 process number
|
||||
this.version = global.version;
|
||||
this.root_path = global.root_path;
|
||||
Log.info("updatenotification: Updater Class Loaded!");
|
||||
Log.info("[updatenotification] Updater Class Loaded!");
|
||||
}
|
||||
|
||||
// [main command] parse if module update is needed
|
||||
@@ -81,7 +81,7 @@ class Updater {
|
||||
|
||||
await Promise.all(parser);
|
||||
let updater = Object.values(this.moduleList);
|
||||
Log.debug("updatenotification Update Result:", updater);
|
||||
Log.debug("[updatenotification] Update Result:", updater);
|
||||
return updater;
|
||||
}
|
||||
|
||||
@@ -107,24 +107,24 @@ class Updater {
|
||||
if (module.updateCommand) {
|
||||
Command = module.updateCommand;
|
||||
} else {
|
||||
Log.warn(`updatenotification: Update of ${module.name} is not supported.`);
|
||||
Log.warn(`[updatenotification] Update of ${module.name} is not supported.`);
|
||||
return Result;
|
||||
}
|
||||
Log.info(`updatenotification: Updating ${module.name}...`);
|
||||
Log.info(`[updatenotification] Updating ${module.name}...`);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
Exec(Command, { cwd: modulePath, timeout: this.timeout }, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
Log.error(`updatenotification: exec error: ${error}`);
|
||||
Log.error(`[updatenotification] exec error: ${error}`);
|
||||
Result.error = true;
|
||||
} else {
|
||||
Log.info(`updatenotification: Update logs of ${module.name}: ${stdout}`);
|
||||
Log.info(`[updatenotification]:Update logs of ${module.name}: ${stdout}`);
|
||||
Result.updated = true;
|
||||
if (this.autoRestart) {
|
||||
Log.info("updatenotification: Update done");
|
||||
Log.info("[updatenotification] Update done");
|
||||
setTimeout(() => this.restart(), 3000);
|
||||
} else {
|
||||
Log.info("updatenotification: Update done, don't forget to restart MagicMirror!");
|
||||
Log.info("[updatenotification] Update done, don't forget to restart MagicMirror!");
|
||||
Result.needRestart = true;
|
||||
}
|
||||
}
|
||||
@@ -139,20 +139,20 @@ class Updater {
|
||||
else this.nodeRestart();
|
||||
}
|
||||
|
||||
// restart MagicMiror with "pm2": use PM2Id for restart it
|
||||
// restart MagicMirror with "pm2": use PM2Id for restart it
|
||||
pm2Restart () {
|
||||
Log.info("updatenotification: PM2 will restarting MagicMirror...");
|
||||
Log.info("[updatenotification] [PM2] restarting MagicMirror...");
|
||||
const pm2 = require("pm2");
|
||||
pm2.restart(this.PM2Id, (err, proc) => {
|
||||
if (err) {
|
||||
Log.error("updatenotification:[PM2] restart Error", err);
|
||||
Log.error("[updatenotification] [PM2] restart Error", err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// restart MagicMiror with "node --run start"
|
||||
// restart MagicMirror with "node --run start"
|
||||
nodeRestart () {
|
||||
Log.info("updatenotification: Restarting MagicMirror...");
|
||||
Log.info("[updatenotification] Restarting MagicMirror...");
|
||||
const out = process.stdout;
|
||||
const err = process.stderr;
|
||||
const subprocess = Spawn("node --run start", { cwd: this.root_path, shell: true, detached: true, stdio: ["ignore", out, err] });
|
||||
@@ -162,49 +162,49 @@ class Updater {
|
||||
|
||||
// Check using pm2
|
||||
check_PM2_Process () {
|
||||
Log.info("updatenotification: Checking PM2 using...");
|
||||
Log.info("[updatenotification] Checking PM2 using...");
|
||||
return new Promise((resolve) => {
|
||||
if (fs.existsSync("/.dockerenv")) {
|
||||
Log.info("updatenotification: Running in docker container, not using PM2 ...");
|
||||
Log.info("[updatenotification] Running in docker container, not using PM2 ...");
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.env.unique_id === undefined) {
|
||||
Log.info("updatenotification: [PM2] You are not using pm2");
|
||||
Log.info("[updatenotification] [PM2] You are not using pm2");
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Log.debug(`updatenotification: [PM2] Search for pm2 id: ${process.env.pm_id} -- name: ${process.env.name} -- unique_id: ${process.env.unique_id}`);
|
||||
Log.debug(`[updatenotification] [PM2] Search for pm2 id: ${process.env.pm_id} -- name: ${process.env.name} -- unique_id: ${process.env.unique_id}`);
|
||||
|
||||
const pm2 = require("pm2");
|
||||
pm2.connect((err) => {
|
||||
if (err) {
|
||||
Log.error("updatenotification: [PM2]", err);
|
||||
Log.error("[updatenotification] [PM2]", err);
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
pm2.list((err, list) => {
|
||||
if (err) {
|
||||
Log.error("updatenotification: [PM2] Can't get process List!");
|
||||
Log.error("[updatenotification] [PM2] Can't get process List!");
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
list.forEach((pm) => {
|
||||
Log.debug(`updatenotification: [PM2] found pm2 process id: ${pm.pm_id} -- name: ${pm.name} -- unique_id: ${pm.pm2_env.unique_id}`);
|
||||
Log.debug(`[updatenotification] [PM2] found pm2 process id: ${pm.pm_id} -- name: ${pm.name} -- unique_id: ${pm.pm2_env.unique_id}`);
|
||||
if (pm.pm2_env.status === "online" && process.env.name === pm.name && +process.env.pm_id === +pm.pm_id && process.env.unique_id === pm.pm2_env.unique_id) {
|
||||
this.PM2Id = pm.pm_id;
|
||||
this.usePM2 = true;
|
||||
Log.info(`updatenotification: [PM2] You are using pm2 with id: ${this.PM2Id} (${pm.name})`);
|
||||
Log.info(`[updatenotification] [PM2] You are using pm2 with id: ${this.PM2Id} (${pm.name})`);
|
||||
resolve(true);
|
||||
} else {
|
||||
Log.debug(`updatenotification: [PM2] pm2 process id: ${pm.pm_id} don't match...`);
|
||||
Log.debug(`[updatenotification] [PM2] pm2 process id: ${pm.pm_id} don't match...`);
|
||||
}
|
||||
});
|
||||
pm2.disconnect();
|
||||
if (!this.usePM2) {
|
||||
Log.info("updatenotification: [PM2] You are not using pm2");
|
||||
Log.info("[updatenotification] [PM2] You are not using pm2");
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -60,7 +60,7 @@ WeatherProvider.register("envcanada", {
|
||||
* Called when the weather provider is started
|
||||
*/
|
||||
start () {
|
||||
Log.info(`Weather provider: ${this.providerName} started.`);
|
||||
Log.info(`[weatherprovider.envcanada] ${this.providerName} started.`);
|
||||
this.setFetchedLocation(this.config.location);
|
||||
},
|
||||
|
||||
@@ -103,13 +103,13 @@ WeatherProvider.register("envcanada", {
|
||||
fetchCommon (target) {
|
||||
const forecastURL = this.getUrl(); // Get the approriate URL for the MSC Datamart Index page
|
||||
|
||||
Log.debug(`[weather.envcanada] ${target} Index url: ${forecastURL}`);
|
||||
Log.debug(`[weatherprovider.envcanada] ${target} Index url: ${forecastURL}`);
|
||||
|
||||
this.fetchData(forecastURL, "xml") // Query the Index page URL
|
||||
.then((indexData) => {
|
||||
if (!indexData) {
|
||||
// Did not receive usable new data.
|
||||
Log.info(`weather.envcanada ${target} - did not receive usable index data`);
|
||||
Log.info(`[weatherprovider.envcanada] ${target} - did not receive usable index data`);
|
||||
this.updateAvailable(); // If there were issues, update anyways to reset timer
|
||||
return;
|
||||
}
|
||||
@@ -133,7 +133,7 @@ WeatherProvider.register("envcanada", {
|
||||
forecastFileURL = forecastURL + forecastFile; // Create full URL to the city's weather data
|
||||
}
|
||||
|
||||
Log.debug(`[weather.envcanada] ${target} Citypage url: ${forecastFileURL}`);
|
||||
Log.debug(`[weatherprovider.envcanada] ${target} Citypage url: ${forecastFileURL}`);
|
||||
|
||||
/*
|
||||
* If the Citypage filename has not changed since the last Weather refresh, the forecast has not changed and
|
||||
@@ -141,19 +141,19 @@ WeatherProvider.register("envcanada", {
|
||||
*/
|
||||
|
||||
if (target === "Current" && this.lastCityPageCurrent === forecastFileURL) {
|
||||
Log.debug(`[weather.envcanada] ${target} - Newest Citypage has already been seen - skipping!`);
|
||||
Log.debug(`[weatherprovider.envcanada] ${target} - Newest Citypage has already been seen - skipping!`);
|
||||
this.updateAvailable(); // Update anyways to reset refresh timer
|
||||
return;
|
||||
}
|
||||
|
||||
if (target === "Forecast" && this.lastCityPageForecast === forecastFileURL) {
|
||||
Log.debug(`[weather.envcanada] ${target} - Newest Citypage has already been seen - skipping!`);
|
||||
Log.debug(`[weatherprovider.envcanada] ${target} - Newest Citypage has already been seen - skipping!`);
|
||||
this.updateAvailable(); // Update anyways to reset refresh timer
|
||||
return;
|
||||
}
|
||||
|
||||
if (target === "Hourly" && this.lastCityPageHourly === forecastFileURL) {
|
||||
Log.debug(`[weather.envcanada] ${target} - Newest Citypage has already been seen - skipping!`);
|
||||
Log.debug(`[weatherprovider.envcanada] ${target} - Newest Citypage has already been seen - skipping!`);
|
||||
this.updateAvailable(); // Update anyways to reset refresh timer
|
||||
return;
|
||||
}
|
||||
@@ -162,7 +162,7 @@ WeatherProvider.register("envcanada", {
|
||||
.then((cityData) => {
|
||||
if (!cityData) {
|
||||
// Did not receive usable new data.
|
||||
Log.info(`weather.envcanada ${target} - did not receive usable citypage data`);
|
||||
Log.info(`[weatherprovider.envcanada] ${target} - did not receive usable citypage data`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ WeatherProvider.register("envcanada", {
|
||||
* With the city's weather data read, parse the resulting XML document for the appropriate weather data
|
||||
* elements to create a weather object. Next, set Weather modules details from that object.
|
||||
*/
|
||||
Log.debug(`[weather.envcanada] ${target} - Citypage has been read and will be processed for updates`);
|
||||
Log.debug(`[weatherprovider.envcanada] ${target} - Citypage has been read and will be processed for updates`);
|
||||
|
||||
if (target === "Current") {
|
||||
const currentWeather = this.generateWeatherObjectFromCurrentWeather(cityData);
|
||||
@@ -191,12 +191,12 @@ WeatherProvider.register("envcanada", {
|
||||
}
|
||||
})
|
||||
.catch(function (cityRequest) {
|
||||
Log.info(`weather.envcanada ${target} - could not load citypage data from: ${forecastFileURL}`);
|
||||
Log.info(`[weatherprovider.envcanada] ${target} - could not load citypage data from: ${forecastFileURL}`);
|
||||
})
|
||||
.finally(() => this.updateAvailable()); // Update no matter what to reset weather refresh timer
|
||||
})
|
||||
.catch(function (indexRequest) {
|
||||
Log.error(`weather.envcanada ${target} - could not load index data ... `, indexRequest);
|
||||
Log.error(`[weatherprovider.envcanada] ${target} - could not load index data ... `, indexRequest);
|
||||
this.updateAvailable(); // If there were issues, update anyways to reset timer
|
||||
});
|
||||
},
|
||||
|
||||
@@ -155,7 +155,7 @@ WeatherProvider.register("openmeteo", {
|
||||
this.setCurrentWeather(currentWeather);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.openmeteo] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -173,7 +173,7 @@ WeatherProvider.register("openmeteo", {
|
||||
this.setWeatherForecast(dailyForecast);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.openmeteo] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -191,7 +191,7 @@ WeatherProvider.register("openmeteo", {
|
||||
this.setWeatherHourly(hourlyForecast);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.openmeteo] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -217,7 +217,7 @@ WeatherProvider.register("openmeteo", {
|
||||
this.config.maxEntries = Math.max(1, Math.min(this.config.maxEntries, maxEntriesLimit));
|
||||
|
||||
if (!this.config.type) {
|
||||
Log.error("type not configured and could not resolve it");
|
||||
Log.error("[weatherprovider.openmeteo] type not configured and could not resolve it");
|
||||
}
|
||||
|
||||
this.fetchLocation();
|
||||
@@ -340,7 +340,7 @@ WeatherProvider.register("openmeteo", {
|
||||
this.fetchedLocationName = `${data.city}, ${data.principalSubdivisionCode}`;
|
||||
})
|
||||
.catch((request) => {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.openmeteo] Could not load data ... ", request);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ WeatherProvider.register("openweathermap", {
|
||||
this.setCurrentWeather(currentWeather);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.openweathermap] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -64,7 +64,7 @@ WeatherProvider.register("openweathermap", {
|
||||
this.setFetchedLocation(location);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.openweathermap] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -88,7 +88,7 @@ WeatherProvider.register("openweathermap", {
|
||||
this.setWeatherHourly(weatherData.hours);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.openweathermap] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
|
||||
@@ -34,7 +34,7 @@ WeatherProvider.register("pirateweather", {
|
||||
this.setCurrentWeather(currentWeather);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.pirateweather] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -51,7 +51,7 @@ WeatherProvider.register("pirateweather", {
|
||||
this.setWeatherForecast(forecast);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.pirateweather] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
|
||||
@@ -28,7 +28,7 @@ WeatherProvider.register("smhi", {
|
||||
this.setFetchedLocation(this.config.location || `(${coordinates.lat},${coordinates.lon})`);
|
||||
this.setCurrentWeather(weatherObject);
|
||||
})
|
||||
.catch((error) => Log.error(`Could not load data: ${error.message}`))
|
||||
.catch((error) => Log.error(`[weatherprovider.smhi] Could not load data: ${error.message}`))
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
|
||||
@@ -43,7 +43,7 @@ WeatherProvider.register("smhi", {
|
||||
this.setFetchedLocation(this.config.location || `(${coordinates.lat},${coordinates.lon})`);
|
||||
this.setWeatherForecast(weatherObjects);
|
||||
})
|
||||
.catch((error) => Log.error(`Could not load data: ${error.message}`))
|
||||
.catch((error) => Log.error(`[weatherprovider.smhi] Could not load data: ${error.message}`))
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
|
||||
@@ -58,7 +58,7 @@ WeatherProvider.register("smhi", {
|
||||
this.setFetchedLocation(this.config.location || `(${coordinates.lat},${coordinates.lon})`);
|
||||
this.setWeatherHourly(weatherObjects);
|
||||
})
|
||||
.catch((error) => Log.error(`Could not load data: ${error.message}`))
|
||||
.catch((error) => Log.error(`[weatherprovider.smhi] Could not load data: ${error.message}`))
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
|
||||
@@ -69,7 +69,7 @@ WeatherProvider.register("smhi", {
|
||||
setConfig (config) {
|
||||
this.config = config;
|
||||
if (!config.precipitationValue || ["pmin", "pmean", "pmedian", "pmax"].indexOf(config.precipitationValue) === -1) {
|
||||
Log.log(`invalid or not set: ${config.precipitationValue}`);
|
||||
Log.log(`[weatherprovider.smhi] invalid or not set: ${config.precipitationValue}`);
|
||||
config.precipitationValue = this.defaults.precipitationValue;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -39,7 +39,7 @@ WeatherProvider.register("ukmetoffice", {
|
||||
this.setCurrentWeather(currentWeather);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.ukmetoffice] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -63,7 +63,7 @@ WeatherProvider.register("ukmetoffice", {
|
||||
this.setWeatherForecast(forecast);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.ukmetoffice] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
|
||||
@@ -86,8 +86,7 @@ WeatherProvider.register("ukmetofficedatahub", {
|
||||
* Did not receive usable new data.
|
||||
* Maybe this needs a better check?
|
||||
*/
|
||||
Log.error("Possibly bad current/hourly data?");
|
||||
Log.error(data);
|
||||
Log.error("[weatherprovider.ukmetofficedatahub] Possibly bad current/hourly data?", data);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,7 +99,7 @@ WeatherProvider.register("ukmetofficedatahub", {
|
||||
})
|
||||
|
||||
// Catch any error(s)
|
||||
.catch((error) => Log.error(`Could not load data: ${error.message}`))
|
||||
.catch((error) => Log.error(`[weatherprovider.ukmetofficedatahub] Could not load data: ${error.message}`))
|
||||
|
||||
// Let the module know there is data available
|
||||
.finally(() => this.updateAvailable());
|
||||
@@ -162,8 +161,7 @@ WeatherProvider.register("ukmetofficedatahub", {
|
||||
* Did not receive usable new data.
|
||||
* Maybe this needs a better check?
|
||||
*/
|
||||
Log.error("Possibly bad forecast data?");
|
||||
Log.error(data);
|
||||
Log.error("[weatherprovider.ukmetofficedatahub] Possibly bad forecast data?", data);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -176,7 +174,7 @@ WeatherProvider.register("ukmetofficedatahub", {
|
||||
})
|
||||
|
||||
// Catch any error(s)
|
||||
.catch((error) => Log.error(`Could not load data: ${error.message}`))
|
||||
.catch((error) => Log.error(`[weatherprovider.ukmetofficedatahub] Could not load data: ${error.message}`))
|
||||
|
||||
// Let the module know there is new data available
|
||||
.finally(() => this.updateAvailable());
|
||||
|
||||
@@ -36,7 +36,7 @@ WeatherProvider.register("weatherbit", {
|
||||
this.setCurrentWeather(currentWeather);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.weatherbit] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -55,7 +55,7 @@ WeatherProvider.register("weatherbit", {
|
||||
this.fetchedLocationName = `${data.city_name}, ${data.state_code}`;
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.weatherbit] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -79,7 +79,7 @@ WeatherProvider.register("weatherbit", {
|
||||
this.config.weatherEndpoint = "/current";
|
||||
break;
|
||||
default:
|
||||
Log.error("weatherEndpoint not configured and could not resolve it based on type");
|
||||
Log.error("[weatherprovider.weatherbit] weatherEndpoint not configured and could not resolve it based on type");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -41,7 +41,7 @@ WeatherProvider.register("weatherflow", {
|
||||
this.fetchedLocationName = data.location_name;
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.weatherflow] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -81,7 +81,7 @@ WeatherProvider.register("weatherflow", {
|
||||
this.fetchedLocationName = data.location_name;
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.weatherflow] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -112,7 +112,7 @@ WeatherProvider.register("weatherflow", {
|
||||
this.fetchedLocationName = data.location_name;
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.weatherflow] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
|
||||
@@ -41,11 +41,6 @@ WeatherProvider.register("weathergov", {
|
||||
this.fetchWxGovURLs(this.config);
|
||||
},
|
||||
|
||||
// Called when the weather provider is about to start.
|
||||
start () {
|
||||
Log.info(`Weather provider: ${this.providerName} started.`);
|
||||
},
|
||||
|
||||
// This returns the name of the fetched location or an empty string.
|
||||
fetchedLocation () {
|
||||
return this.fetchedLocationName || "";
|
||||
@@ -54,7 +49,7 @@ WeatherProvider.register("weathergov", {
|
||||
// Overwrite the fetchCurrentWeather method.
|
||||
fetchCurrentWeather () {
|
||||
if (!this.configURLs) {
|
||||
Log.info("fetchCurrentWeather: fetch wx waiting on config URLs");
|
||||
Log.info("[weatherprovider.weathergov] fetchCurrentWeather: fetch wx waiting on config URLs");
|
||||
return;
|
||||
}
|
||||
this.fetchData(this.stationObsURL)
|
||||
@@ -67,7 +62,7 @@ WeatherProvider.register("weathergov", {
|
||||
this.setCurrentWeather(currentWeather);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load station obs data ... ", request);
|
||||
Log.error("[weatherprovider.weathergov] Could not load station obs data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -75,7 +70,7 @@ WeatherProvider.register("weathergov", {
|
||||
// Overwrite the fetchWeatherForecast method.
|
||||
fetchWeatherForecast () {
|
||||
if (!this.configURLs) {
|
||||
Log.info("fetchWeatherForecast: fetch wx waiting on config URLs");
|
||||
Log.info("[weatherprovider.weathergov] fetchWeatherForecast: fetch wx waiting on config URLs");
|
||||
return;
|
||||
}
|
||||
this.fetchData(this.forecastURL)
|
||||
@@ -88,7 +83,7 @@ WeatherProvider.register("weathergov", {
|
||||
this.setWeatherForecast(forecast);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load forecast hourly data ... ", request);
|
||||
Log.error("[weatherprovider.weathergov] Could not load forecast hourly data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -96,7 +91,7 @@ WeatherProvider.register("weathergov", {
|
||||
// Overwrite the fetchWeatherHourly method.
|
||||
fetchWeatherHourly () {
|
||||
if (!this.configURLs) {
|
||||
Log.info("fetchWeatherHourly: fetch wx waiting on config URLs");
|
||||
Log.info("[weatherprovider.weathergov] fetchWeatherHourly: fetch wx waiting on config URLs");
|
||||
return;
|
||||
}
|
||||
this.fetchData(this.forecastHourlyURL)
|
||||
@@ -113,7 +108,7 @@ WeatherProvider.register("weathergov", {
|
||||
this.setWeatherHourly(hourly);
|
||||
})
|
||||
.catch(function (request) {
|
||||
Log.error("Could not load data ... ", request);
|
||||
Log.error("[weatherprovider.weathergov] Could not load data ... ", request);
|
||||
})
|
||||
.finally(() => this.updateAvailable());
|
||||
},
|
||||
@@ -131,7 +126,7 @@ WeatherProvider.register("weathergov", {
|
||||
return;
|
||||
}
|
||||
this.fetchedLocationName = `${data.properties.relativeLocation.properties.city}, ${data.properties.relativeLocation.properties.state}`;
|
||||
Log.log(`Forecast location is ${this.fetchedLocationName}`);
|
||||
Log.log(`[weatherprovider.weathergov] Forecast location is ${this.fetchedLocationName}`);
|
||||
this.forecastURL = `${data.properties.forecast}?units=si`;
|
||||
this.forecastHourlyURL = `${data.properties.forecastHourly}?units=si`;
|
||||
this.forecastGridDataURL = data.properties.forecastGridData;
|
||||
@@ -147,7 +142,7 @@ WeatherProvider.register("weathergov", {
|
||||
this.stationObsURL = `${obsData.features[0].id}/observations/latest`;
|
||||
})
|
||||
.catch((err) => {
|
||||
Log.error(err);
|
||||
Log.error("[weatherprovider.weathergov] fetchWxGovURLs error: ", err);
|
||||
})
|
||||
.finally(() => {
|
||||
// excellent, let's fetch some actual wx data
|
||||
|
||||
@@ -20,14 +20,14 @@ WeatherProvider.register("yr", {
|
||||
start () {
|
||||
if (typeof Storage === "undefined") {
|
||||
//local storage unavailable
|
||||
Log.error("The Yr weather provider requires local storage.");
|
||||
Log.error("[weatherprovider.yr] The Yr weather provider requires local storage.");
|
||||
throw new Error("Local storage not available");
|
||||
}
|
||||
if (this.config.updateInterval < 600000) {
|
||||
Log.warn("The Yr weather provider requires a minimum update interval of 10 minutes (600 000 ms). The configuration has been adjusted to meet this requirement.");
|
||||
Log.warn("[weatherprovider.yr] The Yr weather provider requires a minimum update interval of 10 minutes (600 000 ms). The configuration has been adjusted to meet this requirement.");
|
||||
this.delegate.config.updateInterval = 600000;
|
||||
}
|
||||
Log.info(`Weather provider: ${this.providerName} started.`);
|
||||
Log.info(`[weatherprovider.yr] ${this.providerName} started.`);
|
||||
},
|
||||
|
||||
fetchCurrentWeather () {
|
||||
@@ -37,7 +37,7 @@ WeatherProvider.register("yr", {
|
||||
this.updateAvailable();
|
||||
})
|
||||
.catch((error) => {
|
||||
Log.error(error);
|
||||
Log.error("[weatherprovider.yr] fetchCurrentWeather error:", error);
|
||||
this.updateAvailable();
|
||||
});
|
||||
},
|
||||
@@ -45,10 +45,10 @@ WeatherProvider.register("yr", {
|
||||
async getCurrentWeather () {
|
||||
const [weatherData, stellarData] = await Promise.all([this.getWeatherData(), this.getStellarData()]);
|
||||
if (!stellarData) {
|
||||
Log.warn("No stellar data available.");
|
||||
Log.warn("[weatherprovider.yr] No stellar data available.");
|
||||
}
|
||||
if (!weatherData.properties.timeseries || !weatherData.properties.timeseries[0]) {
|
||||
Log.error("No weather data available.");
|
||||
Log.error("[weatherprovider.yr] No weather data available.");
|
||||
return;
|
||||
}
|
||||
const currentTime = moment();
|
||||
@@ -105,12 +105,12 @@ WeatherProvider.register("yr", {
|
||||
let weatherData = this.getWeatherDataFromCache();
|
||||
if (this.weatherDataIsValid(weatherData)) {
|
||||
localStorage.removeItem("yrIsFetchingWeatherData");
|
||||
Log.debug("Weather data found in cache.");
|
||||
Log.debug("[weatherprovider.yr] Weather data found in cache.");
|
||||
resolve(weatherData);
|
||||
} else {
|
||||
this.getWeatherDataFromYr(weatherData?.downloadedAt)
|
||||
.then((weatherData) => {
|
||||
Log.debug("Got weather data from yr.");
|
||||
Log.debug("[weatherprovider.yr] Got weather data from yr.");
|
||||
let data;
|
||||
if (weatherData) {
|
||||
this.cacheWeatherData(weatherData);
|
||||
@@ -122,9 +122,9 @@ WeatherProvider.register("yr", {
|
||||
resolve(data);
|
||||
})
|
||||
.catch((err) => {
|
||||
Log.error(err);
|
||||
Log.error("[weatherprovider.yr] getWeatherDataFromYr error: ", err);
|
||||
if (weatherData) {
|
||||
Log.warn("Using outdated cached weather data.");
|
||||
Log.warn("[weatherprovider.yr] Using outdated cached weather data.");
|
||||
resolve(weatherData);
|
||||
} else {
|
||||
reject("Unable to get weather data from Yr.");
|
||||
@@ -171,18 +171,18 @@ WeatherProvider.register("yr", {
|
||||
return data;
|
||||
})
|
||||
.catch((err) => {
|
||||
Log.error("Could not load weather data.", err);
|
||||
Log.error("[weatherprovider.yr] Could not load weather data.", err);
|
||||
throw new Error(err);
|
||||
});
|
||||
},
|
||||
|
||||
getConfigOptions () {
|
||||
if (!this.config.lat) {
|
||||
Log.error("Latitude not provided.");
|
||||
Log.error("[weatherprovider.yr] Latitude not provided.");
|
||||
throw new Error("Latitude not provided.");
|
||||
}
|
||||
if (!this.config.lon) {
|
||||
Log.error("Longitude not provided.");
|
||||
Log.error("[weatherprovider.yr] Longitude not provided.");
|
||||
throw new Error("Longitude not provided.");
|
||||
}
|
||||
|
||||
@@ -196,12 +196,12 @@ WeatherProvider.register("yr", {
|
||||
let { lat, lon, altitude } = this.getConfigOptions();
|
||||
|
||||
if (lat.includes(".") && lat.split(".")[1].length > 4) {
|
||||
Log.warn("Latitude is too specific for weather data. Do not use more than four decimals. Trimming to maximum length.");
|
||||
Log.warn("[weatherprovider.yr] Latitude is too specific for weather data. Do not use more than four decimals. Trimming to maximum length.");
|
||||
const latParts = lat.split(".");
|
||||
lat = `${latParts[0]}.${latParts[1].substring(0, 4)}`;
|
||||
}
|
||||
if (lon.includes(".") && lon.split(".")[1].length > 4) {
|
||||
Log.warn("Longitude is too specific for weather data. Do not use more than four decimals. Trimming to maximum length.");
|
||||
Log.warn("[weatherprovider.yr] Longitude is too specific for weather data. Do not use more than four decimals. Trimming to maximum length.");
|
||||
const lonParts = lon.split(".");
|
||||
lon = `${lonParts[0]}.${lonParts[1].substring(0, 4)}`;
|
||||
}
|
||||
@@ -249,11 +249,11 @@ WeatherProvider.register("yr", {
|
||||
const today = moment().format("YYYY-MM-DD");
|
||||
const tomorrow = moment().add(1, "days").format("YYYY-MM-DD");
|
||||
if (stellarData && stellarData.today && stellarData.today.date === today && stellarData.tomorrow && stellarData.tomorrow.date === tomorrow) {
|
||||
Log.debug("Stellar data found in cache.");
|
||||
Log.debug("[weatherprovider.yr] Stellar data found in cache.");
|
||||
localStorage.removeItem("yrIsFetchingStellarData");
|
||||
resolve(stellarData);
|
||||
} else if (stellarData && stellarData.tomorrow && stellarData.tomorrow.date === today) {
|
||||
Log.debug("stellar data for today found in cache, but not for tomorrow.");
|
||||
Log.debug("[weatherprovider.yr] Stellar data for today found in cache, but not for tomorrow.");
|
||||
stellarData.today = stellarData.tomorrow;
|
||||
this.getStellarDataFromYr(tomorrow)
|
||||
.then((data) => {
|
||||
@@ -267,7 +267,7 @@ WeatherProvider.register("yr", {
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
Log.error(err);
|
||||
Log.error("[weatherprovider.yr] getStellarDataFromYr error: ", err);
|
||||
reject(`Unable to get stellar data from Yr for ${tomorrow}`);
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -286,12 +286,12 @@ WeatherProvider.register("yr", {
|
||||
this.cacheStellarData(data);
|
||||
resolve(data);
|
||||
} else {
|
||||
Log.error(`Something went wrong when fetching stellar data. Responses: ${stellarData}`);
|
||||
Log.error(`[weatherprovider.yr] Something went wrong when fetching stellar data. Responses: ${stellarData}`);
|
||||
reject(stellarData);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
Log.error(err);
|
||||
Log.error("[weatherprovider.yr] getStellarDataFromYr error: ", err);
|
||||
reject("Unable to get stellar data from Yr.");
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -313,11 +313,11 @@ WeatherProvider.register("yr", {
|
||||
const requestHeaders = [{ name: "Accept", value: "application/json" }];
|
||||
return this.fetchData(this.getStellarDataUrl(date, days), "json", requestHeaders)
|
||||
.then((data) => {
|
||||
Log.debug("Got stellar data from yr.");
|
||||
Log.debug("[weatherprovider.yr] Got stellar data from yr.");
|
||||
return data;
|
||||
})
|
||||
.catch((err) => {
|
||||
Log.error("Could not load weather data.", err);
|
||||
Log.error("[weatherprovider.yr] Could not load weather data.", err);
|
||||
throw new Error(err);
|
||||
});
|
||||
},
|
||||
@@ -326,12 +326,12 @@ WeatherProvider.register("yr", {
|
||||
let { lat, lon, altitude } = this.getConfigOptions();
|
||||
|
||||
if (lat.includes(".") && lat.split(".")[1].length > 4) {
|
||||
Log.warn("Latitude is too specific for stellar data. Do not use more than four decimals. Trimming to maximum length.");
|
||||
Log.warn("[weatherprovider.yr] Latitude is too specific for stellar data. Do not use more than four decimals. Trimming to maximum length.");
|
||||
const latParts = lat.split(".");
|
||||
lat = `${latParts[0]}.${latParts[1].substring(0, 4)}`;
|
||||
}
|
||||
if (lon.includes(".") && lon.split(".")[1].length > 4) {
|
||||
Log.warn("Longitude is too specific for stellar data. Do not use more than four decimals. Trimming to maximum length.");
|
||||
Log.warn("[weatherprovider.yr] Longitude is too specific for stellar data. Do not use more than four decimals. Trimming to maximum length.");
|
||||
const lonParts = lon.split(".");
|
||||
lon = `${lonParts[0]}.${lonParts[1].substring(0, 4)}`;
|
||||
}
|
||||
@@ -505,7 +505,7 @@ WeatherProvider.register("yr", {
|
||||
this.updateAvailable();
|
||||
})
|
||||
.catch((error) => {
|
||||
Log.error(error);
|
||||
Log.error("[weatherprovider.yr] fetchWeatherHourly error: ", error);
|
||||
this.updateAvailable();
|
||||
});
|
||||
},
|
||||
@@ -513,11 +513,11 @@ WeatherProvider.register("yr", {
|
||||
async getWeatherForecast (type) {
|
||||
const [weatherData, stellarData] = await Promise.all([this.getWeatherData(), this.getStellarData()]);
|
||||
if (!weatherData.properties.timeseries || !weatherData.properties.timeseries[0]) {
|
||||
Log.error("No weather data available.");
|
||||
Log.error("[weatherprovider.yr] No weather data available.");
|
||||
return;
|
||||
}
|
||||
if (!stellarData) {
|
||||
Log.warn("No stellar data available.");
|
||||
Log.warn("[weatherprovider.yr] No stellar data available.");
|
||||
}
|
||||
let forecasts;
|
||||
switch (type) {
|
||||
@@ -616,7 +616,7 @@ WeatherProvider.register("yr", {
|
||||
this.updateAvailable();
|
||||
})
|
||||
.catch((error) => {
|
||||
Log.error(error);
|
||||
Log.error("[weatherprovider.yr] fetchWeatherForecast error: ", error);
|
||||
this.updateAvailable();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -76,10 +76,10 @@ Module.register("weather", {
|
||||
moment.locale(this.config.lang);
|
||||
|
||||
if (this.config.useKmh) {
|
||||
Log.warn("Your are using the deprecated config values 'useKmh'. Please switch to windUnits!");
|
||||
Log.warn("[weather] Deprecation warning: Your are using the deprecated config values 'useKmh'. Please switch to windUnits!");
|
||||
this.windUnits = "kmh";
|
||||
} else if (this.config.useBeaufort) {
|
||||
Log.warn("Your are using the deprecated config values 'useBeaufort'. Please switch to windUnits!");
|
||||
Log.warn("[weather] Deprecation warning: Your are using the deprecated config values 'useBeaufort'. Please switch to windUnits!");
|
||||
this.windUnits = "beaufort";
|
||||
}
|
||||
if (typeof this.config.showHumidity === "boolean") {
|
||||
@@ -109,7 +109,7 @@ Module.register("weather", {
|
||||
for (let event of payload) {
|
||||
if (event.location || event.geo) {
|
||||
this.firstEvent = event;
|
||||
Log.debug("First upcoming event with location: ", event);
|
||||
Log.debug("[weather] First upcoming event with location: ", event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -163,7 +163,7 @@ Module.register("weather", {
|
||||
|
||||
// What to do when the weather provider has new information available?
|
||||
updateAvailable () {
|
||||
Log.log("New weather information available.");
|
||||
Log.log("[weather] New weather information available.");
|
||||
// this value was changed from 0 to 300 to stabilize weather tests:
|
||||
this.updateDom(300);
|
||||
this.scheduleUpdate();
|
||||
@@ -208,7 +208,7 @@ Module.register("weather", {
|
||||
this.weatherProvider.fetchWeatherForecast();
|
||||
break;
|
||||
default:
|
||||
Log.error(`Invalid type ${this.config.type} configured (must be one of 'current', 'hourly', 'daily' or 'forecast')`);
|
||||
Log.error(`[weather] Invalid type ${this.config.type} configured (must be one of 'current', 'hourly', 'daily' or 'forecast')`);
|
||||
}
|
||||
}, nextLoad);
|
||||
},
|
||||
|
||||
@@ -25,36 +25,36 @@ const WeatherProvider = Class.extend({
|
||||
// Called when a weather provider is initialized.
|
||||
init (config) {
|
||||
this.config = config;
|
||||
Log.info(`Weather provider: ${this.providerName} initialized.`);
|
||||
Log.info(`[weatherprovider] ${this.providerName} initialized.`);
|
||||
},
|
||||
|
||||
// Called to set the config, this config is the same as the weather module's config.
|
||||
setConfig (config) {
|
||||
this.config = config;
|
||||
Log.info(`Weather provider: ${this.providerName} config set.`, this.config);
|
||||
Log.info(`[weatherprovider] ${this.providerName} config set.`, this.config);
|
||||
},
|
||||
|
||||
// Called when the weather provider is about to start.
|
||||
start () {
|
||||
Log.info(`Weather provider: ${this.providerName} started.`);
|
||||
Log.info(`[weatherprovider] ${this.providerName} started.`);
|
||||
},
|
||||
|
||||
// This method should start the API request to fetch the current weather.
|
||||
// This method should definitely be overwritten in the provider.
|
||||
fetchCurrentWeather () {
|
||||
Log.warn(`Weather provider: ${this.providerName} does not subclass the fetchCurrentWeather method.`);
|
||||
Log.warn(`[weatherprovider] ${this.providerName} does not subclass the fetchCurrentWeather method.`);
|
||||
},
|
||||
|
||||
// This method should start the API request to fetch the weather forecast.
|
||||
// This method should definitely be overwritten in the provider.
|
||||
fetchWeatherForecast () {
|
||||
Log.warn(`Weather provider: ${this.providerName} does not subclass the fetchWeatherForecast method.`);
|
||||
Log.warn(`[weatherprovider] ${this.providerName} does not subclass the fetchWeatherForecast method.`);
|
||||
},
|
||||
|
||||
// This method should start the API request to fetch the weather hourly.
|
||||
// This method should definitely be overwritten in the provider.
|
||||
fetchWeatherHourly () {
|
||||
Log.warn(`Weather provider: ${this.providerName} does not subclass the fetchWeatherHourly method.`);
|
||||
Log.warn(`[weatherprovider] ${this.providerName} does not subclass the fetchWeatherHourly method.`);
|
||||
},
|
||||
|
||||
// This returns a WeatherDay object for the current weather.
|
||||
@@ -109,7 +109,7 @@ const WeatherProvider = Class.extend({
|
||||
* @param {string} url the url to fetch from
|
||||
* @param {string} type what contenttype to expect in the response, can be "json" or "xml"
|
||||
* @param {Array.<{name: string, value:string}>} requestHeaders the HTTP headers to send
|
||||
* @param {Array.<string>} expectedResponseHeaders the expected HTTP headers to recieve
|
||||
* @param {Array.<string>} expectedResponseHeaders the expected HTTP headers to receive
|
||||
* @returns {Promise} resolved when the fetch is done
|
||||
*/
|
||||
async fetchData (url, type = "json", requestHeaders = undefined, expectedResponseHeaders = undefined) {
|
||||
|
||||
@@ -106,7 +106,7 @@ describe("Updatenotification", () => {
|
||||
expect(repos).toHaveLength(0);
|
||||
|
||||
const { error } = require("logger");
|
||||
expect(error).toHaveBeenCalledWith(`Failed to retrieve repo info for ${moduleName}: Failed to retrieve status`);
|
||||
expect(error).toHaveBeenCalledWith(`[updatenotification] Failed to retrieve repo info for ${moduleName}: Failed to retrieve status`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -145,7 +145,7 @@ describe("Updatenotification", () => {
|
||||
expect(repos).toHaveLength(0);
|
||||
|
||||
const { error } = require("logger");
|
||||
expect(error).toHaveBeenCalledWith(`Failed to retrieve repo info for ${moduleName}: Failed to retrieve status`);
|
||||
expect(error).toHaveBeenCalledWith(`[updatenotification] Failed to retrieve repo info for ${moduleName}: Failed to retrieve status`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -186,7 +186,7 @@ describe("Updatenotification", () => {
|
||||
expect(repos).toHaveLength(0);
|
||||
|
||||
const { error } = require("logger");
|
||||
expect(error).toHaveBeenCalledWith(`Failed to retrieve repo info for ${moduleName}: Failed to retrieve status`);
|
||||
expect(error).toHaveBeenCalledWith(`[updatenotification] Failed to retrieve repo info for ${moduleName}: Failed to retrieve status`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -227,7 +227,7 @@ describe("Updatenotification", () => {
|
||||
expect(repos).toHaveLength(0);
|
||||
|
||||
const { error } = require("logger");
|
||||
expect(error).toHaveBeenCalledWith(`Failed to retrieve repo info for ${moduleName}: Failed to retrieve status`);
|
||||
expect(error).toHaveBeenCalledWith(`[updatenotification] Failed to retrieve repo info for ${moduleName}: Failed to retrieve status`);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user