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
|
#!/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 day 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 actually tomorrow in which case we'll return the zeroth item of the array - this is probably wrong if the day is Friday, Saturday or Sunday as timetables switch on those days.
echo $(echo "Route $stop leaving from $(echo $nextbus | jq -s '.[0].stop_name') at $(echo $nextbus | jq -s '.[0].departure_time') tomorrow" | sed 's/"//g')
exit 0
}
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
|