DB profile

mostly copied from db-hafas
This commit is contained in:
Jannis R 2017-11-12 23:51:39 +01:00
parent 47b5ef7ed5
commit 4356032308
No known key found for this signature in database
GPG key ID: 0FE83946296A88A5
5 changed files with 255 additions and 1 deletions

109
p/db/index.js Normal file
View file

@ -0,0 +1,109 @@
'use strict'
const crypto = require('crypto')
const _formatStation = require('../../format/station')
const _parseLine = require('../../parse/line')
const {accessibility, bike} = require('../../format/filters')
const modes = require('./modes')
const formatLoyaltyCard = require('./loyalty-cards').format
const transformReqBody = (body) => {
body.client = {id: 'DB', v: '16040000', type: 'IPH', name: 'DB Navigator'}
body.ext = 'DB.R15.12.a'
body.ver = '1.15'
body.auth = {type: 'AID', aid: 'n91dB8Z77MLdoR0K'}
return body
}
const salt = 'bdI8UVj40K5fvxwf'
const transformReq = (req) => {
const hash = crypto.createHash('md5')
hash.update(req.body + salt)
if (!req.query) req.query = {}
req.query.checksum = hash.digest('hex')
return req
}
const transformJourneysQuery = (query, opt) => {
const filters = query.jnyFltrL
if (opt.accessibility && accessibility[opt.accessibility]) {
filters.push(accessibility[opt.accessibility])
}
if (opt.bike) filters.push(bike)
query.trfReq = {
jnyCl: 2, // todo
tvlrProf: [{
type: 'E',
redtnCard: opt.loyaltyCard
? formatLoyaltyCard(opt.loyaltyCard)
: null
}],
cType: 'PK'
}
return query
}
const parseLine = (profile, l) => {
const res = _parseLine(profile, l)
res.mode = res.product = null
if ('class' in res) {
const data = modes.bitmasks[parseInt(res.class)]
if (data) {
res.mode = data.mode
res.product = data.product
}
}
return res
}
const isIBNR = /^\d{6,}$/
const formatStation = (id) => {
if (!isIBNR.test(id)) throw new Error('station ID must be an IBNR.')
return _formatStation(id)
}
const defaultProducts = {
suburban: true,
subway: true,
tram: true,
bus: true,
ferry: true,
national: true,
nationalExp: true,
regional: true,
regionalExp: true
}
// todo: find option for absolute number of results
const dbProfile = {
timezone: 'Europe/Berlin',
endpoint: 'https://reiseauskunft.bahn.de/bin/mgate.exe',
transformReqBody,
transformReq,
transformJourneysQuery,
// todo: parseLocation
parseLine,
formatStation,
formatProducts: (products) => {
products = Object.assign(Object.create(null), defaultProducts, products)
return {
type: 'PROD',
mode: 'INC',
value: modes.stringifyBitmask(products) + ''
}
}
}
module.exports = dbProfile

30
p/db/loyalty-cards.js Normal file
View file

@ -0,0 +1,30 @@
'use strict'
const c = {
NONE: Symbol('no loyaly card'),
BAHNCARD: Symbol('Bahncard'),
VORTEILSCARD: Symbol('VorteilsCard'),
HALBTAXABO: Symbol('HalbtaxAbo'),
VOORDEELURENABO: Symbol('Voordeelurenabo'),
SHCARD: Symbol('SH-Card'),
GENERALABONNEMENT: Symbol('General-Abonnement')
}
// see https://gist.github.com/juliuste/202bb04f450a79f8fa12a2ec3abcd72d
const formatLoyaltyCard = (data) => {
if (data.type === c.BAHNCARD) {
if (data.discount === 25) return c.class === 1 ? 1 : 2
if (data.discount === 50) return c.class === 1 ? 3 : 4
}
if (data.type === c.VORTEILSCARD) return 9
if (data.type === c.HALBTAXABO) return data.railplus ? 10 : 11
if (data.type === c.VOORDEELURENABO) return data.railplus ? 12 : 13
if (data.type === c.SHCARD) return 14
if (data.type === c.GENERALABONNEMENT) return 15
return 0
}
module.exports = {
data: c,
format: formatLoyaltyCard
}

113
p/db/modes.js Normal file
View file

@ -0,0 +1,113 @@
'use strict'
const m = {
nationalExp: {
bitmask: 1,
name: 'InterCityExpress',
short: 'ICE',
mode: 'train',
product: 'nationalExp'
},
national: {
bitmask: 2,
name: 'InterCity & EuroCity',
short: 'IC/EC',
mode: 'train',
product: 'national'
},
regionalExp: {
bitmask: 4,
name: 'InterRegio',
short: 'IR',
mode: 'train',
product: 'regionalExp'
},
regional: {
bitmask: 8,
name: 'RegionalExpress & Regio',
short: 'RE/RB',
mode: 'train',
product: 'regional'
},
suburban: {
bitmask: 16,
name: 'S-Bahn',
short: 'S',
mode: 'train',
product: 'suburban'
},
bus: {
bitmask: 32,
name: 'Bus',
short: 'B',
mode: 'bus',
product: 'bus'
},
ferry: {
bitmask: 64,
name: 'Ferry',
short: 'F',
mode: 'ferry',
product: 'ferry'
},
subway: {
bitmask: 128,
name: 'U-Bahn',
short: 'U',
mode: 'train',
product: 'subway'
},
tram: {
bitmask: 256,
name: 'Tram',
short: 'T',
mode: 'tram',
product: 'tram'
},
taxi: {
bitmask: 512,
name: 'Group Taxi',
short: 'Taxi',
mode: null, // todo
product: 'taxi'
},
unknown: {
bitmask: 0,
name: 'unknown',
short: '?',
product: 'unknown'
}
}
m.bitmasks = []
m.bitmasks[1] = m.nationalExp
m.bitmasks[2] = m.national
m.bitmasks[4] = m.regionalExp
m.bitmasks[8] = m.regional
m.bitmasks[16] = m.suburban
m.bitmasks[32] = m.bus
m.bitmasks[64] = m.ferry
m.bitmasks[128] = m.subway
m.bitmasks[256] = m.tram
m.bitmasks[512] = m.taxi
// todo: move up
m.stringifyBitmask = (products) => {
let bitmask = 0
for (let product in products) {
if (products[product] === true) bitmask += m[product].bitmask
}
return bitmask
}
// todo: move up
m.parseBitmask = (bitmask) => {
let products = {}, i = 1
do {
products[m.bitmasks[i].product] = !!(bitmask & i)
i *= 2
} while (m.bitmasks[i] && m.bitmasks[i].product)
return products
}
module.exports = m

View file

@ -7,7 +7,8 @@
"index.js", "index.js",
"lib", "lib",
"parse", "parse",
"format" "format",
"p"
], ],
"author": "Jannis R <mail@jannisr.de>", "author": "Jannis R <mail@jannisr.de>",
"homepage": "https://github.com/derhuerst/hafas-client", "homepage": "https://github.com/derhuerst/hafas-client",

View file

@ -5,6 +5,7 @@ const tape = require('tape')
const isRoughlyEqual = require('is-roughly-equal') const isRoughlyEqual = require('is-roughly-equal')
const createClient = require('..') const createClient = require('..')
const dbProfile = require('../p/db')
const { const {
findStation, findStation,
assertValidStation, assertValidStation,