Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
var httpreq = require('httpreq');
var ical = require('ical.js');
var Mustache = require('mustache');
var URL = 'https://stratum0.org/kalender/termine.ics';
var TEMPLATE = '';
require('fs').readFile('modules/calendar/template.mustache', 'utf-8', function (err, data) {
TEMPLATE = data;
});
var CALENDAR;
function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
function parseDate(s) {
var i = parseInt;
if (s.indexOf('T') > -1) {
return new Date(i(s.substr(0,4)), i(s.substr(4,2))-1, i(s.substr(6,2)),
i(s.substr(9,2)), i(s.substr(11,2)), i(s.substr(13,2)));
} else {
return new Date(i(s.substr(0,4)), i(s.substr(4,2))-1, i(s.substr(6,2)));
}
}
function getData(count, cb) {
httpreq.get(URL, function (err, res) {
var ics = res.body.replace(/[0-9]{8}T[0-9]{6}/g, '$&Z');
var cal = new ical.Component(ical.parse(ics));
var rawEvents = cal.getAllSubcomponents('vevent').map(function (raw) {
return new ical.Event(raw);
});
var events = [];
var ev, p = function (p) {return ev.component.getFirstPropertyValue(p);};
for (var i in rawEvents) {
ev = rawEvents[i];
if (ev.isRecurring()) {
var iter = ev.iterator();
var duration = p('dtend').toUnixTime()-p('dtstart').toUnixTime();
for (var i = 0; i < 100; i++) {
var next = iter.next();
if (next === undefined) {break;}
var start = next.toUnixTime();
events.push({
title: p('summary'),
start: start,
end: start + duration
});
}
} else {
events.push({
title: p('summary'),
start: p('dtstart').toUnixTime(),
end: p('dtend').toUnixTime(),
});
}
}
events.sort(function (a, b) {
return a.start - b.start;
});
var threshold = Date.now()/1000 - 5*60*60; //show 5 hours ago
var i;
for (i in events) {
if (events[i].end > threshold) {
i = parseInt(i);
break;
}
}
var now = new Date();
cb(events.slice(i, i+count).map(function (ev) {
var start = new Date(ev.start*1000);
if (start.getMonth() == now.getMonth() && start.getDate() == now.getDate()) {
ev.startRendered = pad(start.getHours(),2)+':'+pad(start.getMinutes(),2);
} else {
ev.startRendered = DOW[start.getDay()]+', '+pad(start.getDate(),2)
+'.'+pad(start.getMonth(),2)+'. '+pad(start.getHours(),2)
+':'+pad(start.getMinutes(),2);
}
var end = new Date(ev.end*1000);
if (ev.end - ev.start >= 60*60*24) {
ev.endRendered = DOW[end.getDay()]+' '+pad(end.getHours(),2)
+':'+pad(end.getMinutes(),2);
} else {
ev.endRendered = pad(end.getHours(),2)+':'+pad(end.getMinutes(),2);
}
var dur = Math.floor((ev.end-ev.start)/60);
ev.duration = pad(Math.floor(dur/60),2)+':'+pad((dur%60),2)
if (start.getTime() < now.getTime()) {
if (end.getTime() < now.getTime()) {
ev.past = true;
} else {
ev.now = true;
}
}
return ev
}));
});
}
module.exports = function (io) {
getData(8, function (data) {
CALENDAR = data;
io.emit('calendar', Mustache.render(TEMPLATE, CALENDAR));
if (firstRunCallback) {
firstRunCallback()
firstRunCallback = null;
}
update(function () {
var pushToClients = function (sock) {
sock.emit('calendar', Mustache.render(TEMPLATE, CALENDAR));
});
io.on('connect', pushToClients);
pushToClients(io);
});
setInterval(update, 600000);