VBB: parse tickets, change client ID

ported over from derhuerst/vbb-hafas@74680b7
This commit is contained in:
Jannis R 2017-12-11 15:41:27 +01:00
parent 3ea4fd3e40
commit 36825d3e2a
No known key found for this signature in database
GPG key ID: 0FE83946296A88A5
6 changed files with 78 additions and 7 deletions

View file

@ -6,7 +6,7 @@ const dbProfile = require('./p/db')
const client = createClient(dbProfile) const client = createClient(dbProfile)
// Berlin Jungfernheide to München Hbf // Berlin Jungfernheide to München Hbf
client.journeys('8011167', '8000261', {results: 1}) client.journeys('8011167', '8000261', {results: 1, tickets: true})
// client.departures('8011167', {duration: 1}) // client.departures('8011167', {duration: 1})
// client.locations('Berlin Jungfernheide') // client.locations('Berlin Jungfernheide')
// client.locations('ATZE Musiktheater', {poi: true, addressses: false, fuzzy: false}) // client.locations('ATZE Musiktheater', {poi: true, addressses: false, fuzzy: false})

View file

@ -57,6 +57,7 @@ const createClient = (profile) => {
// todo: does this work with every endpoint? // todo: does this work with every endpoint?
accessibility: 'none', // 'none', 'partial' or 'complete' accessibility: 'none', // 'none', 'partial' or 'complete'
bike: false, // only bike-friendly journeys bike: false, // only bike-friendly journeys
tickets: false, // return tickets?
}, opt) }, opt)
if (opt.via) opt.via = profile.formatLocation(profile, opt.via) if (opt.via) opt.via = profile.formatLocation(profile, opt.via)
opt.when = opt.when || new Date() opt.when = opt.when || new Date()
@ -78,7 +79,7 @@ const createClient = (profile) => {
// todo: what are all these for? // todo: what are all these for?
getPT: true, getPT: true,
outFrwd: true, outFrwd: true,
getTariff: false, getTariff: !!opt.tickets,
getIV: false, // walk & bike as alternatives? getIV: false, // walk & bike as alternatives?
getPolyline: false // shape for displaying on a map? getPolyline: false // shape for displaying on a map?
}, opt) }, opt)

View file

@ -3,10 +3,12 @@
const shorten = require('vbb-short-station-name') const shorten = require('vbb-short-station-name')
const {to12Digit, to9Digit} = require('vbb-translate-ids') const {to12Digit, to9Digit} = require('vbb-translate-ids')
const parseLineName = require('vbb-parse-line') const parseLineName = require('vbb-parse-line')
const parseTicket = require('vbb-parse-ticket')
const _formatStation = require('../../format/station')
const _parseLine = require('../../parse/line') const _parseLine = require('../../parse/line')
const _parseLocation = require('../../parse/location') const _parseLocation = require('../../parse/location')
const _createParseJourney = require('../../parse/journey')
const _formatStation = require('../../format/station')
const createParseBitmask = require('../../parse/products-bitmask') const createParseBitmask = require('../../parse/products-bitmask')
const createFormatBitmask = require('../../format/products-bitmask') const createFormatBitmask = require('../../format/products-bitmask')
@ -15,8 +17,8 @@ const modes = require('./modes')
const formatBitmask = createFormatBitmask(modes) const formatBitmask = createFormatBitmask(modes)
const transformReqBody = (body) => { const transformReqBody = (body) => {
body.client = {type: 'IPA', id: 'BVG'} body.client = {type: 'IPA', id: 'VBB', name: 'vbbPROD', v: '4010300'}
body.ext = 'VBB.2' body.ext = 'VBB.1'
body.ver = '1.11' body.ver = '1.11'
body.auth = {type: 'AID', aid: 'hafas-vbb-apps'} body.auth = {type: 'AID', aid: 'hafas-vbb-apps'}
@ -58,6 +60,36 @@ const parseLocation = (profile, l) => {
return res return res
} }
const createParseJourney = (profile, stations, lines, remarks) => {
const parseJourney = _createParseJourney(profile, stations, lines, remarks)
const parseJourneyWithTickets = (j) => {
const res = parseJourney(j)
if (
j.trfRes &&
Array.isArray(j.trfRes.fareSetL) &&
j.trfRes.fareSetL[0] &&
Array.isArray(j.trfRes.fareSetL[0].fareL)
) {
res.tickets = []
const sets = j.trfRes.fareSetL[0].fareL
for (let s of sets) {
if (!Array.isArray(s.ticketL) || s.ticketL.length === 0) continue
for (let t of s.ticketL) {
const ticket = parseTicket(t)
ticket.name = s.name + ' ' + ticket.name
res.tickets.push(ticket)
}
}
}
return res
}
return parseJourneyWithTickets
}
const isIBNR = /^\d{9,}$/ const isIBNR = /^\d{9,}$/
const formatStation = (id) => { const formatStation = (id) => {
if (!isIBNR.test(id)) throw new Error('station ID must be an IBNR.') if (!isIBNR.test(id)) throw new Error('station ID must be an IBNR.')
@ -92,6 +124,7 @@ const vbbProfile = {
parseLocation, parseLocation,
parseLine, parseLine,
parseProducts: createParseBitmask(modes.bitmasks), parseProducts: createParseBitmask(modes.bitmasks),
parseJourney: createParseJourney,
formatStation, formatStation,
formatProducts, formatProducts,

View file

@ -33,6 +33,7 @@
"pinkie-promise": "^2.0.1", "pinkie-promise": "^2.0.1",
"query-string": "^5.0.0", "query-string": "^5.0.0",
"slugg": "^1.2.0", "slugg": "^1.2.0",
"vbb-parse-ticket": "^0.2.1",
"vbb-short-station-name": "^0.4.0", "vbb-short-station-name": "^0.4.0",
"vbb-translate-ids": "^3.1.0" "vbb-translate-ids": "^3.1.0"
}, },

View file

@ -97,6 +97,37 @@ const assertValidWhen = (t, w) => {
t.ok(isValidWhen(w), 'invalid when') t.ok(isValidWhen(w), 'invalid when')
} }
const assertValidTicket = (t, ti) => {
t.strictEqual(typeof ti.name, 'string')
t.ok(ti.name.length > 0)
if (ti.price !== null) {
t.strictEqual(typeof ti.price, 'number')
t.ok(ti.price > 0)
}
if (ti.amount !== null) {
t.strictEqual(typeof ti.amount, 'number')
t.ok(ti.amount > 0)
}
if ('bike' in ti) t.strictEqual(typeof ti.bike, 'boolean')
if ('shortTrip' in ti) t.strictEqual(typeof ti.shortTrip, 'boolean')
if ('group' in ti) t.strictEqual(typeof ti.group, 'boolean')
if ('fullDay' in ti) t.strictEqual(typeof ti.fullDay, 'boolean')
if (ti.tariff !== null) {
t.strictEqual(typeof ti.tariff, 'string')
t.ok(ti.tariff.length > 0)
}
if (ti.coverage !== null) {
t.strictEqual(typeof ti.coverage, 'string')
t.ok(ti.coverage.length > 0)
}
if (ti.variant !== null) {
t.strictEqual(typeof ti.variant, 'string')
t.ok(ti.variant.length > 0)
}
}
module.exports = { module.exports = {
assertValidStation, assertValidStation,
assertValidPoi, assertValidPoi,
@ -106,5 +137,6 @@ module.exports = {
assertValidLine, assertValidLine,
isValidDateTime, isValidDateTime,
assertValidStopover, assertValidStopover,
hour, when, isValidWhen, assertValidWhen hour, when, isValidWhen, assertValidWhen,
assertValidTicket
} }

View file

@ -19,7 +19,8 @@ const {
assertValidLine: _assertValidLine, assertValidLine: _assertValidLine,
assertValidStopover, assertValidStopover,
hour, when, hour, when,
assertValidWhen // todo: timezone assertValidWhen, // todo: timezone
assertValidTicket
} = require('./util') } = require('./util')
const assertValidStation = (t, s, coordsOptional = false) => { const assertValidStation = (t, s, coordsOptional = false) => {
@ -100,6 +101,9 @@ test('journeys  station to station', co.wrap(function* (t) {
t.ok(Array.isArray(part.passed)) t.ok(Array.isArray(part.passed))
for (let passed of part.passed) assertValidStopover(t, passed) for (let passed of part.passed) assertValidStopover(t, passed)
t.ok(Array.isArray(journey.tickets))
for (let ticket of journey.tickets) assertValidTicket(t, ticket)
} }
t.end() t.end()
})) }))