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
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..09615a46 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',
'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/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
+}
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 = $('