mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-22 22:59:35 +02:00
parse trip.scheduledDays ✅
This commit is contained in:
parent
b6900a3ddb
commit
a60083f8d1
7 changed files with 126 additions and 42 deletions
3
index.js
3
index.js
|
@ -490,7 +490,8 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
polyline: false, // return a track shape?
|
||||
subStops: true, // parse & expose sub-stops of stations?
|
||||
entrances: true, // parse & expose entrances of stops/stations?
|
||||
remarks: true // parse & expose hints & warnings?
|
||||
remarks: true, // parse & expose hints & warnings?
|
||||
scheduledDays: false, // parse & expose dates trip is valid on?
|
||||
}, opt)
|
||||
|
||||
const req = profile.formatTripReq({profile, opt}, id, lineName)
|
||||
|
|
|
@ -19,6 +19,7 @@ const parseProductsBitmask = require('../parse/products-bitmask')
|
|||
const parseIcon = require('../parse/icon')
|
||||
const parseWhen = require('../parse/when')
|
||||
const parsePrognosisType = require('../parse/prognosis-type')
|
||||
const parseScheduledDays = require('../parse/scheduled-days')
|
||||
const parseDeparture = require('../parse/departure')
|
||||
const parseArrival = require('../parse/arrival')
|
||||
const parseTrip = require('../parse/trip')
|
||||
|
@ -85,6 +86,7 @@ const defaultProfile = {
|
|||
parseIcon,
|
||||
parseWhen,
|
||||
parsePrognosisType,
|
||||
parseScheduledDays,
|
||||
parseDeparture,
|
||||
parseArrival,
|
||||
parseTrip,
|
||||
|
|
|
@ -1,40 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const {DateTime} = require('luxon')
|
||||
const findRemarks = require('./find-remarks')
|
||||
|
||||
// todo: DRY with parse/date-time.js
|
||||
const parseDate = (date) => {
|
||||
const res = {
|
||||
year: parseInt(date.substr(-8, 4)),
|
||||
month: parseInt(date.substr(-4, 2)),
|
||||
day: parseInt(date.substr(-2, 2)),
|
||||
}
|
||||
if (!Number.isInteger(res.year) || !Number.isInteger(res.month) || !Number.isInteger(res.day)) {
|
||||
throw new Error('invalid date format: ' + date)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
const parseScheduledDays = (sDaysB, fpB, fpE, profile) => {
|
||||
sDaysB = Buffer.from(sDaysB, 'hex')
|
||||
const res = Object.create(null)
|
||||
|
||||
const _fpB = parseDate(fpB)
|
||||
let d = DateTime.fromObject({
|
||||
zone: profile.timezone, locale: profile.locale,
|
||||
year: _fpB.year, month: _fpB.month, day: _fpB.day,
|
||||
hour: 0, minute: 0, second: 0, millisecond: 0
|
||||
})
|
||||
for (let b = 0; b < sDaysB.length; b++) {
|
||||
for (let i = 0; i < 8; i++) {
|
||||
res[d.toISODate()] = (sDaysB[b] & Math.pow(2, 7 - i)) > 0
|
||||
d = d.plus({days: 1})
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// todo: c.conSubscr (e.g. `F`)
|
||||
// todo: c.trfRes x vbb-parse-ticket
|
||||
// todo: c.sotRating, c.isSotCon, c.sotCtxt
|
||||
|
@ -70,13 +37,9 @@ const parseJourney = (ctx, j) => { // j = raw jouney
|
|||
res.remarks = findRemarks(j.msgL).map(([remark]) => remark)
|
||||
}
|
||||
|
||||
if (opt.scheduledDays) {
|
||||
// sDaysB is a bitmap mapping all days from fpB (first date of schedule) to fpE (last date in schedule).
|
||||
const {sDaysB} = j.sDays
|
||||
const {fpB, fpE} = ctx.res
|
||||
if (sDaysB && fpB && fpE) {
|
||||
res.scheduledDays = parseScheduledDays(sDaysB, fpB, fpE, profile)
|
||||
}
|
||||
if (opt.scheduledDays && j.sDays) {
|
||||
// todo [breaking]: rename to scheduledDates
|
||||
res.scheduledDays = profile.parseScheduledDays(ctx, j.sDays)
|
||||
}
|
||||
|
||||
return res
|
||||
|
|
43
parse/scheduled-days.js
Normal file
43
parse/scheduled-days.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
'use strict'
|
||||
|
||||
const {DateTime} = require('luxon')
|
||||
|
||||
// todo: DRY with parse/date-time.js
|
||||
const parseDate = (date) => {
|
||||
const res = {
|
||||
year: parseInt(date.substr(-8, 4)),
|
||||
month: parseInt(date.substr(-4, 2)),
|
||||
day: parseInt(date.substr(-2, 2)),
|
||||
}
|
||||
if (!Number.isInteger(res.year) || !Number.isInteger(res.month) || !Number.isInteger(res.day)) {
|
||||
throw new Error('invalid date format: ' + date)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
const parseScheduledDays = (ctx, sDays) => {
|
||||
const {profile} = ctx
|
||||
|
||||
// sDaysB is a bitmap mapping all days from fpB (first date of schedule) to fpE (last date in schedule).
|
||||
const {fpB, fpE} = ctx.res
|
||||
if (!sDays.sDaysB || !fpB || !fpE) return null
|
||||
|
||||
const sDaysB = Buffer.from(sDays.sDaysB, 'hex')
|
||||
const res = Object.create(null)
|
||||
|
||||
const _fpB = parseDate(fpB)
|
||||
let d = DateTime.fromObject({
|
||||
zone: profile.timezone, locale: profile.locale,
|
||||
year: _fpB.year, month: _fpB.month, day: _fpB.day,
|
||||
hour: 0, minute: 0, second: 0, millisecond: 0
|
||||
})
|
||||
for (let b = 0; b < sDaysB.length; b++) {
|
||||
for (let i = 0; i < 8; i++) {
|
||||
res[d.toISODate()] = (sDaysB[b] & Math.pow(2, 7 - i)) > 0
|
||||
d = d.plus({days: 1})
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
module.exports = parseScheduledDays
|
|
@ -5,7 +5,7 @@ const maxBy = require('lodash/maxBy')
|
|||
const last = require('lodash/last')
|
||||
|
||||
const parseTrip = (ctx, t) => { // t = raw trip
|
||||
const {profile, res} = ctx
|
||||
const {profile, opt, res} = ctx
|
||||
|
||||
// pretend the trip is a leg in a journey
|
||||
const fakeLeg = {
|
||||
|
@ -29,6 +29,20 @@ const parseTrip = (ctx, t) => { // t = raw trip
|
|||
delete trip.tripId
|
||||
// todo [breaking]: delete trip.reachable
|
||||
|
||||
if (opt.scheduledDays) {
|
||||
const nrOfStopovers = t.stopL.length
|
||||
// trips seem to use sDaysL[], journeys use sDays
|
||||
const sDaysL = Array.isArray(t.sDaysL) ? t.sDaysL : []
|
||||
const matchingSDays = sDaysL.filter((sDays) => {
|
||||
return sDays.fLocIdx === 0 && sDays.tLocIdx === (nrOfStopovers - 1)
|
||||
})
|
||||
|
||||
// if there are >1 sDays, we don't know how to interpret them
|
||||
const sDays = matchingSDays.length === 1 ? matchingSDays[0] : null
|
||||
// todo [breaking]: rename to scheduledDates
|
||||
trip.scheduledDays = profile.parseScheduledDays(ctx, sDays)
|
||||
}
|
||||
|
||||
if (res.planrtTS) {
|
||||
// todo [breaking]: remove here
|
||||
trip.realtimeDataUpdatedAt = parseInt(res.planrtTS)
|
||||
|
|
|
@ -16,6 +16,7 @@ const opt = {
|
|||
subStops: false,
|
||||
entrances: true,
|
||||
remarks: true,
|
||||
scheduledDays: true,
|
||||
when: '2021-10-28T09:28:00+02:00',
|
||||
}
|
||||
|
||||
|
|
60
test/fixtures/bvg-trip-with-occupancy.js
vendored
60
test/fixtures/bvg-trip-with-occupancy.js
vendored
|
@ -44,6 +44,66 @@ module.exports = {
|
|||
}
|
||||
],
|
||||
occupancy: 'medium',
|
||||
|
||||
scheduledDays: {
|
||||
'2021-10-22': true,
|
||||
'2021-10-23': false,
|
||||
'2021-10-24': false,
|
||||
'2021-10-25': true,
|
||||
'2021-10-26': true,
|
||||
'2021-10-27': true,
|
||||
'2021-10-28': true,
|
||||
'2021-10-29': true,
|
||||
'2021-10-30': false,
|
||||
'2021-10-31': false,
|
||||
'2021-11-01': true,
|
||||
'2021-11-02': true,
|
||||
'2021-11-03': true,
|
||||
'2021-11-04': true,
|
||||
'2021-11-05': true,
|
||||
'2021-11-06': false,
|
||||
'2021-11-07': false,
|
||||
'2021-11-08': true,
|
||||
'2021-11-09': true,
|
||||
'2021-11-10': true,
|
||||
'2021-11-11': true,
|
||||
'2021-11-12': true,
|
||||
'2021-11-13': false,
|
||||
'2021-11-14': false,
|
||||
'2021-11-15': true,
|
||||
'2021-11-16': true,
|
||||
'2021-11-17': true,
|
||||
'2021-11-18': true,
|
||||
'2021-11-19': true,
|
||||
'2021-11-20': false,
|
||||
'2021-11-21': false,
|
||||
'2021-11-22': true,
|
||||
'2021-11-23': true,
|
||||
'2021-11-24': true,
|
||||
'2021-11-25': true,
|
||||
'2021-11-26': true,
|
||||
'2021-11-27': false,
|
||||
'2021-11-28': false,
|
||||
'2021-11-29': true,
|
||||
'2021-11-30': true,
|
||||
'2021-12-01': true,
|
||||
'2021-12-02': true,
|
||||
'2021-12-03': true,
|
||||
'2021-12-04': false,
|
||||
'2021-12-05': false,
|
||||
'2021-12-06': true,
|
||||
'2021-12-07': true,
|
||||
'2021-12-08': true,
|
||||
'2021-12-09': true,
|
||||
'2021-12-10': true,
|
||||
'2021-12-11': false,
|
||||
'2021-12-12': false,
|
||||
'2021-12-13': false,
|
||||
'2021-12-14': false,
|
||||
'2021-12-15': false,
|
||||
'2021-12-16': false,
|
||||
},
|
||||
|
||||
realtimeDataUpdatedAt: 1635406146,
|
||||
|
||||
origin: {
|
||||
|
|
Loading…
Add table
Reference in a new issue