mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-22 22:59:35 +02:00
dbnav boards, fixes
This commit is contained in:
parent
6538f814aa
commit
3d998de41c
19 changed files with 434 additions and 97 deletions
|
@ -20,7 +20,7 @@ import {parseLine} from '../parse/line.js';
|
||||||
import {parseLocation} from '../parse/location.js';
|
import {parseLocation} from '../parse/location.js';
|
||||||
import {parsePolyline} from '../parse/polyline.js';
|
import {parsePolyline} from '../parse/polyline.js';
|
||||||
import {parseOperator} from '../parse/operator.js';
|
import {parseOperator} from '../parse/operator.js';
|
||||||
import {parseRemarks} from '../parse/remarks.js';
|
import {parseRemarks, parseCancelled} from '../parse/remarks.js';
|
||||||
import {parseStopover} from '../parse/stopover.js';
|
import {parseStopover} from '../parse/stopover.js';
|
||||||
import {parseLoadFactor, parseArrOrDepWithLoadFactor} from '../parse/load-factor.js';
|
import {parseLoadFactor, parseArrOrDepWithLoadFactor} from '../parse/load-factor.js';
|
||||||
import {parseHintByCode} from '../parse/hints-by-code.js';
|
import {parseHintByCode} from '../parse/hints-by-code.js';
|
||||||
|
@ -31,7 +31,7 @@ import {formatDate} from '../format/date.js';
|
||||||
import {formatProductsFilter} from '../format/products-filter.js';
|
import {formatProductsFilter} from '../format/products-filter.js';
|
||||||
import {formatPoi} from '../format/poi.js';
|
import {formatPoi} from '../format/poi.js';
|
||||||
import {formatStation} from '../format/station.js';
|
import {formatStation} from '../format/station.js';
|
||||||
import {formatTime} from '../format/time.js';
|
import {formatTime, formatTimeOfDay} from '../format/time.js';
|
||||||
import {formatLocation} from '../format/location.js';
|
import {formatLocation} from '../format/location.js';
|
||||||
import {formatLoyaltyCard} from '../format/loyalty-cards.js';
|
import {formatLoyaltyCard} from '../format/loyalty-cards.js';
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ const defaultProfile = {
|
||||||
ageGroup, ageGroupFromAge, ageGroupLabel,
|
ageGroup, ageGroupFromAge, ageGroupLabel,
|
||||||
transformReqBody: id,
|
transformReqBody: id,
|
||||||
transformReq: id,
|
transformReq: id,
|
||||||
randomizeUserAgent: true,
|
randomizeUserAgent: false,
|
||||||
logRequest,
|
logRequest,
|
||||||
logResponse,
|
logResponse,
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ const defaultProfile = {
|
||||||
parsePolyline,
|
parsePolyline,
|
||||||
parseOperator,
|
parseOperator,
|
||||||
parseRemarks,
|
parseRemarks,
|
||||||
|
parseCancelled,
|
||||||
parseStopover,
|
parseStopover,
|
||||||
parseLoadFactor,
|
parseLoadFactor,
|
||||||
parseArrOrDepWithLoadFactor,
|
parseArrOrDepWithLoadFactor,
|
||||||
|
@ -99,6 +100,7 @@ const defaultProfile = {
|
||||||
formatProductsFilter,
|
formatProductsFilter,
|
||||||
formatStation,
|
formatStation,
|
||||||
formatTime,
|
formatTime,
|
||||||
|
formatTimeOfDay,
|
||||||
formatTravellers: notImplemented,
|
formatTravellers: notImplemented,
|
||||||
formatRectangle: id,
|
formatRectangle: id,
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,9 @@ const products = [
|
||||||
short: 'ICE',
|
short: 'ICE',
|
||||||
vendo: 'ICE',
|
vendo: 'ICE',
|
||||||
ris: 'HIGH_SPEED_TRAIN',
|
ris: 'HIGH_SPEED_TRAIN',
|
||||||
|
ris_alt: 'HIGH_SPEED_TRAIN',
|
||||||
dbnav: 'HOCHGESCHWINDIGKEITSZUEGE',
|
dbnav: 'HOCHGESCHWINDIGKEITSZUEGE',
|
||||||
|
dbnav_short: 'ICE',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -18,7 +20,9 @@ const products = [
|
||||||
short: 'IC/EC',
|
short: 'IC/EC',
|
||||||
vendo: 'EC_IC',
|
vendo: 'EC_IC',
|
||||||
ris: 'INTERCITY_TRAIN',
|
ris: 'INTERCITY_TRAIN',
|
||||||
|
ris_alt: 'INTERCITY_TRAIN',
|
||||||
dbnav: 'INTERCITYUNDEUROCITYZUEGE',
|
dbnav: 'INTERCITYUNDEUROCITYZUEGE',
|
||||||
|
dbnav_short: 'IC_EC',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -29,7 +33,9 @@ const products = [
|
||||||
short: 'RE/IR',
|
short: 'RE/IR',
|
||||||
vendo: 'IR',
|
vendo: 'IR',
|
||||||
ris: 'INTER_REGIONAL_TRAIN',
|
ris: 'INTER_REGIONAL_TRAIN',
|
||||||
|
ris_alt: 'INTER_REGIONAL_TRAIN',
|
||||||
dbnav: 'INTERREGIOUNDSCHNELLZUEGE',
|
dbnav: 'INTERREGIOUNDSCHNELLZUEGE',
|
||||||
|
dbnav_short: 'IR',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -40,7 +46,9 @@ const products = [
|
||||||
short: 'RB',
|
short: 'RB',
|
||||||
vendo: 'REGIONAL',
|
vendo: 'REGIONAL',
|
||||||
ris: 'REGIONAL_TRAIN',
|
ris: 'REGIONAL_TRAIN',
|
||||||
|
ris_alt: 'REGIONAL_TRAIN',
|
||||||
dbnav: 'NAHVERKEHRSONSTIGEZUEGE',
|
dbnav: 'NAHVERKEHRSONSTIGEZUEGE',
|
||||||
|
dbnav_short: 'RB',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -51,7 +59,9 @@ const products = [
|
||||||
short: 'S',
|
short: 'S',
|
||||||
vendo: 'SBAHN',
|
vendo: 'SBAHN',
|
||||||
ris: 'CITY_TRAIN',
|
ris: 'CITY_TRAIN',
|
||||||
|
ris_alt: 'CITY_TRAIN',
|
||||||
dbnav: 'SBAHNEN',
|
dbnav: 'SBAHNEN',
|
||||||
|
dbnav_short: 'SBAHN',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -62,7 +72,9 @@ const products = [
|
||||||
short: 'B',
|
short: 'B',
|
||||||
vendo: 'BUS',
|
vendo: 'BUS',
|
||||||
ris: 'BUS',
|
ris: 'BUS',
|
||||||
|
ris_alt: 'BUS',
|
||||||
dbnav: 'BUSSE',
|
dbnav: 'BUSSE',
|
||||||
|
dbnav_short: 'BUS',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -73,7 +85,9 @@ const products = [
|
||||||
short: 'F',
|
short: 'F',
|
||||||
vendo: 'SCHIFF',
|
vendo: 'SCHIFF',
|
||||||
ris: 'FERRY',
|
ris: 'FERRY',
|
||||||
|
ris_alt: 'FERRY',
|
||||||
dbnav: 'SCHIFFE',
|
dbnav: 'SCHIFFE',
|
||||||
|
dbnav_short: 'SCHIFF',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -84,7 +98,9 @@ const products = [
|
||||||
short: 'U',
|
short: 'U',
|
||||||
vendo: 'UBAHN',
|
vendo: 'UBAHN',
|
||||||
ris: 'SUBWAY',
|
ris: 'SUBWAY',
|
||||||
|
ris_alt: 'SUBWAY',
|
||||||
dbnav: 'UBAHN',
|
dbnav: 'UBAHN',
|
||||||
|
dbnav_short: 'UBAHN',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -95,7 +111,9 @@ const products = [
|
||||||
short: 'T',
|
short: 'T',
|
||||||
vendo: 'TRAM',
|
vendo: 'TRAM',
|
||||||
ris: 'TRAM',
|
ris: 'TRAM',
|
||||||
|
ris_alt: 'TRAM',
|
||||||
dbnav: 'STRASSENBAHN',
|
dbnav: 'STRASSENBAHN',
|
||||||
|
dbnav_short: 'STR',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -106,7 +124,9 @@ const products = [
|
||||||
short: 'Taxi',
|
short: 'Taxi',
|
||||||
vendo: 'ANRUFPFLICHTIG',
|
vendo: 'ANRUFPFLICHTIG',
|
||||||
ris: 'TAXI',
|
ris: 'TAXI',
|
||||||
|
ris_alt: 'SHUTTLE',
|
||||||
dbnav: 'ANRUFPFLICHTIGEVERKEHRE',
|
dbnav: 'ANRUFPFLICHTIGEVERKEHRE',
|
||||||
|
dbnav_short: 'ANRUFPFLICHTIGEVERKEHRE',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -5,6 +5,6 @@
|
||||||
"locationsEndpoint": "https://app.vendo.noncd.db.de/mob/location/search",
|
"locationsEndpoint": "https://app.vendo.noncd.db.de/mob/location/search",
|
||||||
"nearbyEndpoint": "https://app.vendo.noncd.db.de/mob/location/nearby",
|
"nearbyEndpoint": "https://app.vendo.noncd.db.de/mob/location/nearby",
|
||||||
"tripEndpoint": "https://app.vendo.noncd.db.de/mob/zuglauf",
|
"tripEndpoint": "https://app.vendo.noncd.db.de/mob/zuglauf",
|
||||||
"boardEndpoint": "https://app.vendo.noncd.db.de/mob/bahnhofstafel/abfahrt",
|
"boardEndpoint": "https://app.vendo.noncd.db.de/mob/bahnhofstafel/",
|
||||||
"defaultLanguage": "en"
|
"defaultLanguage": "en"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ const formatStationBoardReq = (ctx, station, type) => {
|
||||||
path: type == 'departures' ? 'abfahrt' : 'ankunft',
|
path: type == 'departures' ? 'abfahrt' : 'ankunft',
|
||||||
body: {anfragezeit: profile.formatTimeOfDay(profile, opt.when), datum: profile.formatDate(profile, opt.when), ursprungsBahnhofId: profile.formatStation(station).lid, verkehrsmittel: profile.formatProductsFilter(ctx, opt.products || {}, 'dbnav')},
|
body: {anfragezeit: profile.formatTimeOfDay(profile, opt.when), datum: profile.formatDate(profile, opt.when), ursprungsBahnhofId: profile.formatStation(station).lid, verkehrsmittel: profile.formatProductsFilter(ctx, opt.products || {}, 'dbnav')},
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
header: getHeaders('application/x.db.vendo.mob.bahnhofstafeln.v2+json'),
|
headers: getHeaders('application/x.db.vendo.mob.bahnhofstafeln.v2+json'),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,20 @@ const createParseArrOrDep = (prefix) => {
|
||||||
|
|
||||||
const parseArrOrDep = (ctx, d) => { // d = raw arrival/departure
|
const parseArrOrDep = (ctx, d) => { // d = raw arrival/departure
|
||||||
const {profile, opt} = ctx;
|
const {profile, opt} = ctx;
|
||||||
|
const cancelled = profile.parseCancelled(d);
|
||||||
const res = {
|
const res = {
|
||||||
tripId: d.journeyID || d.train.journeyId,
|
tripId: d.journeyID || d.train?.journeyId || d.zuglaufId,
|
||||||
stop: profile.parseLocation(ctx, d.station),
|
stop: profile.parseLocation(ctx, d.station || d.abfrageOrt),
|
||||||
...profile.parseWhen(ctx, null, d.timeSchedule ? d.timeSchedule : d.time, d.timeType != 'SCHEDULE' ? d.timePredicted ? d.timePredicted : d.time : null, d.canceled),
|
...profile.parseWhen(
|
||||||
...profile.parsePlatform(ctx, d.platformSchedule ? d.platformSchedule : d.platform, d.platformPredicted ? d.platformPredicted : d.platform, d.canceled),
|
ctx,
|
||||||
|
null,
|
||||||
|
d.timeSchedule || d.time || d.abgangsDatum || d.ankunftsDatum,
|
||||||
|
d.timeType != 'SCHEDULE' ? d.timePredicted || d.time || d.ezAbgangsDatum || d.ezAnkunftsDatum : null,
|
||||||
|
cancelled),
|
||||||
|
...profile.parsePlatform(ctx, d.platformSchedule || d.platform || d.gleis, d.platformPredicted || d.platform || d.ezGleis, cancelled),
|
||||||
// prognosisType: TODO
|
// prognosisType: TODO
|
||||||
direction: d.transport?.direction?.stopPlaces?.length > 0 && profile.parseStationName(ctx, d.transport?.direction?.stopPlaces[0].name) || profile.parseStationName(ctx, d.destination?.name) || null,
|
direction: d.transport?.direction?.stopPlaces?.length > 0 && profile.parseStationName(ctx, d.transport?.direction?.stopPlaces[0].name) || profile.parseStationName(ctx, d.destination?.name || d.richtung) || null,
|
||||||
provenance: profile.parseStationName(ctx, d.transport?.origin?.name) || profile.parseStationName(ctx, d.origin?.name) || null,
|
provenance: profile.parseStationName(ctx, d.transport?.origin?.name || d.origin?.name || d.abgangsOrt?.name) || null,
|
||||||
line: profile.parseLine(ctx, d) || null,
|
line: profile.parseLine(ctx, d) || null,
|
||||||
remarks: [],
|
remarks: [],
|
||||||
origin: profile.parseLocation(ctx, d.transport?.origin || d.origin) || null,
|
origin: profile.parseLocation(ctx, d.transport?.origin || d.origin) || null,
|
||||||
|
@ -26,7 +31,7 @@ const createParseArrOrDep = (prefix) => {
|
||||||
|
|
||||||
// TODO pos
|
// TODO pos
|
||||||
|
|
||||||
if (d.canceled) {
|
if (cancelled) {
|
||||||
res.cancelled = true;
|
res.cancelled = true;
|
||||||
Object.defineProperty(res, 'canceled', {value: true});
|
Object.defineProperty(res, 'canceled', {value: true});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import {parseRemarks, isStopCancelled} from './remarks.js';
|
|
||||||
|
|
||||||
const locationFallback = (id, name, fallbackLocations) => {
|
const locationFallback = (id, name, fallbackLocations) => {
|
||||||
if (fallbackLocations && (id && fallbackLocations[id] || name && fallbackLocations[name])) {
|
if (fallbackLocations && (id && fallbackLocations[id] || name && fallbackLocations[name])) {
|
||||||
return fallbackLocations[id] || fallbackLocations[name];
|
return fallbackLocations[id] || fallbackLocations[name];
|
||||||
|
@ -20,7 +18,7 @@ const parseJourneyLeg = (ctx, pt, date, fallbackLocations) => { // pt = raw leg
|
||||||
destination: pt.halte?.length > 0 ? profile.parseLocation(ctx, pt.halte[pt.halte.length - 1]) : locationFallback(pt.ankunftsOrtExtId, pt.ankunftsOrt, fallbackLocations),
|
destination: pt.halte?.length > 0 ? profile.parseLocation(ctx, pt.halte[pt.halte.length - 1]) : locationFallback(pt.ankunftsOrtExtId, pt.ankunftsOrt, fallbackLocations),
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancelledDep = pt.halte?.length > 0 && isStopCancelled(pt.halte[0]);
|
const cancelledDep = pt.halte?.length > 0 && profile.parseCancelled(pt.halte[0]);
|
||||||
const dep = profile.parseWhen(ctx, date, pt.abfahrtsZeitpunkt, pt.ezAbfahrtsZeitpunkt, cancelledDep);
|
const dep = profile.parseWhen(ctx, date, pt.abfahrtsZeitpunkt, pt.ezAbfahrtsZeitpunkt, cancelledDep);
|
||||||
res.departure = dep.when;
|
res.departure = dep.when;
|
||||||
res.plannedDeparture = dep.plannedWhen;
|
res.plannedDeparture = dep.plannedWhen;
|
||||||
|
@ -29,7 +27,7 @@ const parseJourneyLeg = (ctx, pt, date, fallbackLocations) => { // pt = raw leg
|
||||||
res.prognosedDeparture = dep.prognosedWhen;
|
res.prognosedDeparture = dep.prognosedWhen;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancelledArr = pt.halte?.length > 0 && isStopCancelled(pt.halte[pt.halte.length - 1]);
|
const cancelledArr = pt.halte?.length > 0 && profile.parseCancelled(pt.halte[pt.halte.length - 1]);
|
||||||
const arr = profile.parseWhen(ctx, date, pt.ankunftsZeitpunkt, pt.ezAnkunftsZeitpunkt, cancelledArr);
|
const arr = profile.parseWhen(ctx, date, pt.ankunftsZeitpunkt, pt.ezAnkunftsZeitpunkt, cancelledArr);
|
||||||
res.arrival = arr.when;
|
res.arrival = arr.when;
|
||||||
res.plannedArrival = arr.plannedWhen;
|
res.plannedArrival = arr.plannedWhen;
|
||||||
|
@ -84,7 +82,7 @@ const parseJourneyLeg = (ctx, pt, date, fallbackLocations) => { // pt = raw leg
|
||||||
res.stopovers = res.stopovers.filter((x) => !x.passBy);
|
res.stopovers = res.stopovers.filter((x) => !x.passBy);
|
||||||
}
|
}
|
||||||
if (opt.remarks) {
|
if (opt.remarks) {
|
||||||
res.remarks = parseRemarks(ctx, pt);
|
res.remarks = profile.parseRemarks(ctx, pt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,19 +5,19 @@ const parseLine = (ctx, p) => {
|
||||||
const fahrtNr = p.verkehrsmittel?.nummer || p.transport?.number || p.train?.no;
|
const fahrtNr = p.verkehrsmittel?.nummer || p.transport?.number || p.train?.no;
|
||||||
const res = {
|
const res = {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
id: slugg(p.verkehrsmittel?.langText || p.transport?.journeyDescription || p.train?.no), // TODO terrible
|
id: slugg(p.verkehrsmittel?.langText || p.transport?.journeyDescription || p.train && p.train.category + ' ' + p.train.lineName + ' ' + p.train.no || p.langtext || p.mitteltext), // TODO terrible
|
||||||
fahrtNr: fahrtNr ? String(fahrtNr) : undefined,
|
fahrtNr: fahrtNr ? String(fahrtNr) : undefined, // TODO extract from zuglaufId?
|
||||||
name: p.verkehrsmittel?.name || p.zugName || p.transport?.journeyDescription || p.train && p.train.category + ' ' + p.train.lineName,
|
name: p.verkehrsmittel?.name || p.zugName || p.transport?.journeyDescription || p.train && p.train.category + ' ' + p.train.lineName || p.langtext || p.mitteltext,
|
||||||
public: true,
|
public: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO res.adminCode
|
// TODO res.adminCode
|
||||||
res.productName = p.verkehrsmittel?.kurzText || p.transport?.category || p.train?.category;
|
res.productName = p.verkehrsmittel?.kurzText || p.transport?.category || p.train?.category || p.kurztext;
|
||||||
const foundProduct = profile.products.find(pp => pp.vendo == p.verkehrsmittel?.produktGattung || pp.ris == p.transport?.type || pp.ris == p.train?.type);
|
const foundProduct = profile.products.find(pp => pp.vendo == p.verkehrsmittel?.produktGattung || pp.ris == p.transport?.type || pp.ris == p.train?.type || pp.ris_alt == p.train?.type || pp.dbnav_short == p.produktGattung);
|
||||||
res.mode = foundProduct?.mode;
|
res.mode = foundProduct?.mode;
|
||||||
res.product = foundProduct?.id;
|
res.product = foundProduct?.id;
|
||||||
|
|
||||||
res.operator = profile.parseOperator(ctx, p.verkehrsmittel?.zugattribute || p.zugattribute);
|
res.operator = profile.parseOperator(ctx, p.verkehrsmittel?.zugattribute || p.zugattribute); // TODO regio-guide op
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,15 +28,15 @@ const parseLocation = (ctx, l) => {
|
||||||
res.longitude = lid.X / 1000000;
|
res.longitude = lid.X / 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l.type === STATION || l.extId || l.evaNumber || l.evaNo || lid.A == 1) {
|
if (l.type === STATION || l.extId || l.evaNumber || l.evaNo || l.evaNr || lid.A == '1') {
|
||||||
let stop = {
|
let stop = {
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: res.id,
|
id: res.id,
|
||||||
name: name,
|
name: name,
|
||||||
location: 'number' === typeof res.latitude
|
|
||||||
? res
|
|
||||||
: null, // todo: remove `.id`
|
|
||||||
};
|
};
|
||||||
|
if ('number' === typeof res.latitude) {
|
||||||
|
stop.location = res; // todo: remove `.id`
|
||||||
|
}
|
||||||
// TODO subStops
|
// TODO subStops
|
||||||
|
|
||||||
if ('products' in l) {
|
if ('products' in l) {
|
||||||
|
@ -57,10 +57,10 @@ const parseLocation = (ctx, l) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
res.name = name;
|
res.name = name;
|
||||||
if (l.type === ADDRESS || lid.A == 2) {
|
if (l.type === ADDRESS || lid.A == '2') {
|
||||||
res.address = name;
|
res.address = name;
|
||||||
}
|
}
|
||||||
if (l.type === POI || lid.A == 4) {
|
if (l.type === POI || lid.A == '4') {
|
||||||
res.poi = true;
|
res.poi = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,17 @@ const parseOperator = (ctx, zugattrib) => {
|
||||||
if (!zugattrib) {
|
if (!zugattrib) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const bef = zugattrib.find(z => z.key == 'BEF');
|
const bef = zugattrib.find(z => z.key == 'BEF' || z.key == 'OP');
|
||||||
if (!bef) {
|
if (!bef) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const name = bef.value && bef.value.trim();
|
const name = bef.value || bef.text;
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: 'operator',
|
type: 'operator',
|
||||||
id: slugg(name), // todo: find a more reliable way
|
id: slugg(name.trim()), // todo: find a more reliable way
|
||||||
name,
|
name,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,44 +3,53 @@ import flatMap from 'lodash/flatMap.js';
|
||||||
const parseRemarks = (ctx, ref) => {
|
const parseRemarks = (ctx, ref) => {
|
||||||
// TODO ereignisZusammenfassung, priorisierteMeldungen?
|
// TODO ereignisZusammenfassung, priorisierteMeldungen?
|
||||||
return flatMap([
|
return flatMap([
|
||||||
ref.risNotizen || [],
|
|
||||||
ref.himMeldungen || [],
|
|
||||||
ref.meldungenAsObject || [],
|
|
||||||
ref.verkehrsmittel?.zugattribute || [],
|
|
||||||
ref.messages || [],
|
|
||||||
ref.attributes || [],
|
|
||||||
ref.disruptions || [],
|
ref.disruptions || [],
|
||||||
|
ref.risNotizen || [],
|
||||||
|
ref.echtzeitNotizen && ref.echtzeitNotizen.map(e => {
|
||||||
|
e.prio = 'HOCH'; return e;
|
||||||
|
}) || [],
|
||||||
|
ref.himMeldungen || [],
|
||||||
|
ref.himNotizen || [],
|
||||||
|
ref.serviceNotiz && [ref.serviceNotiz] || [],
|
||||||
|
ref.messages || [],
|
||||||
|
ref.meldungenAsObject || [],
|
||||||
|
ref.attributNotizen || [],
|
||||||
|
ref.attributes || [],
|
||||||
|
ref.verkehrsmittel?.zugattribute || [],
|
||||||
])
|
])
|
||||||
.map(remark => {
|
.map(remark => {
|
||||||
if (remark.kategorie) {
|
if (remark.kategorie || remark.priority) {
|
||||||
const res = ctx.profile.parseHintByCode(remark);
|
const res = ctx.profile.parseHintByCode(remark);
|
||||||
if (res) {
|
if (res) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let type = 'hint';
|
let type = 'hint';
|
||||||
if (remark.prioritaet || remark.type) {
|
if (remark.prioritaet || remark.prio || remark.type) {
|
||||||
type = 'status';
|
type = 'status';
|
||||||
}
|
}
|
||||||
if (!remark.kategorie && remark.key || remark.disruptionID || remark.prioritaet && remark.prioritaet == 'HOCH') {
|
if (!remark.priority && !remark.kategorie && remark.key || remark.disruptionID
|
||||||
|
|| remark.prioritaet && remark.prioritaet == 'HOCH' || remark.prio && remark.prio == 'HOCH' || remark.priority && remark.priority < 100) {
|
||||||
type = 'warning';
|
type = 'warning';
|
||||||
}
|
}
|
||||||
let res = {
|
let res = {
|
||||||
code: remark.code || remark.key,
|
code: remark.code || remark.key,
|
||||||
summary: remark.nachrichtKurz || remark.value || remark.ueberschrift || remark.text || Object.values(remark.descriptions || {})
|
summary: remark.nachrichtKurz || remark.value || remark.ueberschrift || remark.text
|
||||||
|
|| Object.values(remark.descriptions || {})
|
||||||
.shift()?.textShort,
|
.shift()?.textShort,
|
||||||
text: remark.nachrichtLang || remark.value || remark.text || Object.values(remark.descriptions || {})
|
text: remark.nachrichtLang || remark.value || remark.text
|
||||||
|
|| Object.values(remark.descriptions || {})
|
||||||
.shift()?.text,
|
.shift()?.text,
|
||||||
type: type,
|
type: type,
|
||||||
};
|
};
|
||||||
if (remark.modDateTime) {
|
if (remark.modDateTime || remark.letzteAktualisierung) {
|
||||||
res.modified = ctx.profile.parseDateTime(ctx, null, remark.modDateTime);
|
res.modified = ctx.profile.parseDateTime(ctx, null, remark.modDateTime || remark.letzteAktualisierung);
|
||||||
}
|
}
|
||||||
// TODO fromStops, toStops = routeIdxFrom ??
|
// TODO fromStops, toStops = routeIdxFrom ??
|
||||||
// TODO prio
|
// TODO prio
|
||||||
return res;
|
return res;
|
||||||
})
|
})
|
||||||
.filter(remark => remark.code != 'BEF');
|
.filter(remark => remark.code != 'BEF' && remark.code != 'OP');
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -189,11 +198,15 @@ const parseRemarks = (ctx, ref) => {
|
||||||
]
|
]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const isStopCancelled = (ref) => {
|
const parseCancelled = (ref) => {
|
||||||
return Boolean(ref.risNotizen.find(r => r.key == 'text.realtime.stop.cancelled' || r.type == 'HALT_AUSFALL'));
|
return ref.canceled || ref.cancelled || (ref.risNotizen || ref.echtzeitNotizen) && Boolean((ref.risNotizen || ref.echtzeitNotizen).find(r => r.key == 'text.realtime.stop.cancelled'
|
||||||
|
|| r.type == 'HALT_AUSFALL'
|
||||||
|
|| r.text == 'Halt entfällt'
|
||||||
|
|| r.text == 'Stop cancelled',
|
||||||
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
parseRemarks,
|
parseRemarks,
|
||||||
isStopCancelled,
|
parseCancelled,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import {parseRemarks, isStopCancelled} from './remarks.js';
|
|
||||||
|
|
||||||
const parseStopover = (ctx, st, date) => { // st = raw stopover
|
const parseStopover = (ctx, st, date) => { // st = raw stopover
|
||||||
const {profile, opt} = ctx;
|
const {profile, opt} = ctx;
|
||||||
|
|
||||||
const cancelled = isStopCancelled(st);
|
const cancelled = profile.parseCancelled(st);
|
||||||
const arr = profile.parseWhen(ctx, date, st.ankunftsZeitpunkt, st.ezAnkunftsZeitpunkt, cancelled);
|
const arr = profile.parseWhen(ctx, date, st.ankunftsZeitpunkt, st.ezAnkunftsZeitpunkt, cancelled);
|
||||||
const arrPl = profile.parsePlatform(ctx, st.gleis, st.ezGleis);
|
const arrPl = profile.parsePlatform(ctx, st.gleis, st.ezGleis);
|
||||||
const dep = profile.parseWhen(ctx, date, st.abfahrtsZeitpunkt, st.ezAbfahrtsZeitpunkt, cancelled);
|
const dep = profile.parseWhen(ctx, date, st.abfahrtsZeitpunkt, st.ezAbfahrtsZeitpunkt, cancelled);
|
||||||
|
@ -51,7 +49,7 @@ const parseStopover = (ctx, st, date) => { // st = raw stopover
|
||||||
// TODO res.additional = true;
|
// TODO res.additional = true;
|
||||||
|
|
||||||
if (opt.remarks) {
|
if (opt.remarks) {
|
||||||
res.remarks = parseRemarks(ctx, st);
|
res.remarks = profile.parseRemarks(ctx, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
32
test/dbnav-departures.js
Normal file
32
test/dbnav-departures.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// todo: use import assertions once they're supported by Node.js & ESLint
|
||||||
|
// https://github.com/tc39/proposal-import-assertions
|
||||||
|
import {createRequire} from 'module';
|
||||||
|
const require = createRequire(import.meta.url);
|
||||||
|
|
||||||
|
import tap from 'tap';
|
||||||
|
|
||||||
|
import {createClient} from '../index.js';
|
||||||
|
import {profile as rawProfile} from '../p/db/index.js';
|
||||||
|
const res = require('./fixtures/dbnav-departures.json');
|
||||||
|
import {dbnavDepartures as expected} from './fixtures/dbnav-departures.js';
|
||||||
|
|
||||||
|
const client = createClient(rawProfile, 'public-transport/hafas-client:test');
|
||||||
|
const {profile} = client;
|
||||||
|
|
||||||
|
const opt = {
|
||||||
|
direction: null,
|
||||||
|
duration: 10,
|
||||||
|
linesOfStops: true,
|
||||||
|
remarks: true,
|
||||||
|
stopovers: true,
|
||||||
|
includeRelatedStations: true,
|
||||||
|
when: '2019-08-19T20:30:00+02:00',
|
||||||
|
products: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
tap.test('parses a regio-guide departure correctly', (t) => {
|
||||||
|
const ctx = {profile, opt, common: null, res};
|
||||||
|
const departures = res.bahnhofstafelAbfahrtPositionen.map(d => profile.parseDeparture(ctx, d));
|
||||||
|
t.same(departures, expected);
|
||||||
|
t.end();
|
||||||
|
});
|
14
test/fixtures/db-arrivals.js
vendored
14
test/fixtures/db-arrivals.js
vendored
|
@ -5,7 +5,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '8089100',
|
id: '8089100',
|
||||||
name: 'Berlin Jungfernheide (S)',
|
name: 'Berlin Jungfernheide (S)',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
when: '2024-12-08T01:00:00+01:00',
|
when: '2024-12-08T01:00:00+01:00',
|
||||||
plannedWhen: '2024-12-08T01:00:00+01:00',
|
plannedWhen: '2024-12-08T01:00:00+01:00',
|
||||||
|
@ -37,7 +36,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '8089118',
|
id: '8089118',
|
||||||
name: 'Berlin Beusselstraße',
|
name: 'Berlin Beusselstraße',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
destination: null,
|
destination: null,
|
||||||
},
|
},
|
||||||
|
@ -47,7 +45,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '730985',
|
id: '730985',
|
||||||
name: 'Jungfernheide Bahnhof (S+U), Berlin',
|
name: 'Jungfernheide Bahnhof (S+U), Berlin',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
when: '2024-12-08T01:00:00+01:00',
|
when: '2024-12-08T01:00:00+01:00',
|
||||||
plannedWhen: '2024-12-08T01:00:00+01:00',
|
plannedWhen: '2024-12-08T01:00:00+01:00',
|
||||||
|
@ -85,7 +82,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '732218',
|
id: '732218',
|
||||||
name: 'Rudow (U), Berlin',
|
name: 'Rudow (U), Berlin',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
destination: null,
|
destination: null,
|
||||||
},
|
},
|
||||||
|
@ -95,7 +91,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '730985',
|
id: '730985',
|
||||||
name: 'Jungfernheide Bahnhof (S+U), Berlin',
|
name: 'Jungfernheide Bahnhof (S+U), Berlin',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
when: '2024-12-08T01:03:00+01:00',
|
when: '2024-12-08T01:03:00+01:00',
|
||||||
plannedWhen: '2024-12-08T01:03:00+01:00',
|
plannedWhen: '2024-12-08T01:03:00+01:00',
|
||||||
|
@ -133,7 +128,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '730993',
|
id: '730993',
|
||||||
name: 'Goerdelersteg, Berlin',
|
name: 'Goerdelersteg, Berlin',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
destination: null,
|
destination: null,
|
||||||
},
|
},
|
||||||
|
@ -143,7 +137,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '8089100',
|
id: '8089100',
|
||||||
name: 'Berlin Jungfernheide (S)',
|
name: 'Berlin Jungfernheide (S)',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
when: '2024-12-08T01:05:00+01:00',
|
when: '2024-12-08T01:05:00+01:00',
|
||||||
plannedWhen: '2024-12-08T01:05:00+01:00',
|
plannedWhen: '2024-12-08T01:05:00+01:00',
|
||||||
|
@ -175,7 +168,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '8089118',
|
id: '8089118',
|
||||||
name: 'Berlin Beusselstraße',
|
name: 'Berlin Beusselstraße',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
destination: null,
|
destination: null,
|
||||||
},
|
},
|
||||||
|
@ -185,7 +177,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '730985',
|
id: '730985',
|
||||||
name: 'Jungfernheide Bahnhof (S+U), Berlin',
|
name: 'Jungfernheide Bahnhof (S+U), Berlin',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
when: '2024-12-08T01:10:00+01:00',
|
when: '2024-12-08T01:10:00+01:00',
|
||||||
plannedWhen: '2024-12-08T01:10:00+01:00',
|
plannedWhen: '2024-12-08T01:10:00+01:00',
|
||||||
|
@ -223,7 +214,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '732218',
|
id: '732218',
|
||||||
name: 'Rudow (U), Berlin',
|
name: 'Rudow (U), Berlin',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
destination: null,
|
destination: null,
|
||||||
},
|
},
|
||||||
|
@ -233,7 +223,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '8089100',
|
id: '8089100',
|
||||||
name: 'Berlin Jungfernheide (S)',
|
name: 'Berlin Jungfernheide (S)',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
when: '2024-12-08T01:10:00+01:00',
|
when: '2024-12-08T01:10:00+01:00',
|
||||||
plannedWhen: '2024-12-08T01:10:00+01:00',
|
plannedWhen: '2024-12-08T01:10:00+01:00',
|
||||||
|
@ -265,7 +254,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '8089118',
|
id: '8089118',
|
||||||
name: 'Berlin Beusselstraße',
|
name: 'Berlin Beusselstraße',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
destination: null,
|
destination: null,
|
||||||
},
|
},
|
||||||
|
@ -275,7 +263,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '730985',
|
id: '730985',
|
||||||
name: 'Jungfernheide Bahnhof (S+U), Berlin',
|
name: 'Jungfernheide Bahnhof (S+U), Berlin',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
when: '2024-12-08T01:10:00+01:00',
|
when: '2024-12-08T01:10:00+01:00',
|
||||||
plannedWhen: '2024-12-08T01:10:00+01:00',
|
plannedWhen: '2024-12-08T01:10:00+01:00',
|
||||||
|
@ -313,7 +300,6 @@ const dbArrivals = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '731176',
|
id: '731176',
|
||||||
name: 'Rathaus Spandau (S+U), Berlin',
|
name: 'Rathaus Spandau (S+U), Berlin',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
destination: null,
|
destination: null,
|
||||||
},
|
},
|
||||||
|
|
12
test/fixtures/db-departures-regio-guide.js
vendored
12
test/fixtures/db-departures-regio-guide.js
vendored
|
@ -5,7 +5,6 @@ const dbDepartures = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '8000365',
|
id: '8000365',
|
||||||
name: 'Dombühl',
|
name: 'Dombühl',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
when: '2024-12-12T12:34:00+01:00',
|
when: '2024-12-12T12:34:00+01:00',
|
||||||
plannedWhen: '2024-12-12T12:34:00+01:00',
|
plannedWhen: '2024-12-12T12:34:00+01:00',
|
||||||
|
@ -16,7 +15,7 @@ const dbDepartures = [
|
||||||
provenance: null,
|
provenance: null,
|
||||||
line: {
|
line: {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
id: '88617',
|
id: 're-90-88617',
|
||||||
fahrtNr: '88617',
|
fahrtNr: '88617',
|
||||||
name: 'RE 90',
|
name: 'RE 90',
|
||||||
public: true,
|
public: true,
|
||||||
|
@ -31,7 +30,6 @@ const dbDepartures = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '8000284',
|
id: '8000284',
|
||||||
name: 'Nürnberg Hbf',
|
name: 'Nürnberg Hbf',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -40,7 +38,6 @@ const dbDepartures = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '682943',
|
id: '682943',
|
||||||
name: 'Bahnhof, Dombühl',
|
name: 'Bahnhof, Dombühl',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
when: '2024-12-12T12:50:00+01:00',
|
when: '2024-12-12T12:50:00+01:00',
|
||||||
plannedWhen: '2024-12-12T12:50:00+01:00',
|
plannedWhen: '2024-12-12T12:50:00+01:00',
|
||||||
|
@ -51,7 +48,7 @@ const dbDepartures = [
|
||||||
provenance: null,
|
provenance: null,
|
||||||
line: {
|
line: {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
id: '2221',
|
id: 'bus-813-2221',
|
||||||
fahrtNr: '2221',
|
fahrtNr: '2221',
|
||||||
name: 'Bus 813',
|
name: 'Bus 813',
|
||||||
public: true,
|
public: true,
|
||||||
|
@ -66,7 +63,6 @@ const dbDepartures = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '676542',
|
id: '676542',
|
||||||
name: 'Gymnasium, Dinkelsbühl',
|
name: 'Gymnasium, Dinkelsbühl',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -75,7 +71,6 @@ const dbDepartures = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '682943',
|
id: '682943',
|
||||||
name: 'Bahnhof, Dombühl',
|
name: 'Bahnhof, Dombühl',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
when: '2024-12-12T12:50:00+01:00',
|
when: '2024-12-12T12:50:00+01:00',
|
||||||
plannedWhen: '2024-12-12T12:50:00+01:00',
|
plannedWhen: '2024-12-12T12:50:00+01:00',
|
||||||
|
@ -86,7 +81,7 @@ const dbDepartures = [
|
||||||
provenance: null,
|
provenance: null,
|
||||||
line: {
|
line: {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
id: '2177',
|
id: 'bus-807-2177',
|
||||||
fahrtNr: '2177',
|
fahrtNr: '2177',
|
||||||
name: 'Bus 807',
|
name: 'Bus 807',
|
||||||
public: true,
|
public: true,
|
||||||
|
@ -101,7 +96,6 @@ const dbDepartures = [
|
||||||
type: 'station',
|
type: 'station',
|
||||||
id: '683407',
|
id: '683407',
|
||||||
name: 'Bahnhof, Rothenburg ob der Tauber',
|
name: 'Bahnhof, Rothenburg ob der Tauber',
|
||||||
location: null,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
224
test/fixtures/dbnav-departures.js
vendored
Normal file
224
test/fixtures/dbnav-departures.js
vendored
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
const dbnavDepartures = [
|
||||||
|
{
|
||||||
|
tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#929785#TA#1#DA#291224#1S#374704#1T#1502#LS#465246#LT#1530#PU#81#RT#1#CA#rfb#ZE#9870#ZB#RUF 9870#PC#9#FR#374704#FT#1502#TO#465246#TT#1530#',
|
||||||
|
stop: {
|
||||||
|
type: 'station',
|
||||||
|
id: '374704',
|
||||||
|
name: 'Bahnhof, Rothenburg ob der Tauber',
|
||||||
|
location: {
|
||||||
|
type: 'location',
|
||||||
|
id: '374704',
|
||||||
|
latitude: 49.377189,
|
||||||
|
longitude: 10.191107,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
when: '2024-12-29T15:02:00+01:00',
|
||||||
|
plannedWhen: '2024-12-29T15:02:00+01:00',
|
||||||
|
delay: null,
|
||||||
|
platform: null,
|
||||||
|
plannedPlatform: null,
|
||||||
|
direction: 'ZOB, Creglingen',
|
||||||
|
provenance: null,
|
||||||
|
line: {
|
||||||
|
type: 'line',
|
||||||
|
id: 'ruf-9870',
|
||||||
|
name: 'RUF 9870',
|
||||||
|
fahrtNr: undefined,
|
||||||
|
public: true,
|
||||||
|
productName: 'RUF',
|
||||||
|
mode: 'taxi',
|
||||||
|
product: 'taxi',
|
||||||
|
operator: null,
|
||||||
|
},
|
||||||
|
remarks: [],
|
||||||
|
origin: null,
|
||||||
|
destination: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#214076#TA#1#DA#291224#1S#8005190#1T#1505#LS#8000091#LT#1520#PU#81#RT#1#CA#RB#ZE#58904#ZB#RB 58904#PC#3#FR#8005190#FT#1505#TO#8000091#TT#1520#',
|
||||||
|
stop: {
|
||||||
|
type: 'station',
|
||||||
|
id: '8005190',
|
||||||
|
name: 'Rothenburg ob der Tauber',
|
||||||
|
location: {
|
||||||
|
type: 'location',
|
||||||
|
id: '8005190',
|
||||||
|
latitude: 49.376686,
|
||||||
|
longitude: 10.190702,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
when: '2024-12-29T15:05:00+01:00',
|
||||||
|
plannedWhen: '2024-12-29T15:05:00+01:00',
|
||||||
|
delay: 0,
|
||||||
|
platform: '1',
|
||||||
|
plannedPlatform: '1',
|
||||||
|
direction: 'Steinach(bei Rothenburg ob der Tauber)',
|
||||||
|
provenance: null,
|
||||||
|
line: {
|
||||||
|
type: 'line',
|
||||||
|
id: 'rb-82',
|
||||||
|
name: 'RB 82',
|
||||||
|
fahrtNr: undefined,
|
||||||
|
public: true,
|
||||||
|
productName: 'RB',
|
||||||
|
mode: 'train',
|
||||||
|
product: 'regional',
|
||||||
|
operator: null,
|
||||||
|
},
|
||||||
|
remarks: [],
|
||||||
|
origin: null,
|
||||||
|
destination: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#863886#TA#3#DA#291224#1S#682943#1T#1450#LS#683407#LT#1531#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus 807#PC#5#FR#682943#FT#1450#TO#683407#TT#1531#',
|
||||||
|
stop: {
|
||||||
|
type: 'station',
|
||||||
|
id: '680433',
|
||||||
|
name: 'Schlachthof, Rothenburg ob der Tauber',
|
||||||
|
location: {
|
||||||
|
type: 'location',
|
||||||
|
id: '680433',
|
||||||
|
latitude: 49.373989,
|
||||||
|
longitude: 10.189255,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
when: '2024-12-29T15:30:00+01:00',
|
||||||
|
plannedWhen: '2024-12-29T15:30:00+01:00',
|
||||||
|
delay: null,
|
||||||
|
platform: null,
|
||||||
|
plannedPlatform: null,
|
||||||
|
direction: 'Bahnhof, Rothenburg ob der Tauber',
|
||||||
|
provenance: null,
|
||||||
|
line: {
|
||||||
|
type: 'line',
|
||||||
|
id: 'bus-807',
|
||||||
|
name: 'Bus 807',
|
||||||
|
fahrtNr: undefined,
|
||||||
|
public: true,
|
||||||
|
productName: 'Bus',
|
||||||
|
mode: 'bus',
|
||||||
|
product: 'bus',
|
||||||
|
operator: null,
|
||||||
|
},
|
||||||
|
remarks: [],
|
||||||
|
origin: null,
|
||||||
|
destination: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#863865#TA#0#DA#291224#1S#683407#1T#1532#LS#682943#LT#1624#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus 807#PC#5#FR#683407#FT#1532#TO#682943#TT#1624#',
|
||||||
|
stop: {
|
||||||
|
type: 'station',
|
||||||
|
id: '683407',
|
||||||
|
name: 'Bahnhof, Rothenburg ob der Tauber',
|
||||||
|
location: {
|
||||||
|
type: 'location',
|
||||||
|
id: '683407',
|
||||||
|
latitude: 49.37718,
|
||||||
|
longitude: 10.190711,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
when: '2024-12-29T15:32:00+01:00',
|
||||||
|
plannedWhen: '2024-12-29T15:32:00+01:00',
|
||||||
|
delay: null,
|
||||||
|
platform: null,
|
||||||
|
plannedPlatform: null,
|
||||||
|
direction: 'Bahnhof, Dombühl',
|
||||||
|
provenance: null,
|
||||||
|
line: {
|
||||||
|
type: 'line',
|
||||||
|
id: 'bus-807',
|
||||||
|
name: 'Bus 807',
|
||||||
|
fahrtNr: undefined,
|
||||||
|
public: true,
|
||||||
|
productName: 'Bus',
|
||||||
|
mode: 'bus',
|
||||||
|
product: 'bus',
|
||||||
|
operator: null,
|
||||||
|
},
|
||||||
|
remarks: [],
|
||||||
|
origin: null,
|
||||||
|
destination: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#863865#TA#0#DA#291224#1S#683407#1T#1532#LS#682943#LT#1624#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus 807#PC#5#FR#683407#FT#1532#TO#682943#TT#1624#',
|
||||||
|
stop: {
|
||||||
|
type: 'station',
|
||||||
|
id: '680433',
|
||||||
|
name: 'Schlachthof, Rothenburg ob der Tauber',
|
||||||
|
location: {
|
||||||
|
type: 'location',
|
||||||
|
id: '680433',
|
||||||
|
latitude: 49.373989,
|
||||||
|
longitude: 10.189255,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
when: '2024-12-29T15:33:00+01:00',
|
||||||
|
plannedWhen: '2024-12-29T15:33:00+01:00',
|
||||||
|
delay: null,
|
||||||
|
platform: null,
|
||||||
|
plannedPlatform: null,
|
||||||
|
direction: 'Bahnhof, Dombühl',
|
||||||
|
provenance: null,
|
||||||
|
line: {
|
||||||
|
type: 'line',
|
||||||
|
id: 'bus-807',
|
||||||
|
name: 'Bus 807',
|
||||||
|
fahrtNr: undefined,
|
||||||
|
public: true,
|
||||||
|
productName: 'Bus',
|
||||||
|
mode: 'bus',
|
||||||
|
product: 'bus',
|
||||||
|
operator: null,
|
||||||
|
},
|
||||||
|
remarks: [],
|
||||||
|
origin: null,
|
||||||
|
destination: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tripId: '2|#VN#1#ST#1734722398#PI#1#ZI#864022#TA#1#DA#291224#1S#677019#1T#1458#LS#683407#LT#1548#PU#81#RT#1#CA#Bus#ZE#817#ZB#Bus 817#PC#5#FR#677019#FT#1458#TO#683407#TT#1548#',
|
||||||
|
stop: {
|
||||||
|
type: 'station',
|
||||||
|
id: '680433',
|
||||||
|
name: 'Schlachthof, Rothenburg ob der Tauber',
|
||||||
|
location: {
|
||||||
|
type: 'location',
|
||||||
|
id: '680433',
|
||||||
|
latitude: 49.373989,
|
||||||
|
longitude: 10.189255,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
when: null,
|
||||||
|
plannedWhen: '2024-12-29T15:47:00+01:00',
|
||||||
|
prognosedWhen: null,
|
||||||
|
delay: null,
|
||||||
|
platform: null,
|
||||||
|
plannedPlatform: null,
|
||||||
|
prognosedPlatform: null,
|
||||||
|
direction: 'Bahnhof, Rothenburg ob der Tauber',
|
||||||
|
provenance: null,
|
||||||
|
line: {
|
||||||
|
type: 'line',
|
||||||
|
id: 'bus-817',
|
||||||
|
name: 'Bus 817',
|
||||||
|
fahrtNr: undefined,
|
||||||
|
public: true,
|
||||||
|
productName: 'Bus',
|
||||||
|
mode: 'bus',
|
||||||
|
product: 'bus',
|
||||||
|
operator: null,
|
||||||
|
},
|
||||||
|
remarks: [{
|
||||||
|
code: undefined,
|
||||||
|
summary: 'Halt entfällt',
|
||||||
|
text: 'Halt entfällt',
|
||||||
|
type: 'warning',
|
||||||
|
}],
|
||||||
|
origin: null,
|
||||||
|
destination: null,
|
||||||
|
cancelled: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export {
|
||||||
|
dbnavDepartures,
|
||||||
|
};
|
1
test/fixtures/dbnav-departures.json
vendored
Normal file
1
test/fixtures/dbnav-departures.json
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"bahnhofstafelAbfahrtPositionen":[{"zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#929785#TA#1#DA#291224#1S#374704#1T#1502#LS#465246#LT#1530#PU#81#RT#1#CA#rfb#ZE#9870#ZB#RUF 9870#PC#9#FR#374704#FT#1502#TO#465246#TT#1530#","kurztext":"RUF","mitteltext":"RUF 9870","abfrageOrt":{"name":"Bahnhof, Rothenburg ob der Tauber","locationId":"A=1@O=Bahnhof, Rothenburg ob der Tauber@X=10191107@Y=49377189@U=81@L=374704@","evaNr":"374704","stationId":"5393"},"richtung":"ZOB, Creglingen","echtzeitNotizen":[],"abgangsDatum":"2024-12-29T15:02:00+01:00","produktGattung":"ANRUFPFLICHTIGEVERKEHRE"},{"gleis":"1","zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#214076#TA#1#DA#291224#1S#8005190#1T#1505#LS#8000091#LT#1520#PU#81#RT#1#CA#RB#ZE#58904#ZB#RB 58904#PC#3#FR#8005190#FT#1505#TO#8000091#TT#1520#","kurztext":"RB","mitteltext":"RB 82","abfrageOrt":{"name":"Rothenburg ob der Tauber","locationId":"A=1@O=Rothenburg ob der Tauber@X=10190702@Y=49376686@U=81@L=8005190@i=U×008022698@","evaNr":"8005190","stationId":"5393"},"richtung":"Steinach(bei Rothenburg ob der Tauber)","echtzeitNotizen":[],"abgangsDatum":"2024-12-29T15:05:00+01:00","produktGattung":"RB","ezAbgangsDatum":"2024-12-29T15:05:00+01:00"},{"zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#863886#TA#3#DA#291224#1S#682943#1T#1450#LS#683407#LT#1531#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus 807#PC#5#FR#682943#FT#1450#TO#683407#TT#1531#","kurztext":"Bus","mitteltext":"Bus 807","abfrageOrt":{"name":"Schlachthof, Rothenburg ob der Tauber","locationId":"A=1@O=Schlachthof, Rothenburg ob der Tauber@X=10189255@Y=49373989@U=81@L=680433@","evaNr":"680433"},"richtung":"Bahnhof, Rothenburg ob der Tauber","echtzeitNotizen":[],"abgangsDatum":"2024-12-29T15:30:00+01:00","produktGattung":"BUS"},{"zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#863865#TA#0#DA#291224#1S#683407#1T#1532#LS#682943#LT#1624#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus 807#PC#5#FR#683407#FT#1532#TO#682943#TT#1624#","kurztext":"Bus","mitteltext":"Bus 807","abfrageOrt":{"name":"Bahnhof, Rothenburg ob der Tauber","locationId":"A=1@O=Bahnhof, Rothenburg ob der Tauber@X=10190711@Y=49377180@U=81@L=683407@","evaNr":"683407","stationId":"5393"},"richtung":"Bahnhof, Dombühl","echtzeitNotizen":[],"abgangsDatum":"2024-12-29T15:32:00+01:00","produktGattung":"BUS"},{"zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#863865#TA#0#DA#291224#1S#683407#1T#1532#LS#682943#LT#1624#PU#81#RT#1#CA#Bus#ZE#807#ZB#Bus 807#PC#5#FR#683407#FT#1532#TO#682943#TT#1624#","kurztext":"Bus","mitteltext":"Bus 807","abfrageOrt":{"name":"Schlachthof, Rothenburg ob der Tauber","locationId":"A=1@O=Schlachthof, Rothenburg ob der Tauber@X=10189255@Y=49373989@U=81@L=680433@","evaNr":"680433"},"richtung":"Bahnhof, Dombühl","echtzeitNotizen":[],"abgangsDatum":"2024-12-29T15:33:00+01:00","produktGattung":"BUS"},{"zuglaufId":"2|#VN#1#ST#1734722398#PI#1#ZI#864022#TA#1#DA#291224#1S#677019#1T#1458#LS#683407#LT#1548#PU#81#RT#1#CA#Bus#ZE#817#ZB#Bus 817#PC#5#FR#677019#FT#1458#TO#683407#TT#1548#","kurztext":"Bus","mitteltext":"Bus 817","abfrageOrt":{"name":"Schlachthof, Rothenburg ob der Tauber","locationId":"A=1@O=Schlachthof, Rothenburg ob der Tauber@X=10189255@Y=49373989@U=81@L=680433@","evaNr":"680433"},"richtung":"Bahnhof, Rothenburg ob der Tauber","echtzeitNotizen":[{"text":"Halt entfällt"}],"abgangsDatum":"2024-12-29T15:47:00+01:00","produktGattung":"BUS"}]}
|
|
@ -1,27 +1,9 @@
|
||||||
import tap from 'tap';
|
import tap from 'tap';
|
||||||
import {parseLine as parse} from '../../parse/line.js';
|
import {parseLine as parse} from '../../parse/line.js';
|
||||||
|
import {products} from '../../lib/products.js';
|
||||||
|
|
||||||
const profile = {
|
const profile = {
|
||||||
products: [
|
products: products,
|
||||||
{
|
|
||||||
id: 'nationalExpress',
|
|
||||||
mode: 'train',
|
|
||||||
name: 'InterCityExpress',
|
|
||||||
short: 'ICE',
|
|
||||||
vendo: 'ICE',
|
|
||||||
ris: 'HIGH_SPEED_TRAIN',
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'bus',
|
|
||||||
mode: 'bus',
|
|
||||||
name: 'Bus',
|
|
||||||
short: 'B',
|
|
||||||
vendo: 'BUS',
|
|
||||||
ris: 'BUS',
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
parseOperator: _ => null,
|
parseOperator: _ => null,
|
||||||
};
|
};
|
||||||
const ctx = {
|
const ctx = {
|
||||||
|
@ -172,3 +154,39 @@ tap.test('parses ris entry correctly', (t) => {
|
||||||
t.same(parse(ctx, input), expected);
|
t.same(parse(ctx, input), expected);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
tap.test('parses dbnav ruf correctly', (t) => {
|
||||||
|
const input = {zuglaufId: 'foo', kurztext: 'RUF', mitteltext: 'RUF 9870', produktGattung: 'ANRUFPFLICHTIGEVERKEHRE'};
|
||||||
|
const expected = {
|
||||||
|
type: 'line',
|
||||||
|
id: 'ruf-9870',
|
||||||
|
name: 'RUF 9870',
|
||||||
|
fahrtNr: undefined,
|
||||||
|
public: true,
|
||||||
|
product: 'taxi',
|
||||||
|
productName: 'RUF',
|
||||||
|
mode: 'taxi',
|
||||||
|
operator: null,
|
||||||
|
};
|
||||||
|
t.same(parse(ctx, input), expected);
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('parses regio guide ruf correctly', (t) => {
|
||||||
|
const input = {train: {journeyId: 'foo', category: 'RUF', type: 'SHUTTLE', no: 47403, lineName: '9870'}, category: 'SHUTTLE', administration: {id: 'vrn062', operatorCode: 'DPN', operatorName: 'Nahreisezug'}};
|
||||||
|
const expected = {
|
||||||
|
type: 'line',
|
||||||
|
id: 'ruf-9870-47403',
|
||||||
|
name: 'RUF 9870',
|
||||||
|
fahrtNr: '47403',
|
||||||
|
public: true,
|
||||||
|
product: 'taxi',
|
||||||
|
productName: 'RUF',
|
||||||
|
mode: 'taxi',
|
||||||
|
operator: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
t.same(parse(ctx, input), expected);
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
|
|
@ -37,3 +37,16 @@ tap.test('parses nothing', (t) => {
|
||||||
t.same(parse(ctx, op), null);
|
t.same(parse(ctx, op), null);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
tap.test('parses dbnav operator correctly', (t) => {
|
||||||
|
const op = [{text: 'DB Fernverkehr AG', key: 'OP'}];
|
||||||
|
|
||||||
|
t.same(parse(ctx, op), {
|
||||||
|
type: 'operator',
|
||||||
|
id: 'db-fernverkehr-ag',
|
||||||
|
name: 'DB Fernverkehr AG',
|
||||||
|
});
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -190,3 +190,36 @@ tap.test('parses ris attributes correctly', (t) => {
|
||||||
t.same(parse(ctx, input), expected);
|
t.same(parse(ctx, input), expected);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.test('parses dbnav attributes correctly', (t) => {
|
||||||
|
const input = {
|
||||||
|
echtzeitNotizen: [{text: 'Halt entfällt'}],
|
||||||
|
himNotizen: [{text: 'Coach 27 is closed to passengers today.', prio: 'NORMAL', ueberschrift: 'Information.', letzteAktualisierung: '2024-12-16T08:35:53+00:00'}],
|
||||||
|
attributNotizen: [{text: 'Komfort Check-in possible (visit bahn.de/kci for more information)', key: 'CK', priority: 200}, {text: 'DB Fernverkehr AG', key: 'OP'}],
|
||||||
|
};
|
||||||
|
const expected = [
|
||||||
|
{
|
||||||
|
code: undefined,
|
||||||
|
summary: 'Halt entfällt',
|
||||||
|
text: 'Halt entfällt',
|
||||||
|
type: 'warning',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: undefined,
|
||||||
|
summary: 'Information.',
|
||||||
|
text: 'Coach 27 is closed to passengers today.',
|
||||||
|
modified: '2024-12-16T09:35:53+01:00',
|
||||||
|
type: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'CK',
|
||||||
|
summary: 'Komfort Check-in possible (visit bahn.de/kci for more information)',
|
||||||
|
text: 'Komfort Check-in possible (visit bahn.de/kci for more information)',
|
||||||
|
type: 'hint',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
t.same(parse(ctx, input), expected);
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue