ctucx.git: oeffi-web

[nimlang] oeffisearch fork that works without javascript

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
import json, tables, options, sequtils, strutils, algorithm, math
import nimhafas
import ../cache_types, formaters

template getPlannedOrPrognosedTime(obj: untyped): int64 =
  if not obj.prognosedTime.isNone: 
    obj.prognosedTime.get
  else:
    obj.plannedTime

proc renderJourneys*(data: CacheObject): JsonNode = 
  var data = data;

  result = newJObject()
  
  result["REQ_ID"]   = %data.reqId
  result["FROM"]     = %formatPoint(data.params.fromPoint)
  result["TO"]       = %formatPoint(data.params.toPoint)
  result["JOURNEYS"] = newJArray()

  var journeys = toSeq(data.journeys.pairs).map(proc (i: (string, Journey)): (int, Journey) = (parseInt(i[0]), i[1])).sorted(proc (b, a: (int, Journey)): int = b[0] - a[0])

  for id, journey in items(journeys):
    let departureLeg     = journey.legs[0]
    let arrivalLeg       = journey.legs[journey.legs.len-1]

    let departureTime    = getPlannedOrPrognosedTime(departureLeg.departure)
    let arrivalTime      = getPlannedOrPrognosedTime(arrivalLeg.arrival)

    var products         = initTable[string, seq[string]]()
    var productsCombined:  seq[string]

    var changes:           int
    var changesDuration:   int
    var cancelled:         bool

    var departureDelay:    string
    var arrivalDelay:      string

    var departureHasDelay: bool
    var arrivalHasDelay:   bool

    if departureLeg.departure.prognosedTime.isSome:
      let delay = floorDiv((departureLeg.departure.prognosedTime.get - departureLeg.departure.plannedTime), 60)

      if delay != 0:
        departureHasDelay = true

      if delay > 0:
        departureDelay = "+"

      departureDelay &= $delay

    if arrivalLeg.arrival.prognosedTime.isSome:
      let delay = floorDiv((arrivalLeg.arrival.prognosedTime.get - arrivalLeg.arrival.plannedTime), 60)

      if delay != 0:
        arrivalHasDelay = true

      if delay > 0:
        arrivalDelay = "+"

      arrivalDelay &= $delay

    for leg in journey.legs:
      if leg.cancelled != false:
        cancelled = true

      if leg.isWalking:
        products["Fußweg"] = newSeq[string]()
        continue

      if leg.isTransfer: continue

      inc(changes)

      if not products.contains(leg.line.get.productName):
        products[leg.line.get.productName] = newSeq[string]()

      if leg.line.get.trainTypeShort.isSome():
        products[leg.line.get.productName].add(leg.line.get.trainTypeShort.get)

    for product, types in pairs(products):
      let typesLen = types.len

      if typesLen > 1:
        productsCombined.add(product & " (" & types.join(", ") & ")")
      elif typesLen == 1:
        productsCombined.add(product & " " & types[0])
      else:
        productsCombined.add(product)

    let productsString = productsCombined.join(", ")


    result["JOURNEYS"].add(%* {
        "ID":                  id,
        "ARRIVAL":             formatTime(arrivalTime, ""),
        "ARRIVAL_HAS_DELAY":   arrivalHasDelay,
        "ARRIVAL_DELAY":       arrivalDelay,
        "DEPARTURE":           formatTime(departureTime, ""),
        "DURATION":            formatDuration(arrivalTime - departureTime),
        "DEPARTURE_HAS_DELAY": departureHasDelay,
        "DEPARTURE_DELAY":     departureDelay,
        "CHANGES_DUR":         changesDuration,
        "CHANGES":             changes-1,
        "PRODUCTS":            productsString,
        "IS_CANCELLED":        cancelled
      })