/locations, /locations/nearby, fixes

This commit is contained in:
Traines 2024-12-07 18:29:16 +00:00
parent 2e094c2b78
commit 2f45f66793
7 changed files with 47 additions and 67 deletions

View file

@ -1,12 +1,8 @@
const formatLocationFilter = (stops, addresses, poi) => {
if (stops && addresses && poi) {
return 'ALL';
if (!addresses && !poi) { // TODO other combos?
return 'HALTESTELLEN';
}
return (
(stops ? 'S' : '')
+ (addresses ? 'A' : '')
+ (poi ? 'P' : '')
);
return 'ALL';
};
export {

View file

@ -1,19 +1,10 @@
const formatLocationsReq = (ctx, query) => {
const {profile, opt} = ctx;
return {
cfg: {polyEnc: 'GPA'},
meth: 'LocMatch',
req: {input: {
loc: {
type: profile.formatLocationFilter(opt.stops, opt.addresses, opt.poi),
name: opt.fuzzy
? query + '?'
: query,
},
maxLoc: opt.results,
field: 'S', // todo: what is this?
}},
return {
typ: profile.formatLocationFilter(opt.stops, opt.addresses, opt.poi),
suchbegriff: query,
limit: opt.results,
};
};

View file

@ -2,24 +2,13 @@ const formatNearbyReq = (ctx, location) => {
const {profile, opt} = ctx;
return {
cfg: {polyEnc: 'GPA'},
meth: 'LocGeoPos',
req: {
ring: {
cCrd: {
x: profile.formatCoord(location.longitude),
y: profile.formatCoord(location.latitude),
},
maxDist: opt.distance || -1,
minDist: 0,
},
locFltrL: [
profile.formatProductsFilter(ctx, opt.products || {}),
],
getPOIs: Boolean(opt.poi),
getStops: Boolean(opt.stops),
maxLoc: opt.results,
},
long: location.longitude,
lat: location.latitude,
radius: opt.distance || undefined,
products: profile.formatProductsFilter(ctx, opt.products || {}),
// TODO getPOIs: Boolean(opt.poi),
// TODO getStops: Boolean(opt.stops),
maxNo: opt.results,
};
};

View file

@ -146,7 +146,7 @@ const createClient = (profile, userAgent, opt = {}) => {
results: null, // number of journeys `null` means "whatever HAFAS returns"
via: null, // let journeys pass this station?
stopovers: false, // return stations on the way?
transfers: -1, // maximum nr of transfers
transfers: null, // maximum nr of transfers
transferTime: 0, // minimum time for a single transfer in minutes
// todo: does this work with every endpoint?
accessibility: 'none', // 'none', 'partial' or 'complete'
@ -189,17 +189,17 @@ const createClient = (profile, userAgent, opt = {}) => {
// TODO opt.accessibility
const query = {
//maxUmstiege: opt.transfers,
//minUmstiegszeit: opt.transferTime,
maxUmstiege: opt.transfers,
minUmstiegszeit: opt.transferTime,
deutschlandTicketVorhanden: false,
nurDeutschlandTicketVerbindungen: false,
reservierungsKontingenteVorhanden: false,
schnelleVerbindungen: true,
sitzplatzOnly: false,
abfahrtsHalt: from.lid,
/*zwischenhalte: opt.via
zwischenhalte: opt.via
? [{id: opt.via}]
: [],*/
: null,
ankunftsHalt: to.lid,
produktgattungen: filters,
bikeCarriage: opt.bike,
@ -208,11 +208,11 @@ const createClient = (profile, userAgent, opt = {}) => {
// see rest.exe docs
//ushrp: Boolean(opt.startWithWalking),
};
/*if (journeysRef) { TODO
query.ctxScr = journeysRef;
} else {*/
if (journeysRef) { TODO
query.pagingReference = journeysRef;
} else {
query.anfrageZeitpunkt = profile.formatTime(profile, when);
//}
}
query.ankunftSuche = outFrwd ? 'ABFAHRT' : 'ANKUNFT';
if (opt.results !== null) {
// TODO query.numF = opt.results;
@ -220,7 +220,8 @@ const createClient = (profile, userAgent, opt = {}) => {
const {res, common} = await profile.request({profile, opt}, userAgent, {
endpoint: profile.journeysEndpoint,
req: profile.transformJourneysQuery({profile, opt}, query),
body: profile.transformJourneysQuery({profile, opt}, query),
method: 'post'
});
const ctx = {profile, opt, common, res};
const journeys = res.verbindungen
@ -425,16 +426,17 @@ const createClient = (profile, userAgent, opt = {}) => {
entrances: true, // parse & expose entrances of stops/stations?
linesOfStops: false, // parse & expose lines at each stop/station?
}, opt);
const req = profile.formatLocationsReq({profile, opt}, query);
const {res, common} = await profile.request({profile, opt}, userAgent, req);
if (!res.match || !Array.isArray(res.match.locL)) {
return [];
}
const {res, common} = await profile.request({profile, opt}, userAgent, {
endpoint: profile.locationsEndpoint,
query: req,
method: 'get'
});
const ctx = {profile, opt, common, res};
return res.match.locL.map(loc => profile.parseLocation(ctx, loc));
return res.map(loc => profile.parseLocation(ctx, loc));
};
const stop = async (stop, opt = {}) => {
@ -481,15 +483,14 @@ const createClient = (profile, userAgent, opt = {}) => {
}, opt);
const req = profile.formatNearbyReq({profile, opt}, location);
const {res, common} = await profile.request({profile, opt}, userAgent, {
endpoint: profile.nearbyEndpoint,
query: req,
method: 'get'
});
const {res, common} = await profile.request({profile, opt}, userAgent, req);
if (!Array.isArray(res.locL)) {
return [];
}
// todo: parse `.dur` walking duration?
const ctx = {profile, opt, common, res};
const results = res.locL.map(loc => profile.parseNearby(ctx, loc));
const results = res.map(loc => profile.parseLocation(ctx, loc));
return Number.isInteger(opt.results)
? results.slice(0, opt.results)
: results;

View file

@ -7,6 +7,7 @@ import {formatTripReq} from '../format/trip-req.js';
import {formatRefreshJourneyReq} from '../format/refresh-journey-req.js';
import {formatRemarksReq} from '../format/remarks-req.js';
import {formatLinesReq} from '../format/lines-req.js';
import {formatNearbyReq} from '../format/nearby-req.js';
import {parseDateTime} from '../parse/date-time.js';
import {parsePlatform} from '../parse/platform.js';
@ -64,6 +65,7 @@ const defaultProfile = {
formatRefreshJourneyReq,
formatRemarksReq,
formatLinesReq,
formatNearbyReq,
transformJourneysQuery: id,
parseDateTime,

View file

@ -101,13 +101,13 @@ const request = async (ctx, userAgent, reqData) => {
const endpoint = reqData.endpoint;
delete reqData.endpoint;
const rawReqBody = profile.transformReqBody(ctx, reqData);
const rawReqBody = profile.transformReqBody(ctx, reqData.body);
//console.log(rawReqBody, JSON.stringify(rawReqBody.req.reisende));
const req = profile.transformReq(ctx, {
agent: getAgent(),
method: 'post',
method: reqData.method,
// todo: CORS? referrer policy?
body: JSON.stringify(rawReqBody.req),
body: JSON.stringify(rawReqBody),
headers: {
'Content-Type': 'application/json',
'Accept-Encoding': 'gzip, br, deflate',
@ -118,11 +118,10 @@ const request = async (ctx, userAgent, reqData) => {
'connection': 'keep-alive', // prevent excessive re-connecting
},
redirect: 'follow',
query: {},
query: reqData.query,
});
const url = endpoint + '?' + stringify(req.query);
const url = endpoint + '?' + stringify(req.query, {arrayFormat: 'brackets', encodeValuesOnly: true});
const reqId = randomBytes(3)
.toString('hex');
const fetchReq = new Request(url, req);

View file

@ -1,4 +1,6 @@
{
"journeysEndpoint": "https://int.bahn.de/web/api/angebote/fahrplan",
"locationsEndpoint": "https://int.bahn.de/web/api/reiseloesung/orte",
"nearbyEndpoint": "https://int.bahn.de/web/api/reiseloesung/orte/nearby",
"defaultLanguage": "en"
}