From eb7350fb52b8ec9141e2e91f131abe0d5209122d Mon Sep 17 00:00:00 2001 From: Chris Mulligan Date: Wed, 20 Aug 2014 10:42:02 -0400 Subject: [PATCH 1/4] Add the newsfeed URL to config. Add weather icons to the forecast. --- css/main.css | 10 ++++++++++ js/config.js | 10 ++++++++-- js/main.js | 28 +++++++++++++++++++++++++--- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/css/main.css b/css/main.css index fed22c1b..7fbdd4ed 100644 --- a/css/main.css +++ b/css/main.css @@ -134,6 +134,16 @@ body, html { margin-right: 10px; } +.icon-small +{ + position: relative; + display: inline-block; + font-size: 20px; + padding-left: 10px; + padding-right: -10px; + font-weight: 100; +} + .time .sec { font-size: 25px; color: #666; diff --git a/js/config.js b/js/config.js index b88f939d..8b882afa 100644 --- a/js/config.js +++ b/js/config.js @@ -4,12 +4,18 @@ var lang = window.navigator.language; //var lang = 'en'; //change weather params here: +//units: metric or imperial var weatherParams = { - 'q':'Baarn,Netherlands', - 'units':'metric', + 'q':'New York, NY', + 'units':'imperial', 'lang':lang }; +//var feed = 'http://feeds.nos.nl/nosjournaal?format=rss'; +//var feed = 'http://www.nu.nl/feeds/rss/achterklap.rss'; +//var feed = 'http://www.nu.nl/feeds/rss/opmerkelijk.rss'; +var feed = 'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml'; + // compliments: var compliments = [ 'Hey, handsome!', diff --git a/js/main.js b/js/main.js index 5ee66995..fe5ec00a 100644 --- a/js/main.js +++ b/js/main.js @@ -249,6 +249,26 @@ jQuery(document).ready(function($) { (function updateWeatherForecast() { + var iconTable = { + '01d':'wi-day-sunny', + '02d':'wi-day-cloudy', + '03d':'wi-cloudy', + '04d':'wi-cloudy-windy', + '09d':'wi-showers', + '10d':'wi-rain', + '11d':'wi-thunderstorm', + '13d':'wi-snow', + '50d':'wi-fog', + '01n':'wi-night-clear', + '02n':'wi-night-cloudy', + '03n':'wi-night-cloudy', + '04n':'wi-night-cloudy', + '09n':'wi-night-showers', + '10n':'wi-night-rain', + '11n':'wi-night-thunderstorm', + '13n':'wi-night-snow', + '50n':'wi-night-alt-cloudy-windy' + } $.getJSON('http://api.openweathermap.org/data/2.5/forecast', weatherParams, function(json, textStatus) { var forecastData = {}; @@ -260,10 +280,12 @@ jQuery(document).ready(function($) { if (forecastData[dateKey] == undefined) { forecastData[dateKey] = { 'timestamp':forecast.dt * 1000, + 'icon':forecast.weather[0].icon, 'temp_min':forecast.main.temp, 'temp_max':forecast.main.temp }; } else { + forecastData[dateKey]['icon'] = forecast.weather[0].icon; forecastData[dateKey]['temp_min'] = (forecast.main.temp < forecastData[dateKey]['temp_min']) ? forecast.main.temp : forecastData[dateKey]['temp_min']; forecastData[dateKey]['temp_max'] = (forecast.main.temp > forecastData[dateKey]['temp_max']) ? forecast.main.temp : forecastData[dateKey]['temp_max']; } @@ -275,10 +297,12 @@ jQuery(document).ready(function($) { var opacity = 1; for (var i in forecastData) { var forecast = forecastData[i]; + var iconClass = iconTable[forecast.icon]; var dt = new Date(forecast.timestamp); var row = $('').css('opacity', opacity); row.append($('').addClass('day').html(moment.weekdaysShort(dt.getDay()))); + row.append($('').addClass('icon-small').addClass(iconClass)); row.append($('').addClass('temp-max').html(roundVal(forecast.temp_max))); row.append($('').addClass('temp-min').html(roundVal(forecast.temp_min))); @@ -297,9 +321,7 @@ jQuery(document).ready(function($) { (function fetchNews() { $.feedToJson({ - feed:'http://feeds.nos.nl/nosjournaal?format=rss', - //feed:'http://www.nu.nl/feeds/rss/achterklap.rss', - //feed:'http://www.nu.nl/feeds/rss/opmerkelijk.rss', + feed: feed, success: function(data){ news = []; for (var i in data.item) { From 24ab382bb2f4bbd20e5de18944d98b83115c9ab6 Mon Sep 17 00:00:00 2001 From: Chris Mulligan Date: Wed, 20 Aug 2014 10:42:25 -0400 Subject: [PATCH 2/4] Update ical_parser to parse in UTC and convert to local time. Using j08lue's fork from https://github.com/j08lue/JavaScript-Ical-Parser --- js/ical_parser.js | 64 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 12 deletions(-) mode change 100755 => 100644 js/ical_parser.js diff --git a/js/ical_parser.js b/js/ical_parser.js old mode 100755 new mode 100644 index b01316ad..292f670d --- a/js/ical_parser.js +++ b/js/ical_parser.js @@ -40,7 +40,7 @@ function ical_parser(feed_url, callback){ */ this.makeDate = function(ical_date){ //break date apart - var dt = { + var dtutc = { year: ical_date.substr(0,4), month: ical_date.substr(4,2), day: ical_date.substr(6,2), @@ -48,9 +48,19 @@ function ical_parser(feed_url, callback){ minute: ical_date.substr(11,2) } //Create JS date (months start at 0 in JS - don't ask) - dt.date = new Date(dt.year, (dt.month-1), dt.day, dt.hour, dt.minute); + var utcdatems = Date.UTC(dtutc.year, (dtutc.month-1), dtutc.day, dtutc.hour, dtutc.minute); + var dt = {}; + dt.date = new Date(utcdatems); + + dt.year = dt.date.getFullYear(); + dt.month = ('0' + (dt.date.getMonth()+1)).slice(-2); + dt.day = ('0' + dt.date.getDate()).slice(-2); + dt.hour = ('0' + dt.date.getHours()).slice(-2); + dt.minute = ('0' + dt.date.getMinutes()).slice(-2); + //Get the full name of the given day dt.dayname =["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][dt.date.getDay()]; + dt.monthname = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ][dt.date.getMonth()] ; return dt; } @@ -66,7 +76,7 @@ function ical_parser(feed_url, callback){ this.events = []; //Clean string and split the file so we can handle it (line by line) - cal_array = data.replace(new RegExp( "\\r", "g" ), "").split("\n"); + cal_array = data.replace(new RegExp( "\\r", "g" ), "").replace(/\n /g,"").split("\n"); //Keep track of when we are activly parsing an event var in_event = false; @@ -80,18 +90,23 @@ function ical_parser(feed_url, callback){ cur_event = {}; } //If we encounter end event, complete the object and add it to our events array then clear it for reuse. - if(in_event && ln == 'END:VEVENT'){ + if(in_event && ln == 'END:VEVENT'){ in_event = false; this.events.push(cur_event); cur_event = null; } //If we are in an event - if(in_event){ + else if(in_event){ + //var lntrim = ln.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + //var lnsplit = lntrim.split(':'); + //type = lnsplit[0]; + //val = lnsplit[1]; + //Split the item based on the first ":" idx = ln.indexOf(':'); //Apply trimming to values to reduce risks of badly formatted ical files. type = ln.substr(0,idx).replace(/^\s\s*/, '').replace(/\s\s*$/, '');//Trim - val = ln.substr(idx+1,ln.length-(idx+1)).replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + val = ln.substr(idx+1).replace(/^\s\s*/, '').replace(/\s\s*$/, ''); //If the type is a start date, proccess it and store details if(type =='DTSTART'){ @@ -101,9 +116,10 @@ function ical_parser(feed_url, callback){ cur_event.start_time = dt.hour+':'+dt.minute; cur_event.start_date = dt.day+'/'+dt.month+'/'+dt.year; cur_event.day = dt.dayname; + cur_event.start_date_long = dt.day+'. '+dt.monthname+' '+dt.year ; } //If the type is an end date, do the same as above - if(type =='DTEND'){ + else if(type =='DTEND'){ dt = this.makeDate(val); val = dt.date; //These are helpful for display @@ -112,8 +128,16 @@ function ical_parser(feed_url, callback){ cur_event.day = dt.dayname; } //Convert timestamp - if(type =='DTSTAMP') val = this.makeDate(val).date; - + else if(type =='DTSTAMP'){ + val = this.makeDate(val).date; + } + else { + val = val + .replace(/\\r\\n/g,'
') + .replace(/\\n/g,'
') + .replace(/\\,/g,','); + } + //Add the value to our event object. cur_event[type] = val; } @@ -153,12 +177,28 @@ function ical_parser(feed_url, callback){ var future_events = [], current_date = new Date(); this.events.forEach(function(itm){ - //If the event starts after the current time, add it to the array to return. - if(itm.DTSTART > current_date) future_events.push(itm); + //If the event ends after the current time, add it to the array to return. + if(itm.DTEND > current_date) future_events.push(itm); }); return future_events; } + /** + * getPastEvents + * return all events sheduled to take place before the current date. + * + * @return list of events objects + */ + this.getPastEvents = function(){ + var past_events = [], current_date = new Date(); + + this.events.forEach(function(itm){ + //If the event ended before the current time, add it to the array to return. + if(itm.DTEND <= current_date) past_events.push(itm); + }); + return past_events.reverse(); + } + /** * load * load a new ICAL file. @@ -181,4 +221,4 @@ function ical_parser(feed_url, callback){ this.feed_url = feed_url; //Load the file this.load(this.feed_url); -} \ No newline at end of file +} From b53017199034ee78b53ac17dcfb781901df6753e Mon Sep 17 00:00:00 2001 From: Chris Mulligan Date: Wed, 20 Aug 2014 10:47:54 -0400 Subject: [PATCH 3/4] Reverting to original config parameters --- js/config.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/config.js b/js/config.js index 8b882afa..09615a46 100644 --- a/js/config.js +++ b/js/config.js @@ -6,15 +6,15 @@ var lang = window.navigator.language; //change weather params here: //units: metric or imperial var weatherParams = { - 'q':'New York, NY', - 'units':'imperial', + 'q':'Baarn,Netherlands', + 'units':'metric', 'lang':lang }; -//var feed = 'http://feeds.nos.nl/nosjournaal?format=rss'; +var feed = 'http://feeds.nos.nl/nosjournaal?format=rss'; //var feed = 'http://www.nu.nl/feeds/rss/achterklap.rss'; //var feed = 'http://www.nu.nl/feeds/rss/opmerkelijk.rss'; -var feed = 'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml'; +//var feed = 'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml'; // compliments: var compliments = [ From ad7d7f655f9cfad7b5ac5ebb09e47476fee476c9 Mon Sep 17 00:00:00 2001 From: Chris Mulligan Date: Wed, 20 Aug 2014 10:50:36 -0400 Subject: [PATCH 4/4] README improvements --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 851b25f4..c21b1508 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,6 @@ MagicMirror The super magic interface of my personal Magic Mirror. More information about this project can be found on my [blog](http://michaelteeuw.nl/tagged/magicmirror). -Modify js/config.js to change some general variables (language, wather location, compliments) and calendar.php to add your own ICS calendar +Runs as a php script on a web server with basically no external dependencies. Can use socket.io for XBEE integration, but isn't required for basic functionality. + +Modify js/config.js to change some general variables (language, wather location, compliments, news feed RSS) and calendar.php to add your own ICS calendar