import { db } from './dataStorage.js'; import { settingsState } from './settings.js'; import { getHafasClient, client } from './hafasClient.js'; import { trainsearchToHafas, hafasToTrainsearch } from './refresh_token/index.js'; import { CustomDate } from './helpers.js'; import { t } from './translate.js'; const loyaltyCards = { NONE: Symbol('no loyalty card'), BAHNCARD: Symbol('Bahncard'), VORTEILSCARD: Symbol('VorteilsCard'), HALBTAXABO: Symbol('HalbtaxAbo'), VOORDEELURENABO: Symbol('Voordeelurenabo'), SHCARD: Symbol('SH-Card'), GENERALABONNEMENT: Symbol('General-Abonnement'), }; const loyaltyCardsReverse = { 'Symbol(no loyalty card)': 'NONE', 'Symbol(Bahncard)': 'BAHNCARD', 'Symbol(VorteilsCard)': 'VORTEILSCARD', 'Symbol(HalbtaxAbo)': 'HALBTAXABO', 'Symbol(Voordeelurenabo)': 'VOORDEELURENABO', 'Symbol(SH-Card)': 'SHCARD', 'Symbol(General-Abonnement)': 'GENERALABONNEMENT', }; export const loyaltyCardToString = loyaltyCard => loyaltyCardsReverse[loyaltyCard.type.toString()] !== 'NONE' ? `${loyaltyCardsReverse[loyaltyCard.type.toString()]}-${loyaltyCard.discount}-${loyaltyCard.class}` : 'NONE'; export const loyaltyCardFromString = string => { const splitedString = string.split('-'); if (splitedString[0] === 'NONE') return { type: loyaltyCards[splitedString[0]] }; return { type: loyaltyCards[splitedString[0]], discount: splitedString[1], class: splitedString[2] }; }; export const generateSlug = () => { const len = 8; let result = ''; const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; for (let i = 0; i < len; i++) result += characters.charAt(Math.floor(Math.random() * characters.length)); return result; }; const journeySettings = () => { let params = { stopovers: true, polylines: false, tickets: true, language: t('backendLang'), }; if (settingsState.profile === 'db') { params.loyaltyCard = settingsState.loyaltyCard; params.ageGroup = settingsState.ageGroup; } return params; }; const processJourneys = journeys => journeys.forEach(journey => processJourney(journey)); const processJourney = journey => journey.legs.forEach(leg => processLeg(leg)); export const processLeg = leg => { const elements = [ 'plannedDeparture', 'plannedArrival', 'plannedWhen', 'departure', 'arrival', 'when' ]; elements.forEach(element => { if (leg[element]) leg[element] = new CustomDate(leg[element]); }); if (leg.stopovers) leg.stopovers.forEach(stopover => { elements.forEach(element => { if (stopover[element]) stopover[element] = new CustomDate(stopover[element]); }); }); }; export const getFromPoint = journeys => journeys[0].legs[0].origin; export const getToPoint = journeys => journeys[0].legs[journeys[0].legs.length-1].destination; export const newJourneys = async params => { const { from, to, ...moreOpts } = params; let data; const journeySettingsObj = journeySettings(); if (typeof journeySettingsObj.loyaltyCard === 'string') journeySettingsObj.loyaltyCard = loyaltyCardFromString(journeySettingsObj.loyaltyCard); data = await client.journeys(from, to, { ...moreOpts, ...journeySettingsObj }); data.journeys.forEach((journey, index, journeys) => { journeys[index].refreshToken = hafasToTrainsearch(journey.refreshToken); }); data.slug = generateSlug(); data.indexOffset = 0; data.params = params; data.settings = journeySettingsObj; data.profile = settingsState.profile; await addJourneys(data); processJourneys(data.journeys); return data; }; export const addJourneys = async data => { if (!data) return false; if (typeof data.settings.loyaltyCard === 'object') data.settings.loyaltyCard = loyaltyCardToString(data.settings.loyaltyCard); const journeyEntries = data.journeys.map(j => ({ ...j, settings: data.settings, slug: data.slug, })); const journeysOverviewEntry = { ...data, journeys: data.journeys.map(j => j.refreshToken), }; const historyEntry = { profile: data.profile, fromPoint: getFromPoint(data.journeys), viaPoint: data.params.via, toPoint: getToPoint(data.journeys), slug: data.slug }; await db.addJourneys(journeyEntries, journeysOverviewEntry, historyEntry); }; export const getJourneys = async slug => { let data = await db.getJourneysOverview(slug); if (!data) return null; return { ...data, journeys: await Promise.all(data.journeys.map(refreshToken => getJourney(data.profile, refreshToken))), }; }; export const getMoreJourneys = async (slug, mode) => { const saved = await db.getJourneysOverview(slug); const params = { ...saved.params, ...journeySettings() }; if (typeof params.loyaltyCard === 'string') params.loyaltyCard = loyaltyCardFromString(params.loyaltyCard); params[mode+'Than'] = saved[mode+'Ref']; let { departure, arrival, from, to, ...moreOpt } = params; const [newData, ...existingJourneys] = await Promise.all( [ client.journeys(from, to, moreOpt) ].concat(saved.journeys.map(refreshToken => getJourney(saved.profile, refreshToken))) ); const res = { ...saved, ...newData, }; newData.journeys.forEach(journey => { journey.refreshToken = hafasToTrainsearch(journey.refreshToken); }); if (mode === 'earlier') { res.journeys = newData.journeys.concat(existingJourneys); res.indexOffset += newData.journeys.length; // keep old laterRef res.laterRef = saved.laterRef; } else { res.journeys = existingJourneys.concat(newData.journeys); // keep old earlierRef res.earlierRef = saved.earlierRef; } await addJourneys(res); }; export const refreshJourneys = async (slug) => { const saved = await db.getJourneysOverview(slug); await Promise.all(saved.journeys.map(refreshToken => refreshJourney(saved.profile, refreshToken))); }; export const getJourney = async (profile, refreshToken) => { let journeyObject = await db.getJourney(refreshToken); if (!journeyObject || JSON.stringify(journeyObject.settings) != JSON.stringify(journeySettings())) journeyObject = await refreshJourney(profile, refreshToken); processJourney(journeyObject); return journeyObject; }; export const refreshJourney = async (profile, refreshToken) => { const client = await getHafasClient(profile); const params = journeySettings(); if (params.loyaltyCard) params.loyaltyCard = loyaltyCardFromString(params.loyaltyCard); const [ saved, data ] = await Promise.all([ db.getJourney(refreshToken), client.refreshJourney(trainsearchToHafas(refreshToken), params) ]); const journeyObject = data.journey; journeyObject.refreshToken = hafasToTrainsearch(journeyObject.refreshToken); journeyObject.settings = journeySettings(); if (saved) journeyObject.slug = saved.slug; db.updateJourney(journeyObject); processJourney(journeyObject); return journeyObject; };