diff --git a/parse/arrival-or-departure.js b/parse/arrival-or-departure.js index 107e4fee..8c0f4d86 100644 --- a/parse/arrival-or-departure.js +++ b/parse/arrival-or-departure.js @@ -1,5 +1,6 @@ 'use strict' +const parseWhen = require('./when') const findRemarks = require('./find-remarks') const ARRIVAL = 'a' @@ -12,29 +13,21 @@ const createParseArrOrDep = (profile, opt, data, prefix) => { if (prefix !== ARRIVAL && prefix !== DEPARTURE) throw new Error('invalid prefix') const parseArrOrDep = (d) => { - const t = d.stbStop[prefix + 'TimeR'] || d.stbStop[prefix + 'TimeS'] - const tz = d.stbStop[prefix + 'TZOffset'] || null + const tPlanned = d.stbStop[prefix + 'TimeS'] + const tPrognosed = d.stbStop[prefix + 'TimeR'] + const tzOffset = d.stbStop[prefix + 'TZOffset'] || null + const cancelled = !!d.stbStop[prefix + 'Cncl'] const res = { tripId: d.jid, stop: d.stbStop.location || null, - when: profile.parseDateTime(profile, d.date, t, tz), + ...parseWhen(profile, d.date, tPlanned, tPrognosed, tzOffset, cancelled) // todo: for arrivals, this is the *origin*, not the *direction* direction: prefix === DEPARTURE && d.dirTxt && profile.parseStationName(d.dirTxt) || null, line: d.line || null, remarks: [] } - // todo: DRY with parseStopover - // todo: DRY with parseJourneyLeg - const tR = d.stbStop[prefix + 'TimeR'] - const tP = d.stbStop[prefix + 'TimeS'] - if (tR && tP) { - const realtime = profile.parseDateTime(profile, d.date, tR, tz, true) - const planned = profile.parseDateTime(profile, d.date, tP, tz, true) - res.delay = Math.round((realtime - planned) / 1000) - } else res.delay = null - // todo: DRY with parseStopover // todo: DRY with parseJourneyLeg const pR = d.stbStop[prefix + 'PlatfR'] @@ -42,13 +35,9 @@ const createParseArrOrDep = (profile, opt, data, prefix) => { res.platform = pR || pP || null if (pR && pP && pR !== pP) res.scheduledPlatform = pP - // todo: DRY with parseStopover - // todo: DRY with parseJourneyLeg - if (d.stbStop[prefix + 'Cncl']) { + if (cancelled) { res.cancelled = true Object.defineProperty(res, 'canceled', {value: true}) - res.when = res.delay = null - res.scheduledWhen = profile.parseDateTime(profile, d.date, tP, tz) } if (opt.remarks) { diff --git a/parse/journey-leg.js b/parse/journey-leg.js index 652607ce..e0c49c64 100644 --- a/parse/journey-leg.js +++ b/parse/journey-leg.js @@ -1,6 +1,6 @@ 'use strict' -const parseDateTime = require('./date-time') +const parseWhen = require('./when') const findRemarks = require('./find-remarks') const clone = obj => Object.assign({}, obj) @@ -44,32 +44,27 @@ const createParseJourneyLeg = (profile, opt, data) => { // j = journey, pt = part // todo: pt.planrtTS const parseJourneyLeg = (j, pt, parseStopovers = true) => { - const dep = profile.parseDateTime(profile, j.date, pt.dep.dTimeR || pt.dep.dTimeS, pt.dep.dTZOffset) - const arr = profile.parseDateTime(profile, j.date, pt.arr.aTimeR || pt.arr.aTimeS, pt.arr.aTZOffset) const res = { origin: clone(pt.dep.location) || null, - destination: clone(pt.arr.location), - departure: dep, - arrival: arr + destination: clone(pt.arr.location) } + const arr = parseWhen(profile, j.date, pt.arr.aTimeS, pt.arr.aTimeR, pt.arr.aTZOffset, pt.arr.aCncl) + res.arrival = arr.when + res.plannedArrival = arr.plannedWhen + res.arrivalDelay = arr.delay + if (arr.prognosedWhen) res.prognosedArrival = arr.prognosedWhen + + const dep = parseWhen(profile, j.date, pt.dep.dTimeS, pt.dep.dTimeR, pt.dep.dTZOffset, pt.dep.dCncl) + res.departure = dep.when + res.plannedDeparture = dep.plannedWhen + res.departureDelay = dep.delay + if (dep.prognosedWhen) res.prognosedDeparture = dep.prognosedWhen + if (pt.jny) { res.reachable = !!pt.jny.isRchbl } - // todo: DRY with parseDeparture - // todo: DRY with parseStopover - if (pt.dep.dTimeR && pt.dep.dTimeS) { - const realtime = profile.parseDateTime(profile, j.date, pt.dep.dTimeR, pt.dep.dTZOffset, true) - const planned = profile.parseDateTime(profile, j.date, pt.dep.dTimeS, pt.dep.dTZOffset, true) - res.departureDelay = Math.round((realtime - planned) / 1000) - } - if (pt.arr.aTimeR && pt.arr.aTimeS) { - const realtime = profile.parseDateTime(profile, j.date, pt.arr.aTimeR, pt.dep.aTZOffset, true) - const planned = profile.parseDateTime(profile, j.date, pt.arr.aTimeS, pt.dep.aTZOffset, true) - res.arrivalDelay = Math.round((realtime - planned) / 1000) - } - if (pt.jny && pt.jny.polyline) { res.polyline = pt.jny.polyline || null } @@ -129,43 +124,21 @@ const createParseJourneyLeg = (profile, opt, data) => { const parseAlternative = (a) => { // todo: parse this just like a `leg` (breaking) // todo: parse `a.stopL`, `a.ctxRecon`, `a.msgL` - const st0 = a.stopL[0] - - let when = null, delay = null - if (st0) { - const planned = st0.dTimeS && profile.parseDateTime(profile, j.date, st0.dTimeS, st0.dTZOffset) - if (st0.dTimeR && planned) { - const realtime = profile.parseDateTime(profile, j.date, st0.dTimeR, st0.dTZOffset) - when = realtime - delay = Math.round((new Date(realtime) - new Date(planned)) / 1000) - } else if (planned) when = planned - } + const st0 = a.stopL[0] || {} return { tripId: a.jid, line: a.line || null, direction: a.dirTxt || null, - when, delay + ...parseWhen(profile, j.date, st0.dTimeS, st0.dTimeR, st0.dTZOffset, st0.dCncl) } } res.alternatives = freq.jnyL.map(parseAlternative) } } - // todo: DRY with parseDeparture - // todo: DRY with parseStopover if (pt.arr.aCncl || pt.dep.dCncl) { res.cancelled = true Object.defineProperty(res, 'canceled', {value: true}) - if (pt.arr.aCncl) { - res.arrival = res.arrivalPlatform = res.arrivalDelay = null - const arr = profile.parseDateTime(profile, j.date, pt.arr.aTimeS, pt.arr.aTZOffset) - res.scheduledArrival = arr - } - if (pt.dep.dCncl) { - res.departure = res.departurePlatform = res.departureDelay = null - const dep = profile.parseDateTime(profile, j.date, pt.dep.dTimeS, pt.dep.dTZOffset) - res.scheduledDeparture = dep - } } return res diff --git a/parse/stopover.js b/parse/stopover.js index c14d84cf..65785f38 100644 --- a/parse/stopover.js +++ b/parse/stopover.js @@ -1,40 +1,27 @@ 'use strict' +const parseWhen = require('./when') const findRemarks = require('./find-remarks') const createParseStopover = (profile, opt, data, date) => { const parseStopover = (st) => { + const arr = parseWhen(profile, date, st.aTimeS, st.aTimeR, st.aTZOffset, st.aCncl) + const dep = parseWhen(profile, date, st.dTimeS, st.dTimeR, st.dTZOffset, st.dCncl) + const res = { stop: st.location || null, - arrival: null, - arrivalDelay: null, + arrival: arr.when, + plannedArrival: arr.plannedWhen, + arrivalDelay: arr.delay, arrivalPlatform: st.aPlatfR || st.aPlatfS || null, - departure: null, - departureDelay: null, + departure: dep.when, + plannedDeparture: dep.plannedWhen, + departureDelay: dep.delay, departurePlatform: st.dPlatfR || st.dPlatfS || null } - // todo: DRY with parseDeparture - // todo: DRY with parseJourneyLeg - if (st.aTimeR || st.aTimeS) { - const arr = profile.parseDateTime(profile, date, st.aTimeR || st.aTimeS, st.aTZOffset) - res.arrival = arr - } - if (st.aTimeR && st.aTimeS) { - const realtime = profile.parseDateTime(profile, date, st.aTimeR, st.aTZOffset, true) - const planned = profile.parseDateTime(profile, date, st.aTimeS, st.aTZOffset, true) - res.arrivalDelay = Math.round((realtime - planned) / 1000) - } - - if (st.dTimeR || st.dTimeS) { - const dep = profile.parseDateTime(profile, date, st.dTimeR || st.dTimeS, st.dTZOffset) - res.departure = dep - } - if (st.dTimeR && st.dTimeS) { - const realtime = profile.parseDateTime(profile, date, st.dTimeR, st.dTZOffset, true) - const planned = profile.parseDateTime(profile, date, st.dTimeS, st.dTZOffset, true) - res.departureDelay = Math.round((realtime - planned) / 1000) - } + if (arr.prognosedWhen) res.prognosedArrival = arr.prognosedWhen + if (dep.prognosedWhen) res.prognosedDeparture = dep.prognosedWhen if (st.aPlatfR && st.aPlatfS && st.aPlatfR !== st.aPlatfS) { res.scheduledArrivalPlatform = st.aPlatfS @@ -46,27 +33,9 @@ const createParseStopover = (profile, opt, data, date) => { // mark stations the train passes without stopping if(st.dInS === false && st.aOutS === false) res.passBy = true - // todo: DRY with parseDeparture - // todo: DRY with parseJourneyLeg if (st.aCncl || st.dCncl) { res.cancelled = true Object.defineProperty(res, 'canceled', {value: true}) - if (st.aCncl) { - res.formerArrivalDelay = res.arrivalDelay - res.arrival = res.arrivalDelay = null - if (st.aTimeS) { - const arr = profile.parseDateTime(profile, date, st.aTimeS, st.aTZOffset) - res.scheduledArrival = arr - } - } - if (st.dCncl) { - res.formerDepartureDelay = res.departureDelay - res.departure = res.departureDelay = null - if (st.dTimeS) { - const arr = profile.parseDateTime(profile, date, st.dTimeS, st.dTZOffset) - res.scheduledDeparture = arr - } - } } if (opt.remarks && Array.isArray(st.msgL)) { diff --git a/parse/when.js b/parse/when.js new file mode 100644 index 00000000..373d0963 --- /dev/null +++ b/parse/when.js @@ -0,0 +1,31 @@ +'use strict' + +const parseWhen = (profile, date, timeS, timeR, tzOffset, cncl = false) => { + const parse = profile.parseDateTime + + let planned = timeS ? parse(profile, date, timeS, tzOffset, false) : null + let prognosed = timeR ? parse(profile, date, timeR, tzOffset, false) : null + let delay = null + + if (planned && prognosed) { + const tPlanned = parse(profile, date, timeS, tzOffset, true) + const tPrognosed = parse(profile, date, timeR, tzOffset, true) + delay = Math.round((tPrognosed - tPlanned) / 1000) + } + + if (cncl) { + return { + when: null, + plannedWhen: planned, + prognosedWhen: when, + delay + } + } + return { + when: prognosed, + plannedWhen: planned, + delay + } +} + +module.exports = parseWhen