fix: Issue #1798 - fixing recurrent calendar events crosstime DST

This commit is contained in:
Kurtis Blankenship 2020-01-17 22:53:14 -06:00
parent 5bf90ae31d
commit 8aa745471b
10 changed files with 235 additions and 228 deletions

View File

@ -184,7 +184,14 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
// For recurring events, get the set of start dates that fall within the range // For recurring events, get the set of start dates that fall within the range
// of dates we"re looking for. // of dates we"re looking for.
var dates = rule.between(past, future, true, limitFunction); // kblankenship1989 - to fix issue #1798, converting all dates to locale time first, then converting back to UTC time
var pastLocal = moment(past).subtract(past.getTimezoneOffset(), "minutes").toDate();
var futureLocal = moment(past).subtract(future.getTimezoneOffset(), "minutes").toDate();
var datesLocal = rule.between(pastLocal, futureLocal, true, limitFunction);
var dates = datesLocal.map(function(dateLocal) {
var date = moment(dateLocal).add(dateLocal.getTimezoneOffset(), "minutes").toDate();
return date;
});
// The "dates" array contains the set of dates within our desired date range range that are valid // The "dates" array contains the set of dates within our desired date range range that are valid
// for the recurrence rule. *However*, it"s possible for us to have a specific recurrence that // for the recurrence rule. *However*, it"s possible for us to have a specific recurrence that

View File

