Merge branch 'master' of https://github.com/maxious/ACTBus-ui
Merge branch 'master' of https://github.com/maxious/ACTBus-ui

Conflicts:
include/common-template.inc.php

file:a/about.php -> file:b/about.php
--- a/about.php
+++ b/about.php
@@ -12,7 +12,7 @@
 href="https://github.com/maxious/ACTBus-data">transit 
 feed</a> and <a href="https://github.com/maxious/ACTBus-ui">this 
 site</a> available from github.<br />
-Uses jQuery Mobile, PHP, Ruby, Python, Google Transit Feed Specification tools, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service<br />
+Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service<br />
 <br />
 Feedback encouraged; contact maxious@lambdacomplex.org<br />
     <br />
@@ -25,7 +25,7 @@
 All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend, 
 change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site 
 without prior notice. </small>
-<?
+<?php
 include_footer();
 ?>
 

--- a/aws/awsStartup.sh
+++ b/aws/awsStartup.sh
@@ -1,7 +1,8 @@
 #!/bin/bash
-#this script should be run from a fresh git checkout from http://maxious.lambdacomplex.org
+#this script should be run from a fresh git checkout from github
 #ami base must have yum install lighttpd-fastcgi, git, tomcat6 
-#screen php-cli php-gd tomcat6-webapps tomcat6-admin-webapps svn maven2
+#php-cli php-gd tomcat6-webapps tomcat6-admin-webapps svn maven2
+#postgres postgres-server php-pg
 #http://www.how2forge.org/installing-lighttpd-with-php5-and-mysql-support-on-fedora-12
 
 cp /root/aws.php /tmp/
@@ -10,12 +11,22 @@
 chcon -R -h root:object_r:httpd_sys_content_t /var/www/*
 chcon -R -t httpd_sys_content_rw_t /var/www/lib/staticmaplite/cache
 chmod -R 777 /var/www/lib/staticmaplite/cache 
+chcon -R -t httpd_sys_content_rw_t /var/www/labs/tiles
+chmod -R 777 /var/www/labs/tiles
 wget http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \
 -O /var/www/cbrfeed.zip
-easy_install transitfeed
-easy_install simplejson
-screen -S viewsh -X quit
-screen -S viewsh -d -m /var/www/view.sh
+
+createdb transitdata
+createlang -d transitdata plpgsql
+psql -d transitdata -f /var/www/lib/postgis.sql
+# curl https://github.com/maxious/ACTBus-ui/raw/master/transitdata.cbrfeed.sql.gz -o transitdata.cbrfeed.sql.gz 
+#made with pg_dump transitdata | gzip -c >  transitdata.cbrfeed.sql.gz
+gunzip /var/www/transitdata.cbrfeed.sql.gz
+psql -d transitdata -f /var/www/transitdata.cbrfeed.sql
+#createuser transitdata -SDRP
+#password transitdata
+#psql -d transitdata -c \"GRANT SELECT ON TABLE agency,calendar,calendar_dates,routes,stop_times,stops,trips TO transitdata;\"
+php /var/www/updatedb.php
 
 wget http://s3-ap-southeast-1.amazonaws.com/busresources/Graph.obj \
 -O /tmp/Graph.obj
@@ -26,4 +37,3 @@
 -O /usr/share/tomcat6/webapps/opentripplanner-api-webapp.war
 /etc/init.d/tomcat6 restart
 
-

file:b/aws/pg_hba.conf (new)
--- /dev/null
+++ b/aws/pg_hba.conf
@@ -1,1 +1,75 @@
+# PostgreSQL Client Authentication Configuration File
+# ===================================================
+#
+# Refer to the "Client Authentication" section in the
+# PostgreSQL documentation for a complete description
+# of this file.  A short synopsis follows.
+#
+# This file controls: which hosts are allowed to connect, how clients
+# are authenticated, which PostgreSQL user names they can use, which
+# databases they can access.  Records take one of these forms:
+#
+# local      DATABASE  USER  METHOD  [OPTIONS]
+# host       DATABASE  USER  CIDR-ADDRESS  METHOD  [OPTIONS]
+# hostssl    DATABASE  USER  CIDR-ADDRESS  METHOD  [OPTIONS]
+# hostnossl  DATABASE  USER  CIDR-ADDRESS  METHOD  [OPTIONS]
+#
+# (The uppercase items must be replaced by actual values.)
+#
+# The first field is the connection type: "local" is a Unix-domain socket,
+# "host" is either a plain or SSL-encrypted TCP/IP socket, "hostssl" is an
+# SSL-encrypted TCP/IP socket, and "hostnossl" is a plain TCP/IP socket.
+#
+# DATABASE can be "all", "sameuser", "samerole", a database name, or
+# a comma-separated list thereof.
+#
+# USER can be "all", a user name, a group name prefixed with "+", or
+# a comma-separated list thereof.  In both the DATABASE and USER fields
+# you can also write a file name prefixed with "@" to include names from
+# a separate file.
+#
+# CIDR-ADDRESS specifies the set of hosts the record matches.
+# It is made up of an IP address and a CIDR mask that is an integer
+# (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that specifies
+# the number of significant bits in the mask.  Alternatively, you can write
+# an IP address and netmask in separate columns to specify the set of hosts.
+#
+# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi", "krb5",
+# "ident", "pam", "ldap" or "cert".  Note that "password" sends passwords
+# in clear text; "md5" is preferred since it sends encrypted passwords.
+#
+# OPTIONS are a set of options for the authentication in the format
+# NAME=VALUE. The available options depend on the different authentication
+# methods - refer to the "Client Authentication" section in the documentation
+# for a list of which options are available for which authentication methods.
+#
+# Database and user names containing spaces, commas, quotes and other special
+# characters must be quoted. Quoting one of the keywords "all", "sameuser" or
+# "samerole" makes the name lose its special character, and just match a
+# database or username with that name.
+#
+# This file is read on server startup and when the postmaster receives
+# a SIGHUP signal.  If you edit the file on a running system, you have
+# to SIGHUP the postmaster for the changes to take effect.  You can use
+# "pg_ctl reload" to do that.
 
+# Put your actual configuration here
+# ----------------------------------
+#
+# If you want to allow non-local connections, you need to add more
+# "host" records. In that case you will also need to make PostgreSQL listen
+# on a non-local interface via the listen_addresses configuration parameter,
+# or via the -i or -h command line switches.
+#
+
+
+
+# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
+
+# "local" is for Unix domain socket connections only
+local   all         all                               trust
+# IPv4 local connections:
+host    all         all         127.0.0.1/32          trust
+# IPv6 local connections:
+host    all         all         ::1/128               trust
+

 Binary files a/css/images/01-refresh.png and /dev/null differ
file:a/css/images/02-redo.png (deleted)
 Binary files a/css/images/02-redo.png and /dev/null differ
 Binary files a/css/images/06-magnify.png and /dev/null differ
 Binary files a/css/images/07-map-marker.png and /dev/null differ
 Binary files a/css/images/101-gameplan.png and /dev/null differ
file:a/css/images/102-walk.png (deleted)
 Binary files a/css/images/102-walk.png and /dev/null differ
file:a/css/images/103-map.png (deleted)
 Binary files a/css/images/103-map.png and /dev/null differ
 Binary files a/css/images/121-landscape.png and /dev/null differ
 Binary files a/css/images/13-target.png and /dev/null differ
 Binary files a/css/images/139-flags.png and /dev/null differ
 Binary files a/css/images/145-persondot.png and /dev/null differ
 Binary files a/css/images/184-warning.png and /dev/null differ
 Binary files a/css/images/193-location-arrow.png and /dev/null differ
file:a/css/images/28-star.png (deleted)
 Binary files a/css/images/28-star.png and /dev/null differ
file:a/css/images/53-house.png (deleted)
 Binary files a/css/images/53-house.png and /dev/null differ
 Binary files a/css/images/55-network.png and /dev/null differ
 Binary files a/css/images/57-download.png and /dev/null differ
 Binary files a/css/images/58-bookmark.png and /dev/null differ
file:a/css/images/59-flag.png (deleted)
 Binary files a/css/images/59-flag.png and /dev/null differ
 Binary files a/css/images/60-signpost.png and /dev/null differ
file:a/css/images/73-radar.png (deleted)
 Binary files a/css/images/73-radar.png and /dev/null differ
 Binary files a/css/images/74-location.png and /dev/null differ
 Binary files a/css/images/83-calendar.png and /dev/null differ
 Binary files /dev/null and b/css/images/91-beaker-2.png differ
--- a/feedback.php
+++ b/feedback.php
@@ -26,7 +26,7 @@
 }
 if (isset($_REQUEST['feedback']) || isset($_REQUEST['newlocation'])){
 	sendEmail("bus.lambda feedback",print_r($_REQUEST,true));
-	echo "<center><h2>Thank you for your feedback!</h2></center>";
+	echo "<h2 style='text-align: center;'>Thank you for your feedback!</h2>";
 } else {
 $stopid = "";
 $stopcode = "";
@@ -48,7 +48,7 @@
 <small> if you click on feedback from a stop page, these will get filled in automatically. else describe the location/street of the stop in one of these boxes </small><br>
 
 Suggested Stop Location (lat/long or words):  <input type="text" name="newlocation"/><br>
-<small> if your device supports javascript, you can pick a location from the map above</small><br>
+<!--<small> if your device supports javascript, you can pick a location from the map above</small><br>-->
 
 <input type="submit" value="Submit!"/>
 </form>

--- /dev/null
+++ b/include/common-db.inc.php
@@ -1,1 +1,21 @@
+<?php
+  if (php_uname('n') == "actbus-www") {
+    $conn = pg_connect("dbname=transitdata user=transitdata password=transitdata host=db.actbus.dotcloud.com port=2242");
+  } else if (isDebugServer()) {
+    $conn = pg_connect("dbname=transitdata user=postgres password=snmc");
+  } else {
+    $conn = pg_connect("dbname=transitdata user=transitdata password=transitdata ");
+  }
+  if (!$conn) {
+      die("A database error occurred.\n");
+  }
+  
+  function databaseError($errMsg) {
+    die($errMsg);
+  }
+ 
+  include('db/route-dao.inc.php');
+  include('db/trip-dao.inc.php');
+  include('db/stop-dao.inc.php');  
+  ?>
 

--- a/include/common-geo.inc.php
+++ b/include/common-geo.inc.php
@@ -46,9 +46,9 @@
 		$center = $totalLat / sizeof($mapPoints) . "," . $totalLon / sizeof($mapPoints);
 	}
 	$output = "";
-	if ($collapsible) $output.= '<div data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>';
-	$output.= '<center><img src="' . curPageURL() . '/lib/staticmaplite/staticmap.php?center=' . $center . '&zoom=' . $zoom . '&size=' . $width . 'x' . $height . '&markers=' . 
-$markers . '" width=' . $width . ' height=' . $height . '></center>';
+	if ($collapsible) $output.= '<div class="map" data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>';
+	$output.= '<img class="map" src="' . curPageURL() . '/lib/staticmaplite/staticmap.php?center=' . $center . '&amp;zoom=' . $zoom . '&amp;size=' . $width . 'x' . $height . '&amp;markers=' . 
+$markers . '" width=' . $width . ' height=' . $height . '>';
 	if ($collapsible) $output.= '</div>';
 	return $output;
 }
@@ -70,6 +70,7 @@
 	  else return round($km,2)."k";
 	} else return floor($km * 1000);
 }
+
 function decodePolylineToArray($encoded)
 {
 	// source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5

--- a/include/common-net.inc.php
+++ b/include/common-net.inc.php
@@ -5,7 +5,7 @@
 	$ch = curl_init($url);
 	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 	curl_setopt($ch, CURLOPT_HEADER, 0);
-	curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+	curl_setopt($ch, CURLOPT_TIMEOUT, 45);
 	$page = curl_exec($ch);
 	if (curl_errno($ch)) {
 		echo "<font color=red> Database temporarily unavailable: ";

--- a/include/common-session.inc.php
+++ b/include/common-session.inc.php
@@ -9,7 +9,7 @@
 	$_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING);
 	sessionUpdated();
 }
-if (isset($_REQUEST['geolocate'])) {
+if (isset($_REQUEST['geolocate']) && $_REQUEST['geolocate'] != "Enter co-ordinates or address here") {
 	$geocoded = false;
 	if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) {
 		$_SESSION['lat'] = trim(filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
@@ -17,7 +17,6 @@
 	}
 	else {
 		$geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL);
-		echo $_REQUEST['geolocate'];
 		if (startsWith($geolocate, "-")) {
 			$locateparts = explode(",", $geolocate);
 			$_SESSION['lat'] = $locateparts[0];
@@ -52,6 +51,9 @@
 	session_destroy();
 	session_start();
 }
-debug(print_r($_SESSION, true) , "session");
+//debug(print_r($_SESSION, true) , "session");
 
+function current_time() {
+	return ($_SESSION['time']? $_SESSION['time'] : date("H:i:s"));
+}
 ?>

--- a/include/common-template.inc.php
+++ b/include/common-template.inc.php
@@ -1,28 +1,27 @@
 <?php
-  // Copyright 2009 Google Inc. All Rights Reserved.
-  $GA_ACCOUNT = "MO-22173039-1";
-  $GA_PIXEL = "/lib/ga.php";
-
-  function googleAnalyticsGetImageUrl() {
-    global $GA_ACCOUNT, $GA_PIXEL;
-    $url = "";
-    $url .= $GA_PIXEL . "?";
-    $url .= "utmac=" . $GA_ACCOUNT;
-    $url .= "&utmn=" . rand(0, 0x7fffffff);
-    $referer = $_SERVER["HTTP_REFERER"];
-    $query = $_SERVER["QUERY_STRING"];
-    $path = $_SERVER["REQUEST_URI"];
-    if (empty($referer)) {
-      $referer = "-";
-    }
-    $url .= "&utmr=" . urlencode($referer);
-    if (!empty($path)) {
-      $url .= "&utmp=" . urlencode($path);
-    }
-    $url .= "&guid=ON";
-    return str_replace("&", "&amp;", $url);
-  }
-
+// Copyright 2009 Google Inc. All Rights Reserved.
+$GA_ACCOUNT = "MO-22173039-1";
+$GA_PIXEL = "/lib/ga.php";
+function googleAnalyticsGetImageUrl()
+{
+	global $GA_ACCOUNT, $GA_PIXEL;
+	$url = "";
+	$url.= $GA_PIXEL . "?";
+	$url.= "utmac=" . $GA_ACCOUNT;
+	$url.= "&utmn=" . rand(0, 0x7fffffff);
+	$referer = $_SERVER["HTTP_REFERER"];
+	$query = $_SERVER["QUERY_STRING"];
+	$path = $_SERVER["REQUEST_URI"];
+	if (empty($referer)) {
+		$referer = "-";
+	}
+	$url.= "&utmr=" . urlencode($referer);
+	if (!empty($path)) {
+		$url.= "&utmp=" . urlencode($path);
+	}
+	$url.= "&guid=ON";
+	return str_replace("&", "&amp;", $url);
+}
 function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false)
 {
 	echo '
@@ -34,27 +33,34 @@
         <meta name="google-site-verification" 
 content="-53T5Qn4TB_de1NyfR_ZZkEVdUNcNFSaYKSFkWKx-sY" />';
 	if ($datepicker) echo '<link rel="stylesheet"  href="css/jquery.ui.datepicker.mobile.css" />';
-	if (isDebugServer()) echo '<link rel="stylesheet"  href="css/jquery.mobile-1.0a4.css" />
+	if (isDebugServer()) {
+		echo '<link rel="stylesheet"  href="css/jquery.mobile-1.0a4.css" />
+	
          <script type="text/javascript" src="js/jquery-1.5.js"></script>
 	 <script>$(document).bind("mobileinit", function(){
   $.mobile.ajaxEnabled = false;
 });
 </script>
         <script type="text/javascript" src="js/jquery.mobile-1.0a4.js"></script>';
-	else echo '<link rel="stylesheet"  href="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.css" />
+	}
+	else {
+		echo '<link rel="stylesheet"  href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
         <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
 	 <script>$(document).bind("mobileinit", function(){
   $.mobile.ajaxEnabled = false;
 });
 </script>
-        <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.js"></script>';
-	if ($datepicker) echo '<script> 
+        <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>';
+	}
+	if ($datepicker) {
+		echo '<script> 
 		//reset type=date inputs to text
 		$( document ).bind( "mobileinit", function(){
 			$.mobile.page.prototype.options.degradeInputs.date = true;
 		});	
 	</script> 
 	<script src="js/jQuery.ui.datepicker.js"></script>';
+	}
 	echo '<style type="text/css">
      .ui-navbar {
      width: 100%;
@@ -68,10 +74,14 @@
     .ui-listview-filter {
         margin: 0 !important;
      }
-     .ui-icon-navigation {
+    .ui-icon-navigation {
         background-image: url(css/images/113-navigation.png);
         background-position: 1px 0;
      }
+    .ui-icon-beaker {
+        background-image: url(css/images/91-beaker-2.png);
+        background-position: 1px 0;
+    }
     #footer {
         text-size: 0.75em;
         text-align: center;
@@ -92,6 +102,14 @@
     #extrainfo {
     visibility: hidden;
     display: none;
+    }
+    #servicewarning {
+    padding: 1em;
+    margin-bottom: 0.5em;
+    text-size: 0.2em;
+    background-color: #FF9;
+    -moz-border-radius: 15px;
+border-radius: 15px;
     }
     // source http://webaim.org/techniques/skipnav/
     #skip a, #skip a:hover, #skip a:visited 
@@ -145,17 +163,17 @@
 $('#here').show();
 });
 ";
-if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") echo "geolocate();";
-echo "</script> ";
+		if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") echo "geolocate();";
+		echo "</script> ";
 	}
 	if (isAnalyticsOn()) echo '
-<script type="text/javascript">'."
+<script type="text/javascript">' . "
 
   var _gaq = _gaq || [];
   _gaq.push(['_setAccount', 'UA-22173039-1']);
   _gaq.push(['_trackPageview']);
 </script>";
-echo '</head>
+	echo '</head>
 <body>
     <div id="skip">
     <a href="#maincontent">Skip to content</a>
@@ -163,27 +181,32 @@
  ';
 	if ($opendiv) {
 		echo '<div data-role="page"> 
- <script>
-$(document).ready(function ()
-{
-    document.title = "' . $pageTitle . '";
-});
-</script>
 	<div data-role="header" data-position="inline">
-	<a href="'.$_SERVER["HTTP_REFERER"].'" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a> 
+	<a href="' . $_SERVER["HTTP_REFERER"] . '" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a> 
 		<h1>' . $pageTitle . '</h1>
 		<a href="/index.php" data-icon="home" class="ui-btn-right">Home</a>
 	</div><!-- /header -->
         <a name="maincontent" id="maincontent"></a>
         <div data-role="content"> ';
+		$overrides = getServiceOverride();
+		if ($overrides['service_id']) {
+				if ($overrides['service_id'] == "noservice") {
+					echo '<div id="servicewarning">Buses are <strong>not running today</strong> due to industrial action/public holiday. See <a 
+href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>';
+				}
+				else {
+					echo '<div id="servicewarning">Buses are running on an altered timetable today due to industrial action/public holiday. See <a href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>';
+				}
+			}
+		}
 	}
 }
 function include_footer()
 {
-	echo '<div id="footer"><a href="about.php">About/Contact Us</a>&nbsp;<a href="feedback.php">Feedback/Bug Report</a></a>';
+	echo '<div id="footer"><a href="about.php">About/Contact Us</a>&nbsp;<a href="feedback.php">Feedback/Bug Report</a>';
 	echo '</div>';
-        if (isAnalyticsOn()) {
-	echo "<script>  (function() {
+	if (isAnalyticsOn()) {
+		echo "<script>  (function() {
     var ga = document.createElement('script'); ga.type = 
 'text/javascript'; ga.async = true;
     ga.src = ('https:' == document.location.protocol ? 
@@ -191,9 +214,11 @@
     var s = document.getElementsByTagName('script')[0]; 
 s.parentNode.insertBefore(ga, s);
   })();</script>";
-         $googleAnalyticsImageUrl = googleAnalyticsGetImageUrl();
-  echo '<noscript><img src="' . $googleAnalyticsImageUrl . '" /></noscript>';
-    }
+		$googleAnalyticsImageUrl = googleAnalyticsGetImageUrl();
+		echo '<noscript><img src="' . $googleAnalyticsImageUrl . '" /></noscript>';
+
+	}
+			echo "\n</div></div></body></html>";
 }
 function timePlaceSettings($geolocate = false)
 {
@@ -209,7 +234,7 @@
 	}
 	echo '<div data-role="collapsible" data-collapsed="' . !$geoerror . '">
         <h3>Change Time/Place (' . (isset($_SESSION['time']) ? $_SESSION['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...</h3>
-        <form action="'.basename($_SERVER['PHP_SELF'])."?".$_SERVER['QUERY_STRING'].'" method="post">
+        <form action="' . basename($_SERVER['PHP_SELF']) . "?" . $_SERVER['QUERY_STRING'] . '" method="post">
         <div class="ui-body"> 
 		<div data-role="fieldcontain">
 	            <label for="geolocate"> Current Location: </label>
@@ -218,7 +243,7 @@
     		<div data-role="fieldcontain">
 		        <label for="time"> Time: </label>
 		    	<input type="time" name="time" id="time" value="' . (isset($_SESSION['time']) ? $_SESSION['time'] : date("H:i")) . '"/>
-			<a href="#" name="currentTime" id="currentTime" onClick="var d = new Date();'. "$('#time').val(d.getHours() +':'+ (d.getMinutes().toString().length = 1 ? '0'+ d.getMinutes():  d.getMinutes()));".'">Current Time?</a>
+			<a href="#" name="currentTime" id="currentTime" onClick="var d = new Date();' . "$('#time').val(d.getHours() +':'+ (d.getMinutes().toString().length == 1 ? '0'+ d.getMinutes():  d.getMinutes()));" . '">Current Time?</a>
 	        </div>
 		<div data-role="fieldcontain">
 		    <label for="service_period"> Service Period:  </label>
@@ -227,17 +252,18 @@
 		echo "<option value=\"$service_period\"" . (service_period() === $service_period ? " SELECTED" : "") . '>' . ucwords($service_period) . '</option>';
 	}
 	echo '</select>
-			<a href="#" style="display:none" name="currentPeriod" id="currentPeriod"/>Current Period?</a>
+			<a href="#" style="display:none" name="currentPeriod" id="currentPeriod">Current Period?</a>
 		</div>
 		
 		<input type="submit" value="Update"/>
-                </form>
-            </div></div>';
-}
-function trackEvent($category, $action, $label = "", $value = -1) {
-  if (isAnalyticsOn()) {
-    echo "\n<script> _gaq.push(['_trackEvent', '$category', '$action'".($label != "" ? ", '$label'" : "").($value != -1 ? ", $value" : "")."]);</script>";
-  }
+                </div></form>
+            </div>';
+}
+function trackEvent($category, $action, $label = "", $value = - 1)
+{
+	if (isAnalyticsOn()) {
+		echo "\n<script> _gaq.push(['_trackEvent', '$category', '$action'" . ($label != "" ? ", '$label'" : "") . ($value != - 1 ? ", $value" : "") . "]);</script>";
+	}
 }
 ?>
 

--- a/include/common-transit.inc.php
+++ b/include/common-transit.inc.php
@@ -4,9 +4,26 @@
 	'saturday',
 	'weekday'
 );
+function getServiceOverride() {
+	global $conn;
+	$query = "Select * from calendar_dates where date = '".date("Ymd")."' and exception_type = '1'";
+	 debug($query,"database");
+	$result = pg_query($conn, $query);
+	if (!$result) {
+		databaseError(pg_result_error($result));
+		return Array();
+	}
+	return pg_fetch_assoc($result);
+}
 function service_period()
 {
+	
 	if (isset($_SESSION['service_period'])) return $_SESSION['service_period'];
+	$override = getServiceOverride();
+	if ($override['service_id']){
+		return $override['service_id'];
+	}
+
 	switch (date('w')) {
 	case 0:
 		return 'sunday';
@@ -35,39 +52,5 @@
 		return "";
 	}
 }
-function viaPoints($tripid, $stopid, $timingPointsOnly = false)
-{
-	global $APIurl;
-	$url = $APIurl . "/json/tripstoptimes?trip=" . $tripid;
-	$json = json_decode(getPage($url));
-	debug(print_r($json, true));
-	$stops = $json[0];
-	$times = $json[1];
-	$foundStop = false;
-	$viaPoints = Array();
-	foreach ($stops as $key => $row) {
-		if ($foundStop) {
-			if (!$timingPointsOnly || !startsWith($row[5], "Wj")) {
-				$viaPoints[] = Array(
-					"id" => $row[0],
-					"name" => $row[1],
-					"time" => $times[$key]
-				);
-			}
-		}
-		else {
-			if ($row[0] == $stopid) $foundStop = true;
-		}
-	}
-	return $viaPoints;
-}
-function viaPointNames($tripid, $stopid)
-{
-	$points = viaPoints($tripid, $stopid, true);
-	$pointNames = Array();
-	foreach ($points as $point) {
-		$pointNames[] = $point['name'];
-	}
-	return implode(", ", $pointNames);
-}
 ?>
+

file: