From c1be3c55de8b9e4a88e53f79d7ce54016ec4edd0 Mon Sep 17 00:00:00 2001 From: Martin Donnelly Date: Fri, 13 Oct 2017 10:39:58 +0100 Subject: [PATCH] Fixing today, recurring stuff in the calendar. finally --- lib/caltest.js | 67 +++- lib/scratch/today | 2 +- lib/test.js | 31 ++ lib/today/calHandler.js | 299 ++++++++++++----- lib/today/history.js | 51 ++- lib/today/mailer.js | 2 +- lib/today/quotes.js | 61 ++-- lib/today/swedishword.js | 51 ++- lib/today/todayftse.js | 14 +- lib/today/trains.js | 201 ++++++----- lib/today/weather.js | 2 +- lib/todayV2.js | 695 +++++++++++++++++++-------------------- 12 files changed, 813 insertions(+), 663 deletions(-) create mode 100644 lib/test.js diff --git a/lib/caltest.js b/lib/caltest.js index d6bff49..8824860 100644 --- a/lib/caltest.js +++ b/lib/caltest.js @@ -3,29 +3,66 @@ var logger = log4js.getLogger(); var calHandler = require('./today/calHandler'); - require('sugar-date'); var cal = { 'today': [], 'tomorrow': [], 'week': [] }; var _cal_tmp = { 'today': [], 'tomorrow': [], 'week': [] }; -for (var t = 0; t < calHandler.calendars.length;t++) +/* +for (var t = 0; t < calHandler.calendars.length;t++) calHandler.getAdvancedCalV3(calHandler.calendars[t]) - .then((d) => { - 'use strict'; - cal.today = cal.today.concat(d.today); - cal.tomorrow = cal.tomorrow.concat(d.tomorrow); - cal.week = cal.week.concat(d.week); - + .then((d) => { + 'use strict'; + // cal.today = cal.today.concat(d.today); + // cal.tomorrow = cal.tomorrow.concat(d.tomorrow); + cal.week = cal.week.concat(d.week); - logger.error(cal); - }) - .catch((e) => { - 'use strict'; - logger.error(e); - }); - + logger.info(cal); + }) + .catch((e) => { + 'use strict'; + logger.error(e); + }); +*/ +for (const item of calHandler.calendars) + calHandler.getAdvancedCalV3(item) + .then((d) => { + 'use strict'; + // cal.today = cal.today.concat(d.today); + // cal.tomorrow = cal.tomorrow.concat(d.tomorrow); + cal.week = cal.week.concat(d.week); + logger.info(cal); + }) + .catch((e) => { + 'use strict'; + logger.error(e); + }); +/*calHandler.getSimpleCalV3( + 'http://www.pogdesign.co.uk/cat/download_ics/60cfdff469d0490545d33d7e3b5c0bcc') + .then((d) => { + 'use strict'; + let tv = d; + logger.info(tv); + }) + .catch((e) => { + 'use strict'; + logger.error(e); + });*/ + + /*calHandler.getAdvancedCalV3(calHandler.calendars[4]) + .then((d) => { + 'use strict'; + // cal.today = cal.today.concat(d.today); + // cal.tomorrow = cal.tomorrow.concat(d.tomorrow); + cal.week = cal.week.concat(d.week); + + logger.error(cal); + }) + .catch((e) => { + 'use strict'; + logger.error(e); + });*/ diff --git a/lib/scratch/today b/lib/scratch/today index 288f576..31b250f 100644 --- a/lib/scratch/today +++ b/lib/scratch/today @@ -1 +1 @@ -{"last":1493301594148,"data":{"trains":{"last":"2017-04-27T13:53:49.756Z","data":[]},"weather":{"currently":"Mostly Cloudy. Around 6 to 12 degrees.","today":"Partly cloudy throughout the day.","later":"Light rain on Saturday through Monday, with temperatures rising to 15°C on Thursday.","alerts":{},"data":{"latitude":55.95,"longitude":-4.566667,"timezone":"Europe/London","offset":1,"currently":{"time":1493301228,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","nearestStormDistance":31,"nearestStormBearing":9,"precipIntensity":0,"precipProbability":0,"temperature":11.14,"apparentTemperature":11.14,"dewPoint":4.97,"humidity":0.66,"windSpeed":12.68,"windBearing":280,"visibility":9.49,"cloudCover":0.65,"pressure":1018.46,"ozone":365.67},"minutely":{"summary":"Mostly cloudy for the hour.","icon":"partly-cloudy-day","data":[{"time":1493301180,"precipIntensity":0,"precipProbability":0},{"time":1493301240,"precipIntensity":0,"precipProbability":0},{"time":1493301300,"precipIntensity":0,"precipProbability":0},{"time":1493301360,"precipIntensity":0,"precipProbability":0},{"time":1493301420,"precipIntensity":0,"precipProbability":0},{"time":1493301480,"precipIntensity":0,"precipProbability":0},{"time":1493301540,"precipIntensity":0,"precipProbability":0},{"time":1493301600,"precipIntensity":0,"precipProbability":0},{"time":1493301660,"precipIntensity":0,"precipProbability":0},{"time":1493301720,"precipIntensity":0,"precipProbability":0},{"time":1493301780,"precipIntensity":0,"precipProbability":0},{"time":1493301840,"precipIntensity":0,"precipProbability":0},{"time":1493301900,"precipIntensity":0,"precipProbability":0},{"time":1493301960,"precipIntensity":0,"precipProbability":0},{"time":1493302020,"precipIntensity":0,"precipProbability":0},{"time":1493302080,"precipIntensity":0,"precipProbability":0},{"time":1493302140,"precipIntensity":0,"precipProbability":0},{"time":1493302200,"precipIntensity":0,"precipProbability":0},{"time":1493302260,"precipIntensity":0,"precipProbability":0},{"time":1493302320,"precipIntensity":0,"precipProbability":0},{"time":1493302380,"precipIntensity":0,"precipProbability":0},{"time":1493302440,"precipIntensity":0,"precipProbability":0},{"time":1493302500,"precipIntensity":0,"precipProbability":0},{"time":1493302560,"precipIntensity":0,"precipProbability":0},{"time":1493302620,"precipIntensity":0,"precipProbability":0},{"time":1493302680,"precipIntensity":0,"precipProbability":0},{"time":1493302740,"precipIntensity":0,"precipProbability":0},{"time":1493302800,"precipIntensity":0,"precipProbability":0},{"time":1493302860,"precipIntensity":0,"precipProbability":0},{"time":1493302920,"precipIntensity":0,"precipProbability":0},{"time":1493302980,"precipIntensity":0,"precipProbability":0},{"time":1493303040,"precipIntensity":0,"precipProbability":0},{"time":1493303100,"precipIntensity":0,"precipProbability":0},{"time":1493303160,"precipIntensity":0,"precipProbability":0},{"time":1493303220,"precipIntensity":0,"precipProbability":0},{"time":1493303280,"precipIntensity":0,"precipProbability":0},{"time":1493303340,"precipIntensity":0,"precipProbability":0},{"time":1493303400,"precipIntensity":0,"precipProbability":0},{"time":1493303460,"precipIntensity":0,"precipProbability":0},{"time":1493303520,"precipIntensity":0,"precipProbability":0},{"time":1493303580,"precipIntensity":0,"precipProbability":0},{"time":1493303640,"precipIntensity":0,"precipProbability":0},{"time":1493303700,"precipIntensity":0,"precipProbability":0},{"time":1493303760,"precipIntensity":0,"precipProbability":0},{"time":1493303820,"precipIntensity":0,"precipProbability":0},{"time":1493303880,"precipIntensity":0,"precipProbability":0},{"time":1493303940,"precipIntensity":0,"precipProbability":0},{"time":1493304000,"precipIntensity":0,"precipProbability":0},{"time":1493304060,"precipIntensity":0,"precipProbability":0},{"time":1493304120,"precipIntensity":0,"precipProbability":0},{"time":1493304180,"precipIntensity":0,"precipProbability":0},{"time":1493304240,"precipIntensity":0,"precipProbability":0},{"time":1493304300,"precipIntensity":0,"precipProbability":0},{"time":1493304360,"precipIntensity":0,"precipProbability":0},{"time":1493304420,"precipIntensity":0,"precipProbability":0},{"time":1493304480,"precipIntensity":0,"precipProbability":0},{"time":1493304540,"precipIntensity":0,"precipProbability":0},{"time":1493304600,"precipIntensity":0,"precipProbability":0},{"time":1493304660,"precipIntensity":0,"precipProbability":0},{"time":1493304720,"precipIntensity":0,"precipProbability":0},{"time":1493304780,"precipIntensity":0,"precipProbability":0}]},"hourly":{"summary":"Mostly cloudy throughout the day.","icon":"partly-cloudy-night","data":[{"time":1493298000,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":12.11,"apparentTemperature":12.11,"dewPoint":4.79,"humidity":0.61,"windSpeed":12.72,"windBearing":283,"visibility":7.49,"cloudCover":0.66,"pressure":1018.55,"ozone":366.28},{"time":1493301600,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":11.14,"apparentTemperature":11.14,"dewPoint":5.09,"humidity":0.66,"windSpeed":12.67,"windBearing":280,"visibility":9.72,"cloudCover":0.65,"pressure":1018.45,"ozone":365.6},{"time":1493305200,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":11.06,"apparentTemperature":11.06,"dewPoint":5.83,"humidity":0.7,"windSpeed":12.29,"windBearing":279,"visibility":10,"cloudCover":0.64,"pressure":1018.41,"ozone":365.05},{"time":1493308800,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":10.83,"apparentTemperature":10.83,"dewPoint":6.37,"humidity":0.74,"windSpeed":11.55,"windBearing":278,"visibility":10,"cloudCover":0.67,"pressure":1018.44,"ozone":364.71},{"time":1493312400,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":10.26,"apparentTemperature":10.26,"dewPoint":6.35,"humidity":0.77,"windSpeed":10.79,"windBearing":275,"visibility":10,"cloudCover":0.68,"pressure":1018.52,"ozone":364.5},{"time":1493316000,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":9.56,"apparentTemperature":7.18,"dewPoint":6.11,"humidity":0.79,"windSpeed":10.41,"windBearing":272,"visibility":10,"cloudCover":0.69,"pressure":1018.67,"ozone":364.29},{"time":1493319600,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":8.77,"apparentTemperature":6.32,"dewPoint":5.92,"humidity":0.82,"windSpeed":9.72,"windBearing":270,"visibility":10,"cloudCover":0.61,"pressure":1018.93,"ozone":364.01},{"time":1493323200,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":8.32,"apparentTemperature":5.88,"dewPoint":5.88,"humidity":0.85,"windSpeed":9.22,"windBearing":266,"visibility":10,"cloudCover":0.54,"pressure":1019.27,"ozone":363.74},{"time":1493326800,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.98,"apparentTemperature":5.52,"dewPoint":5.87,"humidity":0.86,"windSpeed":8.97,"windBearing":264,"visibility":10,"cloudCover":0.47,"pressure":1019.52,"ozone":363.49},{"time":1493330400,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.91,"apparentTemperature":5.57,"dewPoint":6,"humidity":0.88,"windSpeed":8.35,"windBearing":265,"visibility":10,"cloudCover":0.43,"pressure":1019.58,"ozone":363.28},{"time":1493334000,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.85,"apparentTemperature":5.64,"dewPoint":6.07,"humidity":0.89,"windSpeed":7.78,"windBearing":267,"visibility":10,"cloudCover":0.4,"pressure":1019.51,"ozone":363.09},{"time":1493337600,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.71,"apparentTemperature":5.67,"dewPoint":6.06,"humidity":0.89,"windSpeed":7.03,"windBearing":269,"visibility":10,"cloudCover":0.37,"pressure":1019.38,"ozone":362.9},{"time":1493341200,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.32,"apparentTemperature":5.43,"dewPoint":5.73,"humidity":0.9,"windSpeed":6.27,"windBearing":269,"visibility":10,"cloudCover":0.44,"pressure":1019.21,"ozone":362.73},{"time":1493344800,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":6.99,"apparentTemperature":5.31,"dewPoint":5.47,"humidity":0.9,"windSpeed":5.48,"windBearing":266,"visibility":10,"cloudCover":0.52,"pressure":1019,"ozone":362.56},{"time":1493348400,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":6.73,"apparentTemperature":5.18,"dewPoint":5.23,"humidity":0.9,"windSpeed":4.97,"windBearing":263,"visibility":10,"cloudCover":0.6,"pressure":1018.81,"ozone":362.33},{"time":1493352000,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":6.93,"apparentTemperature":5.56,"dewPoint":5.39,"humidity":0.9,"windSpeed":4.61,"windBearing":264,"visibility":10,"cloudCover":0.64,"pressure":1018.67,"ozone":362.04},{"time":1493355600,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":7.09,"apparentTemperature":5.9,"dewPoint":5.51,"humidity":0.9,"windSpeed":4.26,"windBearing":265,"visibility":10,"cloudCover":0.72,"pressure":1018.57,"ozone":361.68},{"time":1493359200,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":7.23,"apparentTemperature":6.33,"dewPoint":5.54,"humidity":0.89,"windSpeed":3.67,"windBearing":262,"visibility":10,"cloudCover":0.78,"pressure":1018.46,"ozone":361.21},{"time":1493362800,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":7.43,"apparentTemperature":7.43,"dewPoint":5.32,"humidity":0.86,"windSpeed":2.72,"windBearing":257,"visibility":10,"cloudCover":0.8,"pressure":1018.33,"ozone":360.54},{"time":1493366400,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":7.64,"apparentTemperature":7.64,"dewPoint":5.01,"humidity":0.83,"windSpeed":2.2,"windBearing":248,"visibility":10,"cloudCover":0.81,"pressure":1018.2,"ozone":359.75},{"time":1493370000,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":8.12,"apparentTemperature":8.12,"dewPoint":4.93,"humidity":0.8,"windSpeed":2.19,"windBearing":237,"visibility":10,"cloudCover":0.81,"pressure":1017.99,"ozone":359.06},{"time":1493373600,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":8.7,"apparentTemperature":8.7,"dewPoint":5.06,"humidity":0.78,"windSpeed":2.87,"windBearing":225,"visibility":10,"cloudCover":0.84,"pressure":1017.67,"ozone":358.7},{"time":1493377200,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0203,"precipProbability":0.01,"precipType":"rain","temperature":9.43,"apparentTemperature":8.86,"dewPoint":5.28,"humidity":0.75,"windSpeed":3.67,"windBearing":216,"visibility":10,"cloudCover":0.86,"pressure":1017.27,"ozone":358.43},{"time":1493380800,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0203,"precipProbability":0.01,"precipType":"rain","temperature":10.21,"apparentTemperature":10.21,"dewPoint":5.61,"humidity":0.73,"windSpeed":4.48,"windBearing":213,"visibility":10,"cloudCover":0.89,"pressure":1016.84,"ozone":357.75},{"time":1493384400,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":10.81,"apparentTemperature":10.81,"dewPoint":5.94,"humidity":0.72,"windSpeed":4.47,"windBearing":215,"visibility":10,"cloudCover":0.78,"pressure":1016.38,"ozone":356.29},{"time":1493388000,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":11.36,"apparentTemperature":11.36,"dewPoint":6.21,"humidity":0.71,"windSpeed":4.3,"windBearing":216,"visibility":10,"cloudCover":0.68,"pressure":1015.9,"ozone":354.43},{"time":1493391600,"summary":"Partly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":11.68,"apparentTemperature":11.68,"dewPoint":6.34,"humidity":0.7,"windSpeed":4.09,"windBearing":217,"visibility":10,"cloudCover":0.54,"pressure":1015.49,"ozone":352.78},{"time":1493395200,"summary":"Partly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":11.32,"apparentTemperature":11.32,"dewPoint":5.88,"humidity":0.69,"windSpeed":3.8,"windBearing":208,"visibility":10,"cloudCover":0.52,"pressure":1015.19,"ozone":351.53},{"time":1493398800,"summary":"Partly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":10.75,"apparentTemperature":10.75,"dewPoint":5.32,"humidity":0.69,"windSpeed":3.56,"windBearing":198,"visibility":10,"cloudCover":0.51,"pressure":1014.95,"ozone":350.5},{"time":1493402400,"summary":"Partly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":9.97,"apparentTemperature":9.58,"dewPoint":4.64,"humidity":0.69,"windSpeed":3.42,"windBearing":185,"visibility":10,"cloudCover":0.52,"pressure":1014.69,"ozone":349.81},{"time":1493406000,"summary":"Partly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":8.87,"apparentTemperature":8.24,"dewPoint":4.38,"humidity":0.73,"windSpeed":3.6,"windBearing":165,"visibility":10,"cloudCover":0.57,"pressure":1014.4,"ozone":349.56},{"time":1493409600,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":8.02,"apparentTemperature":7.01,"dewPoint":4.38,"humidity":0.78,"windSpeed":4.18,"windBearing":147,"visibility":10,"cloudCover":0.65,"pressure":1014.1,"ozone":349.65},{"time":1493413200,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.33,"apparentTemperature":5.87,"dewPoint":4.44,"humidity":0.82,"windSpeed":5.01,"windBearing":135,"visibility":10,"cloudCover":0.7,"pressure":1013.8,"ozone":349.97},{"time":1493416800,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.14,"apparentTemperature":5.4,"dewPoint":4.38,"humidity":0.83,"windSpeed":5.71,"windBearing":132,"visibility":10,"cloudCover":0.71,"pressure":1013.49,"ozone":350.51},{"time":1493420400,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.18,"apparentTemperature":5.23,"dewPoint":4.49,"humidity":0.83,"windSpeed":6.35,"windBearing":131,"visibility":10,"cloudCover":0.71,"pressure":1013.18,"ozone":351.27},{"time":1493424000,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.22,"apparentTemperature":5.13,"dewPoint":4.63,"humidity":0.84,"windSpeed":6.85,"windBearing":129,"visibility":10,"cloudCover":0.7,"pressure":1012.87,"ozone":352.18},{"time":1493427600,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.26,"apparentTemperature":5.16,"dewPoint":4.88,"humidity":0.85,"windSpeed":6.94,"windBearing":124,"visibility":10,"cloudCover":0.64,"pressure":1012.55,"ozone":353.32},{"time":1493431200,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.19,"apparentTemperature":5.07,"dewPoint":5.04,"humidity":0.86,"windSpeed":6.96,"windBearing":118,"visibility":10,"cloudCover":0.57,"pressure":1012.22,"ozone":354.61},{"time":1493434800,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.08,"apparentTemperature":4.89,"dewPoint":5.11,"humidity":0.87,"windSpeed":7.12,"windBearing":112,"visibility":10,"cloudCover":0.53,"pressure":1011.91,"ozone":355.8},{"time":1493438400,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0,"precipProbability":0,"temperature":7.2,"apparentTemperature":4.98,"dewPoint":5.29,"humidity":0.88,"windSpeed":7.3,"windBearing":109,"visibility":10,"cloudCover":0.58,"pressure":1011.62,"ozone":356.78},{"time":1493442000,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":7.27,"apparentTemperature":4.98,"dewPoint":5.38,"humidity":0.88,"windSpeed":7.58,"windBearing":107,"visibility":10,"cloudCover":0.68,"pressure":1011.34,"ozone":357.67},{"time":1493445600,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":7.24,"apparentTemperature":4.86,"dewPoint":5.32,"humidity":0.88,"windSpeed":7.96,"windBearing":106,"visibility":10,"cloudCover":0.77,"pressure":1011.08,"ozone":358.58},{"time":1493449200,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":7.68,"apparentTemperature":5.27,"dewPoint":5.44,"humidity":0.86,"windSpeed":8.42,"windBearing":114,"visibility":10,"cloudCover":0.79,"pressure":1010.86,"ozone":359.59},{"time":1493452800,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0,"precipProbability":0,"temperature":8.13,"apparentTemperature":5.66,"dewPoint":5.52,"humidity":0.84,"windSpeed":9.17,"windBearing":121,"visibility":10,"cloudCover":0.79,"pressure":1010.66,"ozone":360.63},{"time":1493456400,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0305,"precipProbability":0.02,"precipType":"rain","temperature":8.63,"apparentTemperature":6.12,"dewPoint":5.66,"humidity":0.82,"windSpeed":9.92,"windBearing":127,"visibility":10,"cloudCover":0.78,"pressure":1010.45,"ozone":361.54},{"time":1493460000,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0864,"precipProbability":0.12,"precipType":"rain","temperature":9.17,"apparentTemperature":6.69,"dewPoint":5.89,"humidity":0.8,"windSpeed":10.41,"windBearing":129,"visibility":10,"cloudCover":0.8,"pressure":1010.21,"ozone":362.29},{"time":1493463600,"summary":"Drizzle","icon":"rain","precipIntensity":0.1549,"precipProbability":0.28,"precipType":"rain","temperature":9.82,"apparentTemperature":7.45,"dewPoint":6.27,"humidity":0.79,"windSpeed":10.7,"windBearing":130,"visibility":10,"cloudCover":0.82,"pressure":1009.97,"ozone":362.92},{"time":1493467200,"summary":"Drizzle","icon":"rain","precipIntensity":0.193,"precipProbability":0.38,"precipType":"rain","temperature":10.52,"apparentTemperature":10.52,"dewPoint":6.69,"humidity":0.77,"windSpeed":10.99,"windBearing":130,"visibility":10,"cloudCover":0.82,"pressure":1009.72,"ozone":363.43},{"time":1493470800,"summary":"Drizzle","icon":"rain","precipIntensity":0.1626,"precipProbability":0.3,"precipType":"rain","temperature":11.12,"apparentTemperature":11.12,"dewPoint":7.24,"humidity":0.77,"windSpeed":11.2,"windBearing":130,"visibility":10,"cloudCover":0.74,"pressure":1009.45,"ozone":363.78}]},"daily":{"summary":"Light rain on Saturday through Monday, with temperatures rising to 15°C on Thursday.","icon":"rain","data":[{"time":1493247600,"summary":"Partly cloudy throughout the day.","icon":"partly-cloudy-day","sunriseTime":1493268270,"sunsetTime":1493322575,"moonPhase":0.04,"precipIntensity":0.0152,"precipIntensityMax":0.094,"precipIntensityMaxTime":1493262000,"precipProbability":0.13,"precipType":"rain","temperatureMin":6.28,"temperatureMinTime":1493251200,"temperatureMax":12.11,"temperatureMaxTime":1493298000,"apparentTemperatureMin":3.81,"apparentTemperatureMinTime":1493251200,"apparentTemperatureMax":12.11,"apparentTemperatureMaxTime":1493298000,"dewPoint":4.66,"humidity":0.76,"windSpeed":10.42,"windBearing":268,"visibility":10,"cloudCover":0.55,"pressure":1019.06,"ozone":367.38},{"time":1493334000,"summary":"Mostly cloudy throughout the day.","icon":"partly-cloudy-day","sunriseTime":1493354532,"sunsetTime":1493409097,"moonPhase":0.07,"precipIntensity":0.0076,"precipIntensityMax":0.0203,"precipIntensityMaxTime":1493380800,"precipProbability":0.01,"precipType":"rain","temperatureMin":6.73,"temperatureMinTime":1493348400,"temperatureMax":11.68,"temperatureMaxTime":1493391600,"apparentTemperatureMin":5.18,"apparentTemperatureMinTime":1493348400,"apparentTemperatureMax":11.68,"apparentTemperatureMaxTime":1493391600,"dewPoint":5.34,"humidity":0.8,"windSpeed":3.13,"windBearing":229,"visibility":10,"cloudCover":0.65,"pressure":1016.93,"ozone":356.99},{"time":1493420400,"summary":"Drizzle in the afternoon.","icon":"rain","sunriseTime":1493440794,"sunsetTime":1493495619,"moonPhase":0.11,"precipIntensity":0.0457,"precipIntensityMax":0.193,"precipIntensityMaxTime":1493467200,"precipProbability":0.38,"precipType":"rain","temperatureMin":7.08,"temperatureMinTime":1493434800,"temperatureMax":11.91,"temperatureMaxTime":1493478000,"apparentTemperatureMin":4.86,"apparentTemperatureMinTime":1493445600,"apparentTemperatureMax":11.91,"apparentTemperatureMaxTime":1493478000,"dewPoint":5.71,"humidity":0.8,"windSpeed":8.81,"windBearing":119,"visibility":10,"cloudCover":0.65,"pressure":1010.01,"ozone":361.12},{"time":1493506800,"summary":"Light rain starting in the evening.","icon":"rain","sunriseTime":1493527058,"sunsetTime":1493582141,"moonPhase":0.15,"precipIntensity":0.061,"precipIntensityMax":0.3251,"precipIntensityMaxTime":1493589600,"precipProbability":0.54,"precipType":"rain","temperatureMin":7.94,"temperatureMinTime":1493528400,"temperatureMax":14,"temperatureMaxTime":1493553600,"apparentTemperatureMin":5,"apparentTemperatureMinTime":1493532000,"apparentTemperatureMax":14,"apparentTemperatureMaxTime":1493553600,"dewPoint":5.32,"humidity":0.72,"windSpeed":13.27,"windBearing":96,"visibility":10,"cloudCover":0.68,"pressure":1003.34,"ozone":375.48},{"time":1493593200,"summary":"Light rain until afternoon.","icon":"rain","sunriseTime":1493613324,"sunsetTime":1493668662,"moonPhase":0.19,"precipIntensity":0.1727,"precipIntensityMax":0.3556,"precipIntensityMaxTime":1493629200,"precipProbability":0.56,"precipType":"rain","temperatureMin":6.85,"temperatureMinTime":1493604000,"temperatureMax":12.95,"temperatureMaxTime":1493650800,"apparentTemperatureMin":3.94,"apparentTemperatureMinTime":1493600400,"apparentTemperatureMax":12.95,"apparentTemperatureMaxTime":1493650800,"dewPoint":6.69,"humidity":0.82,"windSpeed":7.99,"windBearing":110,"visibility":10,"cloudCover":0.75,"pressure":1008.09,"ozone":388.48},{"time":1493679600,"summary":"Mostly cloudy throughout the day.","icon":"partly-cloudy-day","sunriseTime":1493699590,"sunsetTime":1493755184,"moonPhase":0.22,"precipIntensity":0.0279,"precipIntensityMax":0.0584,"precipIntensityMaxTime":1493679600,"precipProbability":0.06,"precipType":"rain","temperatureMin":4.81,"temperatureMinTime":1493762400,"temperatureMax":13.65,"temperatureMaxTime":1493737200,"apparentTemperatureMin":2.11,"apparentTemperatureMinTime":1493762400,"apparentTemperatureMax":13.65,"apparentTemperatureMaxTime":1493737200,"dewPoint":6.5,"humidity":0.87,"windSpeed":8.66,"windBearing":88,"visibility":10,"cloudCover":0.76,"pressure":1023.31,"ozone":374.68},{"time":1493766000,"summary":"Partly cloudy overnight.","icon":"partly-cloudy-night","sunriseTime":1493785858,"sunsetTime":1493841705,"moonPhase":0.26,"precipIntensity":0.0229,"precipIntensityMax":0.0381,"precipIntensityMaxTime":1493791200,"precipProbability":0.03,"precipType":"rain","temperatureMin":1.7,"temperatureMinTime":1493780400,"temperatureMax":13.43,"temperatureMaxTime":1493820000,"apparentTemperatureMin":-0.9,"apparentTemperatureMinTime":1493776800,"apparentTemperatureMax":13.43,"apparentTemperatureMaxTime":1493820000,"dewPoint":3.03,"humidity":0.77,"windSpeed":8.67,"windBearing":72,"cloudCover":0.22,"pressure":1032.22,"ozone":358.61},{"time":1493852400,"summary":"Partly cloudy in the morning.","icon":"partly-cloudy-day","sunriseTime":1493872128,"sunsetTime":1493928225,"moonPhase":0.3,"precipIntensity":0.0203,"precipIntensityMax":0.0305,"precipIntensityMaxTime":1493884800,"precipProbability":0.02,"precipType":"rain","temperatureMin":0.68,"temperatureMinTime":1493863200,"temperatureMax":14.8,"temperatureMaxTime":1493910000,"apparentTemperatureMin":-0.95,"apparentTemperatureMinTime":1493863200,"apparentTemperatureMax":14.8,"apparentTemperatureMaxTime":1493910000,"dewPoint":3.18,"humidity":0.74,"windSpeed":5.44,"windBearing":81,"cloudCover":0.25,"pressure":1032.91,"ozone":354.99}]},"flags":{"sources":["datapoint","gfs","cmc","nam","rap","sref","fnmoc","isd","madis","nearest-precip","metwarn","darksky"],"datapoint-stations":["uk-301777","uk-3134","uk-322052","uk-322595","uk-322659","uk-350056","uk-351269","uk-351289","uk-351397","uk-351465","uk-352102","uk-352379","uk-352954","uk-354999","uk-371524","uk-371606"],"isd-stations":["031070-99999","031160-99999","031200-99999","031290-99999","031330-99999","031340-99999","031350-99999","031360-99999","031380-99999","031390-99999","031400-99999","031430-99999","031450-99999","031480-99999","031490-99999","031520-99999"],"madis-stations":["AU945","C9560","C9739","D4018","E0915","E3381","EGPF","EGPK"],"units":"uk2"}}},"history":["The Justice Department sues to block Microsoft Corp.'s purchase of Intuit, saying the deal could lead to higher software prices and diminish innovation. The suit is one of many in the ongoing struggle between Microsoft and the federal government over the company's domination of the software industry."],"today":"Thursday April 27, 2017 - The 116th day of 2017, and there are 248 days until the end of the year","tv":{"entries":[{"summary":"Archer 8x4 - Archer Dreamland: Ladyfingers","dtstart":"2017-04-27T02:00:00.000Z","dtend":"2017-04-27T02:30:00.000Z","description":"While investigating a kidnapping\\, Archer reveals too much","timeStart":"3:00:00","timeEnd":"3:30:00","duration":"30 minutes","combined":"3:00:00 - 'Archer 8x4 - Archer Dreamland: Ladyfingers, 30 minutes","recur":null,"long":"Thursday, 3:00:00 - ","longcombined":"Thursday, 3:00:00 - Archer 8x4 - Archer Dreamland: Ladyfingers, 30 minutes"},{"summary":"Arrow 5x19 - Dangerous Liaisons","dtstart":"2017-04-27T00:00:00.000Z","dtend":"2017-04-27T01:00:00.000Z","description":"Oliver\\, Team Arrow\\, ARGUS and the SCPD kick off a citywide","timeStart":"1:00:00","timeEnd":"2:00:00","duration":"1 hour","combined":"1:00:00 - 'Arrow 5x19 - Dangerous Liaisons, 1 hour","recur":null,"long":"Thursday, 1:00:00 - ","longcombined":"Thursday, 1:00:00 - Arrow 5x19 - Dangerous Liaisons, 1 hour"}]},"cal":{"today":[{"summary":"Depart Lodging","dtstart":"2017-04-26T23:00:00.000Z","dtend":"2017-04-27T23:00:00.000Z","description":"View and/or edit details in TripIt : https://www.tripit.com/tr","timeStart":"0:00:00","timeEnd":"0:00:00","duration":"1 day","combined":"0:00:00 - 'Depart Lodging, 1 day","recur":null,"long":"Thursday, 0:00:00 - ","longcombined":"Thursday, 0:00:00 - Depart Lodging, 1 day"},{"summary":"SCOTRAIL - Haymarket (Edinburgh) to Glasgow Queen Street","dtstart":"2017-04-27T16:35:00.000Z","dtend":"2017-04-27T17:23:00.000Z","description":"View and/or edit details in TripIt : https://www.tripit.com/tr","timeStart":"17:35:00","timeEnd":"18:23:00","duration":"48 minutes","combined":"17:35:00 - 'SCOTRAIL - Haymarket (Edinburgh) to Glasgow Queen Street, 48 minutes","recur":null,"long":"Thursday, 17:35:00 - ","longcombined":"Thursday, 17:35:00 - SCOTRAIL - Haymarket (Edinburgh) to Glasgow Queen Street, 48 minutes"},{"summary":"SCOTRAIL - Glasgow Queen Street to Dumbarton East","dtstart":"2017-04-27T17:36:00.000Z","dtend":"2017-04-27T18:10:00.000Z","description":"View and/or edit details in TripIt : https://www.tripit.com/tr","timeStart":"18:36:00","timeEnd":"19:10:00","duration":"34 minutes","combined":"18:36:00 - 'SCOTRAIL - Glasgow Queen Street to Dumbarton East, 34 minutes","recur":null,"long":"Thursday, 18:36:00 - ","longcombined":"Thursday, 18:36:00 - SCOTRAIL - Glasgow Queen Street to Dumbarton East, 34 minutes"}],"tomorrow":[{"summary":"Update Timesheet","dtstart":"2017-04-28T14:30:00.351Z","dtend":"2017-04-28T15:30:00.351Z","description":"Update the timesheet using https://outsauce.backofficeportal.co","timeStart":"15:30:00","timeEnd":"16:30:00","duration":"1 hour","combined":"15:30:00 - 'Update Timesheet, 1 hour","recur":"FREQ=WEEKLY;COUNT=15;BYDAY=FR","long":"Friday, 15:30:00 - ","longcombined":"Friday, 15:30:00 - Update Timesheet, 1 hour"},{"summary":"Mark Collins's Birthday","dtstart":"2017-04-27T23:00:00.894Z","dtend":"2017-04-28T23:00:00.894Z","description":"\\n\\n","timeStart":"0:00:00","timeEnd":"0:00:00","duration":"1 day","combined":"0:00:00 - 'Mark Collins's Birthday, 1 day","recur":"FREQ=YEARLY;BYMONTH=4;BYMONTHDAY=28","long":"Friday, 0:00:00 - ","longcombined":"Friday, 0:00:00 - Mark Collins's Birthday, 1 day"}],"week":[{"summary":"Early May Bank Holiday","dtstart":"2017-04-30T23:00:00.000Z","dtend":"2017-05-01T23:00:00.000Z","description":"","timeStart":"0:00:00","timeEnd":"0:00:00","duration":"1 day","combined":"0:00:00 - 'Early May Bank Holiday, 1 day","recur":null,"long":"Monday, 0:00:00 - ","longcombined":"Monday, 0:00:00 - Early May Bank Holiday, 1 day"}]},"swedish":{"xml":{"$":{"xmlns:wotd":"http://www.transparent.com/word-of-the-day/"},"words":{"date":"04-27-2017","langname":"Swedish","wordtype":"noun","word":"(en) kikare","wordsound":"http://wotd.transparent.com/swedish/level-1/sound/00422_WOTD_Swedish_Words.mp3","translation":"binoculars","fnphrase":"Räck mig kikaren, är du snäll.","phrasesound":"http://wotd.transparent.com/swedish/level-1/sound/00422_WOTD_Swedish_Sentences.mp3","enphrase":"Please pass me the binoculars.","wotd:transliteratedWord":"","wotd:transliteratedSentence":"","notes":""}}},"fitbit":{},"ftse":[{"name":"Mediclinic International Plc","price":"857.75","change_amount":"+127.00","change_percent":"+17.37%"},{"name":"Persimmon Plc","price":"2,347.50","change_amount":"+62.00","change_percent":"+2.71%"},{"name":"Lloyds Banking Group Plc","price":"68.94","change_amount":"+1.54","change_percent":"+2.28%"},{"name":"Kingfisher","price":"333.15","change_amount":"+6.30","change_percent":"+1.93%"},{"name":"Taylor Wimpey Plc","price":"201.95","change_amount":"+3.40","change_percent":"+1.71%"},{"name":"Barratt Developments Plc","price":"589.75","change_amount":"+8.00","change_percent":"+1.38%"},{"name":"Next Plc","price":"4,292.50","change_amount":"+50.00","change_percent":"+1.18%"},{"name":"London Stock Exchange Group Plc","price":"3,387.50","change_amount":"+39.00","change_percent":"+1.16%"},{"name":"Johnson Matthey Plc","price":"2,977.00","change_amount":"+27.00","change_percent":"+0.92%"},{"name":"Micro Focus International Plc","price":"2,545.00","change_amount":"+22.00","change_percent":"+0.87%"}],"quotes":{"quote":"Be nice to people on your way up because you meet them on your way down.","author":"Jimmy Durante","category":"Famous"}},"expire":3600000,"date":{"year":2017,"month":4,"day":27}} \ No newline at end of file +{"last":1507886169307,"data":{"trains":{"last":"2017-10-13T09:15:30.476Z","data":[{"title":"Autumn 2017: Leaf fall and slippery rails","description":"Hundreds of trees line our railway. Each autumn the leaves line the tracks and as they become compacted they form a slippery layer that sticks to the tracks. This means trains find it harder to move and need to accelerate and brake gently slowing down our trains and this can potentially disrupt your journey. Throughout autumn we will have specialist trains called treatment trains that will be working across the network removing leaves with a high pressured water cannon and applying a gel to help keep you moving safely. We will have specialist controllers who will be managing all things autumn this year. These staff will manage autumn performance, analyse forecasts and mobilise our response teams to affected areas. Click below to find out more on leaf fall and how we handle this;https://www.scotrail.co.uk/blog/autumn-leaves"}]},"weather":{"currently":"Mostly Cloudy. Around 13 to 17 degrees.","today":"Rain until afternoon and breezy in the morning.","later":"Light rain throughout the week, with temperatures falling to 12°C on Thursday.","alerts":[{"title":"Wind Warning","regions":["Strathclyde","Central, Tayside & Fife","Grampian","Northern Ireland","SW Scotland, Lothian Borders","North East England","North West England","Yorkshire & Humber"],"severity":"advisory","time":1508195100,"expires":1508259600,"description":"A spell of very windy weather is likely on Tuesday in association with ex-Ophelia.\n\nRoad, rail, air and ferry services might be affected, with a slight chance of longer journeys times and some roads and bridges could close. There is a slight chance that power cuts may occur, with the potential to affect other services, such as mobile phone coverage.\n","uri":"http://www.metoffice.gov.uk/public/weather/warnings/"}],"data":{"latitude":55.95,"longitude":-4.566667,"timezone":"Europe/London","currently":{"time":1507886129,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","nearestStormDistance":0,"precipIntensity":0.1397,"precipIntensityError":0.1397,"precipProbability":0.16,"precipType":"rain","temperature":17.02,"apparentTemperature":17.05,"dewPoint":14.84,"humidity":0.87,"pressure":1004.78,"windSpeed":18.01,"windGust":33.08,"windBearing":218,"cloudCover":0.83,"uvIndex":1,"visibility":6.01,"ozone":261.87},"minutely":{"summary":"Possible light rain starting in 11 min., stopping 45 min. later.","icon":"rain","data":[{"time":1507886100,"precipIntensity":0.127,"precipIntensityError":0.127,"precipProbability":0.13,"precipType":"rain"},{"time":1507886160,"precipIntensity":0.1524,"precipIntensityError":0.1524,"precipProbability":0.2,"precipType":"rain"},{"time":1507886220,"precipIntensity":0.1524,"precipIntensityError":0.1524,"precipProbability":0.28,"precipType":"rain"},{"time":1507886280,"precipIntensity":0.1778,"precipIntensityError":0.1778,"precipProbability":0.35,"precipType":"rain"},{"time":1507886340,"precipIntensity":0.1778,"precipIntensityError":0.1778,"precipProbability":0.41,"precipType":"rain"},{"time":1507886400,"precipIntensity":0.1778,"precipIntensityError":0.1524,"precipProbability":0.48,"precipType":"rain"},{"time":1507886460,"precipIntensity":0.1778,"precipIntensityError":0.1524,"precipProbability":0.52,"precipType":"rain"},{"time":1507886520,"precipIntensity":0.1778,"precipIntensityError":0.1524,"precipProbability":0.56,"precipType":"rain"},{"time":1507886580,"precipIntensity":0.1778,"precipIntensityError":0.127,"precipProbability":0.58,"precipType":"rain"},{"time":1507886640,"precipIntensity":0.1778,"precipIntensityError":0.127,"precipProbability":0.6,"precipType":"rain"},{"time":1507886700,"precipIntensity":0.1778,"precipIntensityError":0.1524,"precipProbability":0.64,"precipType":"rain"},{"time":1507886760,"precipIntensity":0.2032,"precipIntensityError":0.1524,"precipProbability":0.68,"precipType":"rain"},{"time":1507886820,"precipIntensity":0.2032,"precipIntensityError":0.2032,"precipProbability":0.69,"precipType":"rain"},{"time":1507886880,"precipIntensity":0.2286,"precipIntensityError":0.2286,"precipProbability":0.74,"precipType":"rain"},{"time":1507886940,"precipIntensity":0.254,"precipIntensityError":0.2286,"precipProbability":0.77,"precipType":"rain"},{"time":1507887000,"precipIntensity":0.2794,"precipIntensityError":0.2794,"precipProbability":0.79,"precipType":"rain"},{"time":1507887060,"precipIntensity":0.3048,"precipIntensityError":0.3048,"precipProbability":0.82,"precipType":"rain"},{"time":1507887120,"precipIntensity":0.3302,"precipIntensityError":0.3556,"precipProbability":0.84,"precipType":"rain"},{"time":1507887180,"precipIntensity":0.381,"precipIntensityError":0.381,"precipProbability":0.85,"precipType":"rain"},{"time":1507887240,"precipIntensity":0.4064,"precipIntensityError":0.4572,"precipProbability":0.87,"precipType":"rain"},{"time":1507887300,"precipIntensity":0.4064,"precipIntensityError":0.4826,"precipProbability":0.88,"precipType":"rain"},{"time":1507887360,"precipIntensity":0.4572,"precipIntensityError":0.5334,"precipProbability":0.88,"precipType":"rain"},{"time":1507887420,"precipIntensity":0.4572,"precipIntensityError":0.5334,"precipProbability":0.89,"precipType":"rain"},{"time":1507887480,"precipIntensity":0.4826,"precipIntensityError":0.5588,"precipProbability":0.87,"precipType":"rain"},{"time":1507887540,"precipIntensity":0.508,"precipIntensityError":0.6096,"precipProbability":0.88,"precipType":"rain"},{"time":1507887600,"precipIntensity":0.5334,"precipIntensityError":0.6096,"precipProbability":0.86,"precipType":"rain"},{"time":1507887660,"precipIntensity":0.5334,"precipIntensityError":0.6096,"precipProbability":0.84,"precipType":"rain"},{"time":1507887720,"precipIntensity":0.5588,"precipIntensityError":0.6604,"precipProbability":0.84,"precipType":"rain"},{"time":1507887780,"precipIntensity":0.5588,"precipIntensityError":0.635,"precipProbability":0.82,"precipType":"rain"},{"time":1507887840,"precipIntensity":0.5588,"precipIntensityError":0.635,"precipProbability":0.8,"precipType":"rain"},{"time":1507887900,"precipIntensity":0.5588,"precipIntensityError":0.635,"precipProbability":0.79,"precipType":"rain"},{"time":1507887960,"precipIntensity":0.5588,"precipIntensityError":0.6604,"precipProbability":0.78,"precipType":"rain"},{"time":1507888020,"precipIntensity":0.5588,"precipIntensityError":0.6858,"precipProbability":0.76,"precipType":"rain"},{"time":1507888080,"precipIntensity":0.5588,"precipIntensityError":0.6604,"precipProbability":0.73,"precipType":"rain"},{"time":1507888140,"precipIntensity":0.5334,"precipIntensityError":0.6858,"precipProbability":0.72,"precipType":"rain"},{"time":1507888200,"precipIntensity":0.5334,"precipIntensityError":0.6604,"precipProbability":0.69,"precipType":"rain"},{"time":1507888260,"precipIntensity":0.508,"precipIntensityError":0.635,"precipProbability":0.68,"precipType":"rain"},{"time":1507888320,"precipIntensity":0.508,"precipIntensityError":0.635,"precipProbability":0.67,"precipType":"rain"},{"time":1507888380,"precipIntensity":0.4826,"precipIntensityError":0.6096,"precipProbability":0.64,"precipType":"rain"},{"time":1507888440,"precipIntensity":0.4826,"precipIntensityError":0.635,"precipProbability":0.63,"precipType":"rain"},{"time":1507888500,"precipIntensity":0.4572,"precipIntensityError":0.6096,"precipProbability":0.61,"precipType":"rain"},{"time":1507888560,"precipIntensity":0.4572,"precipIntensityError":0.6096,"precipProbability":0.59,"precipType":"rain"},{"time":1507888620,"precipIntensity":0.4572,"precipIntensityError":0.6096,"precipProbability":0.58,"precipType":"rain"},{"time":1507888680,"precipIntensity":0.4318,"precipIntensityError":0.5842,"precipProbability":0.55,"precipType":"rain"},{"time":1507888740,"precipIntensity":0.4318,"precipIntensityError":0.5588,"precipProbability":0.52,"precipType":"rain"},{"time":1507888800,"precipIntensity":0.4064,"precipIntensityError":0.508,"precipProbability":0.51,"precipType":"rain"},{"time":1507888860,"precipIntensity":0.381,"precipIntensityError":0.508,"precipProbability":0.48,"precipType":"rain"},{"time":1507888920,"precipIntensity":0.381,"precipIntensityError":0.508,"precipProbability":0.46,"precipType":"rain"},{"time":1507888980,"precipIntensity":0.381,"precipIntensityError":0.5334,"precipProbability":0.44,"precipType":"rain"},{"time":1507889040,"precipIntensity":0.3556,"precipIntensityError":0.4826,"precipProbability":0.42,"precipType":"rain"},{"time":1507889100,"precipIntensity":0.381,"precipIntensityError":0.5334,"precipProbability":0.39,"precipType":"rain"},{"time":1507889160,"precipIntensity":0.3556,"precipIntensityError":0.4572,"precipProbability":0.38,"precipType":"rain"},{"time":1507889220,"precipIntensity":0.3556,"precipIntensityError":0.4826,"precipProbability":0.37,"precipType":"rain"},{"time":1507889280,"precipIntensity":0.3556,"precipIntensityError":0.4826,"precipProbability":0.36,"precipType":"rain"},{"time":1507889340,"precipIntensity":0.3556,"precipIntensityError":0.508,"precipProbability":0.33,"precipType":"rain"},{"time":1507889400,"precipIntensity":0.3556,"precipIntensityError":0.5334,"precipProbability":0.32,"precipType":"rain"},{"time":1507889460,"precipIntensity":0.3556,"precipIntensityError":0.4826,"precipProbability":0.31,"precipType":"rain"},{"time":1507889520,"precipIntensity":0.3556,"precipIntensityError":0.5588,"precipProbability":0.29,"precipType":"rain"},{"time":1507889580,"precipIntensity":0.381,"precipIntensityError":0.5588,"precipProbability":0.28,"precipType":"rain"},{"time":1507889640,"precipIntensity":0.4064,"precipIntensityError":0.635,"precipProbability":0.28,"precipType":"rain"},{"time":1507889700,"precipIntensity":0.4064,"precipIntensityError":0.5842,"precipProbability":0.28,"precipType":"rain"}]},"hourly":{"summary":"Rain until this afternoon.","icon":"rain","data":[{"time":1507885200,"summary":"Light Rain","icon":"rain","precipIntensity":0.922,"precipProbability":0.52,"precipType":"rain","temperature":17.02,"apparentTemperature":17.07,"dewPoint":14.98,"humidity":0.88,"pressure":1004.64,"windSpeed":18.26,"windGust":33.5,"windBearing":215,"cloudCover":0.81,"uvIndex":1,"visibility":5.69,"ozone":262.19},{"time":1507888800,"summary":"Light Rain","icon":"rain","precipIntensity":0.6528,"precipProbability":0.5,"precipType":"rain","temperature":17.47,"apparentTemperature":17.48,"dewPoint":14.87,"humidity":0.85,"pressure":1005.17,"windSpeed":17.45,"windGust":31.85,"windBearing":224,"cloudCover":0.89,"uvIndex":1,"visibility":6.9,"ozone":260.95},{"time":1507892400,"summary":"Rain","icon":"rain","precipIntensity":1.5494,"precipProbability":0.5,"precipType":"rain","temperature":17.67,"apparentTemperature":17.67,"dewPoint":14.65,"humidity":0.83,"pressure":1005.81,"windSpeed":16.31,"windGust":30.03,"windBearing":236,"cloudCover":0.96,"uvIndex":1,"visibility":8.05,"ozone":259.58},{"time":1507896000,"summary":"Rain","icon":"rain","precipIntensity":1.5646,"precipProbability":0.48,"precipType":"rain","temperature":17.53,"apparentTemperature":17.53,"dewPoint":14.21,"humidity":0.81,"pressure":1006.48,"windSpeed":15.44,"windGust":28.61,"windBearing":244,"cloudCover":1,"uvIndex":1,"visibility":9.19,"ozone":259.08},{"time":1507899600,"summary":"Light Rain","icon":"rain","precipIntensity":1.1633,"precipProbability":0.44,"precipType":"rain","temperature":16.86,"apparentTemperature":16.86,"dewPoint":13.37,"humidity":0.8,"pressure":1007.17,"windSpeed":15.48,"windGust":28.29,"windBearing":245,"cloudCover":0.98,"uvIndex":1,"visibility":10,"ozone":259.96},{"time":1507903200,"summary":"Light Rain","icon":"rain","precipIntensity":0.6477,"precipProbability":0.35,"precipType":"rain","temperature":15.99,"apparentTemperature":15.99,"dewPoint":12.31,"humidity":0.79,"pressure":1007.89,"windSpeed":16.06,"windGust":28.71,"windBearing":244,"cloudCover":0.94,"uvIndex":1,"visibility":10,"ozone":261.72},{"time":1507906800,"summary":"Light Rain","icon":"rain","precipIntensity":0.3099,"precipProbability":0.23,"precipType":"rain","temperature":15.12,"apparentTemperature":15.12,"dewPoint":11.43,"humidity":0.79,"pressure":1008.55,"windSpeed":16.18,"windGust":29.01,"windBearing":241,"cloudCover":0.9,"uvIndex":1,"visibility":10,"ozone":262.8},{"time":1507910400,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.1194,"precipProbability":0.12,"precipType":"rain","temperature":14.6,"apparentTemperature":14.6,"dewPoint":10.82,"humidity":0.78,"pressure":1009.07,"windSpeed":15.26,"windGust":28.97,"windBearing":241,"cloudCover":0.84,"uvIndex":0,"visibility":10,"ozone":262.65},{"time":1507914000,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0254,"precipProbability":0.04,"precipType":"rain","temperature":14.33,"apparentTemperature":14.33,"dewPoint":10.34,"humidity":0.77,"pressure":1009.53,"windSpeed":13.88,"windGust":28.8,"windBearing":240,"cloudCover":0.76,"uvIndex":0,"visibility":10,"ozone":261.98},{"time":1507917600,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0102,"precipProbability":0.02,"precipType":"rain","temperature":14.14,"apparentTemperature":14.14,"dewPoint":10.03,"humidity":0.76,"pressure":1009.99,"windSpeed":12.74,"windGust":28.55,"windBearing":240,"cloudCover":0.67,"uvIndex":0,"visibility":10,"ozone":261.43},{"time":1507921200,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0102,"precipProbability":0.01,"precipType":"rain","temperature":14.03,"apparentTemperature":14.03,"dewPoint":9.98,"humidity":0.77,"pressure":1010.51,"windSpeed":12.14,"windGust":28.21,"windBearing":239,"cloudCover":0.55,"uvIndex":0,"visibility":10,"ozone":261.19},{"time":1507924800,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0102,"precipProbability":0.01,"precipType":"rain","temperature":13.74,"apparentTemperature":13.74,"dewPoint":10.08,"humidity":0.79,"pressure":1011.01,"windSpeed":11.8,"windGust":27.77,"windBearing":238,"cloudCover":0.42,"uvIndex":0,"visibility":10,"ozone":261.08},{"time":1507928400,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0102,"precipProbability":0.01,"precipType":"rain","temperature":13.38,"apparentTemperature":13.38,"dewPoint":10.09,"humidity":0.8,"pressure":1011.48,"windSpeed":11.68,"windGust":27.35,"windBearing":237,"cloudCover":0.34,"uvIndex":0,"visibility":10,"ozone":261.05},{"time":1507932000,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0051,"precipProbability":0.01,"precipType":"rain","temperature":13.01,"apparentTemperature":13.01,"dewPoint":9.89,"humidity":0.81,"pressure":1011.89,"windSpeed":11.87,"windGust":27.04,"windBearing":239,"cloudCover":0.36,"uvIndex":0,"visibility":10,"ozone":261.16},{"time":1507935600,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0051,"precipProbability":0.01,"precipType":"rain","temperature":12.87,"apparentTemperature":12.87,"dewPoint":9.58,"humidity":0.8,"pressure":1012.26,"windSpeed":12.27,"windGust":26.76,"windBearing":242,"cloudCover":0.43,"uvIndex":0,"visibility":10,"ozone":261.35},{"time":1507939200,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0051,"precipProbability":0.01,"precipType":"rain","temperature":12.91,"apparentTemperature":12.91,"dewPoint":9.3,"humidity":0.79,"pressure":1012.59,"windSpeed":12.53,"windGust":26.47,"windBearing":243,"cloudCover":0.49,"uvIndex":0,"visibility":10,"ozone":261.19},{"time":1507942800,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0051,"precipProbability":0.01,"precipType":"rain","temperature":12.95,"apparentTemperature":12.95,"dewPoint":9.12,"humidity":0.78,"pressure":1012.85,"windSpeed":12.5,"windGust":26.16,"windBearing":242,"cloudCover":0.5,"uvIndex":0,"visibility":10,"ozone":260.42},{"time":1507946400,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0076,"precipProbability":0.02,"precipType":"rain","temperature":12.86,"apparentTemperature":12.86,"dewPoint":8.98,"humidity":0.77,"pressure":1013.09,"windSpeed":12.3,"windGust":25.82,"windBearing":240,"cloudCover":0.5,"uvIndex":0,"visibility":10,"ozone":259.51},{"time":1507950000,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0152,"precipProbability":0.04,"precipType":"rain","temperature":12.59,"apparentTemperature":12.59,"dewPoint":8.88,"humidity":0.78,"pressure":1013.33,"windSpeed":12.15,"windGust":25.5,"windBearing":239,"cloudCover":0.52,"uvIndex":0,"visibility":10,"ozone":258.76},{"time":1507953600,"summary":"Partly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0279,"precipProbability":0.05,"precipType":"rain","temperature":12.28,"apparentTemperature":12.28,"dewPoint":8.83,"humidity":0.79,"pressure":1013.55,"windSpeed":12.07,"windGust":25.28,"windBearing":238,"cloudCover":0.56,"uvIndex":0,"visibility":10,"ozone":258.5},{"time":1507957200,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0483,"precipProbability":0.07,"precipType":"rain","temperature":12.08,"apparentTemperature":12.08,"dewPoint":8.81,"humidity":0.8,"pressure":1013.76,"windSpeed":12.02,"windGust":25.06,"windBearing":238,"cloudCover":0.63,"uvIndex":0,"visibility":10,"ozone":258.5},{"time":1507960800,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.066,"precipProbability":0.08,"precipType":"rain","temperature":12.06,"apparentTemperature":12.06,"dewPoint":8.83,"humidity":0.81,"pressure":1014.01,"windSpeed":12.02,"windGust":24.58,"windBearing":237,"cloudCover":0.69,"uvIndex":0,"visibility":10,"ozone":258.5},{"time":1507964400,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0635,"precipProbability":0.07,"precipType":"rain","temperature":12.2,"apparentTemperature":12.2,"dewPoint":8.91,"humidity":0.8,"pressure":1014.34,"windSpeed":12.11,"windGust":23.65,"windBearing":237,"cloudCover":0.73,"uvIndex":0,"visibility":10,"ozone":258.63},{"time":1507968000,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0508,"precipProbability":0.06,"precipType":"rain","temperature":12.38,"apparentTemperature":12.38,"dewPoint":9.04,"humidity":0.8,"pressure":1014.69,"windSpeed":12.23,"windGust":22.48,"windBearing":238,"cloudCover":0.77,"uvIndex":0,"visibility":10,"ozone":258.66},{"time":1507971600,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0381,"precipProbability":0.05,"precipType":"rain","temperature":12.47,"apparentTemperature":12.47,"dewPoint":9.16,"humidity":0.8,"pressure":1015.01,"windSpeed":12.22,"windGust":21.4,"windBearing":238,"cloudCover":0.81,"uvIndex":0,"visibility":10,"ozone":258.35},{"time":1507975200,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0254,"precipProbability":0.03,"precipType":"rain","temperature":12.62,"apparentTemperature":12.62,"dewPoint":9.23,"humidity":0.8,"pressure":1015.3,"windSpeed":12,"windGust":20.41,"windBearing":238,"cloudCover":0.84,"uvIndex":1,"visibility":10,"ozone":257.34},{"time":1507978800,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0127,"precipProbability":0.02,"precipType":"rain","temperature":12.93,"apparentTemperature":12.93,"dewPoint":9.28,"humidity":0.79,"pressure":1015.56,"windSpeed":11.66,"windGust":19.49,"windBearing":237,"cloudCover":0.86,"uvIndex":1,"visibility":10,"ozone":255.98},{"time":1507982400,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0102,"precipProbability":0.02,"precipType":"rain","temperature":13.35,"apparentTemperature":13.35,"dewPoint":9.33,"humidity":0.77,"pressure":1015.72,"windSpeed":11.15,"windGust":18.86,"windBearing":235,"cloudCover":0.88,"uvIndex":1,"visibility":10,"ozone":254.7},{"time":1507986000,"summary":"Mostly Cloudy","icon":"partly-cloudy-day","precipIntensity":0.0203,"precipProbability":0.03,"precipType":"rain","temperature":13.62,"apparentTemperature":13.62,"dewPoint":9.36,"humidity":0.75,"pressure":1015.78,"windSpeed":10.36,"windGust":18.28,"windBearing":232,"cloudCover":0.92,"uvIndex":1,"visibility":10,"ozone":253.81},{"time":1507989600,"summary":"Overcast","icon":"cloudy","precipIntensity":0.0432,"precipProbability":0.07,"precipType":"rain","temperature":13.64,"apparentTemperature":13.64,"dewPoint":9.38,"humidity":0.75,"pressure":1015.77,"windSpeed":9.34,"windGust":17.99,"windBearing":228,"cloudCover":0.95,"uvIndex":1,"visibility":10,"ozone":253.14},{"time":1507993200,"summary":"Overcast","icon":"cloudy","precipIntensity":0.0686,"precipProbability":0.1,"precipType":"rain","temperature":13.61,"apparentTemperature":13.61,"dewPoint":9.55,"humidity":0.76,"pressure":1015.65,"windSpeed":8.52,"windGust":18.69,"windBearing":221,"cloudCover":0.98,"uvIndex":0,"visibility":9.74,"ozone":252.4},{"time":1507996800,"summary":"Overcast","icon":"cloudy","precipIntensity":0.0711,"precipProbability":0.11,"precipType":"rain","temperature":13.78,"apparentTemperature":13.78,"dewPoint":9.92,"humidity":0.78,"pressure":1015.36,"windSpeed":7.92,"windGust":20.91,"windBearing":212,"cloudCover":0.99,"uvIndex":0,"visibility":8.89,"ozone":251.61},{"time":1508000400,"summary":"Overcast","icon":"cloudy","precipIntensity":0.0762,"precipProbability":0.13,"precipType":"rain","temperature":14.19,"apparentTemperature":14.19,"dewPoint":10.41,"humidity":0.78,"pressure":1014.98,"windSpeed":7.54,"windGust":24.13,"windBearing":200,"cloudCover":0.99,"uvIndex":0,"visibility":8.04,"ozone":250.86},{"time":1508004000,"summary":"Overcast","icon":"cloudy","precipIntensity":0.0838,"precipProbability":0.15,"precipType":"rain","temperature":14.66,"apparentTemperature":14.66,"dewPoint":10.83,"humidity":0.78,"pressure":1014.52,"windSpeed":7.8,"windGust":27.46,"windBearing":191,"cloudCover":0.99,"uvIndex":0,"visibility":7.19,"ozone":250.35},{"time":1508007600,"summary":"Overcast","icon":"cloudy","precipIntensity":0.0762,"precipProbability":0.16,"precipType":"rain","temperature":14.98,"apparentTemperature":14.98,"dewPoint":11.12,"humidity":0.78,"pressure":1014.01,"windSpeed":9.13,"windGust":31.05,"windBearing":187,"cloudCover":1,"uvIndex":0,"visibility":9.75,"ozone":250.36},{"time":1508011200,"summary":"Overcast","icon":"cloudy","precipIntensity":0.0864,"precipProbability":0.2,"precipType":"rain","temperature":15.01,"apparentTemperature":15.01,"dewPoint":11.36,"humidity":0.79,"pressure":1013.44,"windSpeed":11.03,"windGust":34.75,"windBearing":186,"cloudCover":1,"uvIndex":0,"visibility":10,"ozone":250.63},{"time":1508014800,"summary":"Overcast","icon":"cloudy","precipIntensity":0.1041,"precipProbability":0.24,"precipType":"rain","temperature":14.82,"apparentTemperature":14.82,"dewPoint":11.56,"humidity":0.81,"pressure":1012.88,"windSpeed":12.71,"windGust":37.13,"windBearing":186,"cloudCover":0.99,"uvIndex":0,"visibility":10,"ozone":250.6},{"time":1508018400,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0838,"precipProbability":0.26,"precipType":"rain","temperature":14.57,"apparentTemperature":14.57,"dewPoint":11.68,"humidity":0.83,"pressure":1012.32,"windSpeed":13.92,"windGust":37.18,"windBearing":191,"cloudCover":0.93,"uvIndex":0,"visibility":10,"ozone":250.06},{"time":1508022000,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0559,"precipProbability":0.25,"precipType":"rain","temperature":14.47,"apparentTemperature":14.47,"dewPoint":11.72,"humidity":0.84,"pressure":1011.76,"windSpeed":14.97,"windGust":35.94,"windBearing":197,"cloudCover":0.85,"uvIndex":0,"visibility":10,"ozone":249.24},{"time":1508025600,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0432,"precipProbability":0.25,"precipType":"rain","temperature":14.6,"apparentTemperature":14.6,"dewPoint":11.73,"humidity":0.83,"pressure":1011.19,"windSpeed":15.76,"windGust":34.94,"windBearing":201,"cloudCover":0.8,"uvIndex":0,"visibility":9.1,"ozone":248.46},{"time":1508029200,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.033,"precipProbability":0.24,"precipType":"rain","temperature":14.83,"apparentTemperature":14.83,"dewPoint":11.7,"humidity":0.82,"pressure":1010.63,"windSpeed":16.21,"windGust":34.83,"windBearing":202,"cloudCover":0.78,"uvIndex":0,"visibility":9.17,"ozone":247.84},{"time":1508032800,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0254,"precipProbability":0.23,"precipType":"rain","temperature":14.93,"apparentTemperature":14.93,"dewPoint":11.63,"humidity":0.81,"pressure":1010.09,"windSpeed":16.4,"windGust":34.98,"windBearing":201,"cloudCover":0.79,"uvIndex":0,"visibility":9.25,"ozone":247.2},{"time":1508036400,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.0305,"precipProbability":0.24,"precipType":"rain","temperature":14.84,"apparentTemperature":14.84,"dewPoint":11.6,"humidity":0.81,"pressure":1009.55,"windSpeed":16.59,"windGust":34.87,"windBearing":199,"cloudCover":0.81,"uvIndex":0,"visibility":9.32,"ozone":246.75},{"time":1508040000,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.061,"precipProbability":0.28,"precipType":"rain","temperature":14.64,"apparentTemperature":14.64,"dewPoint":11.61,"humidity":0.82,"pressure":1009.01,"windSpeed":16.9,"windGust":34.14,"windBearing":200,"cloudCover":0.81,"uvIndex":0,"visibility":10,"ozone":246.34},{"time":1508043600,"summary":"Mostly Cloudy","icon":"partly-cloudy-night","precipIntensity":0.1245,"precipProbability":0.31,"precipType":"rain","temperature":14.48,"apparentTemperature":14.48,"dewPoint":11.66,"humidity":0.83,"pressure":1008.49,"windSpeed":17.22,"windGust":33.18,"windBearing":201,"cloudCover":0.82,"uvIndex":0,"visibility":10,"ozone":246.11},{"time":1508047200,"summary":"Drizzle","icon":"rain","precipIntensity":0.1854,"precipProbability":0.33,"precipType":"rain","temperature":14.44,"apparentTemperature":14.44,"dewPoint":11.75,"humidity":0.84,"pressure":1008.05,"windSpeed":17.41,"windGust":32.73,"windBearing":201,"cloudCover":0.84,"uvIndex":0,"visibility":10,"ozone":245.85},{"time":1508050800,"summary":"Drizzle","icon":"rain","precipIntensity":0.2261,"precipProbability":0.34,"precipType":"rain","temperature":14.54,"apparentTemperature":14.54,"dewPoint":11.9,"humidity":0.84,"pressure":1007.72,"windSpeed":17.39,"windGust":33.34,"windBearing":200,"cloudCover":0.89,"uvIndex":0,"visibility":10,"ozone":245.71},{"time":1508054400,"summary":"Light Rain","icon":"rain","precipIntensity":0.2972,"precipProbability":0.36,"precipType":"rain","temperature":14.66,"apparentTemperature":14.66,"dewPoint":12.1,"humidity":0.85,"pressure":1007.47,"windSpeed":17.23,"windGust":34.49,"windBearing":199,"cloudCover":0.95,"uvIndex":0,"visibility":10,"ozone":245.73},{"time":1508058000,"summary":"Light Rain","icon":"rain","precipIntensity":0.3734,"precipProbability":0.37,"precipType":"rain","temperature":14.8,"apparentTemperature":14.8,"dewPoint":12.31,"humidity":0.85,"pressure":1007.3,"windSpeed":17.11,"windGust":35.44,"windBearing":198,"cloudCover":1,"uvIndex":0,"visibility":9.32,"ozone":245.57}]},"daily":{"summary":"Light rain throughout the week, with temperatures falling to 12°C on Thursday.","icon":"rain","data":[{"time":1507849200,"summary":"Rain until afternoon and breezy in the morning.","icon":"rain","sunriseTime":1507877192,"sunsetTime":1507915482,"moonPhase":0.78,"precipIntensity":0.5563,"precipIntensityMax":1.5646,"precipIntensityMaxTime":1507896000,"precipProbability":0.57,"precipType":"rain","temperatureHigh":17.67,"temperatureHighTime":1507892400,"temperatureLow":12.06,"temperatureLowTime":1507960800,"apparentTemperatureHigh":17.67,"apparentTemperatureHighTime":1507892400,"apparentTemperatureLow":12.06,"apparentTemperatureLowTime":1507960800,"dewPoint":12.95,"humidity":0.84,"pressure":1006.89,"windSpeed":15.69,"windGust":38.25,"windGustTime":1507852800,"windBearing":222,"cloudCover":0.81,"uvIndex":1,"uvIndexTime":1507885200,"visibility":10,"ozone":264.96,"temperatureMin":13.01,"temperatureMinTime":1507932000,"temperatureMax":17.67,"temperatureMaxTime":1507892400,"apparentTemperatureMin":13.01,"apparentTemperatureMinTime":1507932000,"apparentTemperatureMax":17.67,"apparentTemperatureMaxTime":1507892400},{"time":1507935600,"summary":"Mostly cloudy throughout the day.","icon":"partly-cloudy-day","sunriseTime":1507963714,"sunsetTime":1508001731,"moonPhase":0.82,"precipIntensity":0.0457,"precipIntensityMax":0.1041,"precipIntensityMaxTime":1508014800,"precipProbability":0.26,"precipType":"rain","temperatureHigh":14.66,"temperatureHighTime":1508004000,"temperatureLow":14.44,"temperatureLowTime":1508047200,"apparentTemperatureHigh":14.66,"apparentTemperatureHighTime":1508004000,"apparentTemperatureLow":14.44,"apparentTemperatureLowTime":1508047200,"dewPoint":9.68,"humidity":0.79,"pressure":1014.2,"windSpeed":10.43,"windGust":37.18,"windGustTime":1508018400,"windBearing":226,"cloudCover":0.79,"uvIndex":1,"uvIndexTime":1507975200,"visibility":10,"ozone":255.59,"temperatureMin":12.06,"temperatureMinTime":1507960800,"temperatureMax":15.01,"temperatureMaxTime":1508011200,"apparentTemperatureMin":12.06,"apparentTemperatureMinTime":1507960800,"apparentTemperatureMax":15.01,"apparentTemperatureMaxTime":1508011200},{"time":1508022000,"summary":"Light rain throughout the day.","icon":"rain","sunriseTime":1508050237,"sunsetTime":1508087981,"moonPhase":0.86,"precipIntensity":0.2743,"precipIntensityMax":0.6401,"precipIntensityMaxTime":1508086800,"precipProbability":0.37,"precipType":"rain","temperatureHigh":17.35,"temperatureHighTime":1508076000,"temperatureLow":13.17,"temperatureLowTime":1508130000,"apparentTemperatureHigh":17.35,"apparentTemperatureHighTime":1508076000,"apparentTemperatureLow":13.17,"apparentTemperatureLowTime":1508130000,"dewPoint":12.22,"humidity":0.82,"pressure":1008.67,"windSpeed":14.44,"windGust":36.3,"windGustTime":1508072400,"windBearing":205,"cloudCover":0.93,"uvIndex":1,"uvIndexTime":1508061600,"visibility":10,"ozone":245.3,"temperatureMin":14.33,"temperatureMinTime":1508104800,"temperatureMax":17.35,"temperatureMaxTime":1508076000,"apparentTemperatureMin":14.33,"apparentTemperatureMinTime":1508104800,"apparentTemperatureMax":17.35,"apparentTemperatureMaxTime":1508076000},{"time":1508108400,"summary":"Breezy starting in the afternoon and light rain starting in the evening.","icon":"rain","sunriseTime":1508136761,"sunsetTime":1508174231,"moonPhase":0.89,"precipIntensity":0.094,"precipIntensityMax":0.5207,"precipIntensityMaxTime":1508187600,"precipProbability":0.36,"precipType":"rain","temperatureHigh":15.08,"temperatureHighTime":1508148000,"temperatureLow":12.47,"temperatureLowTime":1508180400,"apparentTemperatureHigh":15.08,"apparentTemperatureHighTime":1508148000,"apparentTemperatureLow":12.47,"apparentTemperatureLowTime":1508180400,"dewPoint":9.53,"humidity":0.75,"pressure":1009.13,"windSpeed":12.57,"windGust":37.47,"windGustTime":1508180400,"windBearing":157,"cloudCover":0.93,"uvIndex":1,"uvIndexTime":1508148000,"visibility":9.7,"ozone":246.61,"temperatureMin":12.47,"temperatureMinTime":1508180400,"temperatureMax":15.08,"temperatureMaxTime":1508148000,"apparentTemperatureMin":12.47,"apparentTemperatureMinTime":1508180400,"apparentTemperatureMax":15.08,"apparentTemperatureMaxTime":1508148000},{"time":1508194800,"summary":"Light rain throughout the day and breezy until afternoon.","icon":"rain","sunriseTime":1508223285,"sunsetTime":1508260483,"moonPhase":0.93,"precipIntensity":0.5766,"precipIntensityMax":1.1303,"precipIntensityMaxTime":1508263200,"precipProbability":0.37,"precipType":"rain","temperatureHigh":15,"temperatureHighTime":1508220000,"temperatureLow":12.08,"temperatureLowTime":1508263200,"apparentTemperatureHigh":15,"apparentTemperatureHighTime":1508220000,"apparentTemperatureLow":12.08,"apparentTemperatureLowTime":1508263200,"dewPoint":9.52,"humidity":0.78,"pressure":1000.3,"windSpeed":21.3,"windGust":52.03,"windGustTime":1508220000,"windBearing":202,"cloudCover":0.97,"uvIndex":1,"uvIndexTime":1508234400,"visibility":10,"ozone":271.88,"temperatureMin":12.08,"temperatureMinTime":1508263200,"temperatureMax":15,"temperatureMaxTime":1508220000,"apparentTemperatureMin":12.08,"apparentTemperatureMinTime":1508263200,"apparentTemperatureMax":15,"apparentTemperatureMaxTime":1508220000},{"time":1508281200,"summary":"Light rain throughout the day and breezy in the morning.","icon":"rain","sunriseTime":1508309809,"sunsetTime":1508346735,"moonPhase":0.96,"precipIntensity":0.4851,"precipIntensityMax":0.8153,"precipIntensityMaxTime":1508295600,"precipProbability":0.32,"precipType":"rain","temperatureHigh":13.65,"temperatureHighTime":1508317200,"temperatureLow":10.42,"temperatureLowTime":1508367600,"apparentTemperatureHigh":13.65,"apparentTemperatureHighTime":1508317200,"apparentTemperatureLow":10.42,"apparentTemperatureLowTime":1508367600,"dewPoint":8.62,"humidity":0.77,"pressure":992.1,"windSpeed":17.05,"windGust":49.33,"windGustTime":1508353200,"windBearing":229,"cloudCover":0.96,"uvIndex":1,"uvIndexTime":1508320800,"visibility":10,"ozone":286.65,"temperatureMin":10.58,"temperatureMinTime":1508364000,"temperatureMax":13.65,"temperatureMaxTime":1508317200,"apparentTemperatureMin":10.58,"apparentTemperatureMinTime":1508364000,"apparentTemperatureMax":13.65,"apparentTemperatureMaxTime":1508317200},{"time":1508367600,"summary":"Light rain in the morning and overnight and breezy in the morning.","icon":"rain","sunriseTime":1508396334,"sunsetTime":1508432988,"moonPhase":0.99,"precipIntensity":0.1702,"precipIntensityMax":0.3556,"precipIntensityMaxTime":1508385600,"precipProbability":0.59,"precipType":"rain","temperatureHigh":11.67,"temperatureHighTime":1508421600,"temperatureLow":9.09,"temperatureLowTime":1508479200,"apparentTemperatureHigh":11.67,"apparentTemperatureHighTime":1508421600,"apparentTemperatureLow":6.22,"apparentTemperatureLowTime":1508482800,"dewPoint":6.19,"humidity":0.73,"pressure":992.75,"windSpeed":14.7,"windGust":47.58,"windGustTime":1508367600,"windBearing":270,"cloudCover":0.79,"uvIndex":1,"uvIndexTime":1508407200,"ozone":321.16,"temperatureMin":10.04,"temperatureMinTime":1508450400,"temperatureMax":11.67,"temperatureMaxTime":1508421600,"apparentTemperatureMin":10.04,"apparentTemperatureMinTime":1508450400,"apparentTemperatureMax":11.67,"apparentTemperatureMaxTime":1508421600},{"time":1508454000,"summary":"Rain throughout the day.","icon":"rain","sunriseTime":1508482859,"sunsetTime":1508519243,"moonPhase":0.03,"precipIntensity":0.7315,"precipIntensityMax":2.4155,"precipIntensityMaxTime":1508479200,"precipProbability":0.7,"precipType":"rain","temperatureHigh":14.23,"temperatureHighTime":1508504400,"temperatureLow":10.34,"temperatureLowTime":1508536800,"apparentTemperatureHigh":14.23,"apparentTemperatureHighTime":1508504400,"apparentTemperatureLow":10.34,"apparentTemperatureLowTime":1508536800,"dewPoint":6.77,"humidity":0.75,"pressure":995.68,"windSpeed":3.92,"windGust":30.3,"windGustTime":1508454000,"windBearing":150,"cloudCover":0.71,"uvIndex":1,"uvIndexTime":1508493600,"ozone":288.68,"temperatureMin":9.09,"temperatureMinTime":1508479200,"temperatureMax":14.23,"temperatureMaxTime":1508504400,"apparentTemperatureMin":6.22,"apparentTemperatureMinTime":1508482800,"apparentTemperatureMax":14.23,"apparentTemperatureMaxTime":1508504400}]},"alerts":[{"title":"Wind Warning","regions":["Strathclyde","Central, Tayside & Fife","Grampian","Northern Ireland","SW Scotland, Lothian Borders","North East England","North West England","Yorkshire & Humber"],"severity":"advisory","time":1508195100,"expires":1508259600,"description":"A spell of very windy weather is likely on Tuesday in association with ex-Ophelia.\n\nRoad, rail, air and ferry services might be affected, with a slight chance of longer journeys times and some roads and bridges could close. There is a slight chance that power cuts may occur, with the potential to affect other services, such as mobile phone coverage.\n","uri":"http://www.metoffice.gov.uk/public/weather/warnings/"}],"flags":{"sources":["datapoint","isd","nearest-precip","metwarn","cmc","gfs","madis","darksky"],"datapoint-stations":["uk-301777","uk-3134","uk-322052","uk-322595","uk-322659","uk-350056","uk-351269","uk-351289","uk-351397","uk-351465","uk-352102","uk-352379","uk-352954","uk-354999","uk-371524","uk-371606"],"isd-stations":["031070-99999","031160-99999","031200-99999","031290-99999","031330-99999","031340-99999","031350-99999","031360-99999","031380-99999","031390-99999","031400-99999","031430-99999","031450-99999","031480-99999","031490-99999","031520-99999"],"units":"uk2"},"offset":1}},"history":["This day in 1713 saw the birth of Allan Ramsay, the Enlightenment painter.","His father was another Allan Ramsay, well known for his poetry. After studying in Italy, Allan Jr. became renowned as one of the best portrait painters of the Rococo era, and painted subjects as important as the future King George III."],"today":"Friday October 13, 2017 - The 285th day of 2017, and there are 79 days until the end of the year","tv":{"entries":[{"summary":"Arrow 6x1 - Fallout","dtstart":"2017-10-13T01:00:00.000Z","dtend":"2017-10-13T02:00:00.000Z","description":"The future of the team is left hanging in the balance after the","timeStart":"2:00:00","timeEnd":"3:00:00","duration":"1 hour","combined":"2:00:00 - 'Arrow 6x1 - Fallout, 1 hour","recur":null,"timeStartMS":7200000,"timeEndMS":10800000,"long":"Friday, 2:00:00 - ","longcombined":"Friday, 2:00:00 - Arrow 6x1 - Fallout, 1 hour"},{"summary":"The Orville 1x6 - Krill","dtstart":"2017-10-13T01:00:00.000Z","dtend":"2017-10-13T02:00:00.000Z","description":"After the Orville crew defeats a Krill attack on a brand-new","timeStart":"2:00:00","timeEnd":"3:00:00","duration":"1 hour","combined":"2:00:00 - 'The Orville 1x6 - Krill, 1 hour","recur":null,"timeStartMS":7200000,"timeEndMS":10800000,"long":"Friday, 2:00:00 - ","longcombined":"Friday, 2:00:00 - The Orville 1x6 - Krill, 1 hour"}]},"cal":{"today":[{"summary":"Update Timesheet","dtstart":"2017-10-13T14:30:00.000Z","dtend":"2017-10-13T15:30:00.000Z","description":"Update the timesheet using https://outsauce.backofficeportal.co","timeStart":"15:30:00","timeEnd":"16:30:00","duration":"1 hour","combined":"15:30:00 - 'Update Timesheet, 1 hour","recur":"FREQ=WEEKLY;COUNT=15;BYDAY=FR","timeStartMS":55800000,"timeEndMS":59400000,"long":"Friday, 15:30:00 - ","longcombined":"Friday, 15:30:00 - Update Timesheet, 1 hour","details":{"_d":12,"_m":1,"_h":15,"_min":30,"_secs":0,"distance":3600000}}],"tomorrow":[],"week":[{"summary":"Farmers market","dtstart":"2017-10-15T10:00:00.000Z","dtend":"2017-10-15T16:00:00.000Z","description":"http://www.farmshop.uk.com/events/loch-lomond-shores-farmers-ma","timeStart":"10:00:00","timeEnd":"16:00:00","duration":"6 hours","combined":"10:00:00 - 'Farmers market, 6 hours","recur":"FREQ=MONTHLY;BYDAY=3SU","timeStartMS":36000000,"timeEndMS":57600000,"long":"Sunday, 10:00:00 - ","longcombined":"Sunday, 10:00:00 - Farmers market, 6 hours","details":{"_d":21,"_m":11,"_h":10,"_min":0,"_secs":0,"distance":21600000}},{"summary":"Bins out","dtstart":"2017-10-16T23:00:00.000Z","dtend":"2017-10-17T23:00:00.000Z","description":"","timeStart":"0:00:00","timeEnd":"0:00:00","duration":"1 day","combined":"0:00:00 - 'Bins out, 1 day","recur":"FREQ=WEEKLY;INTERVAL=2;BYDAY=TU","timeStartMS":0,"timeEndMS":0,"long":"Tuesday, 0:00:00 - ","longcombined":"Tuesday, 0:00:00 - Bins out, 1 day","details":{"_d":13,"_m":0,"_h":0,"_min":0,"_secs":0,"distance":86400000}}]},"swedish":{"xml":{"$":{"xmlns:wotd":"http://www.transparent.com/word-of-the-day/"},"words":{"date":"10-13-2017","langname":"Swedish","wordtype":"expression","word":"åtminstone","wordsound":"http://wotd.transparent.com/swedish/level-1/sound/00114_WOTD_Swedish_Words.mp3","translation":"at least","fnphrase":"Han gjorde åtminstone något; alla andra bara såg på.","phrasesound":"http://wotd.transparent.com/swedish/level-1/sound/00114_WOTD_Swedish_Sentences.mp3","enphrase":"At least he did something; everyone else just watched.","wotd:transliteratedWord":"","wotd:transliteratedSentence":"","notes":""}}},"fitbit":{},"ftse":[{"name":"Pearson Plc","price":"638.75","change_amount":"+17.00","change_percent":"+2.73%"},{"name":"Kingfisher","price":"308.40","change_amount":"+4.50","change_percent":"+1.48%"},{"name":"G4S Plc","price":"282.90","change_amount":"+4.00","change_percent":"+1.43%"},{"name":"Rio Tinto Plc","price":"3,627.25","change_amount":"+46.00","change_percent":"+1.28%"},{"name":"Johnson Matthey Plc","price":"3,446.50","change_amount":"+39.00","change_percent":"+1.14%"},{"name":"Marks & Spencer Group Plc","price":"353.30","change_amount":"+3.30","change_percent":"+0.94%"},{"name":"BHP Billiton Plc","price":"1,387.00","change_amount":"+11.50","change_percent":"+0.84%"},{"name":"Glencore Plc","price":"370.95","change_amount":"+2.95","change_percent":"+0.80%"},{"name":"Sainsbury (J) Plc","price":"241.80","change_amount":"+1.90","change_percent":"+0.79%"},{"name":"ConvaTec Group Plc","price":"282.45","change_amount":"+1.60","change_percent":"+0.57%"}],"quotes":{"quote":"Women might be able to fake orgasms. But men can fake a whole relationship.","author":"Sharon Stone","category":"Famous"}},"expire":3600000,"date":{"year":2017,"month":10,"day":13}} \ No newline at end of file diff --git a/lib/test.js b/lib/test.js new file mode 100644 index 0000000..3e56e4c --- /dev/null +++ b/lib/test.js @@ -0,0 +1,31 @@ +const http = require('http'); +const request = require('request'); +const cheerio = require('cheerio'); +const util = require('util'); +const cron = require('node-cron'); +const dateFormat = require('dateformat'); +const jsonfile = require('jsonfile'); +const fs = require('fs'); +const LocalStorage = require('node-localstorage').LocalStorage; +// var nano = require('nano')('http://martind2000:1V3D4m526i@localhost:5984'); +const logger = require('log4js').getLogger(); +const Sugar = require('sugar'); + +const calHandler = require('./today/calHandler'); +const swedishWord = require('./today/swedishword'); +const weather = require('./today/weather'); +const trains = require('./today/trains'); +const history = require('./today/history'); +const mdMailer = require('./today/mailer'); +const todayFTSE = require('./today/todayftse'); +const quotes = require('./today/quotes'); + +history.updateHistory() + .then((d) => { + 'use strict'; + logger.debug('History result: ', d); + }) + .catch((e) => { + 'use strict'; + console.error(e); + }); diff --git a/lib/today/calHandler.js b/lib/today/calHandler.js index f6eb850..b400b04 100644 --- a/lib/today/calHandler.js +++ b/lib/today/calHandler.js @@ -1,17 +1,19 @@ const request = require('request'); const log4js = require('log4js'); -const logger = log4js.getLogger(); +const logger = log4js.getLogger('calHandler'); const STRING = require('string'); const util = require('util'); const Elapsed = require('elapsed'); const Sugar = require('sugar'); +Sugar.extend(); + logger.level = 'debug'; function processICAL(ical) { 'use strict'; logger.info('+ processICAL'); - const workingBlock = []; + let workingBlock = []; const segments = { 'meetingStartID': 'DTSTART;TZID=Europe/London:', 'meetingStartAlt': 'DTSTART:', @@ -39,8 +41,13 @@ function processICAL(ical) { } function processRecurrence(workBlock) { - const _workBlock = workBlock; - // logger.debug('Processing recurrence...'); + const _workBlock = Object.assign({}, workBlock); + const dateLimit = new Date().reset('month').addMonths(2); + const recurArray = []; + logger.info('---===---'); + logger.debug('>> Processing recurrence...'); + logger.debug(`Expanding ${_workBlock.summary}`); + logger.debug('DateLimit:', dateLimit); // logger.debug('Processing recurrence...'); const weekBits = { 'SU': 0, 'MO': 1, 'TU': 2, 'WE': 3, 'TH': 4, 'FR': 5, 'SA': 6 }; @@ -49,6 +56,7 @@ function processICAL(ical) { const dayNum = now.getDay(); const month = now.getMonth(); const year = now.getFullYear(); + const byDayRegEx = /(\d)(\w.)/; const recurSettings = { 'freq': null, 'wkst': null, 'until': null, 'bymonth': null, 'bymonthday': null, 'interval': null, 'byday': null }; @@ -65,20 +73,26 @@ function processICAL(ical) { if (recurSettings.freq === null && recurSettings.wkst === null && recurSettings.until === null && recurSettings.byday === null && recurSettings.bymonth === null && recurSettings.bymonthday === null && recurSettings.interval === null) return null; - if (recurSettings.until !== null) + if (recurSettings.until !== null) { // have we expired? - // var _until = Date.create(recurSettings.until).isPast(); - return null; + const _until = Date.create(recurSettings.until).isPast(); + if (_until) { + logger.warn('EXPIRED!!'); + + return null; + } + } if (recurSettings.freq !== null) { // logger.debug(_workBlock); let newStart, newEnd; - // let d = new Sugar.Date(); - /* origStart = Date.create(_workBlock.dtstart); - origEnd = Date.create(_workBlock.dtend);*/ - const origStart = new Sugar.Date(_workBlock.dtstart).raw; - const origEnd = new Sugar.Date(_workBlock.dtend).raw; + const origStart = new Date(_workBlock.dtstart); + const origEnd = new Date(_workBlock.dtend); + + const _dstart = new Date(_workBlock.dtstart); + const _dend = new Date(_workBlock.dtend); + logger.debug('>> origStart', origStart); const _d = origStart.getDate(); const _m = origStart.getMonth(); @@ -87,57 +101,141 @@ function processICAL(ical) { const _secs = origStart.getSeconds(); const distance = origEnd - origStart; - // Sugar.Date() + _workBlock.details = { + _d, + _m, + _h, + _min, + _secs, + distance + }; + + logger.debug('freq:', recurSettings.freq); if (recurSettings.freq === 'YEARLY') { + logger.warn('YEARLY'); if (recurSettings.bymonth !== null && recurSettings.bymonthday !== null) { - // ok, a day and month. - newStart = Sugar.Date().set({ 'year':year, 'month': recurSettings.bymonth - 1, 'day': recurSettings.bymonthday, 'hour':_h, 'minutes':_min, 'seconds':_secs }).raw; - newEnd = Sugar.Date(newStart).addMilliseconds(distance).raw; - _workBlock.dtstart = newStart; - _workBlock.dtend = newEnd; + let _yearCount = year; + logger.debug('>> Yearly with specific month / day'); + let newBlock; + newStart = new Date().set({ 'year':_yearCount, 'month': recurSettings.bymonth - 1, 'day': recurSettings.bymonthday, 'hour':_h, 'minutes':_min, 'seconds':_secs }); + newEnd = new Date(_dstart).addMilliseconds(distance); + do { + newBlock = Object.assign({}, _workBlock); + newBlock.dstart = new Date(newStart); + newBlock.dend = new Date(newEnd); + + recurArray.push(newBlock); + _yearCount++; + newStart = new Date().set({ 'year':_yearCount, 'month': recurSettings.bymonth - 1, 'day': recurSettings.bymonthday, 'hour':_h, 'minutes':_min, 'seconds':_secs }); + newEnd = new Date(_dstart).addMilliseconds(distance); + } + while(newStart < dateLimit); } else if (recurSettings.bymonth === null && recurSettings.bymonthday === null) { + logger.debug('>> Yearly no specific month / day'); // extract month and year from dtstart - newStart = Sugar.Date().set({ 'year':year, 'month': _m, 'day': _d, 'hour':_h, 'minutes':_min, 'seconds':_secs }).raw; - newEnd = Sugar.Date(newStart).addMilliseconds(distance).raw; - _workBlock.dtstart = newStart; - _workBlock.dtend = newEnd; + let newBlock; + do { + newBlock = Object.assign({}, _workBlock); + newBlock.dtstart = new Date(_dstart); + newBlock.dtend = new Date(_dend); + logger.info(newBlock.dtstart.medium()); + recurArray.push(newBlock); + + _dstart.advance({ 'year':1 }); + _dend.advance({ 'year':1 }); + } + while(_dstart < dateLimit); } - return _workBlock; + // logger.info('** recurArray', recurArray); + + return recurArray; } - if (recurSettings.freq === 'MONTHLY') - if (recurSettings.bymonthday !== null) { - // ok, a day and month. - newStart = Sugar.Date().set({ 'year':year, 'month': month, 'day': recurSettings.bymonthday, 'hour':_h, 'minutes':_min, 'seconds':_secs }).raw; - newEnd = Sugar.Date(newStart).addMilliseconds(distance).raw; + if (recurSettings.freq === 'MONTHLY' ) { + const interval = parseInt(recurSettings.interval, 10) || 1; + logger.warn(`MONTHLY - ${interval}`); + let newBlock; + if (recurSettings.byday === null) + do { + newBlock = Object.assign({}, _workBlock); + newBlock.dtstart = new Date(_dstart); + newBlock.dtend = new Date(_dend); + logger.info(newBlock.dtstart.medium()); + recurArray.push(newBlock); - _workBlock.dtstart = newStart; - _workBlock.dtend = newEnd; + _dstart.addMonths(interval); + _dend.addMonths(interval); + } + while(_dstart < dateLimit); + + else { + logger.warn('BYDAY!!! ', recurSettings.byday); + _dstart.setUTC(true); + const byday = byDayRegEx.exec(recurSettings.byday); + const dayNumber = weekBits[byday[2]]; + const stepCount = parseInt(byday[1], 10) - 1; + + do { + const _findSun = new Date.create(_dstart, { 'fromUTC': true } ).reset('month'); + + const firstDay = _findSun.getDay(); + // find first occurance of the wanted day. + + if (firstDay !== dayNumber) { + const add = (dayNumber - firstDay + 7) ; + _findSun.addDays(add).addWeeks(stepCount); + } + else + _findSun.addWeeks(stepCount); + + newBlock = Object.assign({}, _workBlock); + newBlock.dtstart = new Date(_findSun).addMilliseconds(_workBlock.timeStartMS); + newBlock.dtend = new Date(_findSun).addMilliseconds(_workBlock.timeEndMS); + logger.info(newBlock.dtstart.medium()); + recurArray.push(newBlock); + // all done, next. + _dstart.reset('month').addDays(32); + _dend.reset('month').addDays(32); + } + while(_dstart < dateLimit); + + // something } - if (recurSettings.freq === 'WEEKLY' && recurSettings.interval === null) { - const byDayBit = recurSettings.byday.split(',')[0]; - const byDayNumber = weekBits[byDayBit]; - if (byDayNumber >= dayNum) { - const daysAdded = byDayNumber - dayNum; - newStart = Sugar.Date().set({ 'year':year, 'month': month, 'day': day, 'hour':_h, 'minutes':_min, 'seconds':_secs }).addDays(daysAdded).raw; - newEnd = Sugar.Date(newStart).addMilliseconds(distance).raw; - _workBlock.dtstart = newStart; - _workBlock.dtend = newEnd; - } + return recurArray; } + + if (recurSettings.freq === 'WEEKLY') { + const interval = parseInt(recurSettings.interval, 10) || 1; + logger.warn(`WEEKLY - ${interval}`); + let newBlock; + + do { + newBlock = Object.assign({}, _workBlock); + newBlock.dtstart = new Date(_dstart); + newBlock.dtend = new Date(_dend); + logger.info(newBlock.dtstart.medium()); + recurArray.push(newBlock); + + _dstart.addWeeks(interval); + _dend.addWeeks(interval); + } + while(_dstart < dateLimit); + } + + return recurArray; } // if we get here we've skipped everything just return the _workblock - return _workBlock; + return []; } function processBlock(block) { let _wb; - let workBlock = { + const workBlock = { 'summary': '', 'dtstart': null, 'dtend': null, @@ -146,7 +244,9 @@ function processICAL(ical) { 'timeEnd': null, 'duration': 0, 'combined': '', - 'recur': null + 'recur': null, + 'timeStartMS': null, + 'timeEndMS': null }; let alarmFlag = false, ws, blockStep; for (let step = 0; step < block.length; step++) { @@ -170,17 +270,17 @@ function processICAL(ical) { } if (blockStep.indexOf(segments.meetingStartAlt) >= 0) { ws = STRING(block[step].split(segments.meetingStartAlt)[1]).collapseWhitespace().s; - console.log('>> ws', ws); + // console.log('>> ws', ws); // workBlock.dtstart = Date.create(ws); // let d = new Sugar.Date(); workBlock.dtstart = new Sugar.Date(ws).raw; - console.log('>> date', workBlock.dtstart); + // console.log('>> date', workBlock.dtstart); } if (blockStep.indexOf(segments.meetingEndAlt) >= 0) { ws = STRING(block[step].split(segments.meetingEndAlt)[1]).collapseWhitespace().s; // workBlock.dtend = Date.create(ws); workBlock.dtend = new Sugar.Date(ws).raw; - console.log('>> date', workBlock.dtend); + // console.log('>> date', workBlock.dtend); } if (blockStep.indexOf(segments.meetingStartAltOther) >= 0) { @@ -190,7 +290,7 @@ function processICAL(ical) { } if (blockStep.indexOf(segments.meetingEndAltOther) >= 0) { ws = STRING(block[step].split(segments.meetingEndAltOther)[1]).collapseWhitespace().s; - console.log('>> ws', ws); + // console.log('>> ws', ws); // workBlock.dtend = Date.create(ws); workBlock.dtend = new Sugar.Date(ws).raw; } @@ -204,34 +304,23 @@ function processICAL(ical) { alarmFlag = true; } - // We have to check recuring stuff before the cron stuff is processed. - - if (workBlock.recur !== null) { - _wb = processRecurrence(workBlock); - // logger.warn('returning:', _wb); - if (_wb !== null) - if (!Array.isArray(_wb)) { - workBlock = _wb; - } - else { - logger.error('We made an array'); - } - } - // logger.debug(workBlock); - // let d = new Sugar.Date(); if (workBlock.dtstart !== null) { // workBlock.timeStart = workBlock.dtstart.format('{24hr}:{mm}:{ss}'); workBlock.timeStart = Sugar.Date(workBlock.dtstart).format('{24hr}:{mm}:{ss}').raw; - console.log('>> workBlock.timeStart', workBlock.timeStart); + workBlock.timeStartMS = ((workBlock.dtstart.getHours() * 60 * 60 ) + (workBlock.dtstart.getMinutes() * 60 ) + workBlock.dtstart.getSeconds()) * 1000; + // console.log('>> workBlock.timeStart', workBlock.timeStart); workBlock.combined = `${workBlock.timeStart} - '`; workBlock.long = `${Sugar.Date(workBlock.dtstart).format('{Weekday}').raw}, ${workBlock.timeStart} - `; - console.log('>> workBlock.long', workBlock.long); + // console.log('>> workBlock.long', workBlock.long); } workBlock.combined = workBlock.combined + workBlock.summary; workBlock.longcombined = workBlock.long + workBlock.summary; - if (workBlock.dtend !== null) + if (workBlock.dtend !== null) { workBlock.timeEnd = Sugar.Date(workBlock.dtend).format('{24hr}:{mm}:{ss}').raw; + workBlock.timeEndMS = ((workBlock.dtend.getHours() * 60 * 60 ) + (workBlock.dtend.getMinutes() * 60 ) + workBlock.dtend.getSeconds()) * 1000; + } + if (workBlock.dtstart !== null && workBlock.dtend !== null) { const elapsedTime = new Elapsed(workBlock.dtstart, workBlock.dtend); @@ -243,6 +332,12 @@ function processICAL(ical) { return workBlock; } + function buildRecurranceArray(wb) { + const _wb = processRecurrence(wb); + + return _wb; + } + const lines = ical.split('\r\n'), l = lines.length; let counter = 0; @@ -272,11 +367,21 @@ function processICAL(ical) { counter = counter + subcounter; const b = processBlock(subBlock); - if (Array.isArray(b)) - logger.error('!returned an array...'); - else - if (b.dtstart !== null) - workingBlock.push(b); + + if (!b.recur ) { + if (Array.isArray(b)) + logger.error('!returned an array...'); + else + if (b.dtstart !== null) + workingBlock.push(b); + } + else { + // logger.warn('We need to spread the recurrance!!'); + // logger.debug(b); + const recurBlocks = buildRecurranceArray(b); + if (recurBlocks && recurBlocks.length > 0) + workingBlock = workingBlock.concat(recurBlocks); + } } logger.info('- processICAL'); @@ -290,7 +395,9 @@ module.exports = { 'https://calendar.google.com/calendar/ical/mt5pgdhknvgoc8usfnrso9vkv0%40group.calendar.google.com/private-58876002af9f302a593acfa6fa792dcf/basic.ics', 'https://www.tripit.com/feed/ical/private/DB96E4BB-94A9BD8F9CC1CF51C6CC0D920840F4F5/tripit.ics', 'https://calendar.google.com/calendar/ical/en.uk%23holiday%40group.v.calendar.google.com/public/basic.ics', - 'https://calendar.google.com/calendar/ical/i8dglj12p5nuv20sbjmun5s588%40group.calendar.google.com/private-c8adccb41e56d6a2f285078aaed313f5/basic.ics'], + 'https://calendar.google.com/calendar/ical/i8dglj12p5nuv20sbjmun5s588%40group.calendar.google.com/private-c8adccb41e56d6a2f285078aaed313f5/basic.ics', + 'https://calendar.google.com/calendar/ical/qppj4ebvdur1qui4v0fdpl7l70%40group.calendar.google.com/private-b5071cb2c3fe49544ffbbd08645088f1/basic.ics', + 'https://calendar.google.com/calendar/ical/8h3vi3rd5rvpfe11klvgre0q4c%40group.calendar.google.com/private-e9df93163a7046658946be45fb08db6f/basic.ics'], 'jsonBlock': [], 'getTodaysSimple': function() { 'use strict'; @@ -299,13 +406,14 @@ module.exports = { 'entries': [] }; - for (let t = 0; t < this.jsonBlock.length; t++) { - // if (this.jsonBlock[t].dtstart.isToday()) - // logger.debug('>> isToday', Sugar.Date(this.jsonBlock[t].dtstart).isToday().raw); - if (Sugar.Date(this.jsonBlock[t].dtstart).isToday().raw) + const _td = new Date.create('today'); + const _tm = new Date.create('tomorrow'); + today.entries = this.jsonBlock.filter((item) => { + if (!item || !item.dtstart || !item.dtend) return false; - today.entries.push(this.jsonBlock[t]); - } + return item.dtstart.isBetween(_td, _tm) || item.dtend.isBetween(_td, _tm); + }); + logger.info('- getTodaysSimple'); return today; @@ -317,10 +425,13 @@ module.exports = { 'entries': [] }; - for (let t = 0; t < this.jsonBlock.length; t++) - if (Sugar.Date(this.jsonBlock[t].dtstart).isTomorrow().raw) + const _tm = new Date.create('tomorrow'); + const _da = new Date.create('tomorrow').addDays(1); + today.entries = this.jsonBlock.filter((item) => { + if (!item || !item.dtstart || !item.dtend) return false; - today.entries.push(this.jsonBlock[t]); + return item.dtstart.isBetween(_tm, _da) || item.dtend.isBetween(_tm, _da); + }); logger.info('- getTomorrow'); @@ -333,19 +444,24 @@ module.exports = { 'entries': [] }; - const now = new Sugar.Date('today').raw; + const now = new Date.create('today'); logger.debug('>> now', now); - const twoDays = new Sugar.Date('today').addDays(2).beginningOfDay().raw; + const twoDays = new Date.create('today').addDays(2).beginningOfDay(); logger.debug('>> twoDays', twoDays); - const sevenDays = new Sugar.Date('today').addDays(7).beginningOfDay().raw; + const sevenDays = new Date.create('today').addDays(7).beginningOfDay(); logger.debug('>> sevenDays', sevenDays); logger.debug('>> trip', { now, twoDays, sevenDays }); - for (let t = 0; t < this.jsonBlock.length; t++) { - logger.debug('>> between', Sugar.Date(this.jsonBlock[t].dtstart).raw, Sugar.Date(this.jsonBlock[t].dtstart).isBetween(twoDays, sevenDays)); - if (Sugar.Date(this.jsonBlock[t].dtstart).isBetween(twoDays, sevenDays).raw) - today.entries.push(this.jsonBlock[t]); - } + /* for (let t = 0; t < this.jsonBlock.length; t++) + // logger.debug('>> between', Sugar.Date(this.jsonBlock[t].dtstart).raw, Sugar.Date(this.jsonBlock[t].dtstart).isBetween(twoDays, sevenDays)); + if (Date(this.jsonBlock[t].dtstart).isBetween(twoDays, sevenDays)) + today.entries.push(this.jsonBlock[t]);*/ + + today.entries = this.jsonBlock.filter((item) => { + if (!item || !item.dtstart || !item.dtend) return false; + + return item.dtstart.isBetween(twoDays, sevenDays) || item.dtend.isBetween(twoDays, sevenDays); + }); logger.info('- getWeek'); @@ -419,14 +535,14 @@ module.exports = { self.jsonBlock = processICAL(body); - // logger.debug(self.jsonBlock); + logger.debug(self.jsonBlock); const st = self.getTodaysSimple(); return resolve(st); }, function(error, response, body) { if (response.statusCode !== 200) { logger.error(response.statusCode); - logger.error(body); + // logger.error(body); return reject(error); } @@ -454,6 +570,7 @@ module.exports = { self.jsonBlock = processICAL(body); + logger.debug('jsonBlock length', self.jsonBlock.length); // logger.debug(self.jsonBlock); const st = self.getTodaysSimple().entries; const tom = self.getTomorrow().entries; @@ -467,7 +584,7 @@ module.exports = { }, function(error, response, body) { if (response.statusCode !== 200) { logger.error(response.statusCode); - logger.error(body); + // logger.error(body); return reject(error); } diff --git a/lib/today/history.js b/lib/today/history.js index 8886a22..3e07f34 100644 --- a/lib/today/history.js +++ b/lib/today/history.js @@ -1,15 +1,15 @@ -var request = require('request'); -var cheerio = require('cheerio'); -var STRING = require('string'); -var logger = require('log4js').getLogger(); +const request = require('request'); +const cheerio = require('cheerio'); +const STRING = require('string'); +const logger = require('log4js').getLogger('history'); module.exports = { 'getTechHistory': function() { - var url; - var d; - var day; - var month; - var monthNames = [ + let url; + let d; + let day; + let month; + const monthNames = [ 'January', 'February', 'March', @@ -42,13 +42,12 @@ module.exports = { return reject(err); // Throw err; - var $ = cheerio.load(body); - var tdihbody = $('#tdihbody'); + const $ = cheerio.load(body); + const tdihbody = $('#tdihbody .tdihevent'); + const output = []; - var output = []; - - tdihbody.find('.tdihevent > p').each(function(div) { - var s = $(this).text(); + tdihbody.find('p').each(function(div) { + const s = $(this).text(); output.push(STRING(s).collapseWhitespace().s); }); @@ -63,11 +62,11 @@ module.exports = { }); }); }, 'getHistory': function() { - var url; - var d = new Date(); - var day; - var month; - var monthNames = [ + let url; + const d = new Date(); + let day; + let month; + const monthNames = [ 'january', 'february', 'march', @@ -100,13 +99,13 @@ module.exports = { return reject(err); // Throw err; - var $ = cheerio.load(body); + const $ = cheerio.load(body); - var nbody = $('DIV#bbcPageContent').first(); - var output = []; + const nbody = $('DIV#bbcPageContent').first(); + const output = []; nbody.find('.story > p').each(function(div) { - var s = $(this).text(); + const s = $(this).text(); if (s.indexOf('Today\'s recipe:') == -1) output.push(s); }); @@ -124,8 +123,8 @@ module.exports = { }, 'updateHistory': function() { 'use strict'; - var output = []; - + let output = []; + return new Promise(function(resolve, reject) { module.exports.getHistory() .then((d) => { diff --git a/lib/today/mailer.js b/lib/today/mailer.js index 4251349..84e5d36 100644 --- a/lib/today/mailer.js +++ b/lib/today/mailer.js @@ -7,7 +7,7 @@ */ var jade = require('pug'), UltraSES = require('ultrases'), dateFormat = require('dateformat'); -var logger = require('log4js').getLogger(); +var logger = require('log4js').getLogger('mailer'); var mailer = new UltraSES({ aws: { diff --git a/lib/today/quotes.js b/lib/today/quotes.js index 23afaa2..5235c05 100644 --- a/lib/today/quotes.js +++ b/lib/today/quotes.js @@ -1,43 +1,40 @@ /** * Created by Martin on 31/03/2016. */ -var https = require('https'); +const https = require('https'); -var STRING = require('string'); -var logger = require('log4js').getLogger(); - -var options = { - host: 'andruxnet-random-famous-quotes.p.mashape.com', - path: '/?cat=famous', - headers: { - accept: "application/json", - "X-Mashape-Key": "5A0H980jK6mshSFL24ZmfiRrNHV2p1d1fhQjsngtx8QWuO9oe4", - 'Content-Type': "application/x-www-form-urlencoded" - - }, - method: 'GET' - }; +const STRING = require('string'); +const logger = require('log4js').getLogger('quotes'); +const options = { + 'host': 'andruxnet-random-famous-quotes.p.mashape.com', + 'path': '/?cat=famous', + 'headers': { + 'accept': 'application/json', + 'X-Mashape-Key': '5A0H980jK6mshSFL24ZmfiRrNHV2p1d1fhQjsngtx8QWuO9oe4', + 'Content-Type': 'application/x-www-form-urlencoded' + }, + 'method': 'GET' +}; module.exports = { - GetQuotes: function() { - 'use strict'; - return new Promise(function(resolve, reject) { - https.request(options).on('response', function (response) { - var data = ''; - response.on("data", function (chunk) { - data += chunk; - }); - response.on('end', function () { - //console.log(data); - //callback(JSON.parse(data)); - resolve(JSON.parse(data)); - }); - }).end(); - + 'GetQuotes': function() { + 'use strict'; + + return new Promise(function(resolve, reject) { + https.request(options).on('response', function (response) { + let data = ''; + response.on('data', function (chunk) { + data += chunk; }); - } - + response.on('end', function () { + // console.log(data); + // callback(JSON.parse(data)); + resolve(JSON.parse(data)); + }); + }).end(); + }); + } }; diff --git a/lib/today/swedishword.js b/lib/today/swedishword.js index 9ee4b80..f26390f 100644 --- a/lib/today/swedishword.js +++ b/lib/today/swedishword.js @@ -1,41 +1,38 @@ /** * Created by Martin on 15/02/2016. */ -let http = require('http'); +const http = require('http'); const request = require('request'); -let util = require('util'); -const logger = require('log4js').getLogger(); +const util = require('util'); +const logger = require('log4js').getLogger('swedish'); const to_json = require('xmljson').to_json; require('sugar-date'); module.exports = { - getSwedishWord: function () { - return new Promise(function(resolve, reject) { + 'getSwedishWord': function () { + return new Promise(function(resolve, reject) { + const t = new Date(), ms = t.getTime(); - const t = new Date(), ms = t.getTime(); - - const url = ['http://wotd.transparent.com/rss/swedish-widget.xml?t=', ms].join(''); - // logger.info(url); - request(url, function (err, resp, body) { - if (err) { - return reject(err); - } - - to_json(body, function (error, data) { - return resolve(data); - }); - - }, function(error, response, body) { - if(response.statusCode !== 200) { - logger.error(response.statusCode); - logger.error(body); - return reject(error); - } - }); + const url = ['http://wotd.transparent.com/rss/swedish-widget.xml?t=', ms].join(''); + // logger.info(url); + request(url, function (err, resp, body) { + if (err) + return reject(err); + to_json(body, function (error, data) { + return resolve(data); }); - } + }, function(error, response, body) { + if(response.statusCode !== 200) { + logger.error(response.statusCode); + logger.error(body); + + return reject(error); + } + }); + }); + } }; -//module.exports.getSwedishWord(); +// module.exports.getSwedishWord(); diff --git a/lib/today/todayftse.js b/lib/today/todayftse.js index 6a30b0b..1301bda 100644 --- a/lib/today/todayftse.js +++ b/lib/today/todayftse.js @@ -9,21 +9,17 @@ const ftse = require('ftse'); module.exports = { - getFTSE: function() { - + 'getFTSE': function() { return new Promise(function(resolve, reject) { - "use strict"; + 'use strict'; - let err = 0; + const err = 0; ftse('100', 10, 'risers', function(items) { - - if (items === err) { + if (items === err) return reject(err); - } + return resolve(items); }); - }); - } }; diff --git a/lib/today/trains.js b/lib/today/trains.js index 3e3acc9..bf8cb17 100644 --- a/lib/today/trains.js +++ b/lib/today/trains.js @@ -1,131 +1,122 @@ /** * Created by Martin on 31/03/2016. */ -let STRING = require('string'); -const logger = require('log4js').getLogger(); +const STRING = require('string'); +const logger = require('log4js').getLogger('trains'); const request = require('request'), cheerio = require('cheerio'); const _ = require('lodash'); const trainList = [ - { - id: 'dbeglq', - url: 'http://www.journeycheck.com/scotrail/route?from=DBE&to=GLQ&action=search&savedRoute=' - }, - { - id: 'glqhym', - url: 'http://www.journeycheck.com/scotrail/route?from=GLQ&to=HYM&action=search&savedRoute=' - } + { + 'id': 'dbeglq', + 'url': 'http://www.journeycheck.com/scotrail/route?from=DBE&to=GLQ&action=search&savedRoute=' + }, + { + 'id': 'glqhym', + 'url': 'http://www.journeycheck.com/scotrail/route?from=GLQ&to=HYM&action=search&savedRoute=' + } ]; module.exports = { - processTrainUpdates: function (body) { - const outputArray = []; - const $ = cheerio.load(body); - const lu = $('DIV#LU').first(); + 'processTrainUpdates': function (body) { + const outputArray = []; + const $ = cheerio.load(body); + const lu = $('DIV#LU').first(); - const us = lu.find('.updatesSection').first(); - us.find('.updateTitle').each(function (div) { - const wO = {title: '', description: ''}; - title = $(this).find('A').first().text().trim(); - wO.title = title; - outputArray.push(wO); - }); + const us = lu.find('.updatesSection').first(); + us.find('.updateTitle').each(function (div) { + const wO = { 'title': '', 'description': '' }; + title = $(this).find('A').first().text().trim(); + wO.title = title; + outputArray.push(wO); + }); - us.find('.updateBodyStart').each(function (div) { + us.find('.updateBodyStart').each(function (div) { + let description = $(this).find('.bodyInner').first().find('.primaryStyle').first().text().trim(); + const splitDesc = description.split('\r\n'); - let description = $(this).find('.bodyInner').first().find('.primaryStyle').first().text().trim(); - const splitDesc = description.split('\r\n'); + const wa = []; + for (let i = 0; i < splitDesc.length; i++) { + let contentCheck = splitDesc[i].trim(); + if (contentCheck.indexOf('Impact') > -1) contentCheck = ''; + if (contentCheck.indexOf('Additional Information') > -1) contentCheck = ''; + if (contentCheck.indexOf('apologise for the delay') > -1) contentCheck = ''; + if (contentCheck.indexOf('Delay Repay') > -1) contentCheck = ''; + if (contentCheck.length > 0) wa.push(contentCheck); + } + description = wa.join(' '); + outputArray[div].description = description; + }); - const wa = []; - for (let i = 0; i < splitDesc.length; i++) { - let contentCheck = splitDesc[i].trim(); - if (contentCheck.indexOf('Impact') > -1) contentCheck = ''; - if (contentCheck.indexOf('Additional Information') > -1) contentCheck = ''; - if (contentCheck.indexOf('apologise for the delay') > -1) contentCheck = ''; - if (contentCheck.indexOf('Delay Repay') > -1) contentCheck = ''; - if (contentCheck.length > 0) wa.push(contentCheck); - } - description = wa.join(' '); - outputArray[div].description = description; - }); + return outputArray; + }, 'getTrainUpdates': function (id, out) { + return new Promise(function (resolve, reject) { + 'use strict'; + logger.info('Getting train events: ', id); + const url = trainList[id].url; - return outputArray; + const now = new Date(); - }, getTrainUpdates: function (id, out) { + // if ((now - eventCache.last) > eventCache.expire) { + request(url, function (err, resp, body) { + if (err) + // logger.error(err); + return reject(err); + // throw err; - return new Promise(function (resolve, reject) { - "use strict"; - logger.info('Getting train events: ', id); - const url = trainList[id].url; + let trainData = module.exports.processTrainUpdates(body); - let now = new Date(); + for (let i = 0; i < out.length; i++) { + let flag = false; + for (let j = 0; j < trainData.length; j++) + flag = _.isEqual(trainData[j], out[i]); - // if ((now - eventCache.last) > eventCache.expire) { - request(url, function (err, resp, body) { - if (err) { - // logger.error(err); - return reject(err); - // throw err; - } + if (!flag) + trainData.push(out[i]); + } + trainData = _.uniq(trainData); - let trainData = module.exports.processTrainUpdates(body); + return resolve(trainData); + }, function (error, response, body) { + if (response.statusCode !== 200) { + logger.error(response.statusCode); + logger.error(body); + } + if (error) + // logger.error(err); + return reject(err); + // throw err; + }); + }); + }, 'updateTrains': function () { + logger.info('New Updating trains..'); - for (let i = 0; i < out.length; i++) { - let flag = false; - for (let j = 0; j < trainData.length; j++) { - flag = _.isEqual(trainData[j], out[i]) - } + const output = []; + + return new Promise(function (resolve, reject) { + 'use strict'; + module.exports.getTrainUpdates(0, []) + .then((d) => { + 'use strict'; - if (!flag) { - trainData.push(out[i]); - } - } - trainData = _.uniq(trainData); - - return resolve(trainData); - - }, function (error, response, body) { - if (response.statusCode !== 200) { - logger.error(response.statusCode); - logger.error(body); - } - if (error) { - // logger.error(err); - return reject(err); - // throw err; - } + module.exports.getTrainUpdates(1, d) + .then((d) => { + 'use strict'; + + return resolve(d); + }) + .catch((e) => { + 'use strict'; + + return reject(e); }); - + }) + .catch((e) => { + 'use strict'; + + return reject(e); }); - - }, updateTrains: function () { - logger.info('New Updating trains..'); - - let output = []; - return new Promise(function (resolve, reject) { - "use strict"; - module.exports.getTrainUpdates(0, []) - .then((d)=> { - "use strict"; - - module.exports.getTrainUpdates(1, d) - .then((d)=> { - "use strict"; - return resolve(d); - - }) - .catch((e)=> { - "use strict"; - return reject(e); - }); - - }) - .catch((e)=> { - "use strict"; - return reject(e); - }); - }); - - } + }); + } }; diff --git a/lib/today/weather.js b/lib/today/weather.js index f34f1ef..8561bee 100644 --- a/lib/today/weather.js +++ b/lib/today/weather.js @@ -3,7 +3,7 @@ */ const Forecast = require('forecast.io'); const STRING = require('string'); -const logger = require('log4js').getLogger(); +const logger = require('log4js').getLogger('weather'); const forecastOptions = { 'APIKey': '9ad2a41d420f3cf4960571bb886f710c', 'units': 'uk2' diff --git a/lib/todayV2.js b/lib/todayV2.js index bbedbfc..007f7e4 100644 --- a/lib/todayV2.js +++ b/lib/todayV2.js @@ -8,10 +8,12 @@ const util = require('util'); const cron = require('node-cron'); const dateFormat = require('dateformat'); const jsonfile = require('jsonfile'); -let fs = require('fs'); -let LocalStorage = require('node-localstorage').LocalStorage; -//var nano = require('nano')('http://martind2000:1V3D4m526i@localhost:5984'); +const fs = require('fs'); +const LocalStorage = require('node-localstorage').LocalStorage; +// var nano = require('nano')('http://martind2000:1V3D4m526i@localhost:5984'); const logger = require('log4js').getLogger(); +const Sugar = require('sugar'); + const calHandler = require('./today/calHandler'); const swedishWord = require('./today/swedishword'); const weather = require('./today/weather'); @@ -21,8 +23,8 @@ const mdMailer = require('./today/mailer'); const mdFitbit = require('./today/fitbit'); const todayFTSE = require('./today/todayftse'); const quotes = require('./today/quotes'); -//var db_name = 'silvrgit'; -//var dbCloudant = nano.use(db_name); +// var db_name = 'silvrgit'; +// var dbCloudant = nano.use(db_name); /* @@ -30,175 +32,173 @@ const quotes = require('./today/quotes'); https://25f854ee-1b51-49ff-acd9-5b0ff478d944-bluemix.cloudant.com/dashboard.html#usage - */ localStorage = new LocalStorage('./scratch'); const credentials = { - "username": "25f854ee-1b51-49ff-acd9-5b0ff478d944-bluemix", - "password": "8e417af1b0462ca55726848846cc6b8696fc76defe9d1864cbc334be59549e0c", - "host": "25f854ee-1b51-49ff-acd9-5b0ff478d944-bluemix.cloudant.com", - "port": 443, - "url": "https://25f854ee-1b51-49ff-acd9-5b0ff478d944-bluemix:8e417af1b0462ca55726848846cc6b8696fc76defe9d1864cbc334be59549e0c@25f854ee-1b51-49ff-acd9-5b0ff478d944-bluemix.cloudant.com", - "database": "today" + 'username': '25f854ee-1b51-49ff-acd9-5b0ff478d944-bluemix', + 'password': '8e417af1b0462ca55726848846cc6b8696fc76defe9d1864cbc334be59549e0c', + 'host': '25f854ee-1b51-49ff-acd9-5b0ff478d944-bluemix.cloudant.com', + 'port': 443, + 'url': 'https://25f854ee-1b51-49ff-acd9-5b0ff478d944-bluemix:8e417af1b0462ca55726848846cc6b8696fc76defe9d1864cbc334be59549e0c@25f854ee-1b51-49ff-acd9-5b0ff478d944-bluemix.cloudant.com', + 'database': 'today' }; const Cloudant = require('cloudant'); -const cloudant = Cloudant({account: credentials.username, password: credentials.password}); +const cloudant = Cloudant({ 'account': credentials.username, 'password': credentials.password }); const dbCloudant = cloudant.db.use(credentials.database); - -require('sugar-date'); - String.prototype.hashCode = function () { - - if (Array.prototype.reduce) { - return this.split('').reduce(function (a, b) { - a = ((a << 5) - a) + b.charCodeAt(0); - return a & a - }, 0); - } else { - - let hash = 0, i, chr, len; - if (this.length === 0) return hash; - for (i = 0, len = this.length; i < len; i++) { - chr = this.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; - hash |= 0; // Convert to 32bit integer - } - return hash; + if (Array.prototype.reduce) + return this.split('').reduce(function (a, b) { + a = ((a << 5) - a) + b.charCodeAt(0); + + return a & a; + }, 0); + else { + let hash = 0, i, chr, len; + if (this.length === 0) return hash; + for (i = 0, len = this.length; i < len; i++) { + chr = this.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; // Convert to 32bit integer } + + return hash; + } }; -let todayCacheSrc = { - last: 0, data: { - trains: {last: 0, data: []}, - weather: {}, - history: [], - today: '', - tv: {entries: []}, - cal: {today: [], tomorrow: [], week: []}, - swedish: {}, - fitbit: {}, - ftse: {} - }, expire: ((60 * 1000) * 60) +const todayCacheSrc = { + 'last': 0, 'data': { + 'trains': { 'last': 0, 'data': [] }, + 'weather': {}, + 'history': [], + 'today': '', + 'tv': { 'entries': [] }, + 'cal': { 'today': [], 'tomorrow': [], 'week': [] }, + 'swedish': {}, + 'fitbit': {}, + 'ftse': {} + }, 'expire': ((60 * 1000) * 60) }; let todayCache = { - last: 0, data: { - trains: {last: 0, data: []}, - weather: {}, - history: [], - today: '', - tv: {entries: []}, - cal: {today: [], tomorrow: [], week: []}, - swedish: {}, - fitbit: {}, - ftse: {} - }, expire: ((60 * 1000) * 60) + 'last': 0, 'data': { + 'trains': { 'last': 0, 'data': [] }, + 'weather': {}, + 'history': [], + 'today': '', + 'tv': { 'entries': [] }, + 'cal': { 'today': [], 'tomorrow': [], 'week': [] }, + 'swedish': {}, + 'fitbit': {}, + 'ftse': {} + }, 'expire': ((60 * 1000) * 60) }; -const file = __dirname + '/' + 'newdata.json'; -let htmlfile = __dirname + '/' + 'today.html'; +const file = `${__dirname }/` + 'newdata.json'; +const htmlfile = `${__dirname }/` + 'today.html'; let eventEmitter; function runable() { - try { - const now = new Date().getTime(); -console.log(todayCache.last); - console.log('last updated', ((now - todayCache.last) / 60000)); - if (now - todayCache.last < 3600000) { - return false; - } else { - todayCache.last = now; - return true; - } + try { + const now = new Date().getTime(); + console.log(todayCache.last); + console.log('last updated', ((now - todayCache.last) / 60000)); + if (now - todayCache.last < 3600000) + return false; + else { + todayCache.last = now; + + return true; } - catch (e) { - logger.debug('Creating new today object.. Lets go!') - todayCache = Object.assign({}, todayCacheSrc); - todayCache.last = new Date().getTime(); - return true; - - } - + } + catch (e) { + logger.debug('Creating new today object.. Lets go!'); + todayCache = Object.assign({}, todayCacheSrc); + todayCache.last = new Date().getTime(); + + return true; + } } function broadcastWeather() { - const wData = { - temperature: todayCache.data.weather.data.currently.temperature, - icon: todayCache.data.weather.data.currently.icon, - summary: todayCache.data.weather.data.currently.summary - }; + const wData = { + 'temperature': todayCache.data.weather.data.currently.temperature, + 'icon': todayCache.data.weather.data.currently.icon, + 'summary': todayCache.data.weather.data.currently.summary + }; - if (todayCache.data.weather.data.hasOwnProperty('alerts')) { - wData.alerts = todayCache.data.weather.data.alerts; - } - eventEmitter.emit('sendSocket', {id: 'weather', data: wData}); + if (todayCache.data.weather.data.hasOwnProperty('alerts')) + wData.alerts = todayCache.data.weather.data.alerts; + + // eventEmitter.emit('sendSocket', { 'id': 'weather', 'data': wData }); } function loadData() { - console.log('Loading old data'); - // localStorage.removeItem('today'); - try { - let tempCache = localStorage.getItem('today'); - if (tempCache !== null) { - todayCache = JSON.parse(tempCache); - } - } - catch (e) { - console.error('Could not load previous data'); - } + console.log('Loading old data'); + // localStorage.removeItem('today'); + try { + const tempCache = localStorage.getItem('today'); + if (tempCache !== null) + todayCache = JSON.parse(tempCache); + } + catch (e) { + console.error('Could not load previous data'); + } } function saveData() { - todayCache.last = new Date().getTime(); - logger.info('Saving...'); - // jsonfile.writeFileSync(file, todayCache); - localStorage.setItem('today', JSON.stringify(todayCache)); + todayCache.last = new Date().getTime(); + logger.info('Saving...'); + // jsonfile.writeFileSync(file, todayCache); + localStorage.setItem('today', JSON.stringify(todayCache)); } function saveToDB(data) { - saveData(); + saveData(); - logger.debug('Inserting into couch...'); - // Logger.info(util.inspect(obj)); - dbCloudant.insert(data, function (err, body, header) { - if (err) { - logger.error('Error inserting into couch'); - logger.error(err); - return; - } - }); + logger.debug('Inserting into couch...'); + // Logger.info(util.inspect(obj)); + dbCloudant.insert(data, function (err, body, header) { + if (err) { + logger.error('Error inserting into couch'); + logger.error(err); + + return; + } + }); } function nth(d) { - // If (d > 3 && d < 21) {return 'th';} // Thanks kennebec - // if (d % 10 === 1) {return 'st';} else if (d % 10 === 2) {return 'nd';} else if (d % 10 === 3) {return 'rd';} else {return 'th';} - const n = d; - return Math.floor(n / 10) === 1 ? 'th' : (n % 10 === 1 ? 'st' : (n % 10 === 2 ? 'nd' : (n % 10 === 3 ? 'rd' : 'th'))); + // If (d > 3 && d < 21) {return 'th';} // Thanks kennebec + // if (d % 10 === 1) {return 'st';} else if (d % 10 === 2) {return 'nd';} else if (d % 10 === 3) {return 'rd';} else {return 'th';} + const n = d; + + return Math.floor(n / 10) === 1 ? 'th' : (n % 10 === 1 ? 'st' : (n % 10 === 2 ? 'nd' : (n % 10 === 3 ? 'rd' : 'th'))); } function dayNumber() { - const now = new Date(); - const start = new Date(now.getFullYear(), 0, 0); - const diff = now - start; - const oneDay = 1000 * 60 * 60 * 24; - return Math.floor(diff / oneDay); + const now = new Date(); + const start = new Date(now.getFullYear(), 0, 0); + const diff = now - start; + const oneDay = 1000 * 60 * 60 * 24; + + return Math.floor(diff / oneDay); } function breakDay() { - const now = new Date(); - return { - year: now.getFullYear(), - month: parseInt(now.getMonth()) + 1, - day: now.getDate() - }; + const now = new Date(); + + return { + 'year': now.getFullYear(), + 'month': parseInt(now.getMonth()) + 1, + 'day': now.getDate() + }; } function reduceTrains(d) { - - const titles = [], ta = []; - // console.log('reducetrains',d); - /*for (let items in d) { + const titles = [], ta = []; + // console.log('reducetrains',d); + /* for (let items in d) { if (typeof d[items].title !== 'undefined') { const hash = d[items].title.hashCode(); if (titles.indexOf(hash) === -1) { @@ -210,288 +210,273 @@ function reduceTrains(d) { }*/ - for (let item in d) { - if (typeof item.title !== 'undefined') { - const hash = item.title.hashCode(); - if (titles.indexOf(hash) === -1) { - titles.push(hash); - ta.push(item); - } - } + for (const item in d) + if (typeof item.title !== 'undefined') { + const hash = item.title.hashCode(); + if (titles.indexOf(hash) === -1) { + titles.push(hash); + ta.push(item); + } } - return ta; + + return ta; } /** * @return {number} */ function DayDiff(CurrentDate) { - const TYear = CurrentDate.getFullYear(); - const TDay = new Date('January, 01, ' + (parseInt(TYear) + 1)); - TDay.getFullYear(TYear); - let DayCount = (TDay - CurrentDate) / (1000 * 60 * 60 * 24); - DayCount = Math.round(DayCount); + const TYear = CurrentDate.getFullYear(); + const TDay = new Date(`January, 01, ${ parseInt(TYear) + 1}`); + TDay.getFullYear(TYear); + let DayCount = (TDay - CurrentDate) / (1000 * 60 * 60 * 24); + DayCount = Math.round(DayCount); - const d = new Date(); - DayCount = d.daysSince('beginning of this year'); - return (DayCount); + const d = new Date(); + DayCount = d.daysSince('beginning of this year'); + + return (DayCount); } Array.prototype.indexOfOld = Array.prototype.indexOf; Array.prototype.indexOf = function (e, fn) { - if (!fn) { - return this.indexOfOld(e); - } else { - if (typeof fn === 'string') { - const att = fn; - fn = function (e) { - return e[att]; - }; - } - return this.map(fn).indexOfOld(e); + if (!fn) + return this.indexOfOld(e); + else { + if (typeof fn === 'string') { + const att = fn; + fn = function (e) { + return e[att]; + }; } + + return this.map(fn).indexOfOld(e); + } }; module.exports = { - setEmitter: function (newEmitter) { - console.log('Setting events', newEmitter); - eventEmitter = newEmitter; - }, - getClock: function (req, res) { - // Console.log(todayCache); - res.render('pages/clock', todayCache); - }, - getToday: function (req, res) { - logger.info(todayCache); - res.render('pages/today', todayCache); - }, - getData: function (req, res) { - res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify(todayCache)); - }, - getTodayDate: function () { - let s; - const d = new Date(); - let nextYear = (parseInt(d.getFullYear()) + 1).toString() + '-01-01'; + 'setEmitter': function (newEmitter) { + console.log('Setting events', newEmitter); + eventEmitter = newEmitter; + }, + 'getClock': function (req, res) { + // Console.log(todayCache); + res.render('pages/clock', todayCache); + }, + 'getToday': function (req, res) { + logger.info(todayCache); + res.render('pages/today', todayCache); + }, + 'getData': function (req, res) { + res.setHeader('Content-Type', 'application/json'); + res.end(JSON.stringify(todayCache)); + }, + 'getTodayDate': function () { + let s; + const d = new Sugar.Date(); + const nextYear = `${(parseInt(d.getFullYear().raw) + 1).toString() }-01-01`; - console.log(d.daysUntil('beginning of next year')); - const daysSinceStart = d.daysSince('beginning of this year'); - const daysRemaining = d.daysUntil('beginning of next year'); + console.log(d.daysUntil('beginning of next year').raw); + const daysSinceStart = d.daysSince('beginning of this year').raw; + const daysRemaining = d.daysUntil('beginning of next year').raw; - todayCache.data.history = []; - s = '' + d.format('{Weekday} {Month} {dd}, {yyyy}') + ' - '; + todayCache.data.history = []; + s = `${ d.format('{Weekday} {Month} {dd}, {yyyy}').raw } - `; - /* + /* s = s + 'The ' + daysSinceStart + nth(daysSinceStart) + ' day of ' + dateFormat( d, 'yyyy') + ', and there are ' + daysRemaining + ' days left until the end of the year.'; */ - s = s + `The ${daysSinceStart + nth(daysSinceStart)} day of ${dateFormat(d, 'yyyy')}, and there are ${daysRemaining} days until the end of the year` + s = `${s }The ${daysSinceStart + nth(daysSinceStart)} day of ${d.format('{yyyy}').raw}, and there are ${daysRemaining} days until the end of the year`; - logger.debug(s); - todayCache.data.today = s; - }, - refreshTrain: function () { + logger.debug(s); + todayCache.data.today = s; + }, + 'refreshTrain': function () { + trains.updateTrains() + .then((d) => { + 'use strict'; - trains.updateTrains() - .then((d) => { - 'use strict'; + d = reduceTrains(d); - d = reduceTrains(d); + // eventEmitter.emit('sendSocket', { 'id': 'trains', 'data': d }); + todayCache.data.trains.data = d; + todayCache.data.trains.last = new Date(); + }) + .catch((e) => { + 'use strict'; + logger.error(e); + }); + }, + 'refreshWeather': function () { + weather.newDoGetWeather() + .then((d) => { + todayCache.data.weather = d; + logger.info('Updating weather'); + broadcastWeather(); + }).catch((e) => { + logger.error(e); + }); + }, - eventEmitter.emit('sendSocket', {id: 'trains', data: d}); - todayCache.data.trains.data = d; - todayCache.data.trains.last = new Date(); - }) - .catch((e) => { - 'use strict'; - logger.error(e); - }); + 'refreshTrainAndWeather': function () { + this.refreshTrain(); + this.refreshWeather(); + }, + 'preLoadToday': function () { + module.exports.getTodayDate(); + todayCache.data.cal = { 'today': [], 'tomorrow': [], 'week': [] }; + weather.newDoGetWeather() + .then((d) => { + todayCache.data.weather = d; + }) + .catch((e) => { + logger.error(e); + }); + trains.updateTrains() + .then((d) => { + 'use strict'; + console.log('Trains: ', d); + todayCache.data.trains.data = d; + todayCache.data.trains.last = new Date(); + }) + .catch((e) => { + 'use strict'; + console.error(e); + }); + history.updateHistory() + .then((d) => { + 'use strict'; + console.log('History result: ', d); + todayCache.data.history = d; + }) + .catch((e) => { + 'use strict'; + console.error(e); + }); + calHandler.getSimpleCalV3( + 'http://www.pogdesign.co.uk/cat/download_ics/60cfdff469d0490545d33d7e3b5c0bcc') + .then((d) => { + 'use strict'; + todayCache.data.tv = d; + }) + .catch((e) => { + 'use strict'; + logger.error(e); + }); - }, - refreshWeather: function () { - weather.newDoGetWeather() - .then((d) => { - todayCache.data.weather = d; - logger.info('Updating weather'); - broadcastWeather(); - }).catch((e) => { - logger.error(e); + todayFTSE.getFTSE() + .then((d) => { + todayCache.data.ftse = d; + }) + .catch((e) => { + logger.error(e); + }); + + quotes.GetQuotes() + .then((d) => { + todayCache.data.quotes = d; + }) + .catch((e) => { + logger.error(e); + }); + + for (let t = 0; t < calHandler.calendars.length; t++) + calHandler.getAdvancedCalV3(calHandler.calendars[t]) + .then((d) => { + 'use strict'; + todayCache.data.cal.today = todayCache.data.cal.today.concat(d.today); + todayCache.data.cal.tomorrow = todayCache.data.cal.tomorrow.concat(d.tomorrow); + todayCache.data.cal.week = todayCache.data.cal.week.concat(d.week); + }) + .catch((e) => { + 'use strict'; + logger.error(e); }); - }, + swedishWord.getSwedishWord() + .then((d) => { + 'use strict'; + console.log('Swedish result: ', d); + todayCache.data.swedish = d; + }) + .catch((e) => { + 'use strict'; + console.error(e); + }); - refreshTrainAndWeather: function () { - this.refreshTrain(); - this.refreshWeather(); - }, - preLoadToday: function () { - module.exports.getTodayDate(); - todayCache.data.cal = {today: [], tomorrow: [], week: []}; - weather.newDoGetWeather() - .then((d) => { - todayCache.data.weather = d; - }) - .catch((e) => { - logger.error(e); - }); - trains.updateTrains() - .then((d) => { - 'use strict'; - console.log('Trains: ', d); - todayCache.data.trains.data = d; - todayCache.data.trains.last = new Date(); - }) - .catch((e) => { - 'use strict'; - console.error(e); - }); - history.updateHistory() - .then((d) => { - 'use strict'; - console.log('History result: ', d); - todayCache.data.history = d; - }) - .catch((e) => { - 'use strict'; - console.error(e); - }); + mdFitbit.getYesterdayFitbit() + .then((d) => { + todayCache.data.fitbit = d; + }) + .catch((e) => { + 'use strict'; + console.error(e); + }); - calHandler.getSimpleCalV3( - 'http://www.pogdesign.co.uk/cat/download_ics/60cfdff469d0490545d33d7e3b5c0bcc') - .then((d) => { - 'use strict'; - todayCache.data.tv = d; - }) - .catch((e) => { - 'use strict'; - logger.error(e); - }); + todayCache.date = breakDay(); + }, + 'preLoadTodayTest': function () { + module.exports.getTodayDate(); + todayCache.data.cal = { 'today': [], 'tomorrow': [], 'week': [] }; - todayFTSE.getFTSE() - .then((d) => { - todayCache.data.ftse = d; - }) - .catch((e) => { - logger.error(e); - }); - - quotes.GetQuotes() - .then((d) => { - todayCache.data.quotes = d; - }) - .catch((e) => { - logger.error(e); - }); - - - for (let t = 0; t < calHandler.calendars.length; t++) { - calHandler.getAdvancedCalV3(calHandler.calendars[t]) - .then((d) => { - 'use strict'; - todayCache.data.cal.today = todayCache.data.cal.today.concat(d.today); - todayCache.data.cal.tomorrow = todayCache.data.cal.tomorrow.concat(d.tomorrow); - todayCache.data.cal.week = todayCache.data.cal.week.concat(d.week); - }) - .catch((e) => { - 'use strict'; - logger.error(e); - }); - } - - swedishWord.getSwedishWord() - .then((d) => { - 'use strict'; - console.log('Swedish result: ', d); - todayCache.data.swedish = d; - }) - .catch((e) => { - 'use strict'; - console.error(e); - }); - - mdFitbit.getYesterdayFitbit() - .then((d) => { - todayCache.data.fitbit = d; - }) - .catch((e) => { - 'use strict'; - console.error(e); - }); - - todayCache.date = breakDay(); - }, - preLoadTodayTest: function () { - module.exports.getTodayDate(); - todayCache.data.cal = {today: [], tomorrow: [], week: []}; - - - todayCache.date = breakDay(); - }, - broadcast: function () { - console.log('BROADCAST'); - broadcastWeather(); - eventEmitter.emit('sendSocket', {id: 'trains', data: todayCache.data.trains.data}); - - } + todayCache.date = breakDay(); + }, + 'broadcast': function () { + console.log('BROADCAST'); + broadcastWeather(); + eventEmitter.emit('sendSocket', { 'id': 'trains', 'data': todayCache.data.trains.data }); + } }; setTimeout(function () { - loadData(); - if (runable()) { - module.exports.preLoadToday(); - } - //Module.exports.preLoadToday(); - + loadData(); + if (runable()) + module.exports.preLoadToday(); + + // Module.exports.preLoadToday(); }, 5000); setTimeout(function () { - // mdMailer.sendEmailV1(todayCache, __dirname); - // saveToDB(todayCache); - saveData(); + mdMailer.sendEmailV1(todayCache, __dirname); + saveToDB(todayCache); + saveData(); }, 45000); setInterval(function () { - // EventEmitter.emit('sendSocket',{id:'weather',data:todayCache.data.weather}); - // broadcastWeather(); - // eventEmitter.emit('sendSocket', {id: 'trains', data: todayCache.data.trains.data}); - + // EventEmitter.emit('sendSocket',{id:'weather',data:todayCache.data.weather}); + // broadcastWeather(); + // eventEmitter.emit('sendSocket', {id: 'trains', data: todayCache.data.trains.data}); }, (60000)); +cron.schedule('15 7 * * *', function () { + if (runable()) { + module.exports.preLoadToday(); -cron.schedule('30 6 * * *', function () { - if (runable()) { - module.exports.preLoadToday(); - } + saveToDB(todayCache); + saveData(); + } - return -1; + return -1; }); cron.schedule('0 */1 * * *', function () { - // Module.exports.refreshTrainAndWeather(); - // this.refreshTrain(); - module.exports.refreshWeather(); + // Module.exports.refreshTrainAndWeather(); + // this.refreshTrain(); + module.exports.refreshWeather(); - return -1; + return -1; }); -cron.schedule('*/15 * * * *', function () { - module.exports.refreshTrain(); - - // Module.exports.refreshWeather(); - - return -1; +cron.schedule('30 7 * * *', function () { + mdMailer.sendEmailV1(todayCache, __dirname); + // saveToDB(todayCache); + // Console.log('tick'); + return -1; }); -cron.schedule('45 6 * * *', function () { - mdMailer.sendEmailV1(todayCache, __dirname); - saveToDB(todayCache); - // Console.log('tick'); - return -1; -}); - -