import json, tables, options, math import nimhafas import ../types, ../cache_types, formaters template getPlannedOrPrognosedTime(obj: untyped): int64 = if not obj.prognosedTime.isNone: obj.prognosedTime.get else: obj.plannedTime template stopGetPlannedOrPrognosedTime(obj: untyped): int64 = if not obj.prognosedTime.isNone: obj.prognosedTime.get elif not obj.plannedTime.isNone: obj.plannedTime.get else: 0 proc renderJourney*(data: CacheObject, id: string): JsonNode = result = newJObject() if not data.journeys.hasKey(id): raise newException(notFoundException, "Diese Reise konnte nicht gefunden werden.") let journey = data.journeys[id] let departureLeg = journey.legs[0] let arrivalLeg = journey.legs[journey.legs.len-1] let departureTime = getPlannedOrPrognosedTime(departureLeg.departure) let arrivalTime = getPlannedOrPrognosedTime(arrivalLeg.arrival) var changes: int64 var changesDuration: int64 var lastArrival: LegPart result["REQ_ID"] = %data.reqId result["ID"] = %id result["FROM"] = %formatPoint(departureLeg.departure.point) result["TO"] = %formatPoint(arrivalLeg.arrival.point) result["DATE"] = %formatTime(departureTime, "date") result["DURATION"] = %formatDuration(arrivalTime - departureTime) result["CHANGES"] = %0 result["LEGS"] = newJArray() for leg in journey.legs: if leg.isWalking != false: result["LEGS"].add(%* { "IS_WALKING": true, "ARRIVAL_POINT": formatPoint(leg.arrival.point), "LOCATION": formatPoint(leg.arrival.point), "DISTANCE": leg.distance.get }) elif leg.isTransfer != false: var distance: int if not leg.distance.isNone: distance = leg.distance.get else: distance = 0 result["LEGS"].add(%* { "IS_TRANSFER": true, "ARRIVAL_POINT": formatPoint(leg.arrival.point), "DISTANCE": distance }) else: let arrivalTime = getPlannedOrPrognosedTime(leg.arrival) let departureTime = getPlannedOrPrognosedTime(leg.departure) var legDuration: int64 var hasAdditionalName: bool var additionalName: string var hasMarudorUrl: bool var marudorUrl: string var hasTrainType: bool var trainType: string # is this leg a change? if lastArrival.plannedTime != 0: let lastArrivalTime = getPlannedOrPrognosedTime(lastArrival) result["LEGS"].add(%* { "IS_CHANGE": true, "DURATION": formatDuration(departureTime - lastArrivalTime) }) if leg.line.get.product == nationalExp or leg.line.get.product == national or leg.line.get.product == regionalExp or leg.line.get.product == regional: hasMarudorUrl = true if not leg.line.get.additionalName.isNone(): hasAdditionalName = true additionalName = leg.line.get.additionalName.get marudorUrl = "https://marudor.de/details/" & leg.line.get.additionalName.get & "/" & $(leg.departure.plannedTime*1000) else: hasAdditionalName = false marudorUrl = "https://marudor.de/details/" & leg.line.get.name & "/" & $(leg.departure.plannedTime*1000) if not leg.line.get.trainType.isNone(): hasTrainType = true trainType = leg.line.get.trainType.get else: hasTrainType = false var remarks = newJArray() if not leg.remarks.isNone(): for remark in leg.remarks.get: if not remark.text.isNone(): remarks.add(%remark.text.get) var stopovers = newJArray() if not leg.stopovers.isNone(): for stopover in leg.stopovers.get: let stopDepartureTime = stopGetPlannedOrPrognosedTime(stopover.departure) let stopArrivalTime = stopGetPlannedOrPrognosedTime(stopover.arrival) var departureDelay: string var arrivalDelay: string var departureTimeFormated: string var arrivalTimeFormated: string var departureHasDelay: bool var arrivalHasDelay: bool var platform: string var platformHasChanged: bool if stopover.departure.plannedTime.isSome and stopover.departure.prognosedTime.isSome: let delay = floorDiv((stopover.departure.prognosedTime.get - stopover.departure.plannedTime.get), 60) if delay != 0: departureHasDelay = true if delay > 0: departureDelay = "+" departureDelay &= $delay if stopover.arrival.plannedTime.isSome and stopover.arrival.prognosedTime.isSome: let delay = floorDiv((stopover.arrival.prognosedTime.get - stopover.arrival.plannedTime.get), 60) if delay != 0: arrivalHasDelay = true if delay > 0: arrivalDelay = "+" arrivalDelay &= $delay if stopDepartureTime > 0: departureTimeFormated = formatTime(stopDepartureTime, "") else: departureTimeFormated = "-" if stopArrivalTime > 0: arrivalTimeFormated = formatTime(stopArrivalTime, "") else: arrivalTimeFormated = "-" if stopover.departure.prognosedPlatform.isSome() or stopover.departure.plannedPlatform.isSome(): if stopover.departure.prognosedPlatform.isSome(): platform = stopover.departure.prognosedPlatform.get platformHasChanged = true elif stopover.departure.plannedPlatform.isSome(): platform = stopover.departure.plannedPlatform.get elif stopover.arrival.prognosedPlatform.isSome() or stopover.arrival.plannedPlatform.isSome(): if stopover.arrival.prognosedPlatform.isSome(): platform = stopover.arrival.prognosedPlatform.get platformHasChanged = true elif stopover.arrival.plannedPlatform.isSome(): platform = stopover.arrival.plannedPlatform.get else: platform = "-" stopovers.add(%* { "STATION_NAME": stopover.stop.name, "STATION_ID": stopover.stop.id, "IS_CANCELLED": stopover.cancelled, "ARRIVAL_TIME": arrivalTimeFormated, "ARRIVAL_HAS_DELAY": arrivalHasDelay, "ARRIVAL_DELAY": arrivalDelay, "DEPARTURE_TIME": departureTimeFormated, "DEPARTURE_HAS_DELAY": departureHasDelay, "DEPARTURE_DELAY": departureDelay, "PLATFORM": platform, "PLATFORM_HAS_CHANGED": platformHasChanged }) legDuration = arrivalTime - departureTime lastArrival = leg.arrival inc(changes) result["LEGS"].add(%* { "IS_VEHICLE": true, "IS_CANCELLED": leg.cancelled, "LINE": leg.line.get.name, "HAS_ADDITIONAL_NAME": hasAdditionalName, "ADDITIONAL_NAME": additionalName, "HAS_MARUDOR_URL": hasMarudorUrl, "MARUDOR_URL": marudorUrl, "HAS_TRAIN_TYPE": hasTrainType, "TRAIN_TYPE": trainType, "DIRECTION": leg.direction.get, "LEG_DURATION": formatDuration(legDuration), "LEG_DEPARTURE_TIMESTAMP": leg.departure.plannedTime, "ARRIVAL_POINT": formatPoint(leg.arrival.point), "DEPARTURE_POINT": formatPoint(leg.departure.point), "STOPOVERS": stopovers, "REMARKS": remarks }) result["CHANGES"] = %(changes-1)