parse bahn.de boards

This commit is contained in:
dabund24 2025-02-05 12:23:57 +01:00
parent 1e7977a8bb
commit 615673e7a0
8 changed files with 54 additions and 18 deletions

View file

@ -105,7 +105,7 @@ const createClient = (profile, userAgent, opt = {}) => {
const {res} = await profile.request({profile, opt}, userAgent, req);
const ctx = {profile, opt, common, res};
const results = (res[resultsField] || res.items || res.bahnhofstafelAbfahrtPositionen || res.bahnhofstafelAnkunftPositionen)
const results = (res[resultsField] || res.items || res.bahnhofstafelAbfahrtPositionen || res.bahnhofstafelAnkunftPositionen || res.entries)
.map(res => parse(ctx, res)); // TODO sort?, slice
return {

View file

@ -6,6 +6,6 @@
"nearbyEndpoint": "https://int.bahn.de/web/api/reiseloesung/orte/nearby",
"tripEndpoint": "https://int.bahn.de/web/api/reiseloesung/fahrt",
"regioGuideTripEndpoint": "https://regio-guide.de/@prd/zupo-travel-information/api/public/ri/journey/",
"boardEndpoint": "https://regio-guide.de/@prd/zupo-travel-information/api/public/ri/board/",
"boardEndpoint": "https://int.bahn.de/web/api/reiseloesung/",
"defaultLanguage": "en"
}

View file

@ -7,6 +7,7 @@ import {formatJourneysReq, formatRefreshJourneyReq} from './journeys-req.js';
import {formatTripReq} from './trip-req.js';
import {formatLocationFilter} from './location-filter.js';
import {formatLocationsReq} from './locations-req.js';
import {formatStationBoardReq} from './station-board-req.js';
const profile = {
...baseProfile,
@ -19,6 +20,7 @@ const profile = {
formatTripReq,
formatLocationsReq,
formatLocationFilter,
formatStationBoardReq,
};
export {

23
p/db/station-board-req.js Normal file
View file

@ -0,0 +1,23 @@
const formatStationBoardReq = (ctx, station, type) => {
const {profile, opt} = ctx;
const maxVias = opt.vias ?? 0;
return {
endpoint: profile.boardEndpoint,
path: type === 'departures' ? 'abfahrten' : 'ankuenfte',
query: {
ortExtId: station,
zeit: profile.formatTimeOfDay(profile, opt.when),
datum: profile.formatDate(profile, opt.when),
mitVias: maxVias !== 0 ? true : undefined,
maxVias,
verkehrsmittel: profile.formatProductsFilter(ctx, opt.products || {}),
},
method: 'GET',
};
};
export {
formatStationBoardReq,
};

View file

@ -10,22 +10,23 @@ const createParseArrOrDep = (prefix) => {
const {profile, opt} = ctx;
const cancelled = profile.parseCancelled(d);
const res = {
tripId: d.journeyID || d.train?.journeyId || d.zuglaufId,
stop: profile.parseLocation(ctx, d.station || d.abfrageOrt),
tripId: d.journeyID || d.journeyId || d.train?.journeyId || d.zuglaufId,
stop: profile.parseLocation(ctx, d.station || d.abfrageOrt || d.bahnhofsId),
...profile.parseWhen(
ctx,
null,
d.timeSchedule || d.time || d.abgangsDatum || d.ankunftsDatum,
d.timeType != 'SCHEDULE' ? d.timePredicted || d.time || d.ezAbgangsDatum || d.ezAnkunftsDatum : null,
d.timeSchedule || d.time || d.zeit || d.abgangsDatum || d.ankunftsDatum,
d.timeType != 'SCHEDULE' ? d.timePredicted || d.time || d.ezZeit || d.ezAbgangsDatum || d.ezAnkunftsDatum : null,
cancelled),
...profile.parsePlatform(ctx, d.platformSchedule || d.platform || d.gleis, d.platformPredicted || d.platform || d.ezGleis, cancelled),
...profile.parsePlatform(ctx, d.platformSchedule || d.gleis || d.platform || d.ezGleis, d.platformPredicted || d.platform || d.ezGleis, cancelled),
// prognosisType: TODO
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,
direction: d.transport?.direction?.stopPlaces?.length > 0 && profile.parseStationName(ctx, d.transport?.direction?.stopPlaces[0].name) || profile.parseStationName(ctx, d.destination?.name || d.richtung || d.terminus) || null,
provenance: profile.parseStationName(ctx, d.transport?.origin?.name || d.origin?.name || d.abgangsOrt?.name) || null,
line: profile.parseLine(ctx, d) || null,
remarks: [],
remarks: profile.parseRemarks(ctx, d),
origin: profile.parseLocation(ctx, d.transport?.origin || d.origin) || null,
destination: profile.parseLocation(ctx, d.transport?.destination || d.destination) || null,
vias: d.ueber,
// loadFactor: profile.parseArrOrDepWithLoadFactor(ctx, d)
};

View file

@ -2,12 +2,12 @@ import slugg from 'slugg';
const parseLine = (ctx, p) => {
const profile = ctx.profile;
const fahrtNr = p.verkehrsmittel?.nummer || p.transport?.number || p.train?.no || p.no || ((p.risZuglaufId || '') + '_').split('_')[1] || p.verkehrsmittelNummer || ((p.mitteltext || '') + ' ').split(' ')[1] || ((p.zugName || '') + ' ').split(' ')[1];
const fahrtNr = p.verkehrsmittel?.nummer || p.transport?.number || p.train?.no || p.no || ((p.risZuglaufId || '') + '_').split('_')[1] || p.verkehrsmittelNummer || ((p.verkehrmittel.langText || '') + ' ').split(' ')[1] || ((p.mitteltext || '') + ' ').split(' ')[1] || ((p.zugName || '') + ' ').split(' ')[1];
const res = {
type: 'line',
id: slugg(p.verkehrsmittel?.langText || p.transport?.journeyDescription || p.risZuglaufId || p.train && p.train.category + ' ' + p.train.lineName + ' ' + p.train.no || p.no && p.name + ' ' + p.no || p.langtext || p.mitteltext || p.zugName), // TODO terrible
id: slugg(p.verkehrsmittel?.langText || p.verkehrmittel?.langText || p.transport?.journeyDescription || p.risZuglaufId || p.train && p.train.category + ' ' + p.train.lineName + ' ' + p.train.no || p.no && p.name + ' ' + p.no || p.langtext || p.mitteltext || p.zugName), // TODO terrible
fahrtNr: String(fahrtNr),
name: p.verkehrsmittel?.langText || p.verkehrsmittel?.name || p.zugName || p.transport && p.transport.category + ' ' + p.transport.line || p.train && p.train.category + ' ' + p.train.lineName || p.name || p.mitteltext || p.langtext,
name: p.verkehrsmittel?.langText || p.verkehrsmittel?.name || p.verkehrmittel?.name || p.verkehrmittel?.langText || p.zugName || p.transport && p.transport.category + ' ' + p.transport.line || p.train && p.train.category + ' ' + p.train.lineName || p.name || p.mitteltext || p.langtext,
public: true,
};
@ -15,7 +15,7 @@ const parseLine = (ctx, p) => {
if (adminCode) {
res.adminCode = adminCode;
}
res.productName = p.verkehrsmittel?.kurzText || p.transport?.category || p.train?.category || p.category || p.kurztext;
res.productName = p.verkehrsmittel?.kurzText || p.verkehrmittel?.kurzText || p.transport?.category || p.train?.category || p.category || p.kurztext;
const foundProduct = profile.products.find(pp => pp.vendo == p.verkehrsmittel?.produktGattung || pp.ris == p.transport?.type || pp.ris == p.train?.type || pp.ris == p.type || pp.ris_alt == p.train?.type || pp.ris_alt == p.type || pp.dbnav_short == p.produktGattung);
res.mode = foundProduct?.mode;
res.product = foundProduct?.id;

View file

@ -13,6 +13,10 @@ const parseLocation = (ctx, l) => {
return null;
}
if (typeof l === 'string') {
return {type: 'station', id: l};
}
const lid = parse(l.id || l.locationId, {delimiter: '@'});
const res = {
type: 'location',

View file

@ -13,6 +13,7 @@ const parseRemarks = (ctx, ref) => {
ref.hims || [],
ref.serviceNotiz && [ref.serviceNotiz] || [],
ref.messages || [],
ref.meldungen || [],
ref.meldungenAsObject || [],
ref.attributNotizen || [],
ref.attributes || [],
@ -202,11 +203,16 @@ const parseRemarks = (ctx, ref) => {
*/
const parseCancelled = (ref) => {
return ref.canceled || ref.cancelled || ref.journeyCancelled || (ref.risNotizen || ref.echtzeitNotizen) && Boolean((ref.risNotizen || ref.echtzeitNotizen).find(r => r.key == 'text.realtime.stop.cancelled'
return ref.canceled
|| ref.cancelled
|| ref.journeyCancelled
|| (ref.risNotizen || ref.echtzeitNotizen || ref.meldungen) && Boolean(
(ref.risNotizen || ref.echtzeitNotizen || ref.meldungen).find(r => r.key == 'text.realtime.stop.cancelled'
|| r.type == 'HALT_AUSFALL'
|| r.text == 'Halt entfällt'
|| r.text == 'Stop cancelled',
));
),
);
};
export {