mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-23 07:09:35 +02:00
query journey parts
This commit is contained in:
parent
e762f30f05
commit
33417a6e61
7 changed files with 125 additions and 80 deletions
34
index.js
34
index.js
|
@ -1,5 +1,8 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
|
const minBy = require('lodash/minBy')
|
||||||
|
const maxBy = require('lodash/maxBy')
|
||||||
|
|
||||||
const defaultProfile = require('./lib/default-profile')
|
const defaultProfile = require('./lib/default-profile')
|
||||||
const request = require('./lib/request')
|
const request = require('./lib/request')
|
||||||
|
|
||||||
|
@ -23,14 +26,14 @@ const createClient = (profile) => {
|
||||||
return request(profile, {
|
return request(profile, {
|
||||||
meth: 'StationBoard',
|
meth: 'StationBoard',
|
||||||
req: {
|
req: {
|
||||||
type: 'DEP',
|
type: 'DEP',
|
||||||
date: profile.formatDate(profile, opt.when),
|
date: profile.formatDate(profile, opt.when),
|
||||||
time: profile.formatTime(profile, opt.when),
|
time: profile.formatTime(profile, opt.when),
|
||||||
stbLoc: profile.formatStation(station),
|
stbLoc: profile.formatStation(station),
|
||||||
dirLoc: dir,
|
dirLoc: dir,
|
||||||
jnyFltrL: [products],
|
jnyFltrL: [products],
|
||||||
dur: opt.duration,
|
dur: opt.duration,
|
||||||
getPasslist: false
|
getPasslist: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then((d) => {
|
.then((d) => {
|
||||||
|
@ -156,7 +159,32 @@ const createClient = (profile) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return {departures, journeys, locations, nearby}
|
const journeyPart = (ref, lineName, opt = {}) => {
|
||||||
|
opt.when = opt.when || new Date()
|
||||||
|
|
||||||
|
return request(profile, {
|
||||||
|
cfg: {polyEnc: 'GPA'},
|
||||||
|
meth: 'JourneyDetails',
|
||||||
|
req: {
|
||||||
|
jid: ref,
|
||||||
|
name: lineName,
|
||||||
|
date: profile.formatDate(profile, opt.when)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((d) => {
|
||||||
|
const parse = profile.parseJourneyPart(profile, d.locations, d.lines, d.remarks)
|
||||||
|
|
||||||
|
const part = { // pretend the part is contained in a journey
|
||||||
|
type: 'JNY',
|
||||||
|
dep: minBy(d.journey.stopL, 'idx'),
|
||||||
|
arr: maxBy(d.journey.stopL, 'idx'),
|
||||||
|
jny: d.journey
|
||||||
|
}
|
||||||
|
return parse(d.journey, part)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {departures, journeys, locations, nearby, journeyPart}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = createClient
|
module.exports = createClient
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
const parseDateTime = require('../parse/date-time')
|
const parseDateTime = require('../parse/date-time')
|
||||||
const parseDeparture = require('../parse/departure')
|
const parseDeparture = require('../parse/departure')
|
||||||
|
const parseJourneyPart = require('../parse/journey-part')
|
||||||
const parseJourney = require('../parse/journey')
|
const parseJourney = require('../parse/journey')
|
||||||
const parseLine = require('../parse/line')
|
const parseLine = require('../parse/line')
|
||||||
const parseLocation = require('../parse/location')
|
const parseLocation = require('../parse/location')
|
||||||
|
@ -32,6 +33,7 @@ const defaultProfile = {
|
||||||
|
|
||||||
parseDateTime,
|
parseDateTime,
|
||||||
parseDeparture,
|
parseDeparture,
|
||||||
|
parseJourneyPart,
|
||||||
parseJourney,
|
parseJourney,
|
||||||
parseLine,
|
parseLine,
|
||||||
parseStationName: id,
|
parseStationName: id,
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fetch-ponyfill": "^4.1.0",
|
"fetch-ponyfill": "^4.1.0",
|
||||||
|
"lodash": "^4.17.4",
|
||||||
"moment-timezone": "^0.5.13",
|
"moment-timezone": "^0.5.13",
|
||||||
"pinkie-promise": "^2.0.1",
|
"pinkie-promise": "^2.0.1",
|
||||||
"query-string": "^5.0.0",
|
"query-string": "^5.0.0",
|
||||||
|
|
|
@ -7,6 +7,7 @@ module.exports = {
|
||||||
remark: require('./remark'),
|
remark: require('./remark'),
|
||||||
operator: require('./operator'),
|
operator: require('./operator'),
|
||||||
stopover: require('./stopover'),
|
stopover: require('./stopover'),
|
||||||
|
journeyPart: require('./journey-part'),
|
||||||
journey: require('./journey'),
|
journey: require('./journey'),
|
||||||
nearby: require('./nearby'),
|
nearby: require('./nearby'),
|
||||||
movement: require('./movement')
|
movement: require('./movement')
|
||||||
|
|
87
parse/journey-part.js
Normal file
87
parse/journey-part.js
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const parseDateTime = require('./date-time')
|
||||||
|
|
||||||
|
const clone = obj => Object.assign({}, obj)
|
||||||
|
|
||||||
|
const createParseJourneyPart = (profile, stations, lines, remarks) => {
|
||||||
|
const tz = profile.timezone
|
||||||
|
|
||||||
|
const parseStopover = (j, st) => {
|
||||||
|
const res = {
|
||||||
|
station: stations[parseInt(st.locX)]
|
||||||
|
}
|
||||||
|
if (st.aTimeR || st.aTimeS) {
|
||||||
|
const arr = parseDateTime(tz, j.date, st.aTimeR || st.aTimeS)
|
||||||
|
res.arrival = arr.format()
|
||||||
|
}
|
||||||
|
if (st.dTimeR || st.dTimeS) {
|
||||||
|
const dep = parseDateTime(tz, j.date, st.dTimeR || st.dTimeS)
|
||||||
|
res.departure = dep.format()
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: finish parse/remark.js first
|
||||||
|
const applyRemark = (j, rm) => {}
|
||||||
|
|
||||||
|
// todo: pt.sDays
|
||||||
|
// todo: pt.dep.dProgType, pt.arr.dProgType
|
||||||
|
// todo: what is pt.jny.dirFlg?
|
||||||
|
// todo: how does pt.freq work?
|
||||||
|
const parseJourneyPart = (j, pt) => { // j = journey, pt = part
|
||||||
|
const dep = profile.parseDateTime(tz, j.date, pt.dep.dTimeR || pt.dep.dTimeS)
|
||||||
|
const arr = profile.parseDateTime(tz, j.date, pt.arr.aTimeR || pt.arr.aTimeS)
|
||||||
|
const res = {
|
||||||
|
origin: clone(stations[parseInt(pt.dep.locX)]) || null,
|
||||||
|
destination: clone(stations[parseInt(pt.arr.locX)]),
|
||||||
|
departure: dep.format(),
|
||||||
|
arrival: arr.format()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pt.dep.dTimeR && pt.dep.dTimeS) {
|
||||||
|
const realtime = profile.parseDateTime(tz, j.date, pt.dep.dTimeR)
|
||||||
|
const planned = profile.parseDateTime(tz, j.date, pt.dep.dTimeS)
|
||||||
|
res.delay = Math.round((realtime - planned) / 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pt.type === 'WALK') {
|
||||||
|
res.mode = 'walking'
|
||||||
|
} else if (pt.type === 'JNY') {
|
||||||
|
res.id = pt.jny.jid
|
||||||
|
res.line = lines[parseInt(pt.jny.prodX)] || null
|
||||||
|
res.direction = profile.parseStationName(pt.jny.dirTxt)
|
||||||
|
|
||||||
|
if (pt.dep.dPlatfS) res.departurePlatform = pt.dep.dPlatfS
|
||||||
|
if (pt.arr.aPlatfS) res.arrivalPlatform = pt.arr.aPlatfS
|
||||||
|
|
||||||
|
if (pt.jny.stopL) {
|
||||||
|
res.passed = pt.jny.stopL.map(stopover => parseStopover(j, stopover))
|
||||||
|
}
|
||||||
|
if (Array.isArray(pt.jny.remL)) {
|
||||||
|
for (let remark of pt.jny.remL) applyRemark(j, remark)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pt.jny.freq && pt.jny.freq.jnyL) {
|
||||||
|
const parseAlternative = (a) => {
|
||||||
|
// todo: realtime
|
||||||
|
const when = profile.parseDateTime(tz, j.date, a.stopL[0].dTimeS)
|
||||||
|
return {
|
||||||
|
line: lines[parseInt(a.prodX)] || null,
|
||||||
|
when: when.format()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.alternatives = pt.jny.freq.jnyL
|
||||||
|
.filter(a => a.stopL[0].locX === pt.dep.locX)
|
||||||
|
.map(parseAlternative)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseJourneyPart
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createParseJourneyPart
|
|
@ -1,85 +1,12 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const parseDateTime = require('./date-time')
|
const parseDateTime = require('./date-time')
|
||||||
|
const createParseJourneyPart = require('./journey-part')
|
||||||
|
|
||||||
const clone = obj => Object.assign({}, obj)
|
const clone = obj => Object.assign({}, obj)
|
||||||
|
|
||||||
const createParseJourney = (profile, stations, lines, remarks) => {
|
const createParseJourney = (profile, stations, lines, remarks) => {
|
||||||
const tz = profile.timezone
|
const parsePart = createParseJourneyPart(profile, stations, lines, remarks)
|
||||||
|
|
||||||
const parseStopover = (j, st) => {
|
|
||||||
const res = {
|
|
||||||
station: stations[parseInt(st.locX)]
|
|
||||||
}
|
|
||||||
if (st.aTimeR || st.aTimeS) {
|
|
||||||
const arr = parseDateTime(tz, j.date, st.aTimeR || st.aTimeS)
|
|
||||||
res.arrival = arr.format()
|
|
||||||
}
|
|
||||||
if (st.dTimeR || st.dTimeS) {
|
|
||||||
const dep = parseDateTime(tz, j.date, st.dTimeR || st.dTimeS)
|
|
||||||
res.departure = dep.format()
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: finish parse/remark.js first
|
|
||||||
const applyRemark = (j, rm) => {}
|
|
||||||
|
|
||||||
// todo: pt.sDays
|
|
||||||
// todo: pt.dep.dProgType, pt.arr.dProgType
|
|
||||||
// todo: what is pt.jny.dirFlg?
|
|
||||||
// todo: how does pt.freq work?
|
|
||||||
const parsePart = (j, pt) => { // j = journey, pt = part
|
|
||||||
const dep = profile.parseDateTime(tz, j.date, pt.dep.dTimeR || pt.dep.dTimeS)
|
|
||||||
const arr = profile.parseDateTime(tz, j.date, pt.arr.aTimeR || pt.arr.aTimeS)
|
|
||||||
const res = {
|
|
||||||
origin: clone(stations[parseInt(pt.dep.locX)]) || null,
|
|
||||||
destination: clone(stations[parseInt(pt.arr.locX)]),
|
|
||||||
departure: dep.format(),
|
|
||||||
arrival: arr.format()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pt.dep.dTimeR && pt.dep.dTimeS) {
|
|
||||||
const realtime = profile.parseDateTime(tz, j.date, pt.dep.dTimeR)
|
|
||||||
const planned = profile.parseDateTime(tz, j.date, pt.dep.dTimeS)
|
|
||||||
res.delay = Math.round((realtime - planned) / 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pt.type === 'WALK') {
|
|
||||||
res.mode = 'walking'
|
|
||||||
} else if (pt.type === 'JNY') {
|
|
||||||
res.id = pt.jny.jid
|
|
||||||
res.line = lines[parseInt(pt.jny.prodX)] || null
|
|
||||||
res.direction = profile.parseStationName(pt.jny.dirTxt)
|
|
||||||
|
|
||||||
if (pt.dep.dPlatfS) res.departurePlatform = pt.dep.dPlatfS
|
|
||||||
if (pt.arr.aPlatfS) res.arrivalPlatform = pt.arr.aPlatfS
|
|
||||||
|
|
||||||
if (pt.jny.stopL) {
|
|
||||||
res.passed = pt.jny.stopL.map(stopover => parseStopover(j, stopover))
|
|
||||||
}
|
|
||||||
if (Array.isArray(pt.jny.remL)) {
|
|
||||||
for (let remark of pt.jny.remL) applyRemark(j, remark)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pt.jny.freq && pt.jny.freq.jnyL) {
|
|
||||||
const parseAlternative = (a) => {
|
|
||||||
// todo: realtime
|
|
||||||
const when = profile.parseDateTime(tz, j.date, a.stopL[0].dTimeS)
|
|
||||||
return {
|
|
||||||
line: lines[parseInt(a.prodX)] || null,
|
|
||||||
when: when.format()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res.alternatives = pt.jny.freq.jnyL
|
|
||||||
.filter(a => a.stopL[0].locX === pt.dep.locX)
|
|
||||||
.map(parseAlternative)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: c.sDays
|
// todo: c.sDays
|
||||||
// todo: c.dep.dProgType, c.arr.dProgType
|
// todo: c.dep.dProgType, c.arr.dProgType
|
||||||
|
|
|
@ -122,8 +122,7 @@ test('journeys – fails with no product', async (t) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// todo
|
test('journey part details', async (t) => {
|
||||||
test.skip('journey part details', async (t) => {
|
|
||||||
const journeys = await client.journeys(spichernstr, amrumerStr, {
|
const journeys = await client.journeys(spichernstr, amrumerStr, {
|
||||||
results: 1, when
|
results: 1, when
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue