deal with some todos, add more

This commit is contained in:
Jannis R 2017-12-12 03:28:54 +01:00
parent eacbd8ef01
commit 81c9411cfe
No known key found for this signature in database
GPG key ID: 0FE83946296A88A5
10 changed files with 78 additions and 43 deletions

View file

@ -73,14 +73,13 @@ const createClient = (profile) => {
viaLocL: opt.via ? [opt.via] : null, viaLocL: opt.via ? [opt.via] : null,
arrLocL: [to], arrLocL: [to],
jnyFltrL: [products], jnyFltrL: [products],
getTariff: !!opt.tickets,
// todo: what is req.gisFltrL? // todo: what is req.gisFltrL?
// todo: what are all these for? getPT: true, // todo: what is this?
getPT: true, outFrwd: true, // todo: what is this?
outFrwd: true, getIV: false, // todo: walk & bike as alternatives?
getTariff: !!opt.tickets, getPolyline: false // todo: shape for displaying on a map?
getIV: false, // walk & bike as alternatives?
getPolyline: false // shape for displaying on a map?
}, opt) }, opt)
return request(profile, { return request(profile, {
@ -193,7 +192,8 @@ const createClient = (profile) => {
opt = Object.assign({ opt = Object.assign({
results: 256, // maximum number of vehicles results: 256, // maximum number of vehicles
duration: 30, // compute frames for the next n seconds duration: 30, // compute frames for the next n seconds
frames: 3 // nr of frames to compute frames: 3, // nr of frames to compute
products: null // optionally an object of booleans
}, opt || {}) }, opt || {})
opt.when = opt.when || new Date() opt.when = opt.when || new Date()
@ -211,8 +211,7 @@ const createClient = (profile) => {
perStep: Math.round(durationPerStep), perStep: Math.round(durationPerStep),
ageOfReport: true, // todo: what is this? ageOfReport: true, // todo: what is this?
jnyFltrL: [ jnyFltrL: [
// todo: use `profile.formatProducts(opt.products || {})` profile.formatProducts(opt.products || {})
{type: 'PROD', mode: 'INC', value: '127'}
], ],
trainPosMode: 'CALC' // todo: what is this? what about realtime? trainPosMode: 'CALC' // todo: what is this? what about realtime?
} }

View file

@ -7,6 +7,8 @@ const types = {
transformReqBody: 'function', transformReqBody: 'function',
transformJourneysQuery: 'function', transformJourneysQuery: 'function',
products: 'object',
parseDateTime: 'function', parseDateTime: 'function',
parseDeparture: 'function', parseDeparture: 'function',
parseJourneyPart: 'function', parseJourneyPart: 'function',
@ -37,6 +39,9 @@ const validateProfile = (profile) => {
if (type !== typeof profile[key]) { if (type !== typeof profile[key]) {
throw new Error(`profile.${key} must be a ${type}.`) throw new Error(`profile.${key} must be a ${type}.`)
} }
if (type === 'object' && profile[key] === null) {
throw new Error(`profile.${key} must not be null.`)
}
} }
} }

View file

@ -144,6 +144,8 @@ const dbProfile = {
transformReq, transformReq,
transformJourneysQuery, transformJourneysQuery,
products: modes.allProducts,
// todo: parseLocation // todo: parseLocation
parseLine, parseLine,
parseProducts: createParseBitmask(modes.bitmasks), parseProducts: createParseBitmask(modes.bitmasks),

View file

@ -91,4 +91,17 @@ m.bitmasks[128] = m.subway
m.bitmasks[256] = m.tram m.bitmasks[256] = m.tram
m.bitmasks[512] = m.taxi m.bitmasks[512] = m.taxi
m.allProducts = [
m.nationalExp,
m.national,
m.regionalExp,
m.regional,
m.suburban,
m.bus,
m.ferry,
m.subway,
m.tram,
m.taxi
]
module.exports = m module.exports = m

View file

@ -4,10 +4,12 @@ const shorten = require('vbb-short-station-name')
const {to12Digit, to9Digit} = require('vbb-translate-ids') const {to12Digit, to9Digit} = require('vbb-translate-ids')
const parseLineName = require('vbb-parse-line') const parseLineName = require('vbb-parse-line')
const parseTicket = require('vbb-parse-ticket') const parseTicket = require('vbb-parse-ticket')
const getStations = require('vbb-stations')
const _parseLine = require('../../parse/line') const _parseLine = require('../../parse/line')
const _parseLocation = require('../../parse/location') const _parseLocation = require('../../parse/location')
const _createParseJourney = require('../../parse/journey') const _createParseJourney = require('../../parse/journey')
const _createParseStopover = require('../../parse/stopover')
const _formatStation = require('../../format/station') const _formatStation = require('../../format/station')
const createParseBitmask = require('../../parse/products-bitmask') const createParseBitmask = require('../../parse/products-bitmask')
const createFormatBitmask = require('../../format/products-bitmask') const createFormatBitmask = require('../../format/products-bitmask')
@ -53,7 +55,10 @@ const parseLocation = (profile, l) => {
if (res.type === 'station') { if (res.type === 'station') {
res.name = shorten(res.name) res.name = shorten(res.name)
res.id = to12Digit(res.id) res.id = to12Digit(res.id)
// todo: https://github.com/derhuerst/vbb-hafas/blob/1c64bfe42422e2648b21016d233c808460250308/lib/parse.js#L67-L75 if (!res.location.latitude || !res.location.longitude) {
const [s] = getStations(res.id)
if (s) Object.assign(res.location, s.coordinates)
}
} }
return res return res
} }
@ -88,6 +93,20 @@ const createParseJourney = (profile, stations, lines, remarks) => {
return parseJourneyWithTickets return parseJourneyWithTickets
} }
const createParseStopover = (profile, stations, lines, remarks, connection) => {
const parseStopover = _createParseStopover(profile, stations, lines, remarks, connection)
const parseStopoverWithShorten = (st) => {
const res = parseStopover(st)
if (res.station && res.station.name) {
res.station.name = shorten(res.station.name)
}
return res
}
return parseStopoverWithShorten
}
const isIBNR = /^\d{9,}$/ const isIBNR = /^\d{9,}$/
const formatStation = (id) => { const formatStation = (id) => {
if (!isIBNR.test(id)) throw new Error('station ID must be an IBNR.') if (!isIBNR.test(id)) throw new Error('station ID must be an IBNR.')
@ -119,11 +138,14 @@ const vbbProfile = {
endpoint: 'https://fahrinfo.vbb.de/bin/mgate.exe', endpoint: 'https://fahrinfo.vbb.de/bin/mgate.exe',
transformReqBody, transformReqBody,
products: modes.allProducts,
parseStationName: shorten, parseStationName: shorten,
parseLocation, parseLocation,
parseLine, parseLine,
parseProducts: createParseBitmask(modes.bitmasks), parseProducts: createParseBitmask(modes.bitmasks),
parseJourney: createParseJourney, parseJourney: createParseJourney,
parseStopover: createParseStopover,
formatStation, formatStation,
formatProducts, formatProducts,

View file

@ -95,6 +95,16 @@ m.categories = [
m.unknown m.unknown
] ]
m.allProducts = [
m.suburban,
m.subway,
m.tram,
m.bus,
m.ferry,
m.express,
m.regional
]
// m.parseCategory = (category) => { // m.parseCategory = (category) => {
// return m.categories[parseInt(category)] || m.unknown // return m.categories[parseInt(category)] || m.unknown
// } // }

View file

@ -35,6 +35,7 @@
"slugg": "^1.2.0", "slugg": "^1.2.0",
"vbb-parse-ticket": "^0.2.1", "vbb-parse-ticket": "^0.2.1",
"vbb-short-station-name": "^0.4.0", "vbb-short-station-name": "^0.4.0",
"vbb-stations": "^5.8.0",
"vbb-translate-ids": "^3.1.0" "vbb-translate-ids": "^3.1.0"
}, },
"devDependencies": { "devDependencies": {

View file

@ -5,22 +5,6 @@ const parseDateTime = require('./date-time')
const clone = obj => Object.assign({}, obj) const clone = obj => Object.assign({}, obj)
const createParseJourneyPart = (profile, stations, lines, remarks) => { const createParseJourneyPart = (profile, stations, lines, remarks) => {
const parseStopover = (j, st) => {
const res = {
station: stations[parseInt(st.locX)]
}
if (st.aTimeR || st.aTimeS) {
const arr = parseDateTime(profile, j.date, st.aTimeR || st.aTimeS)
res.arrival = arr.toISO()
}
if (st.dTimeR || st.dTimeS) {
const dep = parseDateTime(profile, j.date, st.dTimeR || st.dTimeS)
res.departure = dep.toISO()
}
return res
}
// todo: finish parse/remark.js first // todo: finish parse/remark.js first
const applyRemark = (j, rm) => {} const applyRemark = (j, rm) => {}
@ -28,6 +12,7 @@ const createParseJourneyPart = (profile, stations, lines, remarks) => {
// todo: pt.dep.dProgType, pt.arr.dProgType // todo: pt.dep.dProgType, pt.arr.dProgType
// todo: what is pt.jny.dirFlg? // todo: what is pt.jny.dirFlg?
// todo: how does pt.freq work? // todo: how does pt.freq work?
// todo: what is pt.himL?
const parseJourneyPart = (j, pt) => { // j = journey, pt = part const parseJourneyPart = (j, pt) => { // j = journey, pt = part
const dep = profile.parseDateTime(profile, j.date, pt.dep.dTimeR || pt.dep.dTimeS) const dep = profile.parseDateTime(profile, j.date, pt.dep.dTimeR || pt.dep.dTimeS)
const arr = profile.parseDateTime(profile, j.date, pt.arr.aTimeR || pt.arr.aTimeS) const arr = profile.parseDateTime(profile, j.date, pt.arr.aTimeR || pt.arr.aTimeS)
@ -46,7 +31,9 @@ const createParseJourneyPart = (profile, stations, lines, remarks) => {
if (pt.type === 'WALK') { if (pt.type === 'WALK') {
res.mode = 'walking' res.mode = 'walking'
res.public = true
} else if (pt.type === 'JNY') { } else if (pt.type === 'JNY') {
// todo: pull `public` value from `profile.products`
res.id = pt.jny.jid res.id = pt.jny.jid
res.line = lines[parseInt(pt.jny.prodX)] || null res.line = lines[parseInt(pt.jny.prodX)] || null
res.direction = profile.parseStationName(pt.jny.dirTxt) res.direction = profile.parseStationName(pt.jny.dirTxt)
@ -55,7 +42,8 @@ const createParseJourneyPart = (profile, stations, lines, remarks) => {
if (pt.arr.aPlatfS) res.arrivalPlatform = pt.arr.aPlatfS if (pt.arr.aPlatfS) res.arrivalPlatform = pt.arr.aPlatfS
if (pt.jny.stopL) { if (pt.jny.stopL) {
res.passed = pt.jny.stopL.map(stopover => parseStopover(j, stopover)) const parse = profile.parseStopover(profile, stations, lines, remarks, j)
res.passed = pt.jny.stopL.map(parse)
} }
if (Array.isArray(pt.jny.remL)) { if (Array.isArray(pt.jny.remL)) {
for (let remark of pt.jny.remL) applyRemark(j, remark) for (let remark of pt.jny.remL) applyRemark(j, remark)
@ -63,8 +51,8 @@ const createParseJourneyPart = (profile, stations, lines, remarks) => {
if (pt.jny.freq && pt.jny.freq.jnyL) { if (pt.jny.freq && pt.jny.freq.jnyL) {
const parseAlternative = (a) => { const parseAlternative = (a) => {
// todo: realtime const t = a.stopL[0].dTimeS || a.stopL[0].dTimeR
const when = profile.parseDateTime(profile, j.date, a.stopL[0].dTimeS) const when = profile.parseDateTime(profile, j.date, t)
return { return {
line: lines[parseInt(a.prodX)] || null, line: lines[parseInt(a.prodX)] || null,
when: when.toISO() when: when.toISO()

View file

@ -1,8 +1,7 @@
'use strict' 'use strict'
// todo: what is p.number vs p.line? // todo: are p.number and p.line ever different?
// todo: what is p.icoX? // todo: operator from p.oprX?
// todo: what is p.oprX?
const parseLine = (profile, p) => { const parseLine = (profile, p) => {
if (!p) return null // todo: handle this upstream if (!p) return null // todo: handle this upstream
const res = { const res = {

View file

@ -24,12 +24,12 @@ const assertValidPoi = (t, p) => {
t.equal(typeof p.address, 'string') t.equal(typeof p.address, 'string')
t.ok(p.address) t.ok(p.address)
} }
assertValidLocation(t, p, true) // todo: do POIs always have coords? assertValidLocation(t, p, true)
} }
const assertValidAddress = (t, a) => { const assertValidAddress = (t, a) => {
t.equal(typeof a.address, 'string') t.equal(typeof a.address, 'string')
assertValidLocation(t, a, true) // todo: do addresses always have coords? assertValidLocation(t, a, true)
} }
const assertValidLocation = (t, l, coordsOptional = false) => { const assertValidLocation = (t, l, coordsOptional = false) => {
@ -58,18 +58,15 @@ const assertValidLocation = (t, l, coordsOptional = false) => {
} }
} }
// todo: https://github.com/public-transport/friendly-public-transport-format/tree/babf2b82947ab0e655a4a0e1cbee6b5519af9172/spec#modes const validLineModes = [
const isValidMode = (m) => { 'train', 'bus', 'ferry', 'taxi', 'gondola', 'aircraft',
return m === 'walking' || 'car', 'bicycle', 'walking'
m === 'train' || ]
m === 'bus' ||
m === 'ferry'
}
const assertValidLine = (t, l) => { const assertValidLine = (t, l) => {
t.equal(l.type, 'line') t.equal(l.type, 'line')
t.equal(typeof l.name, 'string') t.equal(typeof l.name, 'string')
t.ok(isValidMode(l.mode), 'invalid mode ' + l.mode) t.ok(validLineModes.includes(l.mode), 'invalid mode ' + l.mode)
t.equal(typeof l.product, 'string') t.equal(typeof l.product, 'string')
t.equal(l.public, true) t.equal(l.public, true)
} }
@ -140,7 +137,6 @@ module.exports = {
assertValidPoi, assertValidPoi,
assertValidAddress, assertValidAddress,
assertValidLocation, assertValidLocation,
isValidMode,
assertValidLine, assertValidLine,
isValidDateTime, isValidDateTime,
assertValidStopover, assertValidStopover,