From 0a9b81eeb74429c955e68a985064abe42d9d6cf8 Mon Sep 17 00:00:00 2001 From: marudor Date: Wed, 22 Dec 2021 10:55:16 +0100 Subject: [PATCH] fix: hopefully no more crashes, also removed reihung v2 api (#552) --- .../controller/Reihung/__tests__/v2.test.ts | 63 -- .../server/API/controller/Reihung/monitor.ts | 8 +- packages/server/API/controller/Reihung/v2.ts | 29 - packages/server/API/routes.ts | 217 +----- packages/server/Reihung/OEBBToDB.ts | 239 ------- packages/server/Reihung/getBR.ts | 17 - packages/server/Reihung/identifierNameMap.ts | 34 - packages/server/Reihung/index.ts | 491 -------------- packages/server/coachSequence/monitoring.ts | 48 ++ packages/server/plausible.ts | 52 +- public/swagger.json | 636 ++---------------- 11 files changed, 159 insertions(+), 1675 deletions(-) delete mode 100644 packages/server/API/controller/Reihung/__tests__/v2.test.ts delete mode 100644 packages/server/API/controller/Reihung/v2.ts delete mode 100644 packages/server/Reihung/OEBBToDB.ts delete mode 100644 packages/server/Reihung/getBR.ts delete mode 100644 packages/server/Reihung/identifierNameMap.ts delete mode 100644 packages/server/Reihung/index.ts create mode 100644 packages/server/coachSequence/monitoring.ts diff --git a/packages/server/API/controller/Reihung/__tests__/v2.test.ts b/packages/server/API/controller/Reihung/__tests__/v2.test.ts deleted file mode 100644 index 983d0dc55..000000000 --- a/packages/server/API/controller/Reihung/__tests__/v2.test.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { createTestServer } from 'server/testHelper'; -import { promises as fs } from 'fs'; -import Nock from 'nock'; -import path from 'path'; -import request from 'supertest'; -import type { Formation } from 'types/reihung'; - -describe('Reihung V2', () => { - const nock = Nock('https://ist-wr.noncd.db.de'); - const loadFixture = (fileName: string) => - fs.readFile(path.resolve(__dirname, '__fixtures__/', fileName), 'utf8'); - const server = createTestServer(); - - it('Get ICE1 Reihung', async () => { - nock - .get('/wagenreihung/1.0/373/201911221650') - .reply(200, await loadFixture('ICE1.json')); - - return request(server) - .get('/api/reihung/v2/wagen/373/2019-11-22T15:50:00.000Z') - .expect(({ status, body }: { status: number; body: Formation }) => { - expect(status).toBe(200); - expect(body.allFahrzeuggruppe).toHaveLength(1); - const fahrzeuge = body.allFahrzeuggruppe[0].allFahrzeug; - - expect(fahrzeuge).toHaveLength(14); - const W11 = fahrzeuge.find((f) => f.wagenordnungsnummer === '11'); - const W9 = fahrzeuge.find((f) => f.wagenordnungsnummer === '9'); - const W7 = fahrzeuge.find((f) => f.wagenordnungsnummer === '7'); - - if (!W11 || !W9 || !W7) throw new Error('Missing Waggon'); - - expect(W11.kategorie).toBe('REISEZUGWAGENERSTEKLASSE'); - expect(W11.fahrzeugtyp).toBe('Avmz'); - expect(W11.additionalInfo).toEqual({ - klasse: 1, - icons: {}, - comfort: true, - comfortSeats: expect.stringContaining(''), - }); - expect(W9.kategorie).toBe('REISEZUGWAGENERSTEKLASSE'); - expect(W9.additionalInfo).toEqual({ - klasse: 1, - icons: { - info: true, - toddler: true, - wheelchair: true, - disabled: true, - }, - disabledSeats: expect.stringContaining(''), - }); - expect(W7.additionalInfo).toEqual({ - klasse: 2, - icons: { - disabled: true, - }, - comfort: true, - disabledSeats: expect.stringContaining(''), - comfortSeats: expect.stringContaining(''), - }); - }); - }); -}); diff --git a/packages/server/API/controller/Reihung/monitor.ts b/packages/server/API/controller/Reihung/monitor.ts index e425468fa..f791351f6 100644 --- a/packages/server/API/controller/Reihung/monitor.ts +++ b/packages/server/API/controller/Reihung/monitor.ts @@ -1,6 +1,6 @@ +import { coachSequenceMonitoring } from 'server/coachSequence/monitoring'; import { Controller, Get, Hidden, Res, Route } from 'tsoa'; -import { wagenReihungMonitoring } from 'server/Reihung'; -import type { Formation } from 'types/reihung'; +import type { CoachSequenceInformation } from 'types/coachSequence'; import type { TsoaResponse } from 'tsoa'; @Route('/reihung/monitoring') @@ -9,8 +9,8 @@ export class ReihungMonitoringController extends Controller { @Hidden() async monitoring( @Res() notFoundResponse: TsoaResponse<404, void>, - ): Promise { - const reihung = await wagenReihungMonitoring(); + ): Promise { + const reihung = await coachSequenceMonitoring(); if (!reihung) { return notFoundResponse(404); diff --git a/packages/server/API/controller/Reihung/v2.ts b/packages/server/API/controller/Reihung/v2.ts deleted file mode 100644 index 2febaca35..000000000 --- a/packages/server/API/controller/Reihung/v2.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { - Controller, - Deprecated, - Get, - OperationId, - Request, - Route, - Tags, -} from 'tsoa'; -import { deprecatedAPIUsage } from 'server/plausible'; -import { wagenreihung } from 'server/Reihung'; -import type { Formation } from 'types/reihung'; -import type { Request as KRequest } from 'koa'; - -@Route('/reihung/v2') -export class ReihungControllerV2 extends Controller { - @Get('/wagen/{trainNumber}/{date}') - @Tags('Reihung') - @OperationId('Wagenreihung v2') - @Deprecated() - async wagenreihung( - @Request() req: KRequest, - trainNumber: string, - date: Date, - ): Promise { - deprecatedAPIUsage(req, 'wagenreihung v2'); - return wagenreihung(trainNumber, date); - } -} diff --git a/packages/server/API/routes.ts b/packages/server/API/routes.ts index a3344b43a..c5e10f0ea 100644 --- a/packages/server/API/routes.ts +++ b/packages/server/API/routes.ts @@ -21,8 +21,6 @@ import { ReihungMonitoringController } from './controller/Reihung/monitor'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa import { ReihungControllerV1 } from './controller/Reihung/v1'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa -import { ReihungControllerV2 } from './controller/Reihung/v2'; -// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa import { ReihungControllerV4 } from './controller/Reihung/v4'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa import { StopPlaceController } from './controller/StopPlace/v1'; @@ -1555,183 +1553,6 @@ const models: TsoaRoute.Models = { "type": {"ref":"OEBBInfo","validators":{}}, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "AdditionalFahrzeugInfo": { - "dataType": "refObject", - "properties": { - "klasse": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":[0]},{"dataType":"enum","enums":[1]},{"dataType":"enum","enums":[2]},{"dataType":"enum","enums":[3]},{"dataType":"enum","enums":[4]}],"required":true}, - "icons": {"dataType":"nestedObjectLiteral","nestedProperties":{"wifi":{"dataType":"boolean"},"toddler":{"dataType":"boolean"},"family":{"dataType":"boolean"},"info":{"dataType":"boolean"},"quiet":{"dataType":"boolean"},"disabled":{"dataType":"boolean"},"bike":{"dataType":"boolean"},"wheelchair":{"dataType":"boolean"},"dining":{"dataType":"boolean"}},"required":true}, - "comfort": {"dataType":"boolean"}, - "comfortSeats": {"dataType":"string"}, - "disabledSeats": {"dataType":"string"}, - "familySeats": {"dataType":"string"}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "Fahrzeugausstattung": { - "dataType": "refObject", - "properties": { - "anzahl": {"dataType":"string","required":true}, - "ausstattungsart": {"dataType":"string","required":true}, - "bezeichnung": {"dataType":"string","required":true}, - "status": {"dataType":"string","required":true}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "FahrzeugKategorie": { - "dataType": "refAlias", - "type": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["DOPPELSTOCKSTEUERWAGENERSTEZWEITEKLASSE"]},{"dataType":"enum","enums":["DOPPELSTOCKSTEUERWAGENZWEITEKLASSE"]},{"dataType":"enum","enums":["DOPPELSTOCKWAGENERSTEKLASSE"]},{"dataType":"enum","enums":["DOPPELSTOCKWAGENERSTEZWEITEKLASSE"]},{"dataType":"enum","enums":["DOPPELSTOCKWAGENZWEITEKLASSE"]},{"dataType":"enum","enums":["HALBSPEISEWAGENERSTEKLASSE"]},{"dataType":"enum","enums":["HALBSPEISEWAGENZWEITEKLASSE"]},{"dataType":"enum","enums":["LOK"]},{"dataType":"enum","enums":["REISEZUGWAGENERSTEKLASSE"]},{"dataType":"enum","enums":["REISEZUGWAGENERSTEZWEITEKLASSE"]},{"dataType":"enum","enums":["REISEZUGWAGENZWEITEKLASSE"]},{"dataType":"enum","enums":["SPEISEWAGEN"]},{"dataType":"enum","enums":["STEUERWAGENERSTEKLASSE"]},{"dataType":"enum","enums":["STEUERWAGENERSTEZWEITEKLASSE"]},{"dataType":"enum","enums":["STEUERWAGENZWEITEKLASSE"]},{"dataType":"enum","enums":["TRIEBKOPF"]},{"dataType":"enum","enums":[""]}],"validators":{}}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "Position": { - "dataType": "refObject", - "properties": { - "endemeter": {"dataType":"string","required":true}, - "endeprozent": {"dataType":"string","required":true}, - "startmeter": {"dataType":"string","required":true}, - "startprozent": {"dataType":"string","required":true}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "Fahrzeug": { - "dataType": "refObject", - "properties": { - "allFahrzeugausstattung": {"dataType":"array","array":{"dataType":"refObject","ref":"Fahrzeugausstattung"},"required":true}, - "kategorie": {"ref":"FahrzeugKategorie","required":true}, - "fahrzeugnummer": {"dataType":"string","required":true}, - "orientierung": {"dataType":"string","required":true}, - "positioningruppe": {"dataType":"string","required":true}, - "fahrzeugsektor": {"dataType":"string","required":true}, - "fahrzeugtyp": {"dataType":"string","required":true}, - "wagenordnungsnummer": {"dataType":"string","required":true}, - "positionamhalt": {"ref":"Position","required":true}, - "status": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["GESCHLOSSEN"]},{"dataType":"string"}],"required":true}, - "additionalInfo": {"ref":"AdditionalFahrzeugInfo","required":true}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "AvailableBR": { - "dataType": "refAlias", - "type": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["401"]},{"dataType":"enum","enums":["402"]},{"dataType":"enum","enums":["403"]},{"dataType":"enum","enums":["406"]},{"dataType":"enum","enums":["407"]},{"dataType":"enum","enums":["410.1"]},{"dataType":"enum","enums":["411"]},{"dataType":"enum","enums":["412"]},{"dataType":"enum","enums":["415"]}],"validators":{}}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "AvailableIdentifier": { - "dataType": "refAlias", - "type": {"dataType":"union","subSchemas":[{"ref":"AvailableBR"},{"dataType":"enum","enums":["401.LDV"]},{"dataType":"enum","enums":["401.9"]},{"dataType":"enum","enums":["411.S1"]},{"dataType":"enum","enums":["411.S2"]},{"dataType":"enum","enums":["412.7"]},{"dataType":"enum","enums":["412.13"]},{"dataType":"enum","enums":["403.R"]},{"dataType":"enum","enums":["403.S1"]},{"dataType":"enum","enums":["403.S2"]},{"dataType":"enum","enums":["406.R"]},{"dataType":"enum","enums":["IC2.TWIN"]},{"dataType":"enum","enums":["IC2.KISS"]},{"dataType":"enum","enums":["MET"]},{"dataType":"enum","enums":["TGV"]}],"validators":{}}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "BRInfo": { - "dataType": "refObject", - "properties": { - "name": {"dataType":"string","required":true}, - "BR": {"ref":"AvailableBR"}, - "identifier": {"ref":"AvailableIdentifier"}, - "noPdf": {"dataType":"boolean"}, - "country": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["DE"]},{"dataType":"enum","enums":["AT"]}]}, - "showBRInfo": {"dataType":"boolean"}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "BaseFahrzeug": { - "dataType": "refObject", - "properties": { - "allFahrzeugausstattung": {"dataType":"array","array":{"dataType":"refObject","ref":"Fahrzeugausstattung"},"required":true}, - "kategorie": {"ref":"FahrzeugKategorie","required":true}, - "fahrzeugnummer": {"dataType":"string","required":true}, - "orientierung": {"dataType":"string","required":true}, - "positioningruppe": {"dataType":"string","required":true}, - "fahrzeugsektor": {"dataType":"string","required":true}, - "fahrzeugtyp": {"dataType":"string","required":true}, - "wagenordnungsnummer": {"dataType":"string","required":true}, - "positionamhalt": {"ref":"Position","required":true}, - "status": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["GESCHLOSSEN"]},{"dataType":"string"}],"required":true}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "Fahrzeuggruppe": { - "dataType": "refObject", - "properties": { - "allFahrzeug": {"dataType":"array","array":{"dataType":"refObject","ref":"Fahrzeug"},"required":true}, - "fahrzeuggruppebezeichnung": {"dataType":"string","required":true}, - "zielbetriebsstellename": {"dataType":"string","required":true}, - "startbetriebsstellename": {"dataType":"string","required":true}, - "verkehrlichezugnummer": {"dataType":"string","required":true}, - "goesToFrance": {"dataType":"boolean","required":true}, - "startPercentage": {"dataType":"double","required":true}, - "endPercentage": {"dataType":"double","required":true}, - "tzn": {"dataType":"string"}, - "name": {"dataType":"string"}, - "br": {"ref":"BRInfo"}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "BaseFahrzeuggruppe": { - "dataType": "refObject", - "properties": { - "allFahrzeug": {"dataType":"array","array":{"dataType":"refObject","ref":"BaseFahrzeug"},"required":true}, - "fahrzeuggruppebezeichnung": {"dataType":"string","required":true}, - "zielbetriebsstellename": {"dataType":"string","required":true}, - "startbetriebsstellename": {"dataType":"string","required":true}, - "verkehrlichezugnummer": {"dataType":"string","required":true}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "Sektor": { - "dataType": "refObject", - "properties": { - "positionamgleis": {"ref":"Position","required":true}, - "sektorbezeichnung": {"dataType":"string","required":true}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "Halt": { - "dataType": "refObject", - "properties": { - "abfahrtszeit": {"dataType":"string"}, - "ankunftszeit": {"dataType":"string"}, - "bahnhofsname": {"dataType":"string","required":true}, - "evanummer": {"dataType":"string","required":true}, - "gleisbezeichnung": {"dataType":"string"}, - "haltid": {"dataType":"string","required":true}, - "rl100": {"dataType":"string","required":true}, - "allSektor": {"dataType":"array","array":{"dataType":"refObject","ref":"Sektor"},"required":true}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "Formation": { - "dataType": "refObject", - "properties": { - "fahrtrichtung": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["VORWAERTS"]},{"dataType":"enum","enums":["RUCKWAERTS"]}],"required":true}, - "allFahrzeuggruppe": {"dataType":"array","array":{"dataType":"refObject","ref":"Fahrzeuggruppe"},"required":true}, - "halt": {"ref":"Halt","required":true}, - "liniebezeichnung": {"dataType":"string","required":true}, - "zuggattung": {"dataType":"string","required":true}, - "zugnummer": {"dataType":"string","required":true}, - "serviceid": {"dataType":"string","required":true}, - "planstarttag": {"dataType":"string","required":true}, - "fahrtid": {"dataType":"string","required":true}, - "istplaninformation": {"dataType":"boolean","required":true}, - "reportedZuggattung": {"dataType":"string","required":true}, - "differentDestination": {"dataType":"boolean"}, - "differentZugnummer": {"dataType":"boolean"}, - "scale": {"dataType":"double","required":true}, - "startPercentage": {"dataType":"double","required":true}, - "endPercentage": {"dataType":"double","required":true}, - "realFahrtrichtung": {"dataType":"boolean"}, - "isRealtime": {"dataType":"boolean","required":true}, - }, - "additionalProperties": false, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "CoachSequencePosition": { "dataType": "refObject", "properties": { @@ -1768,6 +1589,11 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "FahrzeugKategorie": { + "dataType": "refAlias", + "type": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["DOPPELSTOCKSTEUERWAGENERSTEZWEITEKLASSE"]},{"dataType":"enum","enums":["DOPPELSTOCKSTEUERWAGENZWEITEKLASSE"]},{"dataType":"enum","enums":["DOPPELSTOCKWAGENERSTEKLASSE"]},{"dataType":"enum","enums":["DOPPELSTOCKWAGENERSTEZWEITEKLASSE"]},{"dataType":"enum","enums":["DOPPELSTOCKWAGENZWEITEKLASSE"]},{"dataType":"enum","enums":["HALBSPEISEWAGENERSTEKLASSE"]},{"dataType":"enum","enums":["HALBSPEISEWAGENZWEITEKLASSE"]},{"dataType":"enum","enums":["LOK"]},{"dataType":"enum","enums":["REISEZUGWAGENERSTEKLASSE"]},{"dataType":"enum","enums":["REISEZUGWAGENERSTEZWEITEKLASSE"]},{"dataType":"enum","enums":["REISEZUGWAGENZWEITEKLASSE"]},{"dataType":"enum","enums":["SPEISEWAGEN"]},{"dataType":"enum","enums":["STEUERWAGENERSTEKLASSE"]},{"dataType":"enum","enums":["STEUERWAGENERSTEZWEITEKLASSE"]},{"dataType":"enum","enums":["STEUERWAGENZWEITEKLASSE"]},{"dataType":"enum","enums":["TRIEBKOPF"]},{"dataType":"enum","enums":[""]}],"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "CoachSequenceCoachFeatures": { "dataType": "refObject", "properties": { @@ -1811,6 +1637,16 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AvailableBR": { + "dataType": "refAlias", + "type": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["401"]},{"dataType":"enum","enums":["402"]},{"dataType":"enum","enums":["403"]},{"dataType":"enum","enums":["406"]},{"dataType":"enum","enums":["407"]},{"dataType":"enum","enums":["410.1"]},{"dataType":"enum","enums":["411"]},{"dataType":"enum","enums":["412"]},{"dataType":"enum","enums":["415"]}],"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AvailableIdentifier": { + "dataType": "refAlias", + "type": {"dataType":"union","subSchemas":[{"ref":"AvailableBR"},{"dataType":"enum","enums":["401.LDV"]},{"dataType":"enum","enums":["401.9"]},{"dataType":"enum","enums":["411.S1"]},{"dataType":"enum","enums":["411.S2"]},{"dataType":"enum","enums":["412.7"]},{"dataType":"enum","enums":["412.13"]},{"dataType":"enum","enums":["403.R"]},{"dataType":"enum","enums":["403.S1"]},{"dataType":"enum","enums":["403.S2"]},{"dataType":"enum","enums":["406.R"]},{"dataType":"enum","enums":["IC2.TWIN"]},{"dataType":"enum","enums":["IC2.KISS"]},{"dataType":"enum","enums":["MET"]},{"dataType":"enum","enums":["TGV"]}],"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "CoachSequenceBaureihe": { "dataType": "refObject", "properties": { @@ -2694,29 +2530,6 @@ export function RegisterRoutes(router: KoaRouter) { return promiseHandler(controller, promise, context, undefined, next); }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - router.get('/api/reihung/v2/wagen/:trainNumber/:date', - async function ReihungControllerV2_wagenreihung(context: any, next: any) { - const args = { - req: {"in":"request","name":"req","required":true,"dataType":"object"}, - trainNumber: {"in":"path","name":"trainNumber","required":true,"dataType":"string"}, - date: {"in":"path","name":"date","required":true,"dataType":"datetime"}, - }; - - let validatedArgs: any[] = []; - try { - validatedArgs = getValidatedArgs(args, context, next); - } catch (err) { - const error = err as any; - context.status = error.status; - context.throw(error.status, JSON.stringify({ fields: error.fields })); - } - - const controller = new ReihungControllerV2(); - - const promise = controller.wagenreihung.apply(controller, validatedArgs as any); - return promiseHandler(controller, promise, context, undefined, next); - }); - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa router.get('/api/reihung/v4/wagen/:trainNumber', async function ReihungControllerV4_wagenreihung(context: any, next: any) { const args = { diff --git a/packages/server/Reihung/OEBBToDB.ts b/packages/server/Reihung/OEBBToDB.ts deleted file mode 100644 index 56310849a..000000000 --- a/packages/server/Reihung/OEBBToDB.ts +++ /dev/null @@ -1,239 +0,0 @@ -import { addBRtoGruppe, calculateComfort } from 'server/Reihung'; -import { addDays, addHours, addMinutes, parseISO } from 'date-fns'; -import type { - Fahrzeug, - Fahrzeuggruppe, - Formation, - Position, - Sektor, -} from 'types/reihung'; -import type { - OEBBCoachSequenceWagon, - OEBBInfo, - OEBBPlatformInfo, - OEBBTimeFormat, -} from 'oebb/types/coachSequence'; - -function parseOEBBTime(dateString: string, time: OEBBTimeFormat) { - let date = parseISO(dateString); - date = addDays(date, time.days); - date = addHours(date, time.hours); - date = addMinutes(date, time.days); - return date; -} - -function getSectors(platformInfo?: OEBBPlatformInfo): Sektor[] { - if (!platformInfo) return []; - const sectors: Sektor[] = []; - let startmeter = 0; - const maxMeter = platformInfo.length; - - platformInfo.sectors.forEach((s) => { - sectors.push({ - sektorbezeichnung: s.name, - positionamgleis: { - startmeter: startmeter.toString(), - startprozent: ((startmeter / maxMeter) * 100).toString(), - endemeter: (startmeter + s.length).toString(), - endeprozent: (((startmeter + s.length) / maxMeter) * 100).toString(), - }, - }); - startmeter += s.length; - }); - - return sectors; -} - -function getFahrzeuggruppen(info: OEBBInfo): Fahrzeuggruppe[] { - if (!info.train) return []; - let currentWagons: OEBBCoachSequenceWagon[] = []; - const wagonsForGroups: OEBBCoachSequenceWagon[][] = []; - let oldDestination: string | undefined = undefined; - info.train.wagons.forEach((w) => { - if (oldDestination && oldDestination !== w.destination) { - wagonsForGroups.push(currentWagons); - currentWagons = []; - } - currentWagons.push(w); - oldDestination = w.destination; - }); - wagonsForGroups.push(currentWagons); - - let startOffset = info.trainOnPlatform?.position || 0; - const maxMeter = - info.platform?.length || - info.train.wagons.reduce((sum, w) => sum + w.lengthOverBuffers, 0); - - return wagonsForGroups.map((wagons) => { - const fahrzeuge: Fahrzeug[] = []; - const positions: Position[] = []; - - for (const w of wagons) { - const endemeter = startOffset + w.lengthOverBuffers; - const startprozent = (startOffset / maxMeter) * 100; - const endeprozent = (endemeter / maxMeter) * 100; - const position: Position = { - startmeter: String(startOffset), - endemeter: String(endemeter), - startprozent: String(startprozent), - endeprozent: String(endeprozent), - }; - positions.push(position); - startOffset = endemeter; - } - - wagons.forEach((w, i) => { - fahrzeuge.push({ - additionalInfo: { - icons: { - bike: w.isBicycleAllowed, - dining: w.isDining, - info: w.isInfoPoint, - wheelchair: w.capacityWheelChair > 0, - quiet: w.isQuietZone, - family: w.isChildCinema || w.isPlayZone, - wifi: w.hasWifi, - }, - klasse: OEBBWagonToKlasse(w), - }, - allFahrzeugausstattung: [], - wagenordnungsnummer: w.ranking ? String(w.ranking) : '', - fahrzeugnummer: w.uicNumber || '', - fahrzeugtyp: w.kind || '', - kategorie: '', - orientierung: '', - status: w.isLocked ? 'GESCHLOSSEN' : '', - positioningruppe: String(i), - fahrzeugsektor: '', - positionamhalt: positions[i], - }); - }); - - const startPercentage = Math.min( - ...fahrzeuge.map((f) => Number.parseFloat(f.positionamhalt.startprozent)), - ); - const endPercentage = Math.max( - ...fahrzeuge.map((f) => Number.parseFloat(f.positionamhalt.endeprozent)), - ); - - let verkehrlichezugnummer = ''; - const destinationDB640 = wagons[0].destination; - const train = info.train; - if (train && train.stations) { - if (train.wagons.length === wagons.length) { - verkehrlichezugnummer = info.timeTableInfo.trainNr.toString(); - } else { - const stationsForTrain = train.stations; - if ( - stationsForTrain[stationsForTrain.length - 1] === destinationDB640 - ) { - verkehrlichezugnummer = train.trainNr.toString(); - } else if (info.timeTableInfo.portions.length <= 2) { - verkehrlichezugnummer = - info.timeTableInfo.portions - .find((p) => p.trainNr !== train.trainNr) - ?.trainNr.toString() || ''; - } - } - } - - return { - allFahrzeug: fahrzeuge, - goesToFrance: false, - endPercentage, - startPercentage, - fahrzeuggruppebezeichnung: '', - startbetriebsstellename: wagons[0].origin, - zielbetriebsstellename: wagons[0].destinationName, - verkehrlichezugnummer, - }; - }); -} - -export function OEBBToDB(info: OEBBInfo): Formation | null { - if (!info.train) return null; - // Some wagons are missing position information - if (info.train.wagons.some((w) => !w.lengthOverBuffers)) return null; - const trainType = info.timeTableInfo.trainName - .replace(info.timeTableInfo.trainNr.toString(), '') - .trim(); - const fahrzeuggruppen = getFahrzeuggruppen(info); - const startPercentage = Math.min( - ...fahrzeuggruppen.map((f) => f.startPercentage), - ); - const endPercentage = Math.max( - ...fahrzeuggruppen.map((f) => f.endPercentage), - ); - - const fahrzeugGruppenRelevantForDifferentDestination = fahrzeuggruppen.filter( - (g) => - g.allFahrzeug.some( - (f) => f.additionalInfo.klasse !== 4 && f.status !== 'GESCHLOSSEN', - ), - ); - - const formation: Formation = { - fahrtid: '', - fahrtrichtung: 'VORWAERTS', - halt: { - bahnhofsname: info.timeTableInfo.stationName, - evanummer: '', - haltid: '', - rl100: '', - abfahrtszeit: parseOEBBTime( - info.timeTableInfo.date, - info.timeTableInfo.time.reported || info.timeTableInfo.time.scheduled, - ).toISOString(), - allSektor: getSectors(info.platform), - gleisbezeichnung: info.platform?.platform.toString(), - }, - isRealtime: info.train?.isReported ?? false, - istplaninformation: false, - liniebezeichnung: '', - planstarttag: info.timeTableInfo.date, - reportedZuggattung: trainType, - zuggattung: trainType, - serviceid: '', - zugnummer: info.timeTableInfo.trainNr.toString(), - realFahrtrichtung: info.trainOnPlatform - ? !info.trainOnPlatform.departureTowardsFirstSector - : undefined, - scale: 100 / (endPercentage - startPercentage), - startPercentage, - endPercentage, - allFahrzeuggruppe: fahrzeuggruppen, - differentDestination: - fahrzeugGruppenRelevantForDifferentDestination.length > 1, - differentZugnummer: info.timeTableInfo.portions.length > 1, - }; - - formation.allFahrzeuggruppe.forEach((g) => { - addBRtoGruppe(g, formation); - g.allFahrzeug.forEach((f) => { - calculateComfort(f, g); - }); - }); - - return formation; -} - -function OEBBWagonToKlasse( - wagon: OEBBCoachSequenceWagon, -): Fahrzeug['additionalInfo']['klasse'] { - if (wagon.kind === 'TFZ') return 4; - // TODO: Is business really first class? - if ( - (wagon.capacityFirstClass || wagon.capacityBusinessClass) && - wagon.capacitySecondClass - ) - return 3; - if (wagon.capacitySecondClass || wagon.isDining) return 2; - // TODO: Is business really first class? - if (wagon.capacityFirstClass || wagon.capacityBusinessClass) return 1; - // TODO: mark this as liegeplätze? - if (wagon.capacityCouchette) return 2; - // TODO: mark this as schlafplätze? - if (wagon.capacitySleeper) return 1; - if (!wagon.ranking) return 4; - return 0; -} diff --git a/packages/server/Reihung/getBR.ts b/packages/server/Reihung/getBR.ts deleted file mode 100644 index 16907e631..000000000 --- a/packages/server/Reihung/getBR.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { getBaureiheByUIC } from 'server/coachSequence/baureihe'; -import type { BRInfo, Fahrzeug } from 'types/reihung'; - -export default (uic: string, fahrzeuge: Fahrzeug[]): undefined | BRInfo => { - const br = getBaureiheByUIC( - uic, - fahrzeuge.map((f) => ({ - class: f.additionalInfo.klasse, - })), - ); - if (!br) return undefined; - return { - name: br.name, - identifier: br.identifier, - BR: br.baureihe, - }; -}; diff --git a/packages/server/Reihung/identifierNameMap.ts b/packages/server/Reihung/identifierNameMap.ts deleted file mode 100644 index 1df2fa9d0..000000000 --- a/packages/server/Reihung/identifierNameMap.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { AvailableIdentifier } from 'types/coachSequence'; -import type { BRInfo } from 'types/reihung'; - -const nameMap: { - [K in AvailableIdentifier]: string; -} = { - '401': 'ICE 1 (BR401)', - '401.9': 'ICE 1 Kurz (BR401)', - '401.LDV': 'ICE 1 LDV (BR401)', - '402': 'ICE 2 (BR402)', - '403': 'ICE 3 (BR403)', - '403.S1': 'ICE 3 (BR403 1. Serie)', - '403.S2': 'ICE 3 (BR403 2. Serie)', - '403.R': 'ICE 3 (BR403 Redesign)', - '406': 'ICE 3 (BR406)', - '406.R': 'ICE 3 (BR406 Redesign)', - '407': 'ICE 3 Velaro (BR407)', - '410.1': 'ICE S (BR410.1)', - '411': 'ICE T (BR411)', - '411.S1': 'ICE T (BR411 1. Serie)', - '411.S2': 'ICE T (BR411 2. Serie)', - '412': 'ICE 4 (BR412)', - '412.7': 'ICE 4 Kurz (BR412)', - '412.13': 'ICE 4 Lang (BR412)', - '415': 'ICE T Kurz (BR415)', - 'IC2.TWIN': 'IC 2 (Twindexx)', - 'IC2.KISS': 'IC 2 (KISS)', - MET: 'MET', - TGV: 'TGV', -}; - -export function getName(br: Omit): string | undefined { - if (br.identifier) return nameMap[br.identifier]; -} diff --git a/packages/server/Reihung/index.ts b/packages/server/Reihung/index.ts deleted file mode 100644 index 8c2fae65f..000000000 --- a/packages/server/Reihung/index.ts +++ /dev/null @@ -1,491 +0,0 @@ -/* eslint-disable array-callback-return */ -/* eslint-disable no-fallthrough */ -import { format } from 'date-fns'; -import { getAbfahrten } from 'server/iris'; -import { - getComfortSeats, - getDisabledSeats, - getFamilySeats, -} from 'server/coachSequence/specialSeats'; -import { getName } from 'server/Reihung/identifierNameMap'; -import { isRedesignByTZ } from 'server/coachSequence/tzInfo'; -import { maxBy, minBy } from 'client/util'; -import { utcToZonedTime } from 'date-fns-tz'; -import Axios from 'axios'; -import getBR from 'server/Reihung/getBR'; -import TrainNames from '../coachSequence/TrainNames'; -import type { - AdditionalFahrzeugInfo, - BRInfo, - Fahrzeug, - Fahrzeuggruppe, - Formation, - Wagenreihung, -} from 'types/reihung'; - -const formatDate = (date: Date) => - format(utcToZonedTime(date, 'Europe/Berlin'), 'yyyyMMddHHmm'); - -const wrUrls = { - apps: 'https://www.apps-bahn.de/wr/wagenreihung/1.0', - noncd: 'https://ist-wr.noncd.db.de/wagenreihung/1.0', -}; -export const getWRLink = ( - trainNumber: string, - date: Date, - type: 'apps' | 'noncd' = 'noncd', -): string => { - return `${wrUrls[type]}/${trainNumber}/${formatDate(date)}`; -}; - -const countryMapping: any = { - 80: 'DE', - 81: 'AT', - 83: 'IT', - 84: 'NL', - 85: 'CH', - 86: 'DK', - 87: 'FR', -}; -const CHICWagons = ['Apmz', 'WRmz', 'Bpmz']; -const getCountry = (fahrzeuge: Fahrzeug[], fahrzeugTypes: string[]) => { - const countries = fahrzeuge.map((f) => { - const countryCode = Number.parseInt(f.fahrzeugnummer.substr(2, 2), 10); - - if (countryCode) { - return countryMapping[countryCode] || countryCode; - } - }); - - const firstCountry = countries.filter(Boolean)[0]; - - if (firstCountry) { - return firstCountry; - } - - const wagenOrdnungsNummern = fahrzeuge.map((f) => - Number.parseInt(f.wagenordnungsnummer, 10), - ); - const minOrdnungsnummer = minBy(wagenOrdnungsNummern)!; - const maxOrdnungsnummer = maxBy(wagenOrdnungsNummern)!; - const groupedFahrzeugTypes = fahrzeugTypes.reduce<{ - [key: string]: number; - }>((agg, current) => { - if (current in agg) agg[current] += 1; - else agg[current] = 1; - return agg; - }, {}); - - if ( - fahrzeuge.length > 10 && - minOrdnungsnummer >= 253 && - maxOrdnungsnummer <= 264 && - fahrzeuge.every((f) => CHICWagons.includes(f.fahrzeugtyp)) - ) { - return 'CH'; - } else if ( - minOrdnungsnummer >= 255 && - maxOrdnungsnummer <= 263 && - groupedFahrzeugTypes.Bdmpz === 1 && - groupedFahrzeugTypes.Bhmpz === 1 - ) { - return 'CZ'; - } else if ( - (minOrdnungsnummer === 81 && maxOrdnungsnummer === 82) || - (minOrdnungsnummer === 71 && maxOrdnungsnummer === 72) - ) { - return 'DK'; - } -}; - -const specificBR = (fahrzeuge: Fahrzeug[]): Omit => { - for (const f of fahrzeuge) { - const br = getBR(f.fahrzeugnummer, fahrzeuge); - - if (br) return br; - } - - if (fahrzeuge.find((f) => f.fahrzeugtyp === 'Apmbzf')) { - return { - identifier: 'MET', - }; - } else if (fahrzeuge.find((f) => f.fahrzeugtyp === 'DBpbzfa')) { - return { - identifier: 'IC2.TWIN', - }; - } else if (fahrzeuge.find((f) => f.fahrzeugtyp === 'DBpdzfa')) { - fahrzeuge.forEach((f) => { - switch (f.fahrzeugtyp) { - case 'DABpzfa': - f.additionalInfo.comfort = true; - f.additionalInfo.icons.disabled = true; - break; - case 'DBpbza': - f.additionalInfo.icons.family = true; - break; - case 'DBpdzfa': - f.additionalInfo.icons.bike = true; - break; - } - }); - return { - identifier: 'IC2.KISS', - noPdf: true, - }; - } - - return { noPdf: true }; -}; - -function fahrtrichtung(fahrzeuge: Fahrzeug[]) { - const first = fahrzeuge[0]; - const last = fahrzeuge[fahrzeuge.length - 1]; - - // "Algorithmus" so bei der DB im Code gefunden - return ( - Number.parseInt(last.positionamhalt.startprozent, 10) > - Number.parseInt(first.positionamhalt.startprozent, 10) - ); -} - -const tznRegex = /(\d+)/; - -function enrichFahrzeug(fahrzeug: Fahrzeug) { - const data: AdditionalFahrzeugInfo = { - klasse: 0, - icons: {}, - }; - - switch (fahrzeug.kategorie) { - case 'DOPPELSTOCKSTEUERWAGENZWEITEKLASSE': - case 'DOPPELSTOCKWAGENZWEITEKLASSE': - case 'REISEZUGWAGENZWEITEKLASSE': - case 'STEUERWAGENZWEITEKLASSE': - data.klasse = 2; - break; - case 'HALBSPEISEWAGENZWEITEKLASSE': - case 'SPEISEWAGEN': - data.klasse = 2; - data.icons.dining = true; - break; - default: - break; - case 'DOPPELSTOCKWAGENERSTEZWEITEKLASSE': - case 'DOPPELSTOCKSTEUERWAGENERSTEZWEITEKLASSE': - case 'STEUERWAGENERSTEZWEITEKLASSE': - case 'REISEZUGWAGENERSTEZWEITEKLASSE': - data.klasse = 3; - break; - case 'HALBSPEISEWAGENERSTEKLASSE': - data.klasse = 1; - data.icons.dining = true; - break; - case 'DOPPELSTOCKWAGENERSTEKLASSE': - case 'REISEZUGWAGENERSTEKLASSE': - case 'STEUERWAGENERSTEKLASSE': - data.klasse = 1; - break; - case 'TRIEBKOPF': - case 'LOK': - data.klasse = 4; - } - - fahrzeug.allFahrzeugausstattung.forEach((ausstattung) => { - switch (ausstattung.ausstattungsart) { - case 'PLAETZEROLLSTUHL': - data.icons.wheelchair = true; - break; - case 'PLAETZEFAHRRAD': - data.icons.bike = true; - break; - case 'BISTRO': - data.icons.dining = true; - break; - case 'RUHE': - data.icons.quiet = true; - break; - case 'FAMILIE': - data.icons.family = true; - break; - case 'PLAETZEBAHNCOMFORT': - data.comfort = true; - break; - case 'PLAETZESCHWERBEH': - data.icons.disabled = true; - break; - case 'INFO': - data.icons.info = true; - break; - case 'ABTEILKLEINKIND': - data.icons.toddler = true; - break; - } - }); - - fahrzeug.additionalInfo = data; -} - -export function addBRtoGruppe( - gruppe: Fahrzeuggruppe, - formation: Formation, -): void { - if (['IC', 'EC', 'ICE', 'ECE'].includes(formation.zuggattung)) { - const gruppenFahrzeugTypes = gruppe.allFahrzeug.map((f) => f.fahrzeugtyp); - - const br = specificBR(gruppe.allFahrzeug); - if (gruppe.fahrzeuggruppebezeichnung.startsWith('IC')) { - const tzn = gruppe.fahrzeuggruppebezeichnung; - - gruppe.tzn = tznRegex.exec(tzn)?.[0]; - gruppe.name = TrainNames(gruppe.tzn); - - if (br?.identifier && isRedesignByTZ(gruppe.tzn)) { - // @ts-expect-error this works - br.identifier = br.identifier.replace('.S1', '').replace('.S2', ''); - br.identifier += '.R'; - } - } - gruppe.br = { - ...br, - name: getName(br) ?? formation.zuggattung, - }; - if (gruppe.br) { - gruppe.br.country = getCountry(gruppe.allFahrzeug, gruppenFahrzeugTypes); - gruppe.br.showBRInfo = Boolean(gruppe.br.BR || !gruppe.br.noPdf); - } - } -} - -export function calculateComfort( - fahrzeug: Fahrzeug, - gruppe: Fahrzeuggruppe, -): void { - const data = fahrzeug.additionalInfo; - if (gruppe.goesToFrance) { - data.comfort = false; - data.icons.disabled = false; - data.icons.family = false; - } - - if (gruppe.br?.name === 'MET') { - if ( - fahrzeug.wagenordnungsnummer === '5' || - fahrzeug.wagenordnungsnummer === '6' - ) { - data.comfort = true; - } - if (fahrzeug.fahrzeugtyp === 'Bpmz') { - fahrzeug.fahrzeugtyp = 'Apmz'; - } - } - - if (gruppe.br) { - if (data.comfort) { - data.comfortSeats = getComfortSeats(gruppe.br.identifier, data.klasse); - } - if (data.icons.disabled) { - data.disabledSeats = getDisabledSeats( - gruppe.br.identifier, - data.klasse, - fahrzeug.wagenordnungsnummer, - ); - } - if (data.icons.family) { - data.familySeats = getFamilySeats(gruppe.br.identifier); - } - } -} - -const wrFetchTimeout = process.env.NODE_ENV === 'production' ? 2500 : 10000; - -async function getBestReihung(trainNumber: string, date: Date) { - if (trainNumber.length <= 4) { - try { - const cancelToken = new Axios.CancelToken((c) => { - setTimeout(c, wrFetchTimeout); - }); - const info = ( - await Axios.get(getWRLink(trainNumber, date), { - cancelToken, - }) - ).data; - return info; - } catch { - // we just ignore it and try the next one - } - } - const cancelToken = new Axios.CancelToken((c) => { - setTimeout(c, wrFetchTimeout); - }); - const info = ( - await Axios.get(getWRLink(trainNumber, date, 'apps'), { - cancelToken, - }) - ).data; - return info; -} -// https://www.apps-bahn.de/wr/wagenreihung/1.0/6/201802021930 -export async function wagenreihung( - trainNumber: string, - date: Date, - retry = 2, -): Promise { - let info: Wagenreihung; - - try { - info = await getBestReihung(trainNumber, date); - } catch (e) { - if (Axios.isCancel(e)) { - if (retry) return wagenreihung(trainNumber, date, retry - 1); - throw { - response: { - status: 404, - statusText: 'Timeout', - data: 404, - }, - }; - } - - throw { - response: { - status: 404, - statusText: 'Not Found', - data: 404, - }, - }; - } - - // @ts-expect-error We're enriching information now. - const enrichedFormation: Formation = info.data.istformation; - - let startPercentage = 100; - let endPercentage = 0; - - const reallyHasReihung = enrichedFormation.allFahrzeuggruppe.every((g) => - g.allFahrzeug.every((f) => { - const start = Number.parseFloat(f.positionamhalt.startprozent); - const end = Number.parseFloat(f.positionamhalt.endeprozent); - - if (!start && !end) return false; - - if (start < startPercentage) { - startPercentage = start; - } - if (end > endPercentage) { - endPercentage = end; - } - - return true; - }), - ); - - if (!reallyHasReihung) { - throw { status: 404, statusText: 'Data invalid' }; - } - - const fahrzeuge: Fahrzeug[] = []; - - enrichedFormation.differentDestination = false; - enrichedFormation.differentZugnummer = false; - enrichedFormation.allFahrzeuggruppe.forEach((g, index, gruppen) => { - if (index > 0) { - const previousGruppe = gruppen[index - 1]; - - if (previousGruppe.verkehrlichezugnummer !== g.verkehrlichezugnummer) { - enrichedFormation.differentZugnummer = true; - } - if (previousGruppe.zielbetriebsstellename !== g.zielbetriebsstellename) { - enrichedFormation.differentDestination = true; - } - } - g.allFahrzeug.forEach((fahrzeug) => { - enrichFahrzeug(fahrzeug); - fahrzeuge.push(fahrzeug); - }); - - addBRtoGruppe(g, enrichedFormation); - - // https://inside.bahn.de/entstehung-zugnummern/?dbkanal_006=L01_S01_D088_KTL0006_INSIDE-BAHN-2019_Zugnummern_LZ01 - const trainNumberAsNumber = Number.parseInt(g.verkehrlichezugnummer, 10); - - g.goesToFrance = trainNumberAsNumber >= 9550 && trainNumberAsNumber <= 9599; - - g.allFahrzeug.forEach((f) => { - calculateComfort(f, g); - }); - - const minFahrzeug = minBy(g.allFahrzeug, (f) => - Number.parseInt(f.positionamhalt.startprozent, 10), - ); - const maxFahrzeug = maxBy(g.allFahrzeug, (f) => - Number.parseInt(f.positionamhalt.endeprozent, 10), - ); - - if (minFahrzeug) { - g.startPercentage = Number.parseInt( - minFahrzeug.positionamhalt.startprozent, - 10, - ); - } - if (maxFahrzeug) { - g.endPercentage = Number.parseInt( - maxFahrzeug.positionamhalt.endeprozent, - 10, - ); - } - }); - - enrichedFormation.realFahrtrichtung = fahrtrichtung(fahrzeuge); - - enrichedFormation.scale = 100 / (endPercentage - startPercentage); - enrichedFormation.startPercentage = startPercentage; - enrichedFormation.endPercentage = endPercentage; - enrichedFormation.isRealtime = fahrzeuge.every( - (f) => f.kategorie === 'LOK' || f.fahrzeugnummer, - ); - - return enrichedFormation; -} - -function wagenReihungSpecificMonitoring(id: string, departure: Date) { - return wagenreihung(id, departure); -} - -export async function wagenReihungMonitoring(): Promise { - const abfahrten = await getAbfahrten('8002549', false, { - lookahead: 300, - }); - const maybeDepartures = abfahrten.departures.filter( - (d) => d.reihung && d.departure, - ); - - let departure = maybeDepartures.shift(); - - while (departure) { - const departureTime = - departure.departure && departure.departure.scheduledTime; - - if (!departureTime) { - departure = maybeDepartures.shift(); - } else { - try { - // eslint-disable-next-line no-await-in-loop - const wr = await wagenReihungSpecificMonitoring( - departure.train.number, - departureTime, - ); - - if (wr) return wr; - departure = maybeDepartures.shift(); - } catch (e) { - // eslint-disable-next-line no-console - // console.warn( - // 'Failed to get WR for Monitoring!', - // e, - // departure && departure.train, - // ); - departure = maybeDepartures.shift(); - } - } - } -} diff --git a/packages/server/coachSequence/monitoring.ts b/packages/server/coachSequence/monitoring.ts new file mode 100644 index 000000000..eb3af4d42 --- /dev/null +++ b/packages/server/coachSequence/monitoring.ts @@ -0,0 +1,48 @@ +import { coachSequence } from 'server/coachSequence'; +import { getAbfahrten } from 'server/iris'; +import type { CoachSequenceInformation } from 'types/coachSequence'; + +function wagenReihungSpecificMonitoring(id: string, departure: Date) { + return coachSequence(id, departure); +} + +export async function coachSequenceMonitoring(): Promise< + CoachSequenceInformation | undefined +> { + const abfahrten = await getAbfahrten('8002549', false, { + lookahead: 300, + }); + const maybeDepartures = abfahrten.departures.filter( + (d) => d.reihung && d.departure, + ); + + let departure = maybeDepartures.shift(); + + while (departure) { + const departureTime = + departure.departure && departure.departure.scheduledTime; + + if (!departureTime) { + departure = maybeDepartures.shift(); + } else { + try { + // eslint-disable-next-line no-await-in-loop + const wr = await wagenReihungSpecificMonitoring( + departure.train.number, + departureTime, + ); + + if (wr) return wr; + departure = maybeDepartures.shift(); + } catch (e) { + // eslint-disable-next-line no-console + // console.warn( + // 'Failed to get WR for Monitoring!', + // e, + // departure && departure.train, + // ); + departure = maybeDepartures.shift(); + } + } + } +} diff --git a/packages/server/plausible.ts b/packages/server/plausible.ts index f6bb13d28..5610b0704 100644 --- a/packages/server/plausible.ts +++ b/packages/server/plausible.ts @@ -4,28 +4,36 @@ import type { Request } from 'koa'; const url = process.env.PLAUSIBLE_URL; const domain = process.env.ENVIRONMENT; -export function deprecatedAPIUsage(req: Request, name: string): void { - if (!url || !domain) { - return; - } - void Axios.post( - url, - { - name, - url: req.href, - domain, - referrer: req.header.referer, - props: { - userAgent: req.header['user-agent'], - ip: req.header['x-real-ip'], - userAgentIp: `${req.header['x-real-ip']}: ${req.header['user-agent']}`, +export async function deprecatedAPIUsage( + req: Request, + name: string, +): Promise { + try { + if (!url || !domain) { + return; + } + await Axios.post( + url, + { + name, + url: req.href, + domain, + referrer: req.header.referer, + props: { + userAgent: req.header['user-agent'], + ip: req.header['x-real-ip'], + userAgentIp: `${req.header['x-real-ip']}: ${req.header['user-agent']}`, + }, }, - }, - { - headers: { - 'user-agent': req.header['user-agent']! || '', - 'x-forwarded-for': (req.header['x-real-ip'] as string) || req.ip || '', + { + headers: { + 'user-agent': req.header['user-agent']! || '', + 'x-forwarded-for': + (req.header['x-real-ip'] as string) || req.ip || '', + }, }, - }, - ); + ); + } catch { + //ignore errors + } } diff --git a/public/swagger.json b/public/swagger.json index 4f7d92177..1e28e7e77 100644 --- a/public/swagger.json +++ b/public/swagger.json @@ -3621,541 +3621,6 @@ "$ref": "#/components/schemas/OEBBInfo", "description": "Obtain the return type of a function type" }, - "AdditionalFahrzeugInfo": { - "properties": { - "klasse": { - "type": "number", - "enum": [0, 1, 2, 3, 4], - "description": "0: Unknown; 1: erste; 2: zweite; 3: 1&2; 4: Not for passengers" - }, - "icons": { - "properties": { - "wifi": { - "type": "boolean" - }, - "toddler": { - "type": "boolean" - }, - "family": { - "type": "boolean" - }, - "info": { - "type": "boolean" - }, - "quiet": { - "type": "boolean" - }, - "disabled": { - "type": "boolean" - }, - "bike": { - "type": "boolean" - }, - "wheelchair": { - "type": "boolean" - }, - "dining": { - "type": "boolean" - } - }, - "type": "object" - }, - "comfort": { - "type": "boolean" - }, - "comfortSeats": { - "type": "string" - }, - "disabledSeats": { - "type": "string" - }, - "familySeats": { - "type": "string" - } - }, - "required": ["klasse", "icons"], - "type": "object", - "additionalProperties": false - }, - "Fahrzeugausstattung": { - "properties": { - "anzahl": { - "type": "string" - }, - "ausstattungsart": { - "type": "string" - }, - "bezeichnung": { - "type": "string" - }, - "status": { - "type": "string" - } - }, - "required": ["anzahl", "ausstattungsart", "bezeichnung", "status"], - "type": "object", - "additionalProperties": false - }, - "FahrzeugKategorie": { - "type": "string", - "enum": [ - "DOPPELSTOCKSTEUERWAGENERSTEZWEITEKLASSE", - "DOPPELSTOCKSTEUERWAGENZWEITEKLASSE", - "DOPPELSTOCKWAGENERSTEKLASSE", - "DOPPELSTOCKWAGENERSTEZWEITEKLASSE", - "DOPPELSTOCKWAGENZWEITEKLASSE", - "HALBSPEISEWAGENERSTEKLASSE", - "HALBSPEISEWAGENZWEITEKLASSE", - "LOK", - "REISEZUGWAGENERSTEKLASSE", - "REISEZUGWAGENERSTEZWEITEKLASSE", - "REISEZUGWAGENZWEITEKLASSE", - "SPEISEWAGEN", - "STEUERWAGENERSTEKLASSE", - "STEUERWAGENERSTEZWEITEKLASSE", - "STEUERWAGENZWEITEKLASSE", - "TRIEBKOPF", - "" - ] - }, - "Position": { - "properties": { - "endemeter": { - "type": "string" - }, - "endeprozent": { - "type": "string" - }, - "startmeter": { - "type": "string" - }, - "startprozent": { - "type": "string" - } - }, - "required": ["endemeter", "endeprozent", "startmeter", "startprozent"], - "type": "object", - "additionalProperties": false - }, - "Fahrzeug": { - "properties": { - "allFahrzeugausstattung": { - "items": { - "$ref": "#/components/schemas/Fahrzeugausstattung" - }, - "type": "array" - }, - "kategorie": { - "$ref": "#/components/schemas/FahrzeugKategorie" - }, - "fahrzeugnummer": { - "type": "string" - }, - "orientierung": { - "type": "string" - }, - "positioningruppe": { - "type": "string" - }, - "fahrzeugsektor": { - "type": "string" - }, - "fahrzeugtyp": { - "type": "string" - }, - "wagenordnungsnummer": { - "type": "string" - }, - "positionamhalt": { - "$ref": "#/components/schemas/Position" - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": ["GESCHLOSSEN"] - } - ] - }, - "additionalInfo": { - "$ref": "#/components/schemas/AdditionalFahrzeugInfo" - } - }, - "required": [ - "allFahrzeugausstattung", - "kategorie", - "fahrzeugnummer", - "orientierung", - "positioningruppe", - "fahrzeugsektor", - "fahrzeugtyp", - "wagenordnungsnummer", - "positionamhalt", - "status", - "additionalInfo" - ], - "type": "object", - "additionalProperties": false - }, - "AvailableBR": { - "type": "string", - "enum": [ - "401", - "402", - "403", - "406", - "407", - "411", - "412", - "415", - "410.1" - ] - }, - "AvailableIdentifier": { - "anyOf": [ - { - "$ref": "#/components/schemas/AvailableBR" - }, - { - "type": "string", - "enum": [ - "401.LDV", - "401.9", - "411.S1", - "411.S2", - "412.7", - "412.13", - "403.R", - "403.S1", - "403.S2", - "406.R", - "IC2.TWIN", - "IC2.KISS", - "MET", - "TGV" - ] - } - ] - }, - "BRInfo": { - "properties": { - "name": { - "type": "string" - }, - "BR": { - "$ref": "#/components/schemas/AvailableBR" - }, - "identifier": { - "$ref": "#/components/schemas/AvailableIdentifier" - }, - "noPdf": { - "type": "boolean" - }, - "country": { - "type": "string", - "enum": ["DE", "AT"] - }, - "showBRInfo": { - "type": "boolean" - } - }, - "required": ["name"], - "type": "object", - "additionalProperties": false - }, - "BaseFahrzeug": { - "properties": { - "allFahrzeugausstattung": { - "items": { - "$ref": "#/components/schemas/Fahrzeugausstattung" - }, - "type": "array" - }, - "kategorie": { - "$ref": "#/components/schemas/FahrzeugKategorie" - }, - "fahrzeugnummer": { - "type": "string" - }, - "orientierung": { - "type": "string" - }, - "positioningruppe": { - "type": "string" - }, - "fahrzeugsektor": { - "type": "string" - }, - "fahrzeugtyp": { - "type": "string" - }, - "wagenordnungsnummer": { - "type": "string" - }, - "positionamhalt": { - "$ref": "#/components/schemas/Position" - }, - "status": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": ["GESCHLOSSEN"] - } - ] - } - }, - "required": [ - "allFahrzeugausstattung", - "kategorie", - "fahrzeugnummer", - "orientierung", - "positioningruppe", - "fahrzeugsektor", - "fahrzeugtyp", - "wagenordnungsnummer", - "positionamhalt", - "status" - ], - "type": "object", - "additionalProperties": false - }, - "Fahrzeuggruppe": { - "properties": { - "allFahrzeug": { - "items": { - "$ref": "#/components/schemas/Fahrzeug" - }, - "type": "array" - }, - "fahrzeuggruppebezeichnung": { - "type": "string" - }, - "zielbetriebsstellename": { - "type": "string" - }, - "startbetriebsstellename": { - "type": "string" - }, - "verkehrlichezugnummer": { - "type": "string" - }, - "goesToFrance": { - "type": "boolean" - }, - "startPercentage": { - "type": "number", - "format": "double" - }, - "endPercentage": { - "type": "number", - "format": "double" - }, - "tzn": { - "type": "string", - "description": "0169 for instance, from Gruppenbezeichnung" - }, - "name": { - "type": "string", - "description": "Worms for instance" - }, - "br": { - "$ref": "#/components/schemas/BRInfo" - } - }, - "required": [ - "allFahrzeug", - "fahrzeuggruppebezeichnung", - "zielbetriebsstellename", - "startbetriebsstellename", - "verkehrlichezugnummer", - "goesToFrance", - "startPercentage", - "endPercentage" - ], - "type": "object", - "additionalProperties": false - }, - "BaseFahrzeuggruppe": { - "properties": { - "allFahrzeug": { - "items": { - "$ref": "#/components/schemas/BaseFahrzeug" - }, - "type": "array" - }, - "fahrzeuggruppebezeichnung": { - "type": "string" - }, - "zielbetriebsstellename": { - "type": "string" - }, - "startbetriebsstellename": { - "type": "string" - }, - "verkehrlichezugnummer": { - "type": "string" - } - }, - "required": [ - "allFahrzeug", - "fahrzeuggruppebezeichnung", - "zielbetriebsstellename", - "startbetriebsstellename", - "verkehrlichezugnummer" - ], - "type": "object", - "additionalProperties": false - }, - "Sektor": { - "properties": { - "positionamgleis": { - "$ref": "#/components/schemas/Position" - }, - "sektorbezeichnung": { - "type": "string" - } - }, - "required": ["positionamgleis", "sektorbezeichnung"], - "type": "object", - "additionalProperties": false - }, - "Halt": { - "properties": { - "abfahrtszeit": { - "type": "string" - }, - "ankunftszeit": { - "type": "string" - }, - "bahnhofsname": { - "type": "string" - }, - "evanummer": { - "type": "string" - }, - "gleisbezeichnung": { - "type": "string" - }, - "haltid": { - "type": "string" - }, - "rl100": { - "type": "string" - }, - "allSektor": { - "items": { - "$ref": "#/components/schemas/Sektor" - }, - "type": "array" - } - }, - "required": [ - "bahnhofsname", - "evanummer", - "haltid", - "rl100", - "allSektor" - ], - "type": "object", - "additionalProperties": false - }, - "Formation": { - "properties": { - "fahrtrichtung": { - "type": "string", - "enum": ["VORWAERTS", "RUCKWAERTS"], - "description": "Should always be VORWAERTS" - }, - "allFahrzeuggruppe": { - "items": { - "$ref": "#/components/schemas/Fahrzeuggruppe" - }, - "type": "array" - }, - "halt": { - "$ref": "#/components/schemas/Halt" - }, - "liniebezeichnung": { - "type": "string" - }, - "zuggattung": { - "type": "string" - }, - "zugnummer": { - "type": "string" - }, - "serviceid": { - "type": "string", - "description": "???" - }, - "planstarttag": { - "type": "string" - }, - "fahrtid": { - "type": "string", - "description": "???" - }, - "istplaninformation": { - "type": "boolean" - }, - "reportedZuggattung": { - "type": "string", - "description": "Train Category that was reported" - }, - "differentDestination": { - "type": "boolean", - "description": "do groups have a different destination" - }, - "differentZugnummer": { - "type": "boolean", - "description": "Do we have several trains in one? (Flügelung)" - }, - "scale": { - "type": "number", - "format": "double" - }, - "startPercentage": { - "type": "number", - "format": "double" - }, - "endPercentage": { - "type": "number", - "format": "double" - }, - "realFahrtrichtung": { - "type": "boolean", - "description": "true = Vorwärts, undefined = we do not know" - }, - "isRealtime": { - "type": "boolean" - } - }, - "required": [ - "fahrtrichtung", - "allFahrzeuggruppe", - "halt", - "liniebezeichnung", - "zuggattung", - "zugnummer", - "serviceid", - "planstarttag", - "fahrtid", - "istplaninformation", - "reportedZuggattung", - "scale", - "startPercentage", - "endPercentage", - "isRealtime" - ], - "type": "object", - "additionalProperties": false - }, "CoachSequencePosition": { "properties": { "startPercent": { @@ -4213,6 +3678,28 @@ "type": "object", "additionalProperties": false }, + "FahrzeugKategorie": { + "type": "string", + "enum": [ + "DOPPELSTOCKSTEUERWAGENERSTEZWEITEKLASSE", + "DOPPELSTOCKSTEUERWAGENZWEITEKLASSE", + "DOPPELSTOCKWAGENERSTEKLASSE", + "DOPPELSTOCKWAGENERSTEZWEITEKLASSE", + "DOPPELSTOCKWAGENZWEITEKLASSE", + "HALBSPEISEWAGENERSTEKLASSE", + "HALBSPEISEWAGENZWEITEKLASSE", + "LOK", + "REISEZUGWAGENERSTEKLASSE", + "REISEZUGWAGENERSTEZWEITEKLASSE", + "REISEZUGWAGENZWEITEKLASSE", + "SPEISEWAGEN", + "STEUERWAGENERSTEKLASSE", + "STEUERWAGENERSTEZWEITEKLASSE", + "STEUERWAGENZWEITEKLASSE", + "TRIEBKOPF", + "" + ] + }, "CoachSequenceCoachFeatures": { "properties": { "dining": { @@ -4301,6 +3788,46 @@ "type": "object", "additionalProperties": false }, + "AvailableBR": { + "type": "string", + "enum": [ + "401", + "402", + "403", + "406", + "407", + "411", + "412", + "415", + "410.1" + ] + }, + "AvailableIdentifier": { + "anyOf": [ + { + "$ref": "#/components/schemas/AvailableBR" + }, + { + "type": "string", + "enum": [ + "401.LDV", + "401.9", + "411.S1", + "411.S2", + "412.7", + "412.13", + "403.R", + "403.S1", + "403.S2", + "406.R", + "IC2.TWIN", + "IC2.KISS", + "MET", + "TGV" + ] + } + ] + }, "CoachSequenceBaureihe": { "properties": { "name": { @@ -5828,45 +5355,6 @@ } } }, - "/reihung/v2/wagen/{trainNumber}/{date}": { - "get": { - "operationId": "Wagenreihung v2", - "responses": { - "200": { - "description": "Ok", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Formation" - } - } - } - } - }, - "tags": ["Reihung"], - "deprecated": true, - "security": [], - "parameters": [ - { - "in": "path", - "name": "trainNumber", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "path", - "name": "date", - "required": true, - "schema": { - "format": "date-time", - "type": "string" - } - } - ] - } - }, "/reihung/v4/wagen/{trainNumber}": { "get": { "operationId": "Wagenreihung v4",