@ -26,6 +26,17 @@ exports.parseFile = function(filename){
var rrule = require('rrule').RRule var rrule = require('rrule').RRule
function getLocaleISOString(date) {
var year = date.getFullYear().toString(10).padStart(4,'0');
var month = date.getMonth().toString(10).padStart(2,'0');
var day = date.getDate().toString(10).padStart(2,'0');
var hour = date.getHours().toString(10).padStart(2,'0');
var minute = date.getMinutes().toString(10).padStart(2,'0');
var second = date.getSeconds().toString(10).padStart(2,'0');
return `${year}${month}${day}T${hour}${minute}${second}Z`;
}
ical.objectHandlers['RRULE'] = function(val, params, curr, stack, line){ ical.objectHandlers['RRULE'] = function(val, params, curr, stack, line){
curr.rrule = line; curr.rrule = line;
return curr return curr
@ -50,8 +61,8 @@ ical.objectHandlers['END'] = function (val, params, curr, stack) {
if (typeof curr.start.toISOString === 'function') { if (typeof curr.start.toISOString === 'function') {
try { try {
rule += ';DTSTART=' + curr.start.toISOString().replace(/[-:]/g, ''); // kblankenship1989 - to fix issue #1798, converting all dates to locale time first, then converting back to UTC time
rule = rule.replace(/\.[0-9]{3}/, ''); rule += ';DTSTART=' + getLocaleISOString(curr.start);
} catch (error) { } catch (error) {
console.error("ERROR when trying to convert to ISOString", error); console.error("ERROR when trying to convert to ISOString", error);
} }

View File

@ -39,7 +39,7 @@ Module.register("compliments", {
afternoonEndTime: 17, afternoonEndTime: 17,
random: true random: true
}, },
lastIndexUsed:-1, lastIndexUsed:-1,
// Set currentweather from module // Set currentweather from module
currentWeatherType: "", currentWeatherType: "",
@ -151,7 +151,7 @@ Module.register("compliments", {
// get the current time of day compliments list // get the current time of day compliments list
var compliments = this.complimentArray(); var compliments = this.complimentArray();
// variable for index to next message to display // variable for index to next message to display
let index=0 let index=0;
// are we randomizing // are we randomizing
if(this.config.random){ if(this.config.random){
// yes // yes
@ -160,28 +160,28 @@ Module.register("compliments", {
else{ else{
// no, sequetial // no, sequetial
// if doing sequential, don't fall off the end // if doing sequential, don't fall off the end
index = (this.lastIndexUsed >= (compliments.length-1))?0: ++this.lastIndexUsed index = (this.lastIndexUsed >= (compliments.length-1))?0: ++this.lastIndexUsed;
} }
return compliments[index]; return compliments[index];
}, },
// Override dom generator. // Override dom generator.
getDom: function() { getDom: function() {
var wrapper = document.createElement("div"); var wrapper = document.createElement("div");
wrapper.className = this.config.classes ? this.config.classes : "thin xlarge bright pre-line"; wrapper.className = this.config.classes ? this.config.classes : "thin xlarge bright pre-line";
// get the compliment text // get the compliment text
var complimentText = this.randomCompliment(); var complimentText = this.randomCompliment();
// split it into parts on newline text // split it into parts on newline text
var parts= complimentText.split('\n') var parts= complimentText.split("\n");
// create a span to hold it all // create a span to hold it all
var compliment=document.createElement('span') var compliment=document.createElement("span");
// process all the parts of the compliment text // process all the parts of the compliment text
for (part of parts){ for (part of parts){
// create a text element for each part // create a text element for each part
compliment.appendChild(document.createTextNode(part)) compliment.appendChild(document.createTextNode(part));
// add a break ` // add a break `
compliment.appendChild(document.createElement('BR')) compliment.appendChild(document.createElement("BR"));
} }
// remove the last break // remove the last break
compliment.lastElementChild.remove(); compliment.lastElementChild.remove();

View File

@ -6,31 +6,31 @@
*/ */
let config = { let config = {
port: 8080, port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "en", language: "en",
timeFormat: 12, timeFormat: 12,
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true,
}, },
}, },
modules: [ modules: [
{ {
module: "weather", module: "weather",
position: "bottom_bar", position: "bottom_bar",
config: { config: {
type: "forecast", type: "forecast",
location: "Munich", location: "Munich",
apiKey: "fake key", apiKey: "fake key",
weatherEndpoint: "/forecast/daily", weatherEndpoint: "/forecast/daily",
initialLoadDelay: 3000 initialLoadDelay: 3000
} }
} }
] ]
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/

View File

@ -6,34 +6,34 @@
*/ */
let config = { let config = {
port: 8080, port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "en", language: "en",
timeFormat: 12, timeFormat: 12,
units: "metric", units: "metric",
electronOptions: { electronOptions: {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true,
}, },
}, },
modules: [ modules: [
{ {
module: "weather", module: "weather",
position: "bottom_bar", position: "bottom_bar",
config: { config: {
type: "forecast", type: "forecast",
location: "Munich", location: "Munich",
apiKey: "fake key", apiKey: "fake key",
weatherEndpoint: "/forecast/daily", weatherEndpoint: "/forecast/daily",
initialLoadDelay: 3000, initialLoadDelay: 3000,
showPrecipitationAmount: true, showPrecipitationAmount: true,
colored: true, colored: true,
tableClass: "myTableClass" tableClass: "myTableClass"
} }
} }
] ]
}; };
/*************** DO NOT EDIT THE LINE BELOW ***************/ /*************** DO NOT EDIT THE LINE BELOW ***************/

View File

@ -1,54 +1,54 @@
const _ = require('lodash'); const _ = require("lodash");
function generateWeather(extendedData = {}) { function generateWeather(extendedData = {}) {
return JSON.stringify(_.merge({}, { return JSON.stringify(_.merge({}, {
coord:{ coord:{
lon: 11.58, lon: 11.58,
lat: 48.14 lat: 48.14
}, },
weather:[ weather:[
{ {
id: 615, id: 615,
main: "Snow", main: "Snow",
description: "light rain and snow", description: "light rain and snow",
icon: "13d" icon: "13d"
}, },
{ {
id: 500, id: 500,
main: "Rain", main: "Rain",
description: "light rain", description: "light rain",
icon: "10d" icon: "10d"
} }
], ],
base: "stations", base: "stations",
main:{ main:{
temp: 1.49, temp: 1.49,
pressure: 1005, pressure: 1005,
humidity: 93.7, humidity: 93.7,
temp_min: 1, temp_min: 1,
temp_max: 2 temp_max: 2
}, },
visibility: 7000, visibility: 7000,
wind:{ wind:{
speed: 11.8, speed: 11.8,
deg: 250 deg: 250
}, },
clouds:{ clouds:{
all: 75 all: 75
}, },
dt: 1547387400, dt: 1547387400,
sys:{ sys:{
type: 1, type: 1,
id: 1267, id: 1267,
message: 0.0031, message: 0.0031,
country: "DE", country: "DE",
sunrise: 1547362817, sunrise: 1547362817,
sunset: 1547394301 sunset: 1547394301
}, },
id: 2867714, id: 2867714,
name: "Munich", name: "Munich",
cod: 200 cod: 200
}, extendedData)); }, extendedData));
} }
module.exports = generateWeather; module.exports = generateWeather;

View File

@ -1,97 +1,97 @@
const _ = require('lodash'); const _ = require("lodash");
function generateWeatherForecast(extendedData = {}) { function generateWeatherForecast(extendedData = {}) {
return JSON.stringify(_.merge({}, { return JSON.stringify(_.merge({}, {
"city": { "city": {
"id": 2867714, "id": 2867714,
"name": "Munich", "name": "Munich",
"coord": {"lon": 11.5754, "lat": 48.1371}, "coord": {"lon": 11.5754, "lat": 48.1371},
"country": "DE", "country": "DE",
"population": 1260391, "population": 1260391,
"timezone": 7200 "timezone": 7200
}, },
"cod": "200", "cod": "200",
"message": 0.9653487, "message": 0.9653487,
"cnt": 7, "cnt": 7,
"list": [{ "list": [{
"dt": 1568372400, "dt": 1568372400,
"sunrise": 1568350044, "sunrise": 1568350044,
"sunset": 1568395948, "sunset": 1568395948,
"temp": {"day": 24.44, "min": 15.35, "max": 24.44, "night": 15.35, "eve": 18, "morn": 23.03}, "temp": {"day": 24.44, "min": 15.35, "max": 24.44, "night": 15.35, "eve": 18, "morn": 23.03},
"pressure": 1031.65, "pressure": 1031.65,
"humidity": 70, "humidity": 70,
"weather": [{"id": 801, "main": "Clouds", "description": "few clouds", "icon": "02d"}], "weather": [{"id": 801, "main": "Clouds", "description": "few clouds", "icon": "02d"}],
"speed": 3.35, "speed": 3.35,
"deg": 314, "deg": 314,
"clouds": 21 "clouds": 21
}, { }, {
"dt": 1568458800, "dt": 1568458800,
"sunrise": 1568436525, "sunrise": 1568436525,
"sunset": 1568482223, "sunset": 1568482223,
"temp": {"day": 20.81, "min": 13.56, "max": 21.02, "night": 13.56, "eve": 16.6, "morn": 15.88}, "temp": {"day": 20.81, "min": 13.56, "max": 21.02, "night": 13.56, "eve": 16.6, "morn": 15.88},
"pressure": 1028.81, "pressure": 1028.81,
"humidity": 72, "humidity": 72,
"weather": [{"id": 500, "main": "Rain", "description": "light rain", "icon": "10d"}], "weather": [{"id": 500, "main": "Rain", "description": "light rain", "icon": "10d"}],
"speed": 2.21, "speed": 2.21,
"deg": 81, "deg": 81,
"clouds": 100 "clouds": 100
}, { }, {
"dt": 1568545200, "dt": 1568545200,
"sunrise": 1568523007, "sunrise": 1568523007,
"sunset": 1568568497, "sunset": 1568568497,
"temp": {"day": 22.65, "min": 13.76, "max": 22.88, "night": 15.27, "eve": 17.45, "morn": 13.76}, "temp": {"day": 22.65, "min": 13.76, "max": 22.88, "night": 15.27, "eve": 17.45, "morn": 13.76},
"pressure": 1023.75, "pressure": 1023.75,
"humidity": 64, "humidity": 64,
"weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}],
"speed": 1.15, "speed": 1.15,
"deg": 7, "deg": 7,
"clouds": 0 "clouds": 0
}, { }, {
"dt": 1568631600, "dt": 1568631600,
"sunrise": 1568609489, "sunrise": 1568609489,
"sunset": 1568654771, "sunset": 1568654771,
"temp": {"day": 23.45, "min": 13.95, "max": 23.45, "night": 13.95, "eve": 17.75, "morn": 15.21}, "temp": {"day": 23.45, "min": 13.95, "max": 23.45, "night": 13.95, "eve": 17.75, "morn": 15.21},
"pressure": 1020.41, "pressure": 1020.41,
"humidity": 64, "humidity": 64,
"weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}],
"speed": 3.07, "speed": 3.07,
"deg": 298, "deg": 298,
"clouds": 7 "clouds": 7
}, { }, {
"dt": 1568718000, "dt": 1568718000,
"sunrise": 1568695970, "sunrise": 1568695970,
"sunset": 1568741045, "sunset": 1568741045,
"temp": {"day": 20.55, "min": 10.95, "max": 20.55, "night": 10.95, "eve": 14.82, "morn": 13.24}, "temp": {"day": 20.55, "min": 10.95, "max": 20.55, "night": 10.95, "eve": 14.82, "morn": 13.24},
"pressure": 1019.4, "pressure": 1019.4,
"humidity": 66, "humidity": 66,
"weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}],
"speed": 2.8, "speed": 2.8,
"deg": 333, "deg": 333,
"clouds": 2 "clouds": 2
}, { }, {
"dt": 1568804400, "dt": 1568804400,
"sunrise": 1568782452, "sunrise": 1568782452,
"sunset": 1568827319, "sunset": 1568827319,
"temp": {"day": 18.15, "min": 7.75, "max": 18.15, "night": 7.75, "eve": 12.45, "morn": 9.41}, "temp": {"day": 18.15, "min": 7.75, "max": 18.15, "night": 7.75, "eve": 12.45, "morn": 9.41},
"pressure": 1017.56, "pressure": 1017.56,
"humidity": 52, "humidity": 52,
"weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}],
"speed": 2.92, "speed": 2.92,
"deg": 34, "deg": 34,
"clouds": 0 "clouds": 0
}, { }, {
"dt": 1568890800, "dt": 1568890800,
"sunrise": 1568868934, "sunrise": 1568868934,
"sunset": 1568913593, "sunset": 1568913593,
"temp": {"day": 14.85, "min": 5.56, "max": 15.05, "night": 5.56, "eve": 9.56, "morn": 6.25}, "temp": {"day": 14.85, "min": 5.56, "max": 15.05, "night": 5.56, "eve": 9.56, "morn": 6.25},
"pressure": 1022.7, "pressure": 1022.7,
"humidity": 59, "humidity": 59,
"weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}],
"speed": 2.89, "speed": 2.89,
"deg": 51, "deg": 51,
"clouds": 1 "clouds": 1
}] }]
}, extendedData)); }, extendedData));
} }
module.exports = generateWeatherForecast; module.exports = generateWeatherForecast;

View File

@ -36,9 +36,9 @@ describe("Vendors", function () {
urlVendor = "http://localhost:8080/vendor/" + vendors[vendor]; urlVendor = "http://localhost:8080/vendor/" + vendors[vendor];
request.get(urlVendor, function (err, res, body) { request.get(urlVendor, function (err, res, body) {
if (!err) if (!err)
expect(res.statusCode).to.equal(200); {expect(res.statusCode).to.equal(200);}
else else
mlog.pending(`There error vendor 200 test ${err}`); {mlog.pending(`There error vendor 200 test ${err}`);}
}); });
}); });
}); });
@ -48,9 +48,9 @@ describe("Vendors", function () {
urlVendor = "http://localhost:8080/" + vendors[vendor]; urlVendor = "http://localhost:8080/" + vendors[vendor];
request.get(urlVendor, function (err, res, body) { request.get(urlVendor, function (err, res, body) {
if (!err) if (!err)
expect(res.statusCode).to.equal(404); {expect(res.statusCode).to.equal(404);}
else else
mlog.pending(`There error vendor 404 test ${err}`); {mlog.pending(`There error vendor 404 test ${err}`);}
}); });
}); });
}); });

25
vendor/package-lock.json generated vendored
View File

@ -703,7 +703,6 @@
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
"integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
"optional": true,
"requires": { "requires": {
"is-glob": "^2.0.0" "is-glob": "^2.0.0"
} }
@ -717,8 +716,7 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
"optional": true
}, },
"invert-kv": { "invert-kv": {
"version": "1.0.0", "version": "1.0.0",
@ -737,8 +735,7 @@
"is-buffer": { "is-buffer": {
"version": "1.1.5", "version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
"optional": true
}, },
"is-dotfile": { "is-dotfile": {
"version": "1.0.3", "version": "1.0.3",
@ -764,8 +761,7 @@
"is-extglob": { "is-extglob": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
"optional": true
}, },
"is-fullwidth-code-point": { "is-fullwidth-code-point": {
"version": "1.0.0", "version": "1.0.0",
@ -779,7 +775,6 @@
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
"optional": true,
"requires": { "requires": {
"is-extglob": "^1.0.0" "is-extglob": "^1.0.0"
} }
@ -808,8 +803,7 @@
"isarray": { "isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
"optional": true
}, },
"isobject": { "isobject": {
"version": "2.1.0", "version": "2.1.0",
@ -824,7 +818,6 @@
"version": "3.2.2", "version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"optional": true,
"requires": { "requires": {
"is-buffer": "^1.1.5" "is-buffer": "^1.1.5"
} }
@ -890,7 +883,6 @@
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
"optional": true,
"requires": { "requires": {
"remove-trailing-separator": "^1.0.1" "remove-trailing-separator": "^1.0.1"
} }
@ -1039,14 +1031,12 @@
"remove-trailing-separator": { "remove-trailing-separator": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
"optional": true
}, },
"repeat-element": { "repeat-element": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
"integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo="
"optional": true
}, },
"repeat-string": { "repeat-string": {
"version": "1.6.1", "version": "1.6.1",
@ -1057,8 +1047,7 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
"optional": true
}, },
"set-immediate-shim": { "set-immediate-shim": {
"version": "1.0.1", "version": "1.0.1",