query journey parts

This commit is contained in:
Jannis R 2017-11-20 15:43:13 +01:00
parent e762f30f05
commit 33417a6e61
No known key found for this signature in database
GPG key ID: 0FE83946296A88A5
7 changed files with 125 additions and 80 deletions

View file

@ -1,5 +1,8 @@
'use strict'
const minBy = require('lodash/minBy')
const maxBy = require('lodash/maxBy')
const defaultProfile = require('./lib/default-profile')
const request = require('./lib/request')
@ -23,14 +26,14 @@ const createClient = (profile) => {
return request(profile, {
meth: 'StationBoard',
req: {
type: 'DEP',
type: 'DEP',
date: profile.formatDate(profile, opt.when),
time: profile.formatTime(profile, opt.when),
stbLoc: profile.formatStation(station),
dirLoc: dir,
jnyFltrL: [products],
dur: opt.duration,
getPasslist: false
getPasslist: false
}
})
.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

View file

@ -2,6 +2,7 @@
const parseDateTime = require('../parse/date-time')
const parseDeparture = require('../parse/departure')
const parseJourneyPart = require('../parse/journey-part')
const parseJourney = require('../parse/journey')
const parseLine = require('../parse/line')
const parseLocation = require('../parse/location')
@ -32,6 +33,7 @@ const defaultProfile = {
parseDateTime,
parseDeparture,
parseJourneyPart,
parseJourney,
parseLine,
parseStationName: id,

View file

@ -28,6 +28,7 @@
},
"dependencies": {
"fetch-ponyfill": "^4.1.0",
"lodash": "^4.17.4",
"moment-timezone": "^0.5.13",
"pinkie-promise": "^2.0.1",
"query-string": "^5.0.0",

View file

@ -7,6 +7,7 @@ module.exports = {
remark: require('./remark'),
operator: require('./operator'),
stopover: require('./stopover'),
journeyPart: require('./journey-part'),
journey: require('./journey'),
nearby: require('./nearby'),
movement: require('./movement')

87
parse/journey-part.js Normal file
View 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

View file

@ -1,85 +1,12 @@
'use strict'
const parseDateTime = require('./date-time')
const createParseJourneyPart = require('./journey-part')
const clone = obj => Object.assign({}, obj)
const createParseJourney = (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 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
}
const parsePart = createParseJourneyPart(profile, stations, lines, remarks)
// todo: c.sDays
// todo: c.dep.dProgType, c.arr.dProgType

View file

@ -122,8 +122,7 @@ test('journeys  fails with no product', async (t) => {
}
})
// todo
test.skip('journey part details', async (t) => {
test('journey part details', async (t) => {
const journeys = await client.journeys(spichernstr, amrumerStr, {
results: 1, when
})