summaryrefslogtreecommitdiff
path: root/livetimes.sh
blob: 624b2b3370abaa2c10aff8006a691adb2de4e629 (plain)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/bin/bash

read stop

# function to provide data to a for loop
_jq() {
  echo ${json} | base64 --decode | jq -r ${1}
}

_liveresult() {
  stops=$(curl --fail --silent https://admin.libertybus.je/api/v1/stops/"${stop}")
  stopname=$(echo $stops | jq '.[].name')
  livetimes=$(curl --fail --silent https://admin.libertybus.je/api/v1/soj/stop_updates/${stop})
  exitcode=$?
  # sort livetimes by service_number and eta
  livetimes=$(echo ${livetimes} | jq 'sort_by((.service_number | sub("[^0-9]$"; "") | tonumber), (.service_number | sub("[^A-Z]$"; "") | tostring), .eta)')
  livetimeslen=$(echo ${livetimes} | jq '. | length')
  if [ $exitcode != 0 ]; then
    echo "cURL error - exiting."
    exit 1
  elif [ $livetimeslen = 0 ]; then
    echo "No results found."
    exit 1
  elif [[ ${stopname,,} == *"bus"* ]] || [[ ${stopname,,} == *"station"* ]] || [[ ${stopname,,} == *"stand"* ]]; then
      _rejectbusstation
  else
    for json in $(echo "${livetimes}" | jq -r '.[] | @base64'); do
      if [[ $(_jq '.service_number') != $outroute ]]; then
        result=$(echo $result | sed 's/,$//')
        result="$result | Dest: $(_jq '.destination')[$(_jq '.service_number')] - ETAs: $(_jq '.eta'), "
      else
        result="$result $(_jq '.eta'), "
      fi
      outroute=$(_jq '.service_number')
    done
    result=$(echo $result | sed 's/,$//' | sed 's/|//' )
    echo -e $result
    exit 0
  fi
}

_stopsreturn() {
  stops=$(curl --fail --silent https://admin.libertybus.je/api/v1/stops/"${stop}")
  exitcode=$?
  stopslen=$(echo ${stops} | jq '. | length')
  # if length of $stops array is 1 then only one bus stop matches and we can return live times for that stop
  if [ $exitcode != 0 ]; then
    echo "cURL error - exiting."
    exit 1
  elif [ $stopslen = 1 ]; then
    stop=$(echo ${stops} | jq '.[].stop_id')
    _liveresult
  elif [ $stopslen = 0 ]; then
    echo "No results found."
    exit 1
  # multiple stops returned in $stops so we will return stop names and codes so user can retry
  else
    for json in $(echo "${stops}" | jq -r '.[] | @base64'); do
      result="$result Stop: $(_jq '.name') - Code: $(_jq '.stop_id') |"
      #result="$result Code: $(_jq '.stop_id') |"
    done
    result=$(echo $result | sed 's/ |$//')
    echo -e $result
    exit 0
  fi
}

_rejectbusstation() {
  echo "If you want to see when the next bus for a given route leaves the bus station then try ""!bus <route>"" where <route> is a valid bus route or try ""!bus -h"" for help."
  exit 1
}

# function for now in case I need to reuse somewhere else...
_help() {
  echo "Usage: '!bus <stop>' where <stop> is either the route number, 4 digit stop code, the full unique or partial bus stop name. If a bus stop name is used and there are multiple matches then a list of matching stops will be returned with their codes. -h --help - print this usage information."
  exit 0
}

_nextbus() {
  time=$(date +"%H:%M")
  day=$(date +"%a" | tr [:upper:] [:lower:])
  # set routeday to one of three timetable options
  if [[ $(date +%u) -lt 6 ]]; then
    routeday=mon_fri
  else
    routeday=$(date +"%a" | tr [:upper:] [:lower:])
  fi
  # select all stops from todays trips, where days_of_operation is true for tday, for a given service_number, where stop_name contains "Bus Station Stand"
  nextbus=$(echo $timetables | jq -r --arg routeday "$routeday" --arg day "$day" --arg stop "$stop" '.timetables[] | select(.service_number == $stop) | .timetable.outbound[$routeday].trips[] | select(.days_of_operation[$day] == true) | .stops[] | select(.stop_name | contains("Bus Station Stand"))')
  for json in $(echo "${nextbus}"  | jq -r '. | @base64'); do
    if [[ $(_jq '.departure_time') > $time ]]; then
      echo "Route $stop leaving from $(_jq '.stop_name') at $(_jq '.departure_time')"
      exit 0
    fi
  done
  # if program didn't exit inside for loop then we know the next bus is on a future day so we need to check future days, unfortunately plenty of routes have days where no bus runs so we need to loop until we find the next day with a running bus
  # for loop in range 7 used to prevent possible infinite loop with other methods - if there's not a bus for the next week then something is probably broken
  for in in {1..7}; do
    day=$(date --date="$i day" +"%a" | tr [:upper:] [:lower:])
    case $day in
      mon|tue|wed|thu|fri)
        routeday=mon_fri;;
      sat)
        routeday=sat;;
      sun)
        routeday=sun;;
      *) //
    esac
    nextbus=$(echo $timetables | jq -r --arg routeday "$routeday" --arg day "$day" --arg stop "$stop" '.timetables[] | select(.service_number == $stop) | .timetable.outbound[$routeday].trips[] | select(.days_of_operation[$day] == true) | .stops[] | select(.stop_name | contains("Bus Station Stand"))')
      if [[ ! -z "${nextbus// }" ]]; then
        echo $(echo "Route $stop leaving from $(echo $nextbus | jq -s '.[0].stop_name') at $(echo $nextbus | jq -s '.[0].departure_time') on $day" | sed 's/"//g')
        exit 0
      fi
    done
    # if program didn't exit inside for loop then something is probably broken
    echo "Something broken - hopefully no one ever sees this..."
    exit 1
}

timetables=$(curl --fail --silent https://admin.libertybus.je/cache/timetables/timetable_full.json)
services=$(echo $timetables | jq '.timetables[].service_number')
if [ "$stop" == "-h" ] || [ "$stop" == "--help" ] || [[ -z "${stop// }" ]]; then
  _help
# checks if input pattern matches a 4 digit bus stop code
elif [[ "$stop" =~ ^-?[0-9]+$ ]] && [ $(echo ${#stop} == 4) ]; then
  _liveresult
# checks if input is a valid bus route
elif [[ ${services[@]} =~ ${stop^^} ]]; then
  _nextbus
elif [[ ${stop,,} == *"bus"* ]] || [[ ${stop,,} == *"station"* ]] || [[ ${stop,,} == *"stand"* ]]; then
  _rejectbusstation
else
 _stopsreturn
fi