diff --git a/format/products-bitmask.js b/format/products-bitmask.js deleted file mode 100644 index b3baab87..00000000 --- a/format/products-bitmask.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict' - -const createFormatBitmask = (allProducts) => { - const formatBitmask = (products) => { - if(Object.keys(products).length === 0) throw new Error('products filter must not be empty') - let bitmask = 0 - for (let product in products) { - if (!allProducts[product]) throw new Error('unknown product ' + product) - if (products[product] === true) bitmask += allProducts[product].bitmask - } - return bitmask - } - return formatBitmask -} - -module.exports = createFormatBitmask diff --git a/format/products-filter.js b/format/products-filter.js new file mode 100644 index 00000000..90b1d06b --- /dev/null +++ b/format/products-filter.js @@ -0,0 +1,34 @@ +'use strict' + +const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o) +const hasProp = (o, k) => Object.prototype.hasOwnProperty.call(o, k) + +const createFormatProductsFilter = (profile) => { + const byProduct = {} + const defaultProducts = {} + for (let product of profile.products) { + byProduct[product.product] = product + defaultProducts[product.product] = product.default + } + + const formatProductsFilter = (filter) => { + if (!isObj(filter)) throw new Error('products filter must be an object') + filter = Object.assign({}, defaultProducts, filter) + + let res = 0 + for (let product in filter) { + if (!hasProp(filter, product) || filter[product] !== true) continue + if (!byProduct[product]) throw new Error('unknown product ' + product) + for (let bitmask of byProduct[product].bitmasks) res += bitmask + } + + return { + type: 'PROD', + mode: 'INC', + value: res + '' + } + } + return formatProductsFilter +} + +module.exports = createFormatProductsFilter diff --git a/index.js b/index.js index 44a296d1..4ea95c84 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,7 @@ const maxBy = require('lodash/maxBy') const defaultProfile = require('./lib/default-profile') const createParseBitmask = require('./parse/products-bitmask') +const createFormatProductsFilter = require('./format/products-filter') const validateProfile = require('./lib/validate-profile') const _request = require('./lib/request') @@ -14,6 +15,7 @@ const isNonEmptyString = str => 'string' === typeof str && str.length > 0 const createClient = (profile, request = _request) => { profile = Object.assign({}, defaultProfile, profile) profile.parseProducts = createParseBitmask(profile) + profile.formatProductsFilter = createFormatProductsFilter(profile) validateProfile(profile) const departures = (station, opt = {}) => { @@ -26,7 +28,7 @@ const createClient = (profile, request = _request) => { duration: 10 // show departures for the next n minutes }, opt) opt.when = opt.when || new Date() - const products = profile.formatProducts(opt.products || {}) + const products = profile.formatProductsFilter(opt.products || {}) const dir = opt.direction ? profile.formatStation(opt.direction) : null return request(profile, { @@ -92,7 +94,7 @@ const createClient = (profile, request = _request) => { opt.when = opt.when || new Date() const filters = [ - profile.formatProducts(opt.products || {}) + profile.formatProductsFilter(opt.products || {}) ] if ( opt.accessibility && @@ -319,7 +321,7 @@ const createClient = (profile, request = _request) => { perStep: Math.round(durationPerStep), ageOfReport: true, // todo: what is this? jnyFltrL: [ - profile.formatProducts(opt.products || {}) + profile.formatProductsFilter(opt.products || {}) ], trainPosMode: 'CALC' // todo: what is this? what about realtime? } diff --git a/p/db/index.js b/p/db/index.js index d6fb2708..cd79befb 100644 --- a/p/db/index.js +++ b/p/db/index.js @@ -3,14 +3,11 @@ const _createParseLine = require('../../parse/line') const _createParseJourney = require('../../parse/journey') const _formatStation = require('../../format/station') -const createFormatBitmask = require('../../format/products-bitmask') const {bike} = require('../../format/filters') const products = require('./products') const formatLoyaltyCard = require('./loyalty-cards').format -const formatBitmask = createFormatBitmask(products) - const transformReqBody = (body) => { body.client = {id: 'DB', v: '16040000', type: 'IPH', name: 'DB Navigator'} body.ext = 'DB.R15.12.a' @@ -102,27 +99,6 @@ const formatStation = (id) => { return _formatStation(id) } -const defaultProducts = { - suburban: true, - subway: true, - tram: true, - bus: true, - ferry: true, - national: true, - nationalExp: true, - regional: true, - regionalExp: true, - taxi: false -} -const formatProducts = (products) => { - products = Object.assign(Object.create(null), defaultProducts, products) - return { - type: 'PROD', - mode: 'INC', - value: formatBitmask(products) + '' - } -} - // todo: find option for absolute number of results const dbProfile = { @@ -142,8 +118,7 @@ const dbProfile = { parseLine: createParseLine, parseJourney: createParseJourney, - formatStation, - formatProducts + formatStation } module.exports = dbProfile diff --git a/p/insa/index.js b/p/insa/index.js index 948da700..11709ca1 100644 --- a/p/insa/index.js +++ b/p/insa/index.js @@ -2,18 +2,6 @@ const _createParseLine = require('../../parse/line') const products = require('./products') -const createFormatBitmask = require('../../format/products-bitmask') - -const defaultProducts = { - nationalExp: true, - national: true, - regional: true, - suburban: true, - bus: true, - tram: true, - tourismTrain: true, -} - const transformReqBody = (body) => { body.client = { @@ -50,18 +38,6 @@ const createParseLine = (profile, operators) => { return parseLineWithMode } -const formatProducts = (products) => { - products = Object.assign(Object.create(null), defaultProducts, products) - return { - type: 'PROD', - mode: 'INC', - value: formatBitmask(products) + '' - } -} - -const formatBitmask = createFormatBitmask(products) - - const insaProfile = { locale: 'de-DE', timezone: 'Europe/Berlin', @@ -69,9 +45,6 @@ const insaProfile = { transformReqBody, products: products.allProducts, - formatProducts, - - parseLine: createParseLine, journeyLeg: true, radar: true diff --git a/p/oebb/index.js b/p/oebb/index.js index c0da7427..a3c73a0d 100644 --- a/p/oebb/index.js +++ b/p/oebb/index.js @@ -3,7 +3,6 @@ // todo: https://gist.github.com/anonymous/a5fc856bc80ae7364721943243f934f4#file-haf_config_base-properties-L5 // todo: https://gist.github.com/anonymous/a5fc856bc80ae7364721943243f934f4#file-haf_config_base-properties-L47-L234 -const createFormatBitmask = require('../../format/products-bitmask') const _createParseLine = require('../../parse/line') const _parseLocation = require('../../parse/location') const _createParseMovement = require('../../parse/movement') @@ -81,28 +80,6 @@ const createParseMovement = (profile, locations, lines, remarks) => { return parseMovement } -const defaultProducts = { - nationalExp: true, - national: true, - interregional: true, - regional: true, - suburban: true, - bus: true, - ferry: true, - subway: true, - tram: true, - onCall: true -} -const formatBitmask = createFormatBitmask(products) -const formatProducts = (products) => { - products = Object.assign(Object.create(null), defaultProducts, products) - return { - type: 'PROD', - mode: 'INC', - value: formatBitmask(products) + '' - } -} - const oebbProfile = { locale: 'de-AT', timezone: 'Europe/Vienna', @@ -116,8 +93,6 @@ const oebbProfile = { parseLocation, parseMovement: createParseMovement, - formatProducts, - journeyLeg: true, radar: true } diff --git a/p/vbb/index.js b/p/vbb/index.js index b58d819b..cb926e9d 100644 --- a/p/vbb/index.js +++ b/p/vbb/index.js @@ -12,12 +12,9 @@ const _createParseJourney = require('../../parse/journey') const _createParseStopover = require('../../parse/stopover') const _createParseDeparture = require('../../parse/departure') const _formatStation = require('../../format/station') -const createFormatBitmask = require('../../format/products-bitmask') const products = require('./products') -const formatBitmask = createFormatBitmask(products) - const transformReqBody = (body) => { body.client = {type: 'IPA', id: 'VBB', name: 'vbbPROD', v: '4010300'} body.ext = 'VBB.1' @@ -145,24 +142,6 @@ const formatStation = (id) => { return _formatStation(id) } -const defaultProducts = { - suburban: true, - subway: true, - tram: true, - bus: true, - ferry: true, - express: true, - regional: true -} -const formatProducts = (products) => { - products = Object.assign(Object.create(null), defaultProducts, products) - return { - type: 'PROD', - mode: 'INC', - value: formatBitmask(products) + '' - } -} - const vbbProfile = { locale: 'de-DE', timezone: 'Europe/Berlin', @@ -185,7 +164,6 @@ const vbbProfile = { parseStopover: createParseStopover, formatStation, - formatProducts, journeysNumF: false, journeyLeg: true,