-
Kasalehlia authoredKasalehlia authored
bus.js 4.08 KiB
var fs = require('fs');
var Mustache = require('mustache');
var XML = require('pixl-xml');
var iconv = require('iconv-lite');
var httpreq = require('httpreq');
/// CONFIG
var CITY = 'Braunschweig';
var STOPS = ['Ludwigstraße','Hamburger Straße'];
var ENTRIES = 6;
/// VARS
var CACHED = [];
var TEMPLATES = {};
fs.readFile('modules/bus/outer.mustache', 'utf-8', function (err, data) {
TEMPLATES.outer = data;
});
fs.readFile('modules/bus/inner.mustache', 'utf-8', function (err, data) {
TEMPLATES.inner = data;
});
/// FUNS
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 fetchData(stop, cb) {
var url = "http://62.154.206.87/efaws2/default/XML_DM_REQUEST?sessionID=0&requestID=0&language=de&useRealtime=1&coordOutputFormat=WGS84[DD.ddddd]&locationServerActive=1&mode=direct&dmLineSelectionAll=1&depType=STOPEVENTS&useAllStops=1&command=null&type_dm=stop&name_dm="+CITY+' '+stop+"&mId=efa_rc2"
httpreq.get(url, {binary: true}, function (err, res) {
try {
cb(XML.parse(iconv.decode(res.body, 'latin1')));
} catch(e) {
}
});
}
function renderLine(line) {
var image = '';
if (line.charAt(0) == "M") {
image = 'metro.svg';
line = line.substr(1);
} else if (line.length < 3) {
image = 'tram.svg';
} else {
image = 'bus.svg';
}
return '<img src="/modules/bus/'+image+'"> '+line;
}
function getData(stop, count, cb) {
fetchData(stop, function (data) {
var deps = data.itdDepartureMonitorRequest.itdDepartureList.itdDeparture;
cb(deps.slice(0, count).map(function (dep) {
return {
line: dep.itdServingLine.symbol,
renderedLine: renderLine(dep.itdServingLine.symbol),
dir: dep.itdServingLine.direction.replace(CITY, '').trim(),
platform: dep.platform,
mean: dep.itdServingLine.itdNoTrain.name,
day: pad(dep.itdDateTime.itdDate.day,2),
month: pad(dep.itdDateTime.itdDate.month,2),
hour: pad(dep.itdDateTime.itdTime.hour,2),
minute: pad(dep.itdDateTime.itdTime.minute,2)
};
}));
});
}
function update(io, allStopsDoneCb) {
var done = [];
var context = [];
var innerGetData = function (stop, i) {
var ns = normalizeStop(stop);
getData(stop, ENTRIES, function (deps) {
try {
context[i] = {stop: stop, normalizedStop: ns, deps: deps};
io.emit('bus.'+ns, Mustache.render(TEMPLATES.inner, context[i]));
if (done.indexOf(stop) === -1) {
done.push(stop);
if (done.length === STOPS.length) {
allStopsDoneCb();
}
}
CACHED = context;
} catch (e) {console.log(e);}
// calculate when to update next
var d = new Date();
var hour = d.getHours();
var minute = d.getMinutes();
var depHour = deps[0].hour < hour ? deps[0].hour+24 : deps[0].hour;
var diff = (depHour-hour)*60 + (deps[0].minute-minute);
setTimeout(function () {
innerGetData(stop, i);
}, (diff * 60 + (60-d.getSeconds()) % 60) * 1000);
});
}
STOPS.forEach(function (stop, i) {
innerGetData(stop, i);
});
}
function normalizeStop(stop) {
return stop.replace(/[^a-zA-Z0-9_]/g,'');
}
module.exports = function (io) {
update(io, function () {
var pushToClient = function (sock) {
sock.emit('bus', Mustache.render(TEMPLATES.outer, CACHED));
setTimeout(function () {
for (var i in CACHED) {
sock.emit('bus.'+CACHED[i].normalizedStop,
Mustache.render(TEMPLATES.inner, CACHED[i]));
}
}, 3000); //wait a second to let the client process the outlets
};
io.on('connect', pushToClient);
pushToClient(io);
});
}