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

Conflicts:
include/common.inc.php

file:a/about.php -> file:b/about.php
--- a/about.php
+++ b/about.php
@@ -21,6 +21,10 @@
 , <a href="http://itunes.apple.com/au/app/act-buses/id376634797?mt=8">ACT Buses by David Sullivan</a>) 
 and Android (<a href="https://market.android.com/details?id=com.action">MyBus 2.0 by Imagine Team</a>)
 <br />
+GTFS-realtime API;
+Alerts and Trip Updates (but only Cancelled or Stop Skipped)
+Default format binary but can get JSON by adding ?ascii=yes
+<br />
 <br />
 <small>Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://action.act.gov.au before your trip.
 Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty, 

--- a/include/common-template.inc.php
+++ b/include/common-template.inc.php
@@ -32,7 +32,7 @@
 	<head>
         <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1"> 	
-<title>' . $pageTitle . '</title>
+<title>' . $pageTitle . ' - Canberra Bus Timetable</title>
         <meta name="google-site-verification" content="-53T5Qn4TB_de1NyfR_ZZkEVdUNcNFSaYKSFkWKx-sY" />
 <link rel="dns-prefetch" href="//code.jquery.com">
 <link rel="dns-prefetch" href="//ajax.googleapis.com">
@@ -159,11 +159,11 @@
 				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>';
 			}
 		}
-		if ($serviceAlertsEnabled) {
-		$serviceAlerts = getServiceAlerts("network","network");
-		foreach ($serviceAlerts['entities'] as $entity) {
-			echo "<div id='servicewarning'>".date("F j, g:i a",strtotime($entity['alert']['active_period']['start']))." to ". date("F j, g:i a", strtotime($entity['alert']['active_period']['end']))."<br>Warning: {$entity['alert']['description']['translation']} 
-			<br><a href='{$entity['alert']['url']['translation']}'>Source</a>  </div>";
+		if ($GTFSREnabled) {
+		$serviceAlerts = getServiceAlertsAsArray("agency","0");
+		foreach ($serviceAlerts['entity'] as $entity) {
+			echo "<div id='servicewarning'>".date("F j, g:i a",strtotime($entity['alert']['active_period'][0]['start']))." to ". date("F j, g:i a", strtotime($entity['alert']['active_period'][0]['end']))."{$entity['alert']['header_text']['translation'][0]['text']}<br>Warning: {$entity['alert']['description_text']['translation'][0]['text']} 
+			<br><a href='{$entity['alert']['url']['translation'][0]['text']}'>Source</a>  </div>";
 		}
 	}
 	}

--- a/include/common-transit.inc.php
+++ b/include/common-transit.inc.php
@@ -45,7 +45,48 @@
 		return "";
 	}
 }
-function getServiceAlerts($filter_class, $filter_id) {
+if ($GTFSREnabled) {
+$serviceAlertCause = Array(
+"UNKNOWN_CAUSE" => "Unknown cause",
+"OTHER_CAUSE" => "Other cause",
+"TECHNICAL_PROBLEM" => "Technical problem",
+"STRIKE" => "Strike",
+"DEMONSTRATION" => "Demonstration",
+"ACCIDENT" => "Accident",
+"HOLIDAY" => "Holiday",
+"WEATHER" => "Weather",
+"MAINTENANCE" => "Maintenance",
+"CONSTRUCTION" => "Construction",
+"POLICE_ACTIVITY" => "Police activity",
+"MEDICAL_EMERGENCY" => "Medical emergency"
+);
+$serviceAlertEffect = Array(
+"NO_SERVICE" => "No service",
+"REDUCED_SERVICE" => "Reduced service",
+"SIGNIFICANT_DELAYS" => "Significant delays",
+"DETOUR" => "Detour",
+"ADDITIONAL_SERVICE" => "Additional service",
+"MODIFIED_SERVICE" => "Modified service",
+"OTHER_EFFECT" => "Other effect",
+"UNKNOWN_EFFECT" => "Unknown effect",
+"STOP_MOVED" => "Stop moved");
+
+set_include_path(get_include_path() . PATH_SEPARATOR . $labsPath."lib/Protobuf-PHP/library/DrSlump/");
+
+include_once("Protobuf.php");
+include_once("Protobuf/Message.php");
+include_once("Protobuf/Registry.php");
+include_once("Protobuf/Descriptor.php");
+include_once("Protobuf/Field.php");
+
+include_once($labsPath."lib/Protobuf-PHP/gtfs-realtime.php");
+include_once("Protobuf/CodecInterface.php");
+include_once("Protobuf/Codec/PhpArray.php");
+include_once("Protobuf/Codec/Binary.php");
+include_once("Protobuf/Codec/Binary/Writer.php");
+include_once("Protobuf/Codec/Json.php");
+
+function getServiceAlerts($filter_class = "", $filter_id = "") {
 /*
 
   also need last modified epoch of client gtfs
@@ -65,35 +106,82 @@
             street inform: route inform, trip inform, stop inform
             route patch: trip remove
             */
-$return = Array();
-$return['header']['gtrtfs_version'] = "1";
-$return['header']['timestamp'] = time();
-$return['entities'] = Array();
+            $fm = new transit_realtime\FeedMessage();
+$fh = new transit_realtime\FeedHeader();
+$fh->setGtfsRealtimeVersion(1);
+$fh->setTimestamp(time());
+$fm->setHeader($fh);
 foreach(getCurrentAlerts() as $alert) {
-	$informedEntities = getInformedAlerts($alert['id'],$_REQUEST['filter_class'],$_REQUEST['filter_id']);
+$fe = new transit_realtime\FeedEntity();
+	$fe->setId($alert['id']);
+	$fe->setIsDeleted(false);
+	$alert = new transit_realtime\Alert();	
+		$tr = new transit_realtime\TimeRange();
+			$tr->setStart($alert['start']);
+			$tr->setEnd($alert['end']);
+		$alert-> addActivePeriod($tr);
+			$informedEntities = getInformedAlerts($alert['id'],$_REQUEST['filter_class'],$_REQUEST['filter_id']);
 	if (sizeof($informedEntities) >0) {
-		$entity = Array();
-		$entity['id'] = $alert['id'];
-		$entity['alert']['active_period']['start'] = $alert['start'];
-		$entity['alert']['active_period']['end'] = $alert['end'];
-		$entity['alert']['url']['translation'] = $alert['url'];
-		$entity['alert']['description']['translation'] = $alert['description'];
-		
-		foreach ($informedEntities as $informedEntity) {
-			$informed = Array();
-			$informed[$informedEntity['informed_class']."_id"] = $informedEntity['informed_id'];
-			if ($informedEntity['informed_action'] != "") $informed["x-action"] = $informedEntity['informed_action'];
-			$informed[$informedEntity['class']."_type"] = $informedEntity['type'];
-			$entity['informed'][] = $informed; 
-		}
-		$return['entities'][] = $entity;
-	}
-}
-return $return;
+		$informed = Array();
+		$es = new transit_realtime\EntitySelector();
+		if ($informedEntity['informed_class'] == "agency") {
+			$es->setAgencyId($informedEntity['informed_id']);
+		}
+		if ($informedEntity['informed_class'] == "stop") {
+			$es->setStopId($informedEntity['informed_id']);
+		}
+		if ($informedEntity['informed_class'] == "route") {
+			$es->setRouteId($informedEntity['informed_id']);
+		}
+		if ($informedEntity['informed_class'] == "trip") {
+			$td = new transit_realtime\TripDescriptor();
+				$td->setTripId($informedEntity['informed_id']);
+			$es->setTrip($td);
+		}
+		$alert-> addInformedEntity($es);
+	}
+		$alert->setCause(constant("transit_realtime\Alert\Cause::".$alert['cause']));
+		$alert->setEffect(constant("transit_realtime\Alert\Effect::".$alert['effect']));
+		$tsUrl = new transit_realtime\TranslatedString();
+			$tUrl = new transit_realtime\TranslatedString\Translation();
+				$tUrl->setText($alert['url']);
+				$tUrl->setLanguage("en");
+			$tsUrl->addTranslation($tUrl);
+		$alert->setUrl($tsUrl);
+		$tsHeaderText= new transit_realtime\TranslatedString();
+			$tHeaderText = new transit_realtime\TranslatedString\Translation();
+				$tHeaderText->setText($alert['header']);
+				$tHeaderText->setLanguage("en");
+			$tsHeaderText->addTranslation($tHeaderText);
+		$alert->setHeaderText($tsHeaderText);
+		$tsDescriptionText= new transit_realtime\TranslatedString();
+			$tDescriptionText = new transit_realtime\TranslatedString\Translation();
+				$tDescriptionText->setText($alert['description']);
+				$tDescriptionText->setLanguage("en");
+			$tsDescriptionText->addTranslation($tDescriptionText);
+		$alert->setDescriptionText($tsDescriptionText);
+	$fe->setAlert($alert);
+$fm->addEntity($fe);
+}
+return $fm;
+}
+function getServiceAlertsAsArray($filter_class = "", $filter_id = "") {
+	$codec = new DrSlump\Protobuf\Codec\PhpArray();
+	return $codec->encode(getServiceAlerts($filter_class, $filter_id));
+}
+
+function getServiceAlertsAsBinary($filter_class = "", $filter_id = "") {
+	$codec = new DrSlump\Protobuf\Codec\Binary();
+	return $codec->encode(getServiceAlerts($filter_class, $filter_id));
+}
+
+function getServiceAlertsAsJSON($filter_class = "", $filter_id = "") {
+	$codec = new DrSlump\Protobuf\Codec\Json();
+	return $codec->encode(getServiceAlerts($filter_class, $filter_id));
 }
 function getServiceAlertsByClass() {
 	$return = Array();
-	$alerts = getServiceAlerts("","");
+	$alerts = getServiceAlertsAsArray("","");
 	foreach ($alerts['entities'] as $entity) {
 		foreach ($entity['informed'] as $informed) {
 			foreach($informed as $key => $value){
@@ -103,10 +191,70 @@
 					$id = $value;
 				}
 			}
-		$return[$class][$id][]['entity'] = $entity;
-		$return[$class][$id][]['action'] = $informed["x-action"];
-	}
-	}
+		$return[$class][$id][] = $entity;
+	}
+	}
+}
+
+function getTripUpdates($filter_class = "", $filter_id = "") {
+     $fm = new transit_realtime\FeedMessage();
+$fh = new transit_realtime\FeedHeader();
+$fh->setGtfsRealtimeVersion(1);
+$fh->setTimestamp(time());
+$fm->setHeader($fh);
+foreach(getCurrentAlerts() as $alert) {
+			$informedEntities = getInformedAlerts($alert['id'],$_REQUEST['filter_class'],$_REQUEST['filter_id']);
+	$stops = Array();
+		$routestrips = Array();
+		if (sizeof($informedEntities) >0) {
+		if ($informedEntity['informed_class'] == "stop" && $informed["x-action"] == "remove") {
+			$stops[] = $informedEntity['informed_id'];
+		}
+		if (($informedEntity['informed_class'] == "route" || $informedEntity['informed_class'] == "trip") && $informed["x-action"] == "patch" ) {
+			$routestrips[] = Array( "id" => $informedEntity['informed_id'],
+			"type"=>$informedEntity['informed_class']);
+		}
+		}
+foreach ($routestrips as $routetrip) {
+$fe = new transit_realtime\FeedEntity();
+	$fe->setId($alert['id'].$routetrip['id']);
+	$fe->setIsDeleted(false);
+	$tu = new transit_realtime\TripUpdate();	
+		$td = new transit_realtime\TripDescriptor();
+		if ($routetrip['type'] == "route") {
+			$td->setRouteId($routetrip['id']);
+			} else if ($routetrip['type'] == "trip") {
+				$td->setTripId($routetrip['id']);
+			}
+		$tu->setTrip($td);
+		foreach ($stops as $stop) {
+		$stu = new transit_realtime\TripUpdate\StopTimeUpdate();
+				$stu->setStopId($stop);
+				$stu->setScheduleRelationship(transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SKIPPED);
+		$tu->addStopTimeUpdate($stu);
+	}
+	$fe->setTripUpdate($tu);
+$fm->addEntity($fe);
+}		
+
+}
+return $fm;
+	
+}
+function getTripUpdatesAsArray($filter_class = "", $filter_id = "") {
+	$codec = new DrSlump\Protobuf\Codec\PhpArray();
+	return $codec->encode(getTripUpdates($filter_class, $filter_id));
+}
+
+function getTripUpdatesAsBinary($filter_class = "", $filter_id = "") {
+	$codec = new DrSlump\Protobuf\Codec\Binary();
+	return $codec->encode(getTripUpdates($filter_class, $filter_id));
+}
+
+function getTripUpdatesAsJSON($filter_class = "", $filter_id = "") {
+	$codec = new DrSlump\Protobuf\Codec\Json();
+	return $codec->encode(getTripUpdates($filter_class, $filter_id));
+}
 }
 ?>
 

--- a/include/common.inc.php
+++ b/include/common.inc.php
@@ -10,7 +10,7 @@
 	"database",
 	"other"
 );
-$serviceAlertsEnabled = true;
+$GTFSREnabled = true;
 $cloudmadeAPIkey = "daa03470bb8740298d4b10e3f03d63e6";
 $googleMapsAPIkey = "ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q";
 $otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/';
@@ -32,8 +32,8 @@
 
 function isDebugServer()
 {
-	return php_sapi_name() == "cli" || isset($_SERVER['SERVER_NAME']) && ( $_SERVER['SERVER_NAME'] == "vanille" || $_SERVER['SERVER_NAME'] == "10.1.0.4" || $_SERVER['SERVER_NAME'] == 
-"localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1") ;
+	return php_sapi_name() == "cli" || isset($_SERVER['SERVER_NAME']) && ( $_SERVER['SERVER_NAME'] == "azusa" || $_SERVER['SERVER_NAME'] == "vanille" 
+|| $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1") ;
 }
 
 include_once ("common-geo.inc.php");
@@ -49,7 +49,9 @@
 
 function isAnalyticsOn()
 {
-	return !isDebugServer();
+ $user_agent = $_SERVER['HTTP_USER_AGENT'];
+	return !isDebugServer() && !preg_match('/cloudkick/i', $user_agent) && !preg_match('/googlebot/i', $user_agent) && 
+!preg_match('/baidu/i', $user_agent);
 }
 function isDebug($debugReason = "other")
 {

--- a/include/db/servicealert-dao.inc.php
+++ b/include/db/servicealert-dao.inc.php
@@ -17,7 +17,7 @@
 function getServiceAlert($alertID)
 {
      global $conn;
-     $query = 'SELECT * from servicealerts_alerts where id = :servicealert_id';
+     $query = "SELECT id,extract('epoch', start) as start, extract('epoch', end) as end,cause,effect,header,description,url from servicealerts_alerts where id = :servicealert_id";
      debug($query, "database");
      $query = $conn -> prepare($query);
      $query -> bindParam(":servicealert_id", $alertID);
@@ -30,15 +30,16 @@
     } 
 
 
-function updateServiceAlert($alertID, $start, $end, $description, $url)
+function updateServiceAlert($alertID, $start, $end, $header, $description, $url)
 {
      global $conn;
-     $query = 'update servicealerts_alerts set start=:start, "end"=:end, description=:description, url=:url where id = :servicealert_id';
+     $query = 'update servicealerts_alerts set start=:start, "end"=:end, header=:header, description=:description, url=:url where id = :servicealert_id';
      debug($query, "database");
      $query = $conn -> prepare($query);
      $query -> bindParam(":servicealert_id", $alertID);
      $query -> bindParam(":start", $start);
      $query -> bindParam(":end", $end);
+     $query -> bindParam(":header", $header);
      $query -> bindParam(":description", $description);
      $query -> bindParam(":url", $url);
      $query -> execute();
@@ -51,14 +52,15 @@
     return $query -> fetch(PDO :: FETCH_ASSOC);
     } 
 
-    function addServiceAlert($start, $end, $description, $url)
+    function addServiceAlert($start, $end, $header, $description, $url)
 {
      global $conn;
-     $query = 'INSERT INTO servicealerts_alerts (start, "end", description, url) VALUES (:start, :end, :description, :url) ';
+     $query = 'INSERT INTO servicealerts_alerts (start, "end", header, description, url) VALUES (:start, :end, :header, :description, :url) ';
      debug($query, "database");
      $query = $conn -> prepare($query);
      $query -> bindParam(":start", $start);
      $query -> bindParam(":end", $end);
+     $query -> bindParam(":header", $header);
      $query -> bindParam(":description", $description);
      $query -> bindParam(":url", $url);
      $query -> execute();
@@ -74,7 +76,7 @@
 function getCurrentAlerts()
 {
      global $conn;
-     $query = 'SELECT * from servicealerts_alerts where NOW() > start and NOW() < "end"';
+     $query = "SELECT id,extract('epoch', start) as start, extract('epoch', end) as end,cause,effect,header,description,url from servicealerts_alerts where NOW() > start and NOW() < \"end\"";
      // debug($query, "database");
     $query = $conn -> prepare($query);
      $query -> execute();
@@ -88,7 +90,7 @@
 function getFutureAlerts()
 {
      global $conn;
-     $query = 'SELECT * from servicealerts_alerts where NOW() > start or NOW() < "end"';
+     $query = "SELECT id,extract('epoch', start) as start, extract('epoch', end) as end,cause,effect,header,description,url from servicealerts_alerts where NOW() > start or NOW() < \"end\"";
      // debug($query, "database");
     $query = $conn -> prepare($query);
      $query -> execute();

--- a/labs/servicealert_editor.php
+++ b/labs/servicealert_editor.php
@@ -5,16 +5,14 @@
 /**
  * Currently support:
  * network inform
- * stop remove: trip patch, route inform
+ * stop remove: route patch, stop remove
  * - stop search
- * street inform: route inform, trip inform, stop inform
+ * street inform: route inform, stop inform
  * - street search
- * trip remove: route patch, stop inform 
- * - trip search by route
  */
 if (isset($_REQUEST['saveedit'])) {
     
-    if ($_REQUEST['saveedit'] != "") updateServiceAlert($_REQUEST['saveedit'], $_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['description'], $_REQUEST['url']);
+    if ($_REQUEST['saveedit'] != "") updateServiceAlert($_REQUEST['saveedit'], $_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['header'], $_REQUEST['description'], $_REQUEST['url']);
     else addServiceAlert($_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['description'], $_REQUEST['url']);
      echo "Saved " . $_REQUEST['saveedit'];
      die();
@@ -26,7 +24,7 @@
      die();
      } 
 if ($_REQUEST['networkinform']) {
-    addInformedAlert($_REQUEST['networkinform'], "network", "network", "inform");
+    addInformedAlert($_REQUEST['networkinform'], "agency", "0", "inform");
      echo "Added network inform for" . $_REQUEST['networkinform'];
      die();
      } 
@@ -34,58 +32,27 @@
     addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "remove");
      echo "Added stop remove for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n";
     
-     foreach ($service_periods as $sp) {
-        echo "Patching $sp trips<br>\n";
-         foreach (getStopTrips($_REQUEST['stopid'], $sp) as $trip) {
-            addInformedAlert($_REQUEST['stopsearch'], "trip", $trip['trip_id'], "patch");
-             echo "Added trip patch for" . $_REQUEST['stopsearch'] . ", trip" . $trip['trip_id'] . "<br>\n";
-            
-             } 
-        echo "Informing $sp routes<br>\n";
+     foreach ($service_periods as $sp) { 
+        echo "Remove from $sp routes<br>\n";
          foreach (getStopRoutes($_REQUEST['stopid'], $sp) as $route) {
-            addInformedAlert($_REQUEST['stopsearch'], "route", $route['route_id'], "inform");
-             echo "Added route inform for" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n";
+            addInformedAlert($_REQUEST['stopsearch'], "route", $route['route_id'], "patch");
+             echo "Added route patch for" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n";
              } 
         } 
     die();
      } 
-if ($_REQUEST['routesearch']) {
-    echo "Informing route<br>\n";
-     $stops = Array();
-     echo "Informing trips<br>\n";
-     foreach(getRouteTrips() as $trip) {
-        addInformedAlert($_REQUEST['stopsearch'], "trip", $trip['trip_id'], "patch");
-         echo "Added trip patch for" . $_REQUEST['stopsearch'] . ", trip" . $trip['trip_id'] . "<br>\n";
-         viaPoints($tripID, "", false);
-         } 
-    
-    echo "Informing stops<br>\n";
-     foreach($stops as $stop) {
-        addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "remove");
-         echo "Added stop remove for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n";
-         } 
-    die();
-     } 
 if ($_REQUEST['streetsearch']) {
     
-    echo "Informing stops<br>\n";
+    echo "Informing stops of street<br>\n";
      foreach(getStopByName() as $stop) {
-        addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "remove");
+        addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "inform");
          echo "Added stop inform for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n";
         
          foreach ($service_periods as $sp) {
-            echo "Patching $sp trips<br>\n";
-             foreach (getStopTrips($_REQUEST['stopid'], $sp) as $trip) {
-                addInformedAlert($_REQUEST['stopsearch'], "trip", $trip['trip_id'], "patch");
-                 echo "Added trip inform for" . $_REQUEST['stopsearch'] . ", trip" . $trip['trip_id'] . "<br>\n";
-                
-                 } 
             echo "Informing $sp routes<br>\n";
              foreach (getStopRoutes($_REQUEST['stopid'], $sp) as $route) {
                 addInformedAlert($_REQUEST['stopsearch'], "route", $route['route_id'], "inform");
-                 echo "Added route inform for" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n";
-                
-                
+                 echo "Added route inform for stop" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n";
                  } 
             } 
         die();
@@ -122,6 +89,11 @@
  else echo date("c", strtotime("23:59"));
 ?>"  />
     </div>
+     <div data-role="fieldcontain">
+        <label for="header">Header</label>
+        <input type="text" name="header" id="header" value="<?php echo $alert['header'];
+?>"  />
+    </div>
         <div data-role="fieldcontain">
         <label for="description">Description</label>
         <textarea name="description">
@@ -156,7 +128,7 @@
                 <form action="<?php echo basename(__FILE__) ;
      ?>" method="get">
                 <div data-role="fieldcontain">
-        <label for="stopid">StopID</label>
+        <label for="stopid">StopID to remove</label>
         <input type="text" name="stopid" />
     </div>
         <input type="hidden" name="stopsearch" value="<?php echo $_REQUEST['edit'];
@@ -166,24 +138,14 @@
 <form action="<?php echo basename(__FILE__) ;
      ?>" method="get">
 <div data-role="fieldcontain">
-        <label for="street">Street</label>
+        <label for="street">Street to inform</label>
         <input type="text" name="street" />
     </div>
         <input type="hidden" name="streetsearch" value="<?php echo $_REQUEST['edit'];
      ?>"/>
         <input type="submit" value="Street Search"/>
                 </form>
-                <form action="<?php echo basename(__FILE__) ;
-     ?>" method="get">
-                <div data-role="fieldcontain">
-        <label for="routeid">routeID</label>
-        <input type="text" name="routeid" />
-    </div>
-        <input type="hidden" name="routesearch" value="<?php echo $_REQUEST['edit'];
-     ?>"/>
-        <input type="submit" value="Route Search"/>
-                </form>
-<?php
+  <?php
     
      } 
 include_footer();

--- /dev/null
+++ b/labs/servicealerts_twitter/NameFinder.java
@@ -1,1 +1,56 @@
+InputStream modelIn = new FileInputStream("en-ner-person.bin");
 
+try {
+  TokenNameFinder model = new TokenNameFinderModel(modelIn);
+}
+catch (IOException e) {
+  e.printStackTrace();
+}
+finally {
+  if (modelIn != null) {
+    try {
+      modelIn.close();
+    }
+    catch (IOException e) {
+    }
+  }
+}
+
+NameFinderME nameFinder = new NameFinderME(model);
+
+for (String document[][] : documents) {
+
+  for (String[] sentence : document) {
+    Span nameSpans[] = find(sentence);
+    // do something with the names
+  }
+
+  nameFinder.clearAdaptiveData()
+}
+
+
+                InputStream in = getClass()
+                        .getClassLoader()
+                        .getResourceAsStream(
+                                "opennlp/tools/namefind/AnnotatedSentences.txt");
+
+                String encoding = "ISO-8859-1";
+
+                ObjectStream<NameSample> sampleStream = new NameSampleDataStream(
+                        new PlainTextByLineStream(new InputStreamReader(in,
+                                encoding)));
+
+                TokenNameFinderModel nameFinderModel = NameFinderME.train("en",
+                        "default", sampleStream, Collections
+                                .<String, Object> emptyMap(), 70, 1);
+
+                TokenNameFinder nameFinder = new NameFinderME(nameFinderModel);
+
+                // now test if it can detect the sample sentences
+
+                String sentence[] = { "Alisa", "appreciated", "the", "hint",
+                        "and", "enjoyed", "a", "delicious", "traditional",
+                        "meal." };
+
+                Span names[] = nameFinder.find(sentence);
+

--- /dev/null
+++ b/labs/servicealerts_twitter/pom.xml
@@ -1,1 +1,19 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.lambdacomplex.bus</groupId>
+  <artifactId>servicealerts_twitter</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <dependencies>
+<dependency>
+  <groupId>org.apache.opennlp</groupId>
+  <artifactId>opennlp</artifactId>
+  <version>1.5.1-incubating</version>
+</dependency>
+<dependency>
+  <groupId>org.apache.opennlp</groupId>
+  <artifactId>opennlp-tools</artifactId>
+  <version>1.5.1-incubating</version>
+</dependency>
+  </dependencies>
+</project>
 

--- /dev/null
+++ b/lib/Protobuf-PHP/LICENSE
@@ -1,1 +1,21 @@
+The MIT License
 
+Copyright (c) 2011 Iván -DrSlump- Montes
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

--- /dev/null
+++ b/lib/Protobuf-PHP/README.md
@@ -1,1 +1,198 @@
+Protobuf for PHP
+================
 
+Protobuf for PHP is an implementation of Google's Protocol Buffers for the PHP
+language, supporting its binary data serialization and including a `protoc` 
+plugin to generate PHP classes from .proto files.
+
+Great effort has been put into generating PHP files that include all sort of type
+hints to aide IDE's with autocompletion. Therefore, it can not only be used to
+communicate with Protocol Buffers services but also as a generation tool for 
+_data objects_ no matter what the final serialization is.
+
+For more information see the [included man pages](http://drslump.github.com/Protobuf-PHP/).
+
+
+## Requirements
+
+  - PHP 5.3  
+  - Pear's Console_CommandLine (for the protoc wrapper tool)
+  - Google's `protoc` compiler version 2.3 or above
+  - GMP or BC Math extensions ¹
+
+  ¹ Only needed for negative values in `int32`, `int64` or `fixed64` types. See
+    the _known issues_ section.
+
+
+## Features
+
+### Working
+
+  - Standard types (numbers, string, enums, messages, etc)
+  - Pluggable serialization backends (codecs)
+    - Standard Binary
+    - Standard TextFormat ¹
+    - PhpArray
+    - JSON
+    - [ProtoJson](https://github.com/drslump/ProtoJson) (_TagMap_ and _Indexed_ variants)
+    - XML
+  - Protoc compiler plugin to generate the PHP classes
+  - Extensions
+  - Unknown fields
+  - Packed fields
+  - Reflection
+  - Dynamic messages with annotations support
+  - Generates service interfaces
+  - Includes comments from .proto files in the generated files
+  - Pear package for easy installation
+
+¹ Only serialization is supported
+
+### Future
+
+  - Speed optimized code generation mode
+  - Support numbers beyond PHP's native limits
+
+
+
+## Example usage
+
+    $person = new Tutorial\Person();
+    $person->name = 'DrSlump';
+    $person->setId(12);
+
+    $book = new Tutorial\AddressBook();
+    $book->addPerson($person);
+
+    // Use default codec
+    $data = $book->serialize();
+
+    // Use custom codec
+    $codec = new \DrSlump\Protobuf\Codec\Binary();
+    $data = $codec->encode($book);
+    // ... or ...
+    $data = $book->serialize($codec);
+
+
+## Installation
+
+Install with Pear
+
+    pear channel-discover pear.pollinimini.net
+    pear install drslump/Protobuf-beta
+
+You can also get the latest version by checking out a copy of the
+repository in your computer.
+
+
+
+## Known issues
+
+
+### Types
+
+PHP is very weak when dealing with numbers processing. Several work arounds have been applied
+to the standard binary codec to reduce incompatibilities between Protobuf types and PHP ones.
+
+  - Protobuf stores floating point values using