Skip to content

Instantly share code, notes, and snippets.

@JoelQFernandez
Last active December 14, 2015 03:19
Show Gist options
  • Save JoelQFernandez/5020161 to your computer and use it in GitHub Desktop.
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>
## 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 "&amp;" 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