mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-23 15:19:35 +02:00
request formatters via profile
This commit is contained in:
parent
773035c05d
commit
39a626784b
10 changed files with 194 additions and 99 deletions
20
format/locations-req.js
Normal file
20
format/locations-req.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const formatLocationsReq = (ctx, query) => {
|
||||||
|
const {profile, opt} = ctx
|
||||||
|
|
||||||
|
return {
|
||||||
|
cfg: {polyEnc: 'GPA'},
|
||||||
|
meth: 'LocMatch',
|
||||||
|
req: {input: {
|
||||||
|
loc: {
|
||||||
|
type: profile.formatLocationFilter(opt.stops, opt.addresses, opt.poi),
|
||||||
|
name: opt.fuzzy ? query + '?' : query
|
||||||
|
},
|
||||||
|
maxLoc: opt.results,
|
||||||
|
field: 'S' // todo: what is this?
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = formatLocationsReq
|
25
format/nearby-req.js
Normal file
25
format/nearby-req.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const nearbyReq = (ctx, location) => {
|
||||||
|
const {profile, opt} = ctx
|
||||||
|
|
||||||
|
return {
|
||||||
|
cfg: {polyEnc: 'GPA'},
|
||||||
|
meth: 'LocGeoPos',
|
||||||
|
req: {
|
||||||
|
ring: {
|
||||||
|
cCrd: {
|
||||||
|
x: profile.formatCoord(location.longitude),
|
||||||
|
y: profile.formatCoord(location.latitude)
|
||||||
|
},
|
||||||
|
maxDist: opt.distance || -1,
|
||||||
|
minDist: 0
|
||||||
|
},
|
||||||
|
getPOIs: !!opt.poi,
|
||||||
|
getStops: !!opt.stops,
|
||||||
|
maxLoc: opt.results
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = nearbyReq
|
26
format/radar-req.js
Normal file
26
format/radar-req.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const formatRadarReq = (ctx, north, west, south, east) => {
|
||||||
|
const {profile, opt} = ctx
|
||||||
|
|
||||||
|
return {
|
||||||
|
meth: 'JourneyGeoPos',
|
||||||
|
req: {
|
||||||
|
maxJny: opt.results,
|
||||||
|
onlyRT: false, // todo: does this mean "only realtime"?
|
||||||
|
date: profile.formatDate(profile, opt.when),
|
||||||
|
time: profile.formatTime(profile, opt.when),
|
||||||
|
// todo: would a ring work here as well?
|
||||||
|
rect: profile.formatRectangle(profile, north, west, south, east),
|
||||||
|
perSize: opt.duration * 1000,
|
||||||
|
perStep: Math.round(opt.duration / Math.max(opt.frames, 1) * 1000),
|
||||||
|
ageOfReport: true, // todo: what is this?
|
||||||
|
jnyFltrL: [
|
||||||
|
profile.formatProductsFilter(ctx, opt.products || {})
|
||||||
|
],
|
||||||
|
trainPosMode: 'CALC' // todo: what is this? what about realtime?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = formatRadarReq
|
22
format/reachable-from-req.js
Normal file
22
format/reachable-from-req.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const formatReachableFromReq = (ctx, address) => {
|
||||||
|
const {profile, opt} = ctx
|
||||||
|
|
||||||
|
return {
|
||||||
|
meth: 'LocGeoReach',
|
||||||
|
req: {
|
||||||
|
loc: profile.formatLocation(profile, address, 'address'),
|
||||||
|
maxDur: opt.maxDuration === null ? -1 : opt.maxDuration,
|
||||||
|
maxChg: opt.maxTransfers,
|
||||||
|
date: profile.formatDate(profile, opt.when),
|
||||||
|
time: profile.formatTime(profile, opt.when),
|
||||||
|
period: 120, // todo: what is this?
|
||||||
|
jnyFltrL: [
|
||||||
|
profile.formatProductsFilter(ctx, opt.products || {})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = formatReachableFromReq
|
26
format/station-board-req.js
Normal file
26
format/station-board-req.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const formatStationBoardReq = (ctx, station, type) => {
|
||||||
|
const {profile, opt} = ctx
|
||||||
|
|
||||||
|
const req = {
|
||||||
|
type,
|
||||||
|
date: profile.formatDate(profile, opt.when),
|
||||||
|
time: profile.formatTime(profile, opt.when),
|
||||||
|
stbLoc: station,
|
||||||
|
dirLoc: opt.direction ? profile.formatStation(opt.direction) : null,
|
||||||
|
jnyFltrL: [
|
||||||
|
profile.formatProductsFilter(ctx, opt.products || {})
|
||||||
|
],
|
||||||
|
dur: opt.duration
|
||||||
|
}
|
||||||
|
if (profile.departuresGetPasslist) req.getPasslist = !!opt.stopovers
|
||||||
|
if (profile.departuresStbFltrEquiv) req.stbFltrEquiv = !opt.includeRelatedStations
|
||||||
|
|
||||||
|
return {
|
||||||
|
meth: 'StationBoard',
|
||||||
|
req
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = formatStationBoardReq
|
12
format/stop-req.js
Normal file
12
format/stop-req.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const formatStopReq = (ctx, stopRef) => {
|
||||||
|
return {
|
||||||
|
meth: 'LocDetails',
|
||||||
|
req: {
|
||||||
|
locL: [stopRef]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = formatStopReq
|
19
format/trip-req.js
Normal file
19
format/trip-req.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const formatTripReq = ({opt}, id, lineName) => {
|
||||||
|
return {
|
||||||
|
cfg: {polyEnc: 'GPA'},
|
||||||
|
meth: 'JourneyDetails',
|
||||||
|
req: {
|
||||||
|
// todo: getTrainComposition
|
||||||
|
jid: id,
|
||||||
|
name: lineName,
|
||||||
|
// HAFAS apparently ignores the date in the trip ID and uses the `date` field.
|
||||||
|
// Thus, it will find a different trip if you pass the wrong date via `opt.when`.
|
||||||
|
// date: profile.formatDate(profile, opt.when),
|
||||||
|
getPolyline: !!opt.polyline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = formatTripReq
|
120
index.js
120
index.js
|
@ -60,25 +60,10 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
}, opt)
|
}, opt)
|
||||||
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')
|
||||||
const products = profile.formatProductsFilter({profile}, opt.products || {})
|
|
||||||
|
|
||||||
const dir = opt.direction ? profile.formatStation(opt.direction) : null
|
const req = profile.formatStationBoardReq({profile, opt}, station, type)
|
||||||
const req = {
|
|
||||||
type,
|
|
||||||
date: profile.formatDate(profile, opt.when),
|
|
||||||
time: profile.formatTime(profile, opt.when),
|
|
||||||
stbLoc: station,
|
|
||||||
dirLoc: dir,
|
|
||||||
jnyFltrL: [products],
|
|
||||||
dur: opt.duration
|
|
||||||
}
|
|
||||||
if (profile.departuresGetPasslist) req.getPasslist = !!opt.stopovers
|
|
||||||
if (profile.departuresStbFltrEquiv) req.stbFltrEquiv = !opt.includeRelatedStations
|
|
||||||
|
|
||||||
return profile.request({profile, opt}, userAgent, {
|
return profile.request({profile, opt}, userAgent, req)
|
||||||
meth: 'StationBoard',
|
|
||||||
req
|
|
||||||
})
|
|
||||||
.then(({res, common}) => {
|
.then(({res, common}) => {
|
||||||
if (!Array.isArray(res.jnyL)) return []
|
if (!Array.isArray(res.jnyL)) return []
|
||||||
|
|
||||||
|
@ -297,19 +282,9 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
linesOfStops: false // parse & expose lines at each stop/station?
|
linesOfStops: false // parse & expose lines at each stop/station?
|
||||||
}, opt)
|
}, opt)
|
||||||
|
|
||||||
const f = profile.formatLocationFilter(opt.stops, opt.addresses, opt.poi)
|
const req = profile.formatLocationsReq({profile, opt}, query)
|
||||||
return profile.request({profile, opt}, userAgent, {
|
|
||||||
cfg: {polyEnc: 'GPA'},
|
return profile.request({profile, opt}, userAgent, req)
|
||||||
meth: 'LocMatch',
|
|
||||||
req: {input: {
|
|
||||||
loc: {
|
|
||||||
type: f,
|
|
||||||
name: opt.fuzzy ? query + '?' : query
|
|
||||||
},
|
|
||||||
maxLoc: opt.results,
|
|
||||||
field: 'S' // todo: what is this?
|
|
||||||
}}
|
|
||||||
})
|
|
||||||
.then(({res, common}) => {
|
.then(({res, common}) => {
|
||||||
if (!res.match || !Array.isArray(res.match.locL)) return []
|
if (!res.match || !Array.isArray(res.match.locL)) return []
|
||||||
|
|
||||||
|
@ -326,12 +301,10 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
opt = Object.assign({
|
opt = Object.assign({
|
||||||
linesOfStops: false // parse & expose lines at the stop/station?
|
linesOfStops: false // parse & expose lines at the stop/station?
|
||||||
}, opt)
|
}, opt)
|
||||||
return profile.request({profile, opt}, userAgent, {
|
|
||||||
meth: 'LocDetails',
|
const req = profile.formatStopReq({profile, opt}, stop)
|
||||||
req: {
|
|
||||||
locL: [stop]
|
return profile.request({profile, opt}, userAgent, req)
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(({res, common}) => {
|
.then(({res, common}) => {
|
||||||
if (!res || !Array.isArray(res.locL) || !res.locL[0]) {
|
if (!res || !Array.isArray(res.locL) || !res.locL[0]) {
|
||||||
// todo: proper stack trace?
|
// todo: proper stack trace?
|
||||||
|
@ -354,23 +327,9 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
linesOfStops: false // parse & expose lines at each stop/station?
|
linesOfStops: false // parse & expose lines at each stop/station?
|
||||||
}, opt)
|
}, opt)
|
||||||
|
|
||||||
return profile.request({profile, opt}, userAgent, {
|
const req = profile.formatNearbyReq({profile, opt}, location)
|
||||||
cfg: {polyEnc: 'GPA'},
|
|
||||||
meth: 'LocGeoPos',
|
return profile.request({profile, opt}, userAgent, req)
|
||||||
req: {
|
|
||||||
ring: {
|
|
||||||
cCrd: {
|
|
||||||
x: profile.formatCoord(location.longitude),
|
|
||||||
y: profile.formatCoord(location.latitude)
|
|
||||||
},
|
|
||||||
maxDist: opt.distance || -1,
|
|
||||||
minDist: 0
|
|
||||||
},
|
|
||||||
getPOIs: !!opt.poi,
|
|
||||||
getStops: !!opt.stops,
|
|
||||||
maxLoc: opt.results
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(({common, res}) => {
|
.then(({common, res}) => {
|
||||||
if (!Array.isArray(res.locL)) return []
|
if (!Array.isArray(res.locL)) return []
|
||||||
|
|
||||||
|
@ -392,19 +351,9 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
remarks: true // parse & expose hints & warnings?
|
remarks: true // parse & expose hints & warnings?
|
||||||
}, opt)
|
}, opt)
|
||||||
|
|
||||||
return profile.request({profile, opt}, userAgent, {
|
const req = profile.formatTripReq({profile, opt}, id, lineName)
|
||||||
cfg: {polyEnc: 'GPA'},
|
|
||||||
meth: 'JourneyDetails',
|
return profile.request({profile, opt}, userAgent, req)
|
||||||
req: {
|
|
||||||
// todo: getTrainComposition
|
|
||||||
jid: id,
|
|
||||||
name: lineName,
|
|
||||||
// HAFAS apparently ignores the date in the trip ID and uses the `date` field.
|
|
||||||
// Thus, it will find a different trip if you pass the wrong date via `opt.when`.
|
|
||||||
// date: profile.formatDate(profile, opt.when),
|
|
||||||
getPolyline: !!opt.polyline
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(({common, res}) => {
|
.then(({common, res}) => {
|
||||||
const ctx = {profile, opt, common, res}
|
const ctx = {profile, opt, common, res}
|
||||||
|
|
||||||
|
@ -440,25 +389,9 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
opt.when = new Date(opt.when || Date.now())
|
opt.when = new Date(opt.when || Date.now())
|
||||||
if (Number.isNaN(+opt.when)) throw new TypeError('opt.when is invalid')
|
if (Number.isNaN(+opt.when)) throw new TypeError('opt.when is invalid')
|
||||||
|
|
||||||
const durationPerStep = opt.duration / Math.max(opt.frames, 1) * 1000
|
const req = profile.formatRadarReq({profile, opt}, north, west, south, east)
|
||||||
return profile.request({profile, opt}, userAgent, {
|
|
||||||
meth: 'JourneyGeoPos',
|
return profile.request({profile, opt}, userAgent, req)
|
||||||
req: {
|
|
||||||
maxJny: opt.results,
|
|
||||||
onlyRT: false, // todo: does this mean "only realtime"?
|
|
||||||
date: profile.formatDate(profile, opt.when),
|
|
||||||
time: profile.formatTime(profile, opt.when),
|
|
||||||
// todo: would a ring work here as well?
|
|
||||||
rect: profile.formatRectangle(profile, north, west, south, east),
|
|
||||||
perSize: opt.duration * 1000,
|
|
||||||
perStep: Math.round(durationPerStep),
|
|
||||||
ageOfReport: true, // todo: what is this?
|
|
||||||
jnyFltrL: [
|
|
||||||
profile.formatProductsFilter({profile}, opt.products || {})
|
|
||||||
],
|
|
||||||
trainPosMode: 'CALC' // todo: what is this? what about realtime?
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(({res, common}) => {
|
.then(({res, common}) => {
|
||||||
if (!Array.isArray(res.jnyL)) return []
|
if (!Array.isArray(res.jnyL)) return []
|
||||||
|
|
||||||
|
@ -478,21 +411,10 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
}, opt)
|
}, opt)
|
||||||
if (Number.isNaN(+opt.when)) throw new TypeError('opt.when is invalid')
|
if (Number.isNaN(+opt.when)) throw new TypeError('opt.when is invalid')
|
||||||
|
|
||||||
|
const req = profile.formatReachableFromReq({profile, opt}, address)
|
||||||
|
|
||||||
const refetch = () => {
|
const refetch = () => {
|
||||||
return profile.request({profile, opt}, userAgent, {
|
return profile.request({profile, opt}, userAgent, req)
|
||||||
meth: 'LocGeoReach',
|
|
||||||
req: {
|
|
||||||
loc: profile.formatLocation(profile, address, 'address'),
|
|
||||||
maxDur: opt.maxDuration === null ? -1 : opt.maxDuration,
|
|
||||||
maxChg: opt.maxTransfers,
|
|
||||||
date: profile.formatDate(profile, opt.when),
|
|
||||||
time: profile.formatTime(profile, opt.when),
|
|
||||||
period: 120, // todo: what is this?
|
|
||||||
jnyFltrL: [
|
|
||||||
profile.formatProductsFilter({profile}, opt.products || {})
|
|
||||||
]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(({res, common}) => {
|
.then(({res, common}) => {
|
||||||
if (!Array.isArray(res.posL)) {
|
if (!Array.isArray(res.posL)) {
|
||||||
const err = new Error('invalid response')
|
const err = new Error('invalid response')
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
|
|
||||||
const request = require('../lib/request')
|
const request = require('../lib/request')
|
||||||
|
|
||||||
|
const formatStationBoardReq = require('../format/station-board-req')
|
||||||
|
const formatLocationsReq = require('../format/locations-req')
|
||||||
|
const formatStopReq = require('../format/stop-req')
|
||||||
|
const formatNearbyReq = require('../format/nearby-req')
|
||||||
|
const formatTripReq = require('../format/trip-req')
|
||||||
|
const formatRadarReq = require('../format/radar-req')
|
||||||
|
const formatReachableFromReq = require('../format/reachable-from-req')
|
||||||
|
|
||||||
const parseDateTime = require('../parse/date-time')
|
const parseDateTime = require('../parse/date-time')
|
||||||
const parsePlatform = require('../parse/platform')
|
const parsePlatform = require('../parse/platform')
|
||||||
const parseProductsBitmask = require('../parse/products-bitmask')
|
const parseProductsBitmask = require('../parse/products-bitmask')
|
||||||
|
@ -44,6 +52,13 @@ const defaultProfile = {
|
||||||
addChecksum: false,
|
addChecksum: false,
|
||||||
addMicMac: false,
|
addMicMac: false,
|
||||||
|
|
||||||
|
formatStationBoardReq,
|
||||||
|
formatLocationsReq,
|
||||||
|
formatStopReq,
|
||||||
|
formatNearbyReq,
|
||||||
|
formatTripReq,
|
||||||
|
formatRadarReq,
|
||||||
|
formatReachableFromReq,
|
||||||
transformJourneysQuery: id,
|
transformJourneysQuery: id,
|
||||||
|
|
||||||
parseDateTime,
|
parseDateTime,
|
||||||
|
|
|
@ -7,6 +7,14 @@ const types = {
|
||||||
request: 'function',
|
request: 'function',
|
||||||
transformReq: 'function',
|
transformReq: 'function',
|
||||||
transformReqBody: 'function',
|
transformReqBody: 'function',
|
||||||
|
|
||||||
|
formatStationBoardReq: 'function',
|
||||||
|
formatLocationsReq: 'function',
|
||||||
|
formatStopReq: 'function',
|
||||||
|
formatNearbyReq: 'function',
|
||||||
|
formatTripReq: 'function',
|
||||||
|
formatRadarReq: 'function',
|
||||||
|
formatReachableFromReq: 'function',
|
||||||
transformJourneysQuery: 'function',
|
transformJourneysQuery: 'function',
|
||||||
|
|
||||||
products: 'array',
|
products: 'array',
|
||||||
|
|
Loading…
Add table
Reference in a new issue