Last active
December 14, 2015 03:19
-
-
Save JoelQFernandez/5020161 to your computer and use it in GitHub Desktop.
Menu driven BASH script for accessing CTA Bus Tracker, http://www.ctabustracker.com/bustime/eta/eta.jsp. Also have the option to manually enter the bus stop number to get arrival times. ./CTABusTracker.sh -r <Route Number> -s <Stop ID>
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Filename: CTABusTracker.sh | |
## Author: Joel Fernandez | |
## Date: | |
## Description: Command Line Utility for CTA's Bus Tracker | |
main() | |
{ | |
############################## | |
## Internal Field Separator ## | |
############################## | |
SAVEIFS=$IFS | |
IFS=$(echo -en "\n\b") | |
###################### | |
## Global Variables ## | |
###################### | |
## CTA Bus Tracker ## API Key | |
Key="key=Pt2xR9LVfGhUgmVgiJr25PiMR" | |
## CTA Bus Tracker ## Base URLs | |
TimeURL="http://www.ctabustracker.com/bustime/api/v1/gettime?" | |
VehiclesURL="http://www.ctabustracker.com/bustime/api/v1/getvehicles?" | |
PatternsURL="http://www.ctabustracker.com/bustime/api/v1/getpatterns?" | |
ServiceBulletinsURL="http://www.ctabustracker.com/bustime/api/v1/getservicebulletins?" | |
RoutesURL="http://www.ctabustracker.com/bustime/api/v1/getroutes?" | |
DirectionsURL="http://www.ctabustracker.com/bustime/api/v1/getdirections?" | |
StopsURL="http://www.ctabustracker.com/bustime/api/v1/getstops?" | |
PredictionsURL="http://www.ctabustracker.com/bustime/api/v1/getpredictions?" | |
while getopts “hr:s:” OPTION | |
do | |
case $OPTION in | |
h) | |
usage | |
exit 1 | |
;; | |
r) | |
RT=$OPTARG | |
;; | |
s) | |
STPID=$OPTARG | |
;; | |
?) | |
routes | |
directions | |
stops | |
predictions | |
;; | |
esac | |
done | |
if [[ $RT ]] || [[ $STPID ]]; then | |
predictionsCLI | |
else | |
routes | |
directions | |
stops | |
predictions | |
fi | |
} | |
usage() | |
{ | |
clear; | |
cat << EOF | |
Menu driven and command line BASH script for accessing CTAs Bus Tracker, | |
http://www.ctabustracker.com/bustime/eta/eta.jsp. | |
OPTIONS: | |
-h Help | |
-r Route Number | |
-s Stop ID | |
To get arrival times for the North Ave & Milwaukee/Damen (Blue Line) bus stop, | |
enter the following at the command line. | |
Route Number__ __Stop ID | |
| | | |
| | | |
| | | |
./CTABusTracker.sh -r 72 -s 945 | |
To access the CTA Bus Tracker Menu. Just launch the script without any arguments. | |
EOF | |
} | |
## | |
## Function: XML2ARRAY | |
## Accepts Input From Xpath Query's And Inserts Carriage Return | |
## Between XML Nodes In Order To Save The Query Results As An Array | |
## | |
XML2ARRAY() | |
{ | |
sed 's/></\ | |
</g' | cut -f2 -d">" | cut -f1 -d"<" | |
} | |
############################################################################### | |
## Function: routes() | |
## Get List Of Available Bus Routes And Displays It On The Screen. | |
## The Bus Route Selection Is Passed To The directions() Function. | |
############################################################################### | |
routes() | |
{ | |
routesURL; | |
routesVariables; | |
clear; | |
routesMenu | column; | |
routesSelection; | |
} | |
## | |
## Function: routesURL() | |
## Construct Routes URL, Save HTML Page. | |
## | |
routesURL() | |
{ | |
html=$(curl -s $RoutesURL$Key); | |
} | |
## | |
## Function: routesVariables() | |
## Scrapes The routesURL For Route Numbers And Corresponding | |
## Route Names. | |
## | |
routesVariables() | |
{ | |
routeCount=$(echo "$html" | xpath 'count(/bustime-response/route)' 2> /dev/null); | |
rt=( $(echo "$html" | xpath //rt 2> /dev/null | stopsAMP | XML2ARRAY) ); | |
rtnm=( $(echo "$html" | xpath //rtnm 2> /dev/null | stopsAMP | XML2ARRAY) ); | |
} | |
## | |
## Function: routesMenu() | |
## Menu That Displays A List Of All Available Bus Routes. | |
## Accepts Input From routesVariables() Function. | |
## | |
routesMenu() | |
{ | |
for ((i=0;i<${#rt[@]};i++));do | |
## Add Numerals To The Bus Route Menu | |
printf "%5s%-40s\n" "${rt[i]}) " \ | |
"${rtnm[i]}" | |
done | |
} | |
## | |
## Function: routesSelection() | |
## Accepts User Input And Captures The Bus Route Selection. | |
## | |
routesSelection() | |
{ | |
echo; | |
echo; | |
echo; | |
echo; | |
read -p "PLEASE SELECT THE BUS ROUTE: " REPLY1; | |
echo; | |
echo; | |
} | |
############################################################################### | |
## Function: directions() | |
## Displays The Direction The Bus Routes Goes. | |
## The Direction Selection Is Passed Along To The stops() Function. | |
############################################################################### | |
directions() | |
{ | |
clear; | |
for ((n=0;n<$routeCount;n++)); do | |
if [ ${rt[n]} = $REPLY1 ]; then | |
directionsURL; | |
directionsVariables; | |
directionsMenu | column; | |
directionsSelection; | |
fi; | |
done; | |
} | |
## | |
## Function: directionsURL() | |
## Construct Directions URL, Save HTML Page. | |
## | |
directionsURL() | |
{ | |
html=$( curl -s $DirectionsURL$Key"&rt=""$REPLY1"); | |
} | |
## | |
## Function: directionsVariables() | |
## Scraps The directionsURL For The Direcrections For Each Bus Route. | |
## Accepts Input From The routesSelection() Function. | |
## | |
directionsVariables() | |
{ | |
dir=( $( echo "$html" | xpath //dir 2> /dev/null | XML2ARRAY) ); | |
} | |
## | |
## Function: directionsMenu() | |
## Menu That Displays The Directions A Bus Rout Travels. | |
## Accepts Input From directionsVariables() Function. | |
## | |
directionsMenu() | |
{ | |
for ((i=0;i<${#dir[@]};i++));do | |
## Add Numerals To The Bus Direction Menu | |
printf "%5s%-40s\n" "$(($i+1))) " \ | |
"${dir[i]}" | |
done; | |
} | |
## | |
## Function: directionsSelection() | |
## Accepts User Input And Captures The Bus Direction Selection. | |
## | |
directionsSelection() | |
{ | |
echo; | |
echo; | |
echo; | |
echo; | |
read -p "PLEASE SELECT THE BUSES DIRECTION: " REPLY2; | |
echo; | |
echo; | |
} | |
############################################################################### | |
## Function: stops() | |
## Displays The Bus Stops. | |
## The Bus Stop Selection Is Captured and Passed Along To The | |
## predictions() Function. | |
############################################################################### | |
stops() | |
{ | |
for ((n=1;n<=${#dir[@]};n++));do | |
if [ $REPLY2 = $n ];then | |
stopsURL; | |
stopsVariables | |
echo; | |
echo; | |
clear; | |
stopsMenu | column; | |
stopsReply; | |
fi; | |
done; | |
} | |
## | |
## Function: stopsURL() | |
## Construct Stops URL, Save HTML Page. | |
## | |
stopsURL() | |
{ | |
html=$( curl -s $StopsURL$Key"&rt=""$REPLY1""&dir="$(echo ${dir[$REPLY2-1]} | stopsTWENTY)); | |
} | |
## | |
## Function: stopsVariables() | |
## Scrapes The stopsURL For The Bus Stop And Number. | |
## Accepts Input From The directionsSelection() Function. | |
## | |
stopsVariables() | |
{ | |
stpnm=( $( echo "$html" | xpath //stpnm 2> /dev/null | XML2ARRAY) ); | |
stpid=( $( echo "$html" | xpath //stpid 2> /dev/null | XML2ARRAY) ); | |
} | |
## | |
## Function: stopsMenu() | |
## Menu That Displays The Stop Names For Each Bus Route. | |
## Accepts Input From The stopsVariables() Function. | |
## | |
stopsMenu() | |
{ | |
for ((i=0;i<${#stpnm[@]};i++));do | |
## Add Numerals To The Bus Direction Menu | |
printf "%5s%-40s\n" "$(($i+1))) " \ | |
"${stpnm[i]}" | stopsAMP; | |
done; | |
} | |
## | |
## Function: stopsReply | |
## Accepts User Input And Captures The Bus Stop Selection. | |
## | |
stopsReply() | |
{ | |
echo; | |
echo; | |
echo; | |
echo; | |
read -p "PLEASE SELECT THE BUS STOP: " REPLY3; | |
echo; | |
echo; | |
} | |
## | |
## Function: stopsAMP() | |
## Quick And Dirty sed Command To Remove "&" From The stpnm Variable | |
## In Order For The Bus Stop Name To Be Displayed Properly On The routesMenu(), | |
## predictionsHeader () and predictionsNoHeader() Functions | |
## | |
stopsAMP() | |
{ | |
sed 's/amp;//g'; | |
} | |
## | |
## Function: stopsTWENTY() | |
## Quick And Dirty sed Command To Add "%20" To The dir Variable To Help | |
## Construct URLs For The stopVariables() And predictionsNoHeader() Functions. | |
## | |
stopsTWENTY() | |
{ | |
## Add "%20" To StopURL Variable | |
sed 's/ /%20/g'; | |
} | |
############################################################################### | |
## Function: predictions() | |
## Displays The Predicted Arrival Time For The Bus Stop. | |
############################################################################### | |
predictions() | |
{ | |
for ((n=1;n<=${#stpid[@]};n++));do | |
if [ $REPLY3 = $n ];then | |
predictionsURL; | |
predictionsVariables; | |
fi; | |
done; | |
if [ "$msg" = "No service scheduled" ];then | |
clear; | |
predictionsNoHeader; | |
predictionsNoServiceScheduled; | |
elif [ $prd = 0 ];then | |
clear; | |
predictionsNoHeader; | |
predictionsNoArrivalTimes; | |
else | |
clear; | |
predictionsHeader; | |
for ((i=0;i<"$prd";i++));do | |
predictionsSchedule; | |
done; | |
predictionsMargin | |
fi; | |
} | |
############################################################################### | |
## Function: predictionsCLI() | |
## Displays The Predicted Arrival Time For The Bus Stop From Command | |
## Line Argument. | |
############################################################################### | |
predictionsCLI() | |
{ | |
predictionsCLIURL; | |
predictionsVariables; | |
if [ "$msg" = "No service scheduled" ];then | |
clear; | |
predictionsNoHeader; | |
predictionsNoServiceScheduled; | |
elif [ $prd = 0 ];then | |
clear; | |
predictionsNoHeader; | |
predictionsNoArrivalTimes; | |
else | |
clear; | |
predictionsHeader; | |
for ((i=0;i<"$prd";i++));do | |
predictionsSchedule; | |
done; | |
predictionsMargin | |
fi; | |
} | |
## | |
## Function: predictionsEPOCH() | |
## Converts tmpstmp and prdtm Variables To An EPOCH Value. | |
## Used To Help Calculate The Predicted Arrival Time. | |
## | |
predictionsEPOCH() | |
{ | |
min=$(( 60 )); | |
hr=$(( 60*60 )); | |
day=$(( 60*60*24 )); | |
month=$(( (60*60*24)*(365/12) )); | |
year=$(( 60*60*24*365 )); | |
sed 's/\([0-9][0-9][0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)/\1 \2 \3/g' | \ | |
sed 's/:/ /g' | \ | |
awk '{ print ($1 * '$year') + ($2 * '$month') + ($3 * '$day') + \ | |
($4 * '$hr') + ($5 * '$min') }'; | |
} | |
## | |
## Function: predictionsURL() | |
## Construct Predictions URL, Save HTML Page. | |
## | |
predictionsURL() | |
{ | |
html=$( curl -s $PredictionsURL$Key"&rt=""$REPLY1""&stpid="${stpid[n-1]}); | |
} | |
## | |
## Function: predictionsCLIURL() | |
## Construct Predictions URL From Command Line Arguments, Save HTML Page. | |
## | |
predictionsCLIURL() | |
{ | |
html=$( curl -s $PredictionsURL$Key"&rt="$RT"&stpid="$STPID); | |
} | |
## | |
## Function: predictionsVariables() | |
## Scrapes The predictionsURL For A Bunch Of Variables | |
## | |
predictionsVariables() | |
{ | |
prd=$( echo "$html" | \ | |
xpath 'count(//stpnm)' 2> /dev/null); | |
if [ $prd -ge 5 ];then | |
prd=5; | |
fi; | |
margin=$(( 5 - $prd )); | |
error=( $( echo "$html" | \ | |
grep "<error>" | \ | |
wc -l) ); | |
msg=( $( echo "$html" | \ | |
xpath //msg 2> /dev/null | \ | |
XML2ARRAY) ); | |
tmstmp=( $( echo "$html" | \ | |
xpath //tmstmp 2> /dev/null | \ | |
XML2ARRAY | \ | |
predictionsEPOCH) ); | |
typ=( $( echo "$html" | \ | |
xpath //msg 2> /dev/null | \ | |
XML2ARRAY) ); | |
stpid=( $( echo "$html" | \ | |
xpath //stpid 2> /dev/null | \ | |
XML2ARRAY) ); | |
stpnm=( $( echo "$html" | \ | |
xpath //stpnm 2> /dev/null | \ | |
XML2ARRAY | \ | |
stopsAMP) ); | |
vid=( $( echo "$html" | \ | |
xpath //vid 2> /dev/null | \ | |
XML2ARRAY) ); | |
dstp=( $( echo "$html" | \ | |
xpath //dstp 2> /dev/null | \ | |
XML2ARRAY) ); | |
rt=( $( echo "$html" | \ | |
xpath //rt 2> /dev/null | \ | |
XML2ARRAY) ); | |
rtdir=( $( echo "$html" | \ | |
xpath //rtdir 2> /dev/null | \ | |
XML2ARRAY) ); | |
des=( $( echo "$html" | \ | |
xpath //des 2> /dev/null | \ | |
XML2ARRAY | \ | |
sed 's/ Blue Line//g') ); | |
prdtm=$( echo "$html" | \ | |
xpath //prdtm 2> /dev/null | \ | |
XML2ARRAY | \ | |
predictionsEPOCH); | |
dly=( $( echo "$html" | \ | |
xpath //dly 2> /dev/null | \ | |
XML2ARRAY) ); | |
arrival=( $(echo "$prdtm" | \ | |
awk '{ print ( ( $1 - '$tmstmp' ) / 60 ) }') ); | |
} | |
predictionsNoHeader() | |
{ | |
rtdir=( $( curl -s $DirectionsURL$Key"&rt="${rt[$REPLY1-1]} | \ | |
xpath //dir 2> /dev/null | \ | |
XML2ARRAY) ); | |
for n in ${rtdir[@]};do | |
stpnm=$(curl -s $StopsURL$Key"&rt="${rt[$REPLY1-1]}"&dir="$(echo $n | stopsTWENTY) | \ | |
xpath //stop[stpid=$stpid] | \ | |
xpath //stpnm 2> /dev/null | \ | |
XML2ARRAY | \ | |
stopsAMP); | |
if [ "$stpnm" != "" ];then | |
clear; | |
printf "%2s%38s\n" "${rt[$REPLY1-1]}" "$stpnm"; | |
printf "%40s\n" "$rtdir"; | |
fi; | |
done; | |
} | |
predictionsNoServiceScheduled() | |
{ | |
title="NO SERVICE IS SCHEDULED"; | |
COLUMNS=40;printf "%*s\n" $(((${#title}+$COLUMNS)/2)) "$title"; | |
echo; | |
echo; | |
echo; | |
echo; | |
} | |
predictionsNoArrivalTimes() | |
{ | |
title="NO ARRIVAL TIMES SCHEDULED"; | |
COLUMNS=40;printf "%*s\n" $(((${#title}+$COLUMNS)/2)) "$title"; | |
echo; | |
echo; | |
echo; | |
echo; | |
} | |
predictionsHeader() | |
{ | |
printf "%2s%38s\n" "$rt" "$stpnm"; | |
printf "%40s\n" "$rtdir"; | |
} | |
predictionsSchedule() | |
{ | |
COL1="BUS ${vid[i]}"; | |
COL3="${des[i]}"; | |
COL5=$( | |
if [ "${dly[i]}" = "true" ];then | |
echo "DELAYED" | |
elif [ ${arrival[i]} -le 1 ];then | |
echo "APPROACHING"; | |
else | |
echo "${arrival[i]} MIN"; | |
fi); | |
width=40; | |
width1=$( echo $COL1 | \ | |
wc -c); | |
width3=$( echo $COL3 | \ | |
wc -c); | |
width5=$( echo $COL5 | \ | |
wc -c); | |
width2=$(( ($width - $width1 - $width3 - $width5) / 2 )); | |
width4=$(( $width - $width1 - $width2 - $width3 - $width5 )); | |
printf "%-${width1}s%${width2}s%${width3}s%${width4}s%${width5}s\n" "$COL1" "" "$COL3" "" "$COL5"; | |
} | |
predictionsMargin() | |
{ | |
for ((i=0;i<$margin;i++)); do | |
echo | |
done | |
} | |
main $@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment