mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-23 07:09: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.when = new Date(opt.when || Date.now())
|
||||
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 = {
|
||||
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
|
||||
const req = profile.formatStationBoardReq({profile, opt}, station, type)
|
||||
|
||||
return profile.request({profile, opt}, userAgent, {
|
||||
meth: 'StationBoard',
|
||||
req
|
||||
})
|
||||
return profile.request({profile, opt}, userAgent, req)
|
||||
.then(({res, common}) => {
|
||||
if (!Array.isArray(res.jnyL)) return []
|
||||
|
||||
|
@ -297,19 +282,9 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
linesOfStops: false // parse & expose lines at each stop/station?
|
||||
}, opt)
|
||||
|
||||
const f = profile.formatLocationFilter(opt.stops, opt.addresses, opt.poi)
|
||||
return profile.request({profile, opt}, userAgent, {
|
||||
cfg: {polyEnc: 'GPA'},
|
||||
meth: 'LocMatch',
|
||||
req: {input: {
|
||||
loc: {
|
||||
type: f,
|
||||
name: opt.fuzzy ? query + '?' : query
|
||||
},
|
||||
maxLoc: opt.results,
|
||||
field: 'S' // todo: what is this?
|
||||
}}
|
||||
})
|
||||
const req = profile.formatLocationsReq({profile, opt}, query)
|
||||
|
||||
return profile.request({profile, opt}, userAgent, req)
|
||||
.then(({res, common}) => {
|
||||
if (!res.match || !Array.isArray(res.match.locL)) return []
|
||||
|
||||
|
@ -326,12 +301,10 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
opt = Object.assign({
|
||||
linesOfStops: false // parse & expose lines at the stop/station?
|
||||
}, opt)
|
||||
return profile.request({profile, opt}, userAgent, {
|
||||
meth: 'LocDetails',
|
||||
req: {
|
||||
locL: [stop]
|
||||
}
|
||||
})
|
||||
|
||||
const req = profile.formatStopReq({profile, opt}, stop)
|
||||
|
||||
return profile.request({profile, opt}, userAgent, req)
|
||||
.then(({res, common}) => {
|
||||
if (!res || !Array.isArray(res.locL) || !res.locL[0]) {
|
||||
// todo: proper stack trace?
|
||||
|
@ -354,23 +327,9 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
linesOfStops: false // parse & expose lines at each stop/station?
|
||||
}, opt)
|
||||
|
||||
return profile.request({profile, opt}, userAgent, {
|
||||
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
|
||||
}
|
||||
})
|
||||
const req = profile.formatNearbyReq({profile, opt}, location)
|
||||
|
||||
return profile.request({profile, opt}, userAgent, req)
|
||||
.then(({common, res}) => {
|
||||
if (!Array.isArray(res.locL)) return []
|
||||
|
||||
|
@ -392,19 +351,9 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
remarks: true // parse & expose hints & warnings?
|
||||
}, opt)
|
||||
|
||||
return profile.request({profile, opt}, userAgent, {
|
||||
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
|
||||
}
|
||||
})
|
||||
const req = profile.formatTripReq({profile, opt}, id, lineName)
|
||||
|
||||
return profile.request({profile, opt}, userAgent, req)
|
||||
.then(({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())
|
||||
if (Number.isNaN(+opt.when)) throw new TypeError('opt.when is invalid')
|
||||
|
||||
const durationPerStep = opt.duration / Math.max(opt.frames, 1) * 1000
|
||||
return profile.request({profile, opt}, userAgent, {
|
||||
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(durationPerStep),
|
||||
ageOfReport: true, // todo: what is this?
|
||||
jnyFltrL: [
|
||||
profile.formatProductsFilter({profile}, opt.products || {})
|
||||
],
|
||||
trainPosMode: 'CALC' // todo: what is this? what about realtime?
|
||||
}
|
||||
})
|
||||
const req = profile.formatRadarReq({profile, opt}, north, west, south, east)
|
||||
|
||||
return profile.request({profile, opt}, userAgent, req)
|
||||
.then(({res, common}) => {
|
||||
if (!Array.isArray(res.jnyL)) return []
|
||||
|
||||
|
@ -478,21 +411,10 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
}, opt)
|
||||
if (Number.isNaN(+opt.when)) throw new TypeError('opt.when is invalid')
|
||||
|
||||
const req = profile.formatReachableFromReq({profile, opt}, address)
|
||||
|
||||
const refetch = () => {
|
||||
return profile.request({profile, opt}, userAgent, {
|
||||
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 || {})
|
||||
]
|
||||
}
|
||||
})
|
||||
return profile.request({profile, opt}, userAgent, req)
|
||||
.then(({res, common}) => {
|
||||
if (!Array.isArray(res.posL)) {
|
||||
const err = new Error('invalid response')
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
|
||||
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 parsePlatform = require('../parse/platform')
|
||||
const parseProductsBitmask = require('../parse/products-bitmask')
|
||||
|
@ -44,6 +52,13 @@ const defaultProfile = {
|
|||
addChecksum: false,
|
||||
addMicMac: false,
|
||||
|
||||
formatStationBoardReq,
|
||||
formatLocationsReq,
|
||||
formatStopReq,
|
||||
formatNearbyReq,
|
||||
formatTripReq,
|
||||
formatRadarReq,
|
||||
formatReachableFromReq,
|
||||
transformJourneysQuery: id,
|
||||
|
||||
parseDateTime,
|
||||
|
|
|
@ -7,6 +7,14 @@ const types = {
|
|||
request: 'function',
|
||||
transformReq: 'function',
|
||||
transformReqBody: 'function',
|
||||
|
||||
formatStationBoardReq: 'function',
|
||||
formatLocationsReq: 'function',
|
||||
formatStopReq: 'function',
|
||||
formatNearbyReq: 'function',
|
||||
formatTripReq: 'function',
|
||||
formatRadarReq: 'function',
|
||||
formatReachableFromReq: 'function',
|
||||
transformJourneysQuery: 'function',
|
||||
|
||||
products: 'array',
|
||||
|
|
Loading…
Add table
Reference in a new issue