Skip to content
Snippets Groups Projects
bus.js 3.18 KiB
Newer Older
Kasalehlia's avatar
Kasalehlia committed
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 = null;
var TEMPLATE = '';
fs.readFile('modules/bus/template.mustache', 'utf-8', function (err, data) {
    TEMPLATE = 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) {
    url = "http://mobil.efa.de/mobile3/XSLT_DM_REQUEST?outputFormat=XML&useAllStops=1&useRealtime=1&maxAssignedStops=1&itOptionsActive=1&trITMOTvalue100=5&itdLPxx_dest=&sessionID=0&language=en&locationServerActive=1&mode=direct&limit=60&itdLPxx_script=true&type_dm=stop&placeInfo_dm="+CITY+"&name_dm="+stop;
    httpreq.get(url, {binary: true}, function (err, res) {
        try {
            cb(XML.parse(iconv.decode(res.body, 'latin1')));
        } catch(e) {
        }
Kasalehlia's avatar
Kasalehlia committed
    });
}

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) {
    var done = 0;
    var context = [];
    var innerGetData = function (stop, i) {
        getData(stop, ENTRIES, function (deps) {
            context[i] = {stop: stop, deps: deps};
            if (++done >= STOPS.length) {
                io.emit('bus', Mustache.render(TEMPLATE, context));
                CACHED = context;
            }
            // 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);
    });
}

module.exports = function (io) {
    update(io);
    io.on('connect', function (sock) {
        sock.emit('bus', Mustache.render(TEMPLATE, CACHED));
    });
}