add binary protobuf GTFSRT format
add binary protobuf GTFSRT format

--- a/include/common-template.inc.php
+++ b/include/common-template.inc.php
@@ -42,7 +42,7 @@
 }
 
 function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false) {
-    global $basePath, $GTFSREnabled;
+    global $basePath, $GTFSREnabled, $stopid, $routeid;
     echo '
 <!DOCTYPE html> 
 <html lang="en">
@@ -59,14 +59,13 @@
         $jqmcss = $basePath . "css/jquery.mobile-$jqmVersion.css";
         $jqjs = $basePath . "js/jquery-1.6.4.min.js";
         $jqmjs = $basePath . "js/jquery.mobile-$jqmVersion.js";
-        
+
         $jqmcss = $basePath . "css/jquery.mobile-b90eab4935.css";
         $jqmjs = $basePath . "js/jquery.mobile-b90eab4935.js";
     } else {
         $jqmcss = "//code.jquery.com/mobile/$jqmVersion/jquery.mobile-$jqmVersion.min.css";
         $jqjs = "//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js";
         $jqmjs = "//code.jquery.com/mobile/$jqmVersion/jquery.mobile-$jqmVersion.min.js";
-
     }
     echo '<link rel="stylesheet"  href="' . $jqmcss . '" />
 	<script src="' . $jqjs . '"></script>
@@ -108,7 +107,7 @@
 }';
     echo '</style>';
     echo '<link rel="stylesheet"  href="' . $basePath . 'css/local.css.php" />';
-    if (isIOSDevice()){
+    if (isIOSDevice()) {
         echo '<meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  <link rel="apple-touch-startup-image" href="startup.png" />
@@ -174,19 +173,41 @@
         <a name="maincontent" id="maincontent"></a>
         <div data-role="content"> ';
         if ($GTFSREnabled) {
-        $overrides = getServiceOverride();
-        if (isset($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 
+            $overrides = getServiceOverride();
+            if (isset($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>';
-            }
-        }
-            $serviceAlerts = getServiceAlertsAsArray("agency", "0");
+                } 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>';
+                }
+            }
+            $serviceAlerts = Array();
+            $globalAlerts = getServiceAlertsAsArray("agency", "0");
+            if ($globalAlerts != nullarray) {
+                // echo "getting alerts due to network wide";
+                $serviceAlerts = array_merge($serviceAlerts, $globalAlerts);
+            }
+            if (isset($stopid)) {
+                $stopAlerts = getServiceAlertsAsArray("stop", $stopid);
+                if ($stopAlerts != nullarray) {
+                    // echo "getting alerts due to stop $stopid";
+                    $serviceAlerts = array_merge($serviceAlerts, $stopAlerts);
+                }
+            }
+            if (isset($routeid)) {
+                $routeAlerts = getServiceAlertsAsArray("route", $routeid);
+                if ($routeAlerts != nullarray) {
+                    //    echo "getting alerts due to route $routeid";
+                    $serviceAlerts = array_merge($serviceAlerts, $routeAlerts);
+                }
+            }
             if (isset($serviceAlerts['entity']) && sizeof($serviceAlerts['entity']) > 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']} 
+                    echo "<div id='servicewarning'><b>{$entity['alert']['header_text']['translation'][0]['text']}</b>&nbsp;<small>"
+                    . date("F jS Y, g:i a", $entity['alert']['active_period'][0]['start']) . " to "
+                    . date("F jS Y, g:i a", $entity['alert']['active_period'][0]['end']) . "</small>
+                            <br>Warning: {$entity['alert']['description_text']['translation'][0]['text']} 
                             <br><a href='{$entity['alert']['url']['translation'][0]['text']}'>Source</a>  </div>";
                 }
             }
@@ -212,9 +233,10 @@
     }
     echo "\n</div></div></body></html>";
 }
+
 function timeSettings() {
     global $service_periods;
-echo '<div id="settings" data-role="collapsible" data-collapsed="true">
+    echo '<div id="settings" data-role="collapsible" data-collapsed="true">
 <h3>Change Time (' . (isset($_REQUEST['time']) ? $_REQUEST['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...</h3>
         <form action="' . basename($_SERVER['PHP_SELF']) . '" method="GET">
                <input type="hidden" name="suburb" id="suburb" value="' . (isset($_REQUEST['suburb']) ? $_REQUEST['suburb'] : "") . '"/>
@@ -230,10 +252,10 @@
 		<div data-role="fieldcontain">
 		    <label for="service_period"> Service Period:  </label>
 			<select name="service_period" id="service_period">';
-foreach ($service_periods as $service_period) {
-    echo "<option value=\"$service_period\"" . (service_period() === $service_period ? " SELECTED" : "") . '>' . ucwords($service_period) . '</option>';
-}
-echo '</select>
+    foreach ($service_periods as $service_period) {
+        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>
 		</div>
 		
@@ -241,8 +263,9 @@
                 </div></form>
             </div>';
 }
+
 function placeSettings() {
-    
+
     $geoerror = false;
     $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == "";
 
@@ -275,14 +298,15 @@
 
 //stop list collapsing
 function stopCompare($stopName) {
-    return substr(trim(preg_replace("/\(Platform.*/", "", $stopName)),0,9);
-}
-function stopGroupTitle($stopName,$stopdesc) {
-    if (preg_match("/Dr |Cct |Cir |Av |St |Cr |Parade |Way |Bank /",$stopName)) {
-        $descParts =  explode("<br>",$stopdesc);
-         return trim(str_replace("Street: ","",$descParts[0]));
+    return substr(trim(preg_replace("/\(Platform.*/", "", $stopName)), 0, 9);
+}
+
+function stopGroupTitle($stopName, $stopdesc) {
+    if (preg_match("/Dr |Cct |Cir |Av |St |Cr |Parade |Way |Bank /", $stopName)) {
+        $descParts = explode("<br>", $stopdesc);
+        return trim(str_replace("Street: ", "", $descParts[0]));
     } else {
-        return trim(preg_replace("/\(Platform.*/", "",$stopName));
+        return trim(preg_replace("/\(Platform.*/", "", $stopName));
     }
 }
 

--- a/include/common-transit.inc.php
+++ b/include/common-transit.inc.php
@@ -149,69 +149,104 @@
           street inform: route inform, trip inform, stop inform
           route patch: trip remove
          */
-        $fm = new transit_realtime\FeedMessage();
-        $fh = new transit_realtime\FeedHeader();
-        $fh->setGtfsRealtimeVersion(1);
-        $fh->setTimestamp(time());
-        $fm->setHeader($fh);
-        foreach (getCurrentAlerts() as $alert) {
-            $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) {
-                $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);
+        $current_alerts = getCurrentAlerts();
+        $informed_count = 0;
+        if (sizeof($current_alerts) > 0) {
+
+            $fm = new transit_realtime\FeedMessage();
+            $fh = new transit_realtime\FeedHeader();
+            $fh->setGtfsRealtimeVersion(1);
+            $fh->setTimestamp(time());
+            $fm->setHeader($fh);
+            foreach ($current_alerts as $current_alert) {
+                $affectsFilteredEntities = false;
+                $fe = new transit_realtime\FeedEntity();
+                $fe->setId($current_alert['id']);
+                $fe->setIsDeleted(false);
+                $alert = new transit_realtime\Alert();
+                $tr = new transit_realtime\TimeRange();
+                $tr->setStart($current_alert['start']);
+                $tr->setEnd($current_alert['end']);
+                $alert->addActivePeriod($tr);
+                $informedEntities = getInformedAlerts($current_alert['id'], $filter_class, $filter_id);
+                if (sizeof($informedEntities) > 0) {
+
+                    $affectsFilteredEntities = true;
+                    foreach ($informedEntities as $informedEntity) {
+	$informed_count++;
+                    $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);
+}
+                }
+                if ($current_alert['cause'] != "") {
+                    $alert->setCause(constant("transit_realtime\Alert\Cause::" . $current_alert['cause']));
+                }
+                if ($current_alert['effect'] != "") {
+                    $alert->setEffect(constant("transit_realtime\Alert\Effect::" . $current_alert['effect']));
+                }
+                if ($current_alert['url'] != "") {
+                    $tsUrl = new transit_realtime\TranslatedString();
+                    $tUrl = new transit_realtime\TranslatedString\Translation();
+                    $tUrl->setText($current_alert['url']);
+                    $tUrl->setLanguage("en");
+                    $tsUrl->addTranslation($tUrl);
+                    $alert->setUrl($tsUrl);
+                }
+                if ($current_alert['header'] != "") {
+                    $tsHeaderText = new transit_realtime\TranslatedString();
+                    $tHeaderText = new transit_realtime\TranslatedString\Translation();
+                    $tHeaderText->setText($current_alert['header']);
+                    $tHeaderText->setLanguage("en");
+                    $tsHeaderText->addTranslation($tHeaderText);
+                    $alert->setHeaderText($tsHeaderText);
+                }
+                if ($current_alert['description'] != "") {
+                    $tsDescriptionText = new transit_realtime\TranslatedString();
+                    $tDescriptionText = new transit_realtime\TranslatedString\Translation();
+                    $tDescriptionText->setText(trim($current_alert['description']));
+                    $tDescriptionText->setLanguage("en");
+                    $tsDescriptionText->addTranslation($tDescriptionText);
+                    $alert->setDescriptionText($tsDescriptionText);
+                }
+                $fe->setAlert($alert);
+                if ($affectsFilteredEntities) {
+                    $fm->addEntity($fe);
+                }
+            }
+            if ($informed_count > 0) {
+                return $fm;
+            } else {
+                return null;
+            }
+        } else
+            return null;
+    }
+
+    function getServiceAlertsAsArray($filter_class = "", $filter_id = "") {
+
+        $alerts = getServiceAlerts($filter_class, $filter_id);
+        if ($alerts != null) {
+            $codec = new DrSlump\Protobuf\Codec\PhpArray();
+
+            return $codec->encode($alerts);
+        } else {
+            return nullarray;
         }
-        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 = "") {

--- a/include/common.inc.php
+++ b/include/common.inc.php
@@ -51,8 +51,9 @@
         || strstr($_SERVER['PHP_SELF'], "lib/")
         || strstr($_SERVER['PHP_SELF'], "geo/")
         || strstr($_SERVER['PHP_SELF'], "include/")
-        || strstr($_SERVER['PHP_SELF'], "servicealerts/"))
+        || strstr($_SERVER['PHP_SELF'], "rtpis/")) {
     $basePath = "../";
+}
 
 function isDebugServer() {
     

--- a/include/db/route-dao.inc.php
+++ b/include/db/route-dao.inc.php
@@ -97,7 +97,7 @@
 function getRoutesByNumberSeries($routeNumberSeries = "") {
     global $conn;
     if (strlen($routeNumberSeries) == 1) {
-        return getRoutesByNumber($routeNumberSeries);
+        return getRoute($routeNumberSeries);
     }
     $seriesMin = substr($routeNumberSeries, 0, -1) . "0";
     $seriesMax = substr($routeNumberSeries, 0, -1) . "9";

--- a/include/db/servicealert-dao.inc.php
+++ b/include/db/servicealert-dao.inc.php
@@ -44,17 +44,19 @@
     return $query->fetch(PDO :: FETCH_ASSOC);
 }
 
-function updateServiceAlert($alertID, $start, $end, $header, $description, $url) {
+function updateServiceAlert($alertID, $alert) {
     global $conn;
-    $query = 'update servicealerts_alerts set start=:start, "end"=:end, header=:header, description=:description, url=:url where id = :servicealert_id';
+    $query = 'update servicealerts_alerts set start=:start, "end"=:end, header=:header, description=:description, url=:url, cause=:cause, effect=:effect 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->bindValue(":servicealert_id", $alertID);
+    $query->bindValue(":start", $alert['startdate']);
+    $query->bindValue(":end", $alert['enddate']);
+    $query->bindValue(":header", $alert['header']);
+    $query->bindValue(":description", $alert['description']);
+    $query->bindValue(":url", $alert['url']);
+    $query->bindValue(":cause", $alert['cause']);
+    $query->bindValue(":effect", $alert['effect']);
     $query->execute();
 
     print_r($conn->errorInfo());
@@ -65,16 +67,19 @@
     return $query->fetch(PDO :: FETCH_ASSOC);
 }
 
-function addServiceAlert($start, $end, $header, $description, $url) {
+function addServiceAlert($alert) {
     global $conn;
-    $query = 'INSERT INTO servicealerts_alerts (start, "end", header, description, url) VALUES (:start, :end, :header, :description, :url) ';
+    $query = 'INSERT INTO servicealerts_alerts (start, "end", header, description, url,cause,effect) VALUES (:start, :end, :header, :description, :url,:cause,:effect) ';
     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);
+    //print_r($alert);
+    $query->bindValue(":start", $alert['startdate']);
+    $query->bindValue(":end", $alert['enddate']);
+    $query->bindValue(":header", $alert['header']);
+    $query->bindValue(":description", $alert['description']);
+    $query->bindValue(":url", $alert['url']);
+    $query->bindValue(":cause", $alert['cause']);
+    $query->bindValue(":effect", $alert['effect']);
     $query->execute();
 
     print_r($conn->errorInfo());
@@ -114,6 +119,7 @@
 function getInformedAlerts($id, $filter_class, $filter_id) {
 
     global $conn;
+    //echo "$id, $filter_class, $filter_id\n";
     $query = "SELECT * from servicealerts_informed where servicealert_id = :servicealert_id";
 
     if ($filter_class != "") {
@@ -158,12 +164,14 @@
 
 function addInformedAlert($serviceAlertID, $class, $id, $action) {
     global $conn;
-    $query = 'INSERT INTO servicealerts_informed (servicealert_id , informed_class , informed_id) VALUES(:servicealert_id ,:informed_class, :informed_id)';
+    $query = 'INSERT INTO servicealerts_informed (servicealert_id , informed_class , informed_id, informed_action) 
+        VALUES(:servicealert_id ,:informed_class, :informed_id, :informed_action)';
     debug($query, "database");
     $query = $conn->prepare($query);
     $query->bindParam(":servicealert_id", $serviceAlertID);
     $query->bindParam(":informed_class", $class);
     $query->bindParam(":informed_id", $id);
+    $query->bindParam(":informed_action", $action);
     $query->execute();
 
     print_r($conn->errorInfo());

--- a/include/db/stop-dao.inc.php
+++ b/include/db/stop-dao.inc.php
@@ -89,7 +89,7 @@
     $query = "Select * from stops where stop_name LIKE :name;";
     debug($query, "database");
     $query = $conn->prepare($query);
-    $name = "%" . $name . ";%";
+    $name = $name . "%";
     $query->bindParam(":name", $name);
     $query->execute();
     if (!$query) {

--- /dev/null
+++ b/rtpis/gtfs-realtime.php
@@ -1,1 +1,85 @@
+<?php
 
+/*
+ *    Copyright 2010,2011 Alexander Sadleir 
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+include ('../include/common.inc.php');
+function accept_header($header = false) {
+    // http://jrgns.net/parse_http_accept_header
+    $toret = null;
+    $header = $header ? $header : (array_key_exists('HTTP_ACCEPT', $_SERVER) ? $_SERVER['HTTP_ACCEPT']: false);
+    if ($header) {
+        $types = explode(',', $header);
+        $types = array_map('trim', $types);
+        foreach ($types as $one_type) {
+            $one_type = explode(';', $one_type);
+            $type = array_shift($one_type);
+            if ($type) {
+                list($precedence, $tokens) = self::accept_header_options($one_type);
+                list($main_type, $sub_type) = array_map('trim', explode('/', $type));
+                $toret[] = array('main_type' => $main_type, 'sub_type' => $sub_type, 'precedence' => (float)$precedence, 'tokens' => $tokens);
+            }
+        }
+        usort($toret, array('Parser', 'compare_media_ranges'));
+    }
+    return $toret;
+}
+function usage() {
+echo "Usage notes: Must specify format json/protobuf and gtfs-realtime feedtype alerts/updates. If callback is specified, will provide jsonp. Can filter with parmaters filter_class route/stop and filter_id with the id specified in GTFS.";
+die();
+}
+
+$filter_class = (isset($_REQUEST['filter_class']) ? $_REQUEST['filter_class'] : "");
+$filter_id = (isset($_REQUEST['filter_id']) ? $_REQUEST['filter_id']:"");
+
+$json_types =  Array("application/json","application/x-javascript","text/javascript","text/x-javascript","text/x-json");
+if ($_REQUEST['json']) {
+if ($_REQUEST['alerts']) {
+    $return = getServiceAlertsAsJSON($filter_class,$filter_id);
+} else if ($_REQUEST['updates']) {
+    $return = getTripUpdatesAsJSON($filter_class,$filter_id);
+} else {
+	usage();
+}
+    header('Content-Type: application/json; charset=utf8');
+// header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/');
+    header('Access-Control-Max-Age: 3628800');
+    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
+    if (isset($_GET['callback'])) {
+        $json = '(' . $return . ');'; //must wrap in parens and end with semicolon
+        //print_r($_GET['callback'] . $json); //callback is prepended for json-p
+    }
+    else {
+        echo $return;
+	}
+} else if ($_REQUEST['protobuf']) {
+if ($_REQUEST['alerts']) {
+    $return = getServiceAlertsAsBinary($filter_class,$filter_id);
+} else if ($_REQUEST['updates']) {
+    $return = getTripUpdatesAsBinary($filter_class,$filter_id);
+} else {
+	usage();
+}
+    header('Content-Type: application/x-protobuf');
+header('Content-Disposition: attachment; filename="'.(isset($_REQUEST['updates'])?"updates.":"alerts.").date("c").'.protobuf"');
+// header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/');
+    header('Access-Control-Max-Age: 3628800');
+    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
+        echo $return;
+} else {
+usage();
+}
+?>
+

file:b/rtpis/importer.py (new)
--- /dev/null
+++ b/rtpis/importer.py
@@ -1,1 +1,104 @@
+# info
+# http://stackoverflow.com/questions/4206882/named-entity-recognition-with-preset-list-of-names-for-python-php/4207128#4207128
+# http://alias-i.com/lingpipe/demos/tutorial/ne/read-me.html approximate dist
+# http://streamhacker.com/2008/12/29/how-to-train-a-nltk-chunker/ more training
+# http://www.postgresql.org/docs/9.1/static/pgtrgm.html
 
+# data sources
+# http://twitter.com/#!/ACTEmergencyInf instant site wide
+# http://twitter.com/#!/ACTPol_Traffic
+# http://esa.act.gov.au/feeds/currentincidents.xml
+
+# source: https://gist.github.com/322906/90dea659c04570757cccf0ce1e6d26c9d06f9283
+# to install python -m nltk.downloader punkt
+import nltk
+import tweepy
+import psycopg2
+import pickle
+
+from iniparse import INIConfig
+
+def insert_service_alert_sitewide(heading, message, url):
+        print "NaN"
+
+def insert_service_alert_for_street(streets, heading, message, url):
+    	conn_string = "host='localhost' dbname='energymapper' user='postgres' password='snmc'"
+	# print the connection string we will use to connect
+	print "Connecting to database\n	->%s" % (conn_string)
+	try:
+		# get a connection, if a connect cannot be made an exception will be raised here
+		conn = psycopg2.connect(conn_string)
+
+		# conn.cursor will return a cursor object, you can use this cursor to perform queries
+		cursor = conn.cursor()
+
+		# execute our Query
+		cursor.execute("")
+
+		# retrieve the records from the database
+		records = cursor.fetchall()
+
+  	  	for record in records:
+			ys.append(record[0])
+                # >>> cur.execute("INSERT INTO test (num, data) VALUES (%s, %s)", (42, 'bar'))
+                #>>> cur.statusmessage
+                #'INSERT 0 1'
+	except:
+		# Get the most recent exception
+		exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
+		# Exit the script and print an error telling what happened.
+		sys.exit("Database connection failed!\n ->%s" % (exceptionValue))
+		
+
+def extract_entity_names(t):
+    entity_names = []
+    
+    if hasattr(t, 'node') and t.node:
+        if t.node == 'NE':
+            entity_names.append(' '.join([child[0] for child in t]))
+        else:
+            for child in t:
+                entity_names.extend(extract_entity_names(child))
+                
+    return entity_names
+
+def extract_names(sample):     
+    sentences = nltk.sent_tokenize(sample)
+    tokenized_sentences = [nltk.word_tokenize(sentence) for sentence in sentences]
+    tagged_sentences = [nltk.pos_tag(sentence) for sentence in tokenized_sentences]
+    chunked_sentences = nltk.batch_ne_chunk(tagged_sentences, binary=True)
+    # chunked/tagged may be enough to just find and match the nouns
+
+    entity_names = []
+    for tree in chunked_sentences:
+        # Print results per sentence
+        # print extract_entity_names(tree)
+        
+        entity_names.extend(extract_entity_names(tree))
+
+    # Print all entity names
+    #print entity_names
+
+    # Print unique entity names
+    print set(entity_names)
+
+cfg = INIConfig(open('/tmp/aws.ini'))
+
+auth = tweepy.OAuthHandler(cfg.api_keys.twitter_consumer_key, cfg.api_keys.twitter_consumer_secret)
+auth.set_access_token(cfg.api_keys.twitter_access_token, cfg.api_keys.twitter_access_token_secret)
+
+#api = tweepy.API(auth)
+api = tweepy.API()
+# If the authentication was successful, you should
+# see the name of the account print out
+#print api.me().name
+# https://github.com/tweepy/tweepy/blob/master/tweepy/api.py
+for status in api.user_timeline(screen_name="ACTPol_Traffic",exclude_replies='true'):
+            print status.text
+            print status.created_at
+            print extract_names(status.text)
+# print api.update_status(status="test")
+
+last_tweet_ids = { "lion": "111", "kitty": "2222" } 
+pickle.dump( last_tweet_ids, open( "save.p", "wb" ) )
+last_tweet_ids = pickle.load( open( "save.p", "rb" ) )

file:b/rtpis/index.php (new)
--- /dev/null
+++ b/rtpis/index.php
@@ -1,1 +1,21 @@
+<?php
+include ('../include/common.inc.php');
 
+include_header("Service Alerts", "index");
+echo '<ul data-role="listview" data-theme="e" data-groupingtheme="e">';
+	
+ if ($_SESSION['authed'] == true) {
+ 	echo'	<li><a href="servicealert_editor.php"><h3>servicealert_editor</h3>
+		<p>servicealert_editor</p></a></li>';
+          }
+ 	echo'	<li><a href="servicealert_viewer.php"><h3>Service Alert Viewer</h3>
+		<p>Browse current network alerts</p></a></li>';
+          
+           echo'  </ul>';
+
+?>	    </div>
+<?php
+include_footer()
+?>
+        
+

file:b/rtpis/punkt.zip (new)
--- /dev/null
+++ b/rtpis/punkt.zip

--- /dev/null
+++ b/rtpis/servicealert_editor.php
@@ -1,1 +1,187 @@
+<?php
+/*
+ *    Copyright 2010,2011 Alexander Sadleir 
 
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+include ('../include/common.inc.php');
+auth();
+include_header("Service Alert Editor", "serviceAlertEditor");
+/**
+ * Currently support:
+ * network inform
+ * stop remove: route pa