Only get stop times for stops that have unique stop sequences when combined
Only get stop times for stops that have unique stop sequences when combined

--- a/include/common-template.inc.php
+++ b/include/common-template.inc.php
@@ -236,7 +236,7 @@
 }
 function trackEvent($category, $action, $label = "", $value = -1) {
   if (isAnalyticsOn()) {
-    echo "<script> _gaq.push(['_trackEvent', $category, $action".($label != "" ? ", $label" : "").($value != -1 ? ", $value" : "")."]);</script>";
+    echo "\n<script> _gaq.push(['_trackEvent', '$category', '$action'".($label != "" ? ", '$label'" : "").($value != -1 ? ", $value" : "")."]);</script>";
   }
 }
 ?>

--- a/include/common.inc.php
+++ b/include/common.inc.php
@@ -5,7 +5,7 @@
 	"session",
 	"json",
 	"phperror",
-	"awsgtfs",
+	//"awsgtfs",
 	"awsotp",
 	//"squallotp",
 	//"vanilleotp",

--- a/labs/tripPlannerTester.kml.php
+++ b/labs/tripPlannerTester.kml.php
@@ -159,8 +159,7 @@
 					$regionTimes[] = $time;
 				}
 			}
-			flush();
-			ob_flush();
+			flush(); @ob_flush();
 			curl_close($ch);
 		}
 	}

--- a/schedule_viewer.py
+++ b/schedule_viewer.py
@@ -22,6 +22,8 @@
 
 
 import BaseHTTPServer, sys, urlparse
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+from SocketServer import ForkingMixIn
 import bisect
 from gtfsscheduleviewer.marey_graph import MareyGraph
 import gtfsscheduleviewer
@@ -57,34 +59,8 @@
       return list(iterable)
     return simplejson.JSONEncoder.default(self, obj)
 
-# Code taken from
-# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/425210/index_txt
-# An alternate approach is shown at
-# http://mail.python.org/pipermail/python-list/2003-July/212751.html
-# but it requires multiple threads. A sqlite object can only be used from one
-# thread.
-class StoppableHTTPServer(BaseHTTPServer.HTTPServer):
-  def server_bind(self):
-    BaseHTTPServer.HTTPServer.server_bind(self)
-    self.socket.settimeout(1)
-    self._run = True
-
-  def get_request(self):
-    while self._run:
-      try:
-        sock, addr = self.socket.accept()
-        sock.settimeout(None)
-        return (sock, addr)
-      except socket.timeout:
-        pass
-
-  def stop(self):
-    self._run = False
-
-  def serve(self):
-    while self._run:
-      self.handle_request()
-
+class ForkedHTTPServer(ForkingMixIn, HTTPServer):
+    """Handle requests in a separate forked process."""
 
 def StopToTuple(stop):
   """Return tuple as expected by javascript function addStopMarkerFromList"""
@@ -249,14 +225,14 @@
   def handle_json_wrapper_GET(self, handler, parsed_params, handler_name):
     """Call handler and output the return value in JSON."""
     schedule = self.server.schedule
-    # round times to nearest 100 seconds
+    # round times to nearest 1000 seconds - up to 17 minutes out of date
     if "time" in parsed_params:
-      parsed_params['time'] = int(round(float(parsed_params['time']),-2))
+      parsed_params['time'] = int(round(float(parsed_params['time']),-3))
     paramkey = tuple(sorted(parsed_params.items()))
     if handler_name in self.cache and paramkey in self.cache[handler_name] :
       print ("Cache hit for ",handler_name," params ",parsed_params)
     else:
-      print ("Cache miss for ",handler_name," params ",parsed_params)
+      print ("Cache miss for ",handler_name," params ",parsed_params) 
       result = handler(parsed_params)
       if not handler_name in self.cache:
         self.cache[handler_name] = {}
@@ -496,6 +472,7 @@
       if s.stop_id.lower() == query:
         return StopToTuple(s)
     return []
+    
   def handle_json_GET_stoproutes(self, params):
     """Given a stop_id return all routes to visit the stop."""
     schedule = self.server.schedule
@@ -505,27 +482,32 @@
     result = {}
     for trip in trips:
       route = schedule.GetRoute(trip.route_id)
-      if not route.route_short_name+route.route_long_name+trip.service_id in result:
-        result[route.route_short_name+route.route_long_name+trip.service_id] = (route.route_id, route.route_short_name, route.route_long_name, trip.trip_id, trip.service_id)
+      if service_period == None or trip.service_id == service_period:
+        if not route.route_short_name+route.route_long_name+trip.service_id in result:
+          result[route.route_short_name+route.route_long_name+trip.service_id] = (route.route_id, route.route_short_name, route.route_long_name, trip.trip_id, trip.service_id)
     return result
     
   def handle_json_GET_stopalltrips(self, params):
-    """Given a stop_id return all trips to visit the stop."""
+    """Given a stop_id return all trips to visit the stop (without times)."""
     schedule = self.server.schedule
     stop = schedule.GetStop(params.get('stop', None))
     service_period = params.get('service_period', None)
-    time_trips = stop.GetStopTimeTrips(schedule)
+    trips = stop.GetTrips(schedule)
+    result = []
+    for trip in trips:
+      if service_period == None or trip.service_id == service_period:
+        result.append((trip.trip_id, trip.service_id))
+    return result
+  
+  def handle_json_GET_stopalltriptimes(self, params):
+    """Given a stop_id return all trips to visit the stop (with times).
+    DEPRECIATED?"""
+    schedule = self.server.schedule
+    stop = schedule.GetStop(params.get('stop', None))
+    service_period = params.get('service_period', None)
+    time_trips = stop.GetStopTrips(schedule)
     result = []
     for time, (trip, index), tp in time_trips:
-      headsign = None
-      # Find the most recent headsign from the StopTime objects
-      for stoptime in trip.GetStopTimes()[index::-1]:
-        if stoptime.stop_headsign:
-          headsign = stoptime.stop_headsign
-          break
-      # If stop_headsign isn't found, look for a trip_headsign
-      if not headsign:
-        headsign = trip.trip_headsign
       route = schedule.GetRoute(trip.route_id)
       trip_name = ''
       if route.route_short_name:
@@ -550,7 +532,6 @@
     service_period = params.get('service_period', None)
     time_range = int(params.get('time_range', 24*60*60))
     
-    
     filtered_time_trips = []
     for trip, index in stop._GetTripIndex(schedule):
       tripstarttime = trip.GetStartTime()
@@ -558,20 +539,10 @@
         time, stoptime, tp = trip.GetTimeInterpolatedStops()[index]
         if time > requested_time and time < (requested_time + time_range):
           bisect.insort(filtered_time_trips, (time, (trip, index), tp))
-    
     result = []
     for time, (trip, index), tp in filtered_time_trips:
       if len(result) > limit:
         break
-      headsign = None
-      # Find the most recent headsign from the StopTime objects
-      for stoptime in trip.GetStopTimes()[index::-1]:
-        if stoptime.stop_headsign:
-          headsign = stoptime.stop_headsign
-          break
-      # If stop_headsign isn't found, look for a trip_headsign
-      if not headsign:
-        headsign = trip.trip_headsign
       route = schedule.GetRoute(trip.route_id)
       trip_name = ''
       if route.route_short_name:
@@ -580,9 +551,6 @@
         if len(trip_name):
           trip_name += " - "
         trip_name += route.route_long_name
-        # comment out directions because we already have them in the long name
-      #if headsign:
-      #  trip_name += " (Direction: %s)" % headsign
       if service_period == None or trip.service_id == service_period:
         result.append((time, (trip.trip_id, trip_name, trip.service_id), tp))
     return result
@@ -713,14 +681,13 @@
   t0 = datetime.datetime.now()
   schedule.Load(options.feed_filename)
   print ("Loaded in", (datetime.datetime.now() - t0).seconds , "seconds")
-  server = StoppableHTTPServer(server_address=('', options.port),
+  server = ForkedHTTPServer(server_address=('', options.port),
                                RequestHandlerClass=RequestHandlerClass)
   server.key = options.key
   server.schedule = schedule
   server.file_dir = options.file_dir
   server.host = options.host
-  server.feed_path = options.feed_filename
-  
+  server.feed_path = options.feed_filename  
 
 
   print ("To view, point your browser at http://localhost:%d/" %

file:a/stop.php -> file:b/stop.php
--- a/stop.php
+++ b/stop.php
@@ -20,6 +20,7 @@
 $stopNames = Array();
 $tripStopNumbers = Array();
 $allStopsTrips = Array();
+$fetchedTripSequences = Array();
 $stopLinks = "";
 if (isset($_REQUEST['stopids'])) {
 	$stopids = explode(",", filter_var($_REQUEST['stopids'], FILTER_SANITIZE_STRING));
@@ -45,12 +46,25 @@
 			$sub_stop[2],
 			$sub_stop[3]
 		);
-		$url = $APIurl . "/json/stoptrips?stop=" . $sub_stop[0] . "&time=" . midnight_seconds() . "&service_period=" . service_period();
-		$trips = json_decode(getPage($url));
+                
+                $url = $APIurl . "/json/stopalltrips?stop=" . $sub_stop[0];		$trips = json_decode(getPage($url));
+                $tripSequence = "";
 		foreach ($trips as $trip) {
-			if (!isset($allStopsTrips[$trip[1][0]])) $allStopsTrips[$trip[1][0]] = $trip;
-			$tripStopNumbers[$trip[1][0]][] = $key;
+                        $tripSequence .= "$trip[0],";
+			$tripStopNumbers[$trip[0]][] = $key;
 		}
+                
+                if (!in_array($tripSequence,$fetchedTripSequences)) {
+                    // only fetch new trip sequences
+                    $fetchedTripSequences[] = $tripSequence;
+                    $url = $APIurl . "/json/stoptrips?stop=" . $sub_stop[0] . "&time=" . midnight_seconds() . "&service_period=" . service_period();
+                    $trips = json_decode(getPage($url));
+                    foreach ($trips as $trip) {
+                            if (!isset($allStopsTrips[$trip[1][0]])) $allStopsTrips[$trip[1][0]] = $trip;
+                    }
+                } else {
+                    echo "skipped sequence $tripSequence";
+                }
 	}
 }
 include_header($stop[1], "stop");
@@ -95,6 +109,7 @@
 	echo '</p>';
 	echo '<p class="ui-li-aside"><strong>' . midnight_seconds_to_time($row[0]) . '</strong></p>';
 	echo '</a></li>';
+        flush(); @ob_flush();
 }
 if (sizeof($trips) == 0) echo "<li> <center>No trips in the near future.</center> </li>";
 echo '</ul></div>';

--- a/stopList.php
+++ b/stopList.php
@@ -31,6 +31,7 @@
 		foreach ($suburbs as $suburb) {
 			if (startsWith($suburb, $_REQUEST['firstLetter'])) {
 				echo '<li><a href="stopList.php?suburb=' . urlencode($suburb) . '">' . $suburb . '</a></li>';
+				flush(); @ob_flush();
 			}
 		}
 	}
@@ -101,6 +102,7 @@
 					}
 					echo bracketsMeanNewLine(trim(preg_replace("/\(Platform.*/", "", $row[1])) . '(' . sizeof($stopsGrouped["stop_ids"]) . ' stops)');
 					echo "</a></li>\n";
+					flush(); @ob_flush();
 					$stopsGrouped = Array();
 				}
 				else {
@@ -113,6 +115,7 @@
 					}
 					echo bracketsMeanNewLine($row[1]);
 					echo "</a></li>\n";
+					flush(); @ob_flush();
 				}
 			}
 			else {

file:a/trip.php -> file:b/trip.php
--- a/trip.php
+++ b/trip.php
@@ -40,12 +40,14 @@
 foreach ($routetrips as $othertrip) {
 	echo '<a href="trip.php?tripid=' . $othertrip[1] . "&routeid=" . $routeid . '">' . midnight_seconds_to_time($othertrip[0]) . '</a> ';
 }
+flush(); @ob_flush();
 echo '</p><p><h2>Other directions/timing periods:</h2> ';
 $url = $APIurl . "/json/routesearch?routeshortname=" . rawurlencode($trips[1]->route_short_name);
 $json = json_decode(getPage($url));
 foreach ($json as $row) {
 	if ($row[0] != $routeid) echo '<a href="trip.php?routeid=' . $row[0] . '">' . $row[2] . ' (' . ucwords($row[3]) . ')</a> ';
 }
+flush(); @ob_flush();
 echo '  <ul data-role="listview"  data-inset="true">';
 echo '<li data-role="list-divider">' . midnight_seconds_to_time($times[0]) . '-' . midnight_seconds_to_time($times[sizeof($times) - 1]) . ' ' . $trips[1]->route_long_name . '</li>';
 $stopsGrouped = Array();
@@ -62,6 +64,7 @@
 			echo '<p class="ui-li-aside">' . midnight_seconds_to_time($stopsGrouped['startTime']) . ' to ' . midnight_seconds_to_time($stopsGrouped['endTime']) . '</p>';
 			echo bracketsMeanNewLine($row[1]);
 			echo '</a></li>';
+                        flush(); @ob_flush();
 			$stopsGrouped = Array();
 		}
 		else {
@@ -70,6 +73,7 @@
 			echo '<p class="ui-li-aside">' . midnight_seconds_to_time($times[$key]) . '</p>';
 			echo bracketsMeanNewLine($row[1]);
 			echo '</a></li>';
+                        flush(); @ob_flush();
 		}
 	}
 	else {

--- a/tripPlanner.php
+++ b/tripPlanner.php
@@ -62,6 +62,7 @@
 			echo '<li>';
 			processLeg($legNumber, $leg);
 			echo "</li>";
+                        flush(); @ob_flush();
 		}
 		echo "</ul>";
 	}