request formatters via profile

This commit is contained in:
Jannis R 2019-10-31 20:08:56 +01:00
parent 773035c05d
commit 39a626784b
No known key found for this signature in database
GPG key ID: 0FE83946296A88A5
10 changed files with 194 additions and 99 deletions

20
format/locations-req.js Normal file
View 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
View 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
View 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

View 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

View 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
View 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
View 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
View file

@ -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')

View file

@ -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,

View file

@ -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',