diff --git a/lib/departures.js b/lib/departures.js new file mode 100644 index 0000000..4a15d10 --- /dev/null +++ b/lib/departures.js @@ -0,0 +1,59 @@ +'use strict' + +const parse = require('parse-messy-time') +const hafas = require('db-hafas') +const createDepsInDirection = require('hafas-departures-in-direction') + +const depsInDirection = createDepsInDirection(hafas.departures, hafas.journeyPart) + +const err400 = (msg) => { + const err = new Error(msg) + err.statusCode = 400 + return err +} + +const isNumber = /^\d+$/ + +const departures = (req, res, next) => { + const id = req.params.id.trim() + if (!isNumber.test(id)) return next(err400('Invalid station id.')) + + const opt = {} + if ('when' in req.query) { + opt.when = isNumber.test(req.query.when) + ? new Date(req.query.when * 1000) + : parse(req.query.when) + } + + let task + if ('nextStation' in req.query) { + const nS = req.query.nextStation + if (!isNumber.test(nS)) return next(err400('Invalid nextStation parameter.')) + + if ('results' in req.query) { + const r = +req.query.results + if (Number.isNaN(r)) return next(err400('Invalid results parameter.')) + opt.results = Math.max(0, Math.min(r, 20)) + } + if ('maxQueries' in req.query) { + const mQ = +req.query.maxQueries + if (Number.isNaN(mQ)) return next(err400('Invalid maxQueries parameter.')) + opt.maxQueries = Math.max(0, Math.min(mQ, 30)) + } + + task = depsInDirection(id, nS, opt) + } else { + if ('direction' in req.query) opt.direction = req.query.direction + if ('duration' in req.query) opt.duration = +req.query.duration + task = hafas.departures(id, opt) + } + + task + .then((deps) => { + res.json(deps) + next() + }) + .catch(next) +} + +module.exports = departures diff --git a/lib/journeys.js b/lib/journeys.js new file mode 100644 index 0000000..b4a78a5 --- /dev/null +++ b/lib/journeys.js @@ -0,0 +1,84 @@ +'use strict' + +const time = require('parse-messy-time') +const parse = require('cli-native').to +const hafas = require('db-hafas') + +const err400 = (msg) => { + const err = new Error(msg) + err.statusCode = 400 + return err +} + +const location = (q, t) => { + if (q[t]) return q[t] // station id + else if (q[t + '.latitude'] && q[t + '.longitude']) { + const l = { + type: 'address', + name: 'foo bar', // todo + latitude: +q[t + `.latitude`], + longitude: +q[t + `.longitude`] + } + if (q[t + '.name']) l.name = q[t + '.name'] + if (q[t + '.id']) { + l.type = 'poi' + l.id = q[t + '.id'] + } + return l + } + else return null +} + +const isNumber = /^\d+$/ + +const journeys = (req, res, next) => { + const from = location(req.query, 'from') + if (!from) return next(err400('Missing origin.')) + const to = location(req.query, 'to') + if (!to) return next(err400('Missing destination.')) + + const opt = {} + if ('when' in req.query) { + opt.when = isNumber.test(req.query.when) + ? new Date(req.query.when * 1000) + : time(req.query.when) + } + if ('results' in req.query) { + opt.results = +req.query.results + } + if ('via' in req.query) { + opt.via = req.query.via + } + if ('passedStations' in req.query) { + opt.passedStations = parse(req.query.passedStations) + } + if ('transfers' in req.query) { + opt.transfers = +req.query.transfers + } + if ('transferTime' in req.query) { + opt.transferTime = +req.query.transferTime + } + if ('accessibility' in req.query) { + opt.accessibility = req.query.accessibility + } + if ('bike' in req.query) { + opt.bike = parse(req.query.bike) + } + // todo: loyaltyCard + + const products = [ + 'suburban', 'subway', 'tram', 'bus', 'ferry', 'express', 'regional' + ].reduce((acc, type) => { + if (type in req.query) acc[type] = parse(req.query[type]) + return acc + }, {}) + if (Object.keys(products)) opt.products = products + + hafas.journeys(from, to, opt) + .then((journeys) => { + res.json(journeys) + next() + }, (err) => next(err)) +} + +module.exports = journeys diff --git a/package.json b/package.json index ee92242..87ce6d5 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,16 @@ "node": ">=6" }, "dependencies": { + "cli-native": "^1.0.0", "compression": "^1.7.1", "corser": "^2.0.1", + "db-hafas": "^1.1.0", "express": "^4.16.2", + "hafas-departures-in-direction": "^0.1.0", "hsts": "^2.1.0", "morgan": "^1.9.0", "nocache": "^2.0.0", + "parse-messy-time": "^2.1.0", "shorthash": "^0.0.2" }, "scripts": {