merge refactor-parse-fns into next

This commit is contained in:
Jannis R 2018-06-26 12:52:33 +02:00
commit f5eceafdf3
No known key found for this signature in database
GPG key ID: 0FE83946296A88A5
16 changed files with 94 additions and 66 deletions

View file

@ -37,8 +37,8 @@ Assuming the endpoint returns all lines names prefixed with `foo `, We can strip
// get the default line parser // get the default line parser
const createParseLine = require('hafas-client/parse/line') const createParseLine = require('hafas-client/parse/line')
const createParseLineWithoutFoo = (profile, operators) => { const createParseLineWithoutFoo = (profile, opt, data) => {
const parseLine = createParseLine(profile, operators) const parseLine = createParseLine(profile, opt, data)
// wrapper function with additional logic // wrapper function with additional logic
const parseLineWithoutFoo = (l) => { const parseLineWithoutFoo = (l) => {

View file

@ -36,7 +36,7 @@ const createClient = (profile, request = _request) => {
const products = profile.formatProductsFilter(opt.products || {}) const products = profile.formatProductsFilter(opt.products || {})
const dir = opt.direction ? profile.formatStation(opt.direction) : null const dir = opt.direction ? profile.formatStation(opt.direction) : null
return request(profile, { return request(profile, opt, {
meth: 'StationBoard', meth: 'StationBoard',
req: { req: {
type: 'DEP', type: 'DEP',
@ -51,7 +51,12 @@ const createClient = (profile, request = _request) => {
}) })
.then((d) => { .then((d) => {
if (!Array.isArray(d.jnyL)) return [] // todo: throw err? if (!Array.isArray(d.jnyL)) return [] // todo: throw err?
const parse = profile.parseDeparture(profile, d.locations, d.lines, d.hints, d.warnings) const parse = profile.parseDeparture(profile, opt, {
locations: d.locations,
lines: d.lines,
hints: d.hints,
warnings: d.warnings
})
return d.jnyL.map(parse) return d.jnyL.map(parse)
.sort((a, b) => new Date(a.when) - new Date(b.when)) .sort((a, b) => new Date(a.when) - new Date(b.when))
}) })
@ -158,7 +163,7 @@ const createClient = (profile, request = _request) => {
} }
if (profile.journeysNumF) query.numF = opt.results if (profile.journeysNumF) query.numF = opt.results
return request(profile, { return request(profile, opt, {
cfg: {polyEnc: 'GPA'}, cfg: {polyEnc: 'GPA'},
meth: 'TripSearch', meth: 'TripSearch',
req: profile.transformJourneysQuery(query, opt) req: profile.transformJourneysQuery(query, opt)
@ -166,8 +171,13 @@ const createClient = (profile, request = _request) => {
.then((d) => { .then((d) => {
if (!Array.isArray(d.outConL)) return [] if (!Array.isArray(d.outConL)) return []
const polylines = opt.polylines && d.common.polyL || [] const parse = profile.parseJourney(profile, opt, {
const parse = profile.parseJourney(profile, d.locations, d.lines, d.hints, d.warnings, polylines) locations: d.locations,
lines: d.lines,
hints: d.hints,
warnings: d.warnings,
polylines: opt.polylines && d.common.polyL || []
})
if (!journeys.earlierRef) journeys.earlierRef = d.outCtxScrB if (!journeys.earlierRef) journeys.earlierRef = d.outCtxScrB
@ -205,7 +215,7 @@ const createClient = (profile, request = _request) => {
}, opt) }, opt)
const f = profile.formatLocationFilter(opt.stations, opt.addresses, opt.poi) const f = profile.formatLocationFilter(opt.stations, opt.addresses, opt.poi)
return request(profile, { return request(profile, opt, {
cfg: {polyEnc: 'GPA'}, cfg: {polyEnc: 'GPA'},
meth: 'LocMatch', meth: 'LocMatch',
req: {input: { req: {input: {
@ -220,7 +230,7 @@ const createClient = (profile, request = _request) => {
.then((d) => { .then((d) => {
if (!d.match || !Array.isArray(d.match.locL)) return [] if (!d.match || !Array.isArray(d.match.locL)) return []
const parse = profile.parseLocation const parse = profile.parseLocation
return d.match.locL.map(loc => parse(profile, loc, d.lines)) return d.match.locL.map(loc => parse(profile, opt, {lines: d.lines}, loc))
}) })
} }
@ -229,7 +239,8 @@ const createClient = (profile, request = _request) => {
else if ('string' === typeof station) station = profile.formatStation(station) else if ('string' === typeof station) station = profile.formatStation(station)
else throw new Error('station must be an object or a string.') else throw new Error('station must be an object or a string.')
return request(profile, { const opt = {}
return request(profile, opt, {
meth: 'LocDetails', meth: 'LocDetails',
req: { req: {
locL: [station] locL: [station]
@ -240,7 +251,7 @@ const createClient = (profile, request = _request) => {
// todo: proper stack trace? // todo: proper stack trace?
throw new Error('invalid response') throw new Error('invalid response')
} }
return profile.parseLocation(profile, d.locL[0], d.lines) return profile.parseLocation(profile, opt, {lines: d.lines}, d.locL[0])
}) })
} }
@ -262,7 +273,7 @@ const createClient = (profile, request = _request) => {
stations: true, // return stations? stations: true, // return stations?
}, opt) }, opt)
return request(profile, { return request(profile, opt, {
cfg: {polyEnc: 'GPA'}, cfg: {polyEnc: 'GPA'},
meth: 'LocGeoPos', meth: 'LocGeoPos',
req: { req: {
@ -282,7 +293,7 @@ const createClient = (profile, request = _request) => {
.then((d) => { .then((d) => {
if (!Array.isArray(d.locL)) return [] if (!Array.isArray(d.locL)) return []
const parse = profile.parseNearby const parse = profile.parseNearby
return d.locL.map(loc => parse(profile, loc)) return d.locL.map(loc => parse(profile, opt, d, loc))
}) })
} }
@ -300,7 +311,7 @@ const createClient = (profile, request = _request) => {
opt.when = new Date(opt.when || Date.now()) opt.when = new Date(opt.when || Date.now())
if (Number.isNaN(+opt.when)) throw new Error('opt.when is invalid') if (Number.isNaN(+opt.when)) throw new Error('opt.when is invalid')
return request(profile, { return request(profile, opt, {
cfg: {polyEnc: 'GPA'}, cfg: {polyEnc: 'GPA'},
meth: 'JourneyDetails', meth: 'JourneyDetails',
req: { req: {
@ -312,8 +323,13 @@ const createClient = (profile, request = _request) => {
} }
}) })
.then((d) => { .then((d) => {
const polylines = opt.polyline && d.common.polyL || [] const parse = profile.parseJourneyLeg(profile, opt, {
const parse = profile.parseJourneyLeg(profile, d.locations, d.lines, d.hints, d.warnings, polylines) locations: d.locations,
lines: d.lines,
hints: d.hints,
warnings: d.warnings,
polylines: opt.polyline && d.common.polyL || []
})
const leg = { // pretend the leg is contained in a journey const leg = { // pretend the leg is contained in a journey
type: 'JNY', type: 'JNY',
@ -345,7 +361,7 @@ const createClient = (profile, request = _request) => {
if (Number.isNaN(+opt.when)) throw new Error('opt.when is invalid') if (Number.isNaN(+opt.when)) throw new Error('opt.when is invalid')
const durationPerStep = opt.duration / Math.max(opt.frames, 1) * 1000 const durationPerStep = opt.duration / Math.max(opt.frames, 1) * 1000
return request(profile, { return request(profile, opt, {
meth: 'JourneyGeoPos', meth: 'JourneyGeoPos',
req: { req: {
maxJny: opt.results, maxJny: opt.results,
@ -366,8 +382,13 @@ const createClient = (profile, request = _request) => {
.then((d) => { .then((d) => {
if (!Array.isArray(d.jnyL)) return [] if (!Array.isArray(d.jnyL)) return []
const polylines = opt.polyline && d.common.polyL || [] const parse = profile.parseMovement(profile, opt, {
const parse = profile.parseMovement(profile, d.locations, d.lines, d.hints, d.warnings, polylines) locations: d.locations,
lines: d.lines,
hints: d.hints,
warnings: d.warnings,
polylines: opt.polyline && d.common.polyL || []
})
return d.jnyL.map(parse) return d.jnyL.map(parse)
}) })
} }

View file

@ -11,7 +11,7 @@ const {fetch} = require('fetch-ponyfill')({Promise})
const md5 = input => createHash('md5').update(input).digest() const md5 = input => createHash('md5').update(input).digest()
const request = (profile, data) => { const request = (profile, opt, data) => {
const body = profile.transformReqBody({lang: 'en', svcReqL: [data]}) const body = profile.transformReqBody({lang: 'en', svcReqL: [data]})
const req = profile.transformReq({ const req = profile.transformReq({
method: 'post', method: 'post',
@ -92,11 +92,13 @@ const request = (profile, data) => {
d.operators = c.opL.map(op => profile.parseOperator(profile, op)) d.operators = c.opL.map(op => profile.parseOperator(profile, op))
} }
if (Array.isArray(c.prodL)) { if (Array.isArray(c.prodL)) {
const parse = profile.parseLine(profile, d.operators) const parse = profile.parseLine(profile, opt, {
operators: d.operators
})
d.lines = c.prodL.map(parse) d.lines = c.prodL.map(parse)
} }
if (Array.isArray(c.locL)) { if (Array.isArray(c.locL)) {
const parse = loc => profile.parseLocation(profile, loc, d.lines) const parse = loc => profile.parseLocation(profile, opt, {lines: d.lines}, loc)
d.locations = c.locL.map(parse) d.locations = c.locL.map(parse)
} }
return d return d

View file

@ -34,8 +34,8 @@ const transformJourneysQuery = (query, opt) => {
return query return query
} }
const createParseJourney = (profile, stations, lines, hints, polylines) => { const createParseJourney = (profile, opt, data) => {
const parseJourney = _createParseJourney(profile, stations, lines, hints, polylines) const parseJourney = _createParseJourney(profile, opt, data)
// todo: j.sotRating, j.conSubscr, j.isSotCon, j.showARSLink, k.sotCtxt // todo: j.sotRating, j.conSubscr, j.isSotCon, j.showARSLink, k.sotCtxt
// todo: j.conSubscr, j.showARSLink, j.useableTime // todo: j.conSubscr, j.showARSLink, j.useableTime

View file

@ -21,8 +21,8 @@ const transformReqBody = (body) => {
return body return body
} }
const parseLocation = (profile, l, lines) => { const parseLocation = (profile, opt, data, l) => {
const res = _parseLocation(profile, l, lines) const res = _parseLocation(profile, opt, data, l)
// weird fix for empty lines, e.g. IC/EC at Flensburg Hbf // weird fix for empty lines, e.g. IC/EC at Flensburg Hbf
if (res.lines) { if (res.lines) {
res.lines = res.lines.filter(x => x.id && x.name) res.lines = res.lines.filter(x => x.id && x.name)
@ -36,8 +36,8 @@ const parseLocation = (profile, l, lines) => {
return res return res
} }
const createParseJourney = (profile, stations, lines, hints) => { const createParseJourney = (profile, opt, data) => {
const parseJourney = _createParseJourney(profile, stations, lines, hints) const parseJourney = _createParseJourney(profile, opt, data)
const parseJourneyWithTickets = (j) => { const parseJourneyWithTickets = (j) => {
const res = parseJourney(j) const res = parseJourney(j)
@ -78,8 +78,8 @@ const createParseJourney = (profile, stations, lines, hints) => {
return parseJourneyWithTickets return parseJourneyWithTickets
} }
const createParseMovement = (profile, locations, lines, hints) => { const createParseMovement = (profile, opt, data) => {
const _parseMovement = _createParseMovement(profile, locations, lines, hints) const _parseMovement = _createParseMovement(profile, opt, data)
const parseMovement = (m) => { const parseMovement = (m) => {
const res = _parseMovement(m) const res = _parseMovement(m)
// filter out empty nextStops entries // filter out empty nextStops entries

View file

@ -25,10 +25,10 @@ const transformReqBody = (body) => {
return body return body
} }
const parseLocation = (profile, l, lines) => { const parseLocation = (profile, opt, data, l) => {
// ÖBB has some 'stations' **in austria** with no departures/products, // ÖBB has some 'stations' **in austria** with no departures/products,
// like station entrances, that are actually POIs. // like station entrances, that are actually POIs.
const res = _parseLocation(profile, l, lines) const res = _parseLocation(profile, opt, data, l)
if ( if (
res.type === 'station' && res.type === 'station' &&
!res.products && !res.products &&
@ -44,8 +44,8 @@ const parseLocation = (profile, l, lines) => {
return res return res
} }
const createParseMovement = (profile, locations, lines, hints) => { const createParseMovement = (profile, opt, data) => {
const _parseMovement = _createParseMovement(profile, locations, lines, hints) const _parseMovement = _createParseMovement(profile, opt, data)
const parseMovement = (m) => { const parseMovement = (m) => {
const res = _parseMovement(m) const res = _parseMovement(m)
// filter out POIs // filter out POIs

View file

@ -23,8 +23,8 @@ const transformReqBody = (body) => {
return body return body
} }
const createParseLine = (profile, operators) => { const createParseLine = (profile, opt, data) => {
const parseLine = _createParseLine(profile, operators) const parseLine = _createParseLine(profile, opt, data)
const parseLineWithMoreDetails = (l) => { const parseLineWithMoreDetails = (l) => {
const res = parseLine(l) const res = parseLine(l)
@ -42,8 +42,8 @@ const createParseLine = (profile, operators) => {
return parseLineWithMoreDetails return parseLineWithMoreDetails
} }
const parseLocation = (profile, l, lines) => { const parseLocation = (profile, opt, data, l) => {
const res = _parseLocation(profile, l, lines) const res = _parseLocation(profile, opt, data, l)
if (res.type === 'station') { if (res.type === 'station') {
res.name = shorten(res.name) res.name = shorten(res.name)
@ -56,8 +56,8 @@ const parseLocation = (profile, l, lines) => {
return res return res
} }
const createParseJourney = (profile, stations, lines, hints, polylines) => { const createParseJourney = (profile, opt, data) => {
const parseJourney = _createParseJourney(profile, stations, lines, hints, polylines) const parseJourney = _createParseJourney(profile, opt, data)
const parseJourneyWithTickets = (j) => { const parseJourneyWithTickets = (j) => {
const res = parseJourney(j) const res = parseJourney(j)
@ -86,8 +86,8 @@ const createParseJourney = (profile, stations, lines, hints, polylines) => {
return parseJourneyWithTickets return parseJourneyWithTickets
} }
const createParseDeparture = (profile, stations, lines, hints) => { const createParseDeparture = (profile, opt, data) => {
const parseDeparture = _createParseDeparture(profile, stations, lines, hints) const parseDeparture = _createParseDeparture(profile, opt, data)
const ringbahnClockwise = /^ringbahn s\s?41$/i const ringbahnClockwise = /^ringbahn s\s?41$/i
const ringbahnAnticlockwise = /^ringbahn s\s?42$/i const ringbahnAnticlockwise = /^ringbahn s\s?42$/i

View file

@ -8,12 +8,14 @@ const findRemark = require('./find-remark')
// todo: d.stbStop.dProgType // todo: d.stbStop.dProgType
// todo: d.freq, d.freq.jnyL, see https://github.com/public-transport/hafas-client/blob/9203ed1481f08baacca41ac5e3c19bf022f01b0b/parse.js#L115 // todo: d.freq, d.freq.jnyL, see https://github.com/public-transport/hafas-client/blob/9203ed1481f08baacca41ac5e3c19bf022f01b0b/parse.js#L115
const createParseDeparture = (profile, stations, lines, hints, warnings) => { const createParseDeparture = (profile, opt, data) => {
const {locations, lines, hints, warnings} = data
const parseDeparture = (d) => { const parseDeparture = (d) => {
const when = profile.parseDateTime(profile, d.date, d.stbStop.dTimeR || d.stbStop.dTimeS) const when = profile.parseDateTime(profile, d.date, d.stbStop.dTimeR || d.stbStop.dTimeS)
const res = { const res = {
journeyId: d.jid, journeyId: d.jid,
station: stations[parseInt(d.stbStop.locX)] || null, station: locations[parseInt(d.stbStop.locX)] || null,
when: when.toISO(), when: when.toISO(),
direction: profile.parseStationName(d.dirTxt), direction: profile.parseStationName(d.dirTxt),
line: lines[parseInt(d.prodX)] || null, line: lines[parseInt(d.prodX)] || null,

View file

@ -34,7 +34,8 @@ const applyRemarks = (leg, hints, warnings, refs) => {
} }
} }
const createParseJourneyLeg = (profile, stations, lines, hints, warnings, polylines) => { const createParseJourneyLeg = (profile, opt, data) => {
const {locations, lines, hints, warnings, polylines} = data
// todo: pt.status // todo: pt.status
// todo: pt.sDays // todo: pt.sDays
// todo: pt.dep.dProgType, pt.arr.dProgType // todo: pt.dep.dProgType, pt.arr.dProgType
@ -48,8 +49,8 @@ const createParseJourneyLeg = (profile, stations, lines, hints, warnings, polyli
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)
const res = { const res = {
origin: clone(stations[parseInt(pt.dep.locX)]) || null, origin: clone(locations[parseInt(pt.dep.locX)]) || null,
destination: clone(stations[parseInt(pt.arr.locX)]), destination: clone(locations[parseInt(pt.arr.locX)]),
departure: dep.toISO(), departure: dep.toISO(),
arrival: arr.toISO() arrival: arr.toISO()
} }
@ -71,7 +72,7 @@ const createParseJourneyLeg = (profile, stations, lines, hints, warnings, polyli
let p = pt.jny.polyG.polyXL let p = pt.jny.polyG.polyXL
p = Array.isArray(p) && polylines[p[0]] p = Array.isArray(p) && polylines[p[0]]
// todo: there can be >1 polyline // todo: there can be >1 polyline
const parse = profile.parsePolyline(stations) const parse = profile.parsePolyline(profile, opt, data)
res.polyline = p && parse(p) || null res.polyline = p && parse(p) || null
} }
@ -88,7 +89,7 @@ const createParseJourneyLeg = (profile, stations, lines, hints, warnings, polyli
if (pt.arr.aPlatfS) res.arrivalPlatform = pt.arr.aPlatfS if (pt.arr.aPlatfS) res.arrivalPlatform = pt.arr.aPlatfS
if (parseStopovers && pt.jny.stopL) { if (parseStopovers && pt.jny.stopL) {
const parse = profile.parseStopover(profile, stations, lines, hints, warnings, j.date) const parse = profile.parseStopover(profile, opt, data, j.date)
const stopL = pt.jny.stopL const stopL = pt.jny.stopL
res.stopovers = stopL.map(parse) res.stopovers = stopL.map(parse)

View file

@ -2,8 +2,9 @@
const findRemark = require('./find-remark') const findRemark = require('./find-remark')
const createParseJourney = (profile, stations, lines, hints, warnings, polylines) => { const createParseJourney = (profile, opt, data) => {
const parseLeg = profile.parseJourneyLeg(profile, stations, lines, hints, warnings, polylines) const parseLeg = profile.parseJourneyLeg(profile, opt, data)
const {hints, warnings} = data
// todo: c.sDays // todo: c.sDays
// todo: c.conSubscr // todo: c.conSubscr

View file

@ -2,7 +2,7 @@
const slugg = require('slugg') const slugg = require('slugg')
const createParseLine = (profile, operators) => { const createParseLine = (profile, opt, {operators}) => {
const byBitmask = [] const byBitmask = []
for (let product of profile.products) { for (let product of profile.products) {
for (let bitmask of product.bitmasks) { for (let bitmask of product.bitmasks) {

View file

@ -5,8 +5,7 @@ const STATION = 'S'
const ADDRESS = 'A' const ADDRESS = 'A'
// todo: what is s.rRefL? // todo: what is s.rRefL?
// todo: [breaking] change to createParseLocation(profile, lines) => (l) => loc const parseLocation = (profile, opt, {lines}, l) => {
const parseLocation = (profile, l, lines) => {
const res = {type: 'location'} const res = {type: 'location'}
if (l.crd) { if (l.crd) {
res.latitude = l.crd.y / 1000000 res.latitude = l.crd.y / 1000000

View file

@ -1,6 +1,8 @@
'use strict' 'use strict'
const createParseMovement = (profile, locations, lines, hints, warnings, polylines = []) => { const createParseMovement = (profile, opt, data) => {
const {locations, lines, hints, warnings, polylines} = data
// todo: what is m.dirGeo? maybe the speed? // todo: what is m.dirGeo? maybe the speed?
// todo: what is m.stopL? // todo: what is m.stopL?
// todo: what is m.proc? wut? // todo: what is m.proc? wut?
@ -8,7 +10,7 @@ const createParseMovement = (profile, locations, lines, hints, warnings, polylin
// todo: what is m.ani.dirGeo[n]? maybe the speed? // todo: what is m.ani.dirGeo[n]? maybe the speed?
// todo: what is m.ani.proc[n]? wut? // todo: what is m.ani.proc[n]? wut?
const parseMovement = (m) => { const parseMovement = (m) => {
const pStopover = profile.parseStopover(profile, locations, lines, hints, warnings, m.date) const pStopover = profile.parseStopover(profile, opt, data, m.date)
const res = { const res = {
direction: profile.parseStationName(m.dirTxt), direction: profile.parseStationName(m.dirTxt),
@ -36,13 +38,13 @@ const createParseMovement = (profile, locations, lines, hints, warnings, polylin
} }
if (m.ani.poly) { if (m.ani.poly) {
const parse = profile.parsePolyline(locations) const parse = profile.parsePolyline(profile, opt, data)
res.polyline = parse(m.ani.poly) res.polyline = parse(m.ani.poly)
} else if (m.ani.polyG) { } else if (m.ani.polyG) {
let p = m.ani.polyG.polyXL let p = m.ani.polyG.polyXL
p = Array.isArray(p) && polylines[p[0]] p = Array.isArray(p) && polylines[p[0]]
// todo: there can be >1 polyline // todo: there can be >1 polyline
const parse = profile.parsePolyline(locations) const parse = profile.parsePolyline(profile, opt, data)
res.polyline = p && parse(p) || null res.polyline = p && parse(p) || null
} }
} }

View file

@ -6,9 +6,9 @@
// todo: what is s.wt? // todo: what is s.wt?
// todo: what is s.dur? // todo: what is s.dur?
// todo: [breaking] change to createParseNearby(profile, lines) => (n) => nearby // todo: [breaking] change to createParseNearby(profile, data) => (n) => nearby
const parseNearby = (profile, n, lines) => { const parseNearby = (profile, opt, data, n) => {
const res = profile.parseLocation(profile, n, lines) const res = profile.parseLocation(profile, opt, data, n)
res.distance = n.dist res.distance = n.dist
return res return res
} }

View file

@ -3,7 +3,7 @@
const {toGeoJSON} = require('@mapbox/polyline') const {toGeoJSON} = require('@mapbox/polyline')
const distance = require('gps-distance') const distance = require('gps-distance')
const createParsePolyline = (locations) => { const createParsePolyline = (profile, opt, {locations}) => {
// todo: what is p.delta? // todo: what is p.delta?
// todo: what is p.type? // todo: what is p.type?
// todo: what is p.crdEncS? // todo: what is p.crdEncS?

View file

@ -3,12 +3,12 @@
const findRemark = require('./find-remark') const findRemark = require('./find-remark')
// todo: arrivalDelay, departureDelay or only delay ? // todo: arrivalDelay, departureDelay or only delay ?
// todo: arrivalPlatform, departurePlatform const createParseStopover = (profile, opt, data, date) => {
const createParseStopover = (profile, stations, lines, hints, warnings, date) => { const {locations, lines, hints, warnings} = data
const parseStopover = (st) => { const parseStopover = (st) => {
const res = { const res = {
type: 'stopover', stop: locations[parseInt(st.locX)] || null,
stop: stations[parseInt(st.locX)] || null,
arrival: null, arrival: null,
arrivalDelay: null, arrivalDelay: null,
arrivalPlatform: st.aPlatfR || st.aPlatfS || null, arrivalPlatform: st.aPlatfR || st.aPlatfS || null,