<?php | <?php |
function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false) | function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false) |
{ | { |
echo ' | echo ' |
<!DOCTYPE html> | <!DOCTYPE html> |
<html> | <html> |
<head> | <head> |
<title>' . $pageTitle . '</title>'; | <title>' . $pageTitle . '</title>'; |
if (isDebugServer()) echo '<link rel="stylesheet" href="css/jquery-mobile-1.0a3.css" /> | if (isDebugServer()) echo '<link rel="stylesheet" href="css/jquery-mobile-1.0a3.css" /> |
<script type="text/javascript" src="js/jquery-1.5.js"></script> | <script type="text/javascript" src="js/jquery-1.5.js"></script> |
<script type="text/javascript" src="js/jquery-mobile-1.0a3.js"></script>'; | <script type="text/javascript" src="js/jquery-mobile-1.0a3.js"></script>'; |
else echo '<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.css" /> | else echo '<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.css" /> |
<script type="text/javascript" src="http://code.jquery.com/jquery-1.5.js"></script> | <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.js"></script> |
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.js"></script>'; | <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.js"></script>'; |
echo ' | echo ' |
<link rel="stylesheet" href="css/jquery.ui.datepicker.mobile.css" /> | <link rel="stylesheet" href="css/jquery.ui.datepicker.mobile.css" /> |
<script> | <script> |
//reset type=date inputs to text | //reset type=date inputs to text |
$( document ).bind( "mobileinit", function(){ | $( document ).bind( "mobileinit", function(){ |
$.mobile.page.prototype.options.degradeInputs.date = true; | $.mobile.page.prototype.options.degradeInputs.date = true; |
}); | }); |
</script> | </script> |
<script src="js/jQuery.ui.datepicker.js"></script> | <script src="js/jQuery.ui.datepicker.js"></script> |
<script src="js/jquery.ui.datepicker.mobile.js"></script> | <script src="js/jquery.ui.datepicker.mobile.js"></script> |
<style type="text/css"> | <style type="text/css"> |
.ui-navbar { | .ui-navbar { |
width: 100%; | width: 100%; |
} | } |
.ui-btn-inner { | .ui-btn-inner { |
white-space: normal !important; | white-space: normal !important; |
} | } |
.ui-li-heading { | .ui-li-heading { |
white-space: normal !important; | white-space: normal !important; |
} | } |
.ui-listview-filter { | .ui-listview-filter { |
margin: 0 !important; | margin: 0 !important; |
} | } |
.ui-icon-navigation { | .ui-icon-navigation { |
background-image: url(css/images/113-navigation.png); | background-image: url(css/images/113-navigation.png); |
background-position: 1px 0; | background-position: 1px 0; |
} | } |
#footer { | #footer { |
text-size: 0.75em; | text-size: 0.75em; |
text-align: center; | text-align: center; |
} | } |
body { | body { |
background-color: #F0F0F0; | background-color: #F0F0F0; |
} | } |
</style> | </style> |
<meta name="apple-mobile-web-app-capable" content="yes" /> | <meta name="apple-mobile-web-app-capable" content="yes" /> |
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> | <meta name="apple-mobile-web-app-status-bar-style" content="black" /> |
<link rel="apple-touch-startup-image" href="startup.png" /> | <link rel="apple-touch-startup-image" href="startup.png" /> |
<link rel="apple-touch-icon" href="apple-touch-icon.png" />'; | <link rel="apple-touch-icon" href="apple-touch-icon.png" />'; |
if ($geolocate) { | if ($geolocate) { |
echo "<script> | echo "<script> |
function success(position) { | function success(position) { |
$('#geolocate').val(position.coords.latitude+','+position.coords.longitude); | $('#geolocate').val(position.coords.latitude+','+position.coords.longitude); |
$.ajax({ url: \"common.inc.php?geolocate=yes&lat=\"+position.coords.latitude+\"&lon=\"+position.coords.longitude }); | $.ajax({ url: \"common.inc.php?geolocate=yes&lat=\"+position.coords.latitude+\"&lon=\"+position.coords.longitude }); |
$('#here').click(function(event) { $('#geolocate').val(doAJAXrequestForGeolocSessionHere()); return false;}); | $('#here').click(function(event) { $('#geolocate').val(doAJAXrequestForGeolocSessionHere()); return false;}); |
$('#here').show(); | $('#here').show(); |
} | } |
function error(msg) { | function error(msg) { |
console.log(msg); | console.log(msg); |
} | } |
if (navigator.geolocation) { | if (navigator.geolocation) { |
navigator.geolocation.getCurrentPosition(success, error); | navigator.geolocation.getCurrentPosition(success, error); |
} | } |
</script> "; | </script> "; |
} | } |
echo '</head> | echo '</head> |
<body> | <body> |
'; | '; |
if (isMetricsOn()) { | if (isMetricsOn()) { |
require_once ('owa/owa_env.php'); | require_once ('owa/owa_env.php'); |
require_once (OWA_DIR . 'owa_php.php'); | require_once (OWA_DIR . 'owa_php.php'); |
$owa = new owa_php(); | $owa = new owa_php(); |
global $owaSiteID; | global $owaSiteID; |
$owa->setSiteId($owaSiteID); | $owa->setSiteId($owaSiteID); |
$owa->setPageTitle($pageTitle); | $owa->setPageTitle($pageTitle); |
$owa->setPageType($pageType); | $owa->setPageType($pageType); |
$owa->trackPageView(); | $owa->trackPageView(); |
$owa->placeHelperPageTags(); | $owa->placeHelperPageTags(); |
} | } |
if ($opendiv) { | if ($opendiv) { |
echo '<div data-role="page"> | echo '<div data-role="page"> |
<script> | <script> |
$(document).ready(function () | $(document).ready(function () |
{ | { |
document.title = "' . $pageTitle . '"; | document.title = "' . $pageTitle . '"; |
}); | }); |
</script> | </script> |
<div data-role="header"> | <div data-role="header"> |
<h1>' . $pageTitle . '</h1> | <h1>' . $pageTitle . '</h1> |
</div><!-- /header --> | </div><!-- /header --> |
<div data-role="content"> '; | <div data-role="content"> '; |
} | } |
} | } |
function include_footer() | function include_footer() |
{ | { |
if ($geolocate && isset($_SESSION['lat'])) { | if ($geolocate && isset($_SESSION['lat'])) { |
echo "<script> | echo "<script> |
$('#here').click(function(event) { $('#geolocate').val(doAJAXrequestForGeolocSessionHere()); return false;}); | $('#here').click(function(event) { $('#geolocate').val(doAJAXrequestForGeolocSessionHere()); return false;}); |
$('#here').show(); | $('#here').show(); |
</script>"; | </script>"; |
} | } |
echo '<div id="footer"><a href="about.php">About/Contact Us</a> <a href="feedback.php">Feedback/Bug Report</a></a>'; | echo '<div id="footer"><a href="about.php">About/Contact Us</a> <a href="feedback.php">Feedback/Bug Report</a></a>'; |
echo '</div>'; | echo '</div>'; |
} | } |
function timePlaceSettings($geolocate = false) | function timePlaceSettings($geolocate = false) |
{ | { |
global $service_periods; | global $service_periods; |
$geoerror = false; | $geoerror = false; |
if ($geolocate == true) { | if ($geolocate == true) { |
$geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; | $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; |
} | } |
if ($geoerror) { | if ($geoerror) { |
echo '<div class="error">Sorry, but your location could not currently be detected. | echo '<div class="error">Sorry, but your location could not currently be detected. |
Please allow location permission, wait for your location to be detected, | Please allow location permission, wait for your location to be detected, |
or enter an address/co-ordinates in the box below.</div>'; | or enter an address/co-ordinates in the box below.</div>'; |
} | } |
echo '<div data-role="collapsible" data-collapsed="' . !$geoerror . '"> | echo '<div data-role="collapsible" data-collapsed="' . !$geoerror . '"> |
<h3>Change Time/Place...</h3> | <h3>Change Time/Place (' . (isset($_SESSION['time']) ? $_SESSION['time'] : "Current Time,") . ' '.ucwords(service_period()).')...</h3> |
<form action="" method="post"> | <form action="" method="post"> |
<div class="ui-body"> | <div class="ui-body"> |
<div data-role="fieldcontain"> | <div data-role="fieldcontain"> |
<label for="geolocate"> Current Location: </label> | <label for="geolocate"> Current Location: </label> |
<input type="text" id="geolocate" name="geolocate" value="' . (isset($_SESSION['lat']) && isset($_SESSION['lon']) ? $_SESSION['lat'] . "," . $_SESSION['lon'] : "Enter co-ordinates or address here") . '"/> <a href="#" style="display:none" name="here" id="here"/>Here?</a> | <input type="text" id="geolocate" name="geolocate" value="' . (isset($_SESSION['lat']) && isset($_SESSION['lon']) ? $_SESSION['lat'] . "," . $_SESSION['lon'] : "Enter co-ordinates or address here") . '"/> <a href="#" style="display:none" name="here" id="here"/>Here?</a> |
</div> | </div> |
<div data-role="fieldcontain"> | <div data-role="fieldcontain"> |
<label for="time"> Time: </label> | <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"/>Current Time?</a> | <input type="time" name="time" id="time" value="' . (isset($_SESSION['time']) ? $_SESSION['time'] : date("H:i")) . '"/> <a href="#" name="currentTime" id="currentTime"/>Current Time?</a> |
</div> | </div> |
<div data-role="fieldcontain"> | <div data-role="fieldcontain"> |
<label for="service_period"> Service Period: </label> | <label for="service_period"> Service Period: </label> |
<select name="service_period">'; | <select name="service_period">'; |
foreach ($service_periods as $service_period) { | foreach ($service_periods as $service_period) { |
echo "<option value=\"$service_period\"" . (service_period() === $service_period ? "SELECTED" : "") . '>' . ucwords($service_period) . '</option>'; | echo "<option value=\"$service_period\"" . (service_period() === $service_period ? "SELECTED" : "") . '>' . ucwords($service_period) . '</option>'; |
} | } |
echo '</select> | 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> | </div> |
<input type="submit" value="Update"/> | <input type="submit" value="Update"/> |
</form> | </form> |
</div></div>'; | </div></div>'; |
} | } |
?> | ?> |
<?php | <?php |
date_default_timezone_set('Australia/ACT'); | date_default_timezone_set('Australia/ACT'); |
$APIurl = "http://localhost:8765"; | $APIurl = "http://localhost:8765"; |
$cloudmadeAPIkey = "daa03470bb8740298d4b10e3f03d63e6"; | $cloudmadeAPIkey = "daa03470bb8740298d4b10e3f03d63e6"; |
$googleMapsAPIkey = "ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q"; | $googleMapsAPIkey = "ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q"; |
$otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/'; | $otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/'; |
$owaSiteID = 'fe5b819fa8c424a99ff0764d955d23f3'; | $owaSiteID = 'fe5b819fa8c424a99ff0764d955d23f3'; |
//$debugOkay = Array("session","json","phperror","other"); | //$debugOkay = Array("session","json","phperror","other"); |
$debugOkay = Array( | $debugOkay = Array( |
"session", | "session", |
"json", | "json", |
"phperror" | "phperror", |
"other" | |
); | ); |
if (isDebug("phperror")) error_reporting(E_ALL ^ E_NOTICE); | if (isDebug("phperror")) error_reporting(E_ALL ^ E_NOTICE); |
include_once ("common-geo.inc.php"); | include_once ("common-geo.inc.php"); |
include_once ("common-net.inc.php"); | include_once ("common-net.inc.php"); |
include_once ("common-template.inc.php"); | include_once ("common-template.inc.php"); |
include_once ("common-transit.inc.php"); | include_once ("common-transit.inc.php"); |
// you have to open the session to be able to modify or remove it | // you have to open the session to be able to modify or remove it |
session_start(); | session_start(); |
if (isset($_REQUEST['service_period'])) { | if (isset($_REQUEST['service_period'])) { |
$_SESSION['service_period'] = filter_var($_REQUEST['service_period'], FILTER_SANITIZE_STRING); | $_SESSION['service_period'] = filter_var($_REQUEST['service_period'], FILTER_SANITIZE_STRING); |
} | } |
if (isset($_REQUEST['time'])) { | if (isset($_REQUEST['time'])) { |
$_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING); | $_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING); |
} | } |
if (isset($_REQUEST['geolocate'])) { | if (isset($_REQUEST['geolocate'])) { |
$geocoded = false; | $geocoded = false; |
if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) { | if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) { |
$_SESSION['lat'] = filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | $_SESSION['lat'] = trim(filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); |
$_SESSION['lon'] = filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | $_SESSION['lon'] = trim(filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); |
} | } |
else { | else { |
$contents = geocode(filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL) , true); | $geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL); |
echo $_REQUEST['geolocate']; | |
if (startsWith($geolocate, "-")) { | |
$locateparts = explode(",",$geolocate); | |
$_SESSION['lat'] = $locateparts[0]; | |
$_SESSION['lon'] =$locateparts[1]; | |
} else { | |
$contents = geocode($geolocate, true); | |
print_r($contents); | |
if (isset($contents[0]->centroid)) { | if (isset($contents[0]->centroid)) { |
$geocoded = true; | $geocoded = true; |
$_SESSION['lat'] = $contents[0]->centroid->coordinates[0]; | $_SESSION['lat'] = $contents[0]->centroid->coordinates[0]; |
$_SESSION['lon'] = $contents[0]->centroid->coordinates[1]; | $_SESSION['lon'] = $contents[0]->centroid->coordinates[1]; |
} | } |
else { | else { |
$_SESSION['lat'] = ""; | $_SESSION['lat'] = ""; |
$_SESSION['lon'] = ""; | $_SESSION['lon'] = ""; |
} | |
} | } |
} | } |
if ($_SESSION['lat'] != "" && isMetricsOn()) { | if ($_SESSION['lat'] != "" && isMetricsOn()) { |
// Create a new Instance of the tracker | // Create a new Instance of the tracker |
$owa = new owa_php($config); | $owa = new owa_php($config); |
// Set the ID of the site being tracked | // Set the ID of the site being tracked |
$owa->setSiteId($owaSiteID); | $owa->setSiteId($owaSiteID); |
// Create a new event object | // Create a new event object |
$event = $owa->makeEvent(); | $event = $owa->makeEvent(); |
// Set the Event Type, in this case a "video_play" | // Set the Event Type, in this case a "video_play" |
$event->setEventType('geolocate'); | $event->setEventType('geolocate'); |
// Set a property | // Set a property |
$event->set('lat', $_SESSION['lat']); | $event->set('lat', $_SESSION['lat']); |
$event->set('lon', $_SESSION['lon']); | $event->set('lon', $_SESSION['lon']); |
$event->set('geocoded', $geocoded); | $event->set('geocoded', $geocoded); |
// Track the event | // Track the event |
$owa->trackEvent($event); | $owa->trackEvent($event); |
} | } |
} | } |
debug(print_r($_SESSION, true) , "session"); | debug(print_r($_SESSION, true) , "session"); |
function isDebugServer() | function isDebugServer() |
{ | { |
return $_SERVER['SERVER_NAME'] == "10.0.1.154" || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1" || !$_SERVER['SERVER_NAME']; | return $_SERVER['SERVER_NAME'] == "10.0.1.154" || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1" || !$_SERVER['SERVER_NAME']; |
} | } |
function isDebug($debugReason = "other") | function isDebug($debugReason = "other") |
{ | { |
global $debugOkay; | global $debugOkay; |
return in_array($debugReason, $debugOkay, false) && isDebugServer(); | return in_array($debugReason, $debugOkay, false) && isDebugServer(); |
} | } |
function isMetricsOn() | function isMetricsOn() |
{ | { |
return !isDebugServer(); | return !isDebugServer(); |
} | } |
function debug($msg, $debugReason = "other") | function debug($msg, $debugReason = "other") |
{ | { |
if (isDebug($debugReason)) echo "\n<!-- " . date(DATE_RFC822) . "\n $msg -->\n"; | if (isDebug($debugReason)) echo "\n<!-- " . date(DATE_RFC822) . "\n $msg -->\n"; |
} | } |
function isFastDevice() | function isFastDevice() |
{ | { |
$ua = $_SERVER['HTTP_USER_AGENT']; | $ua = $_SERVER['HTTP_USER_AGENT']; |
$fastDevices = Array( | $fastDevices = Array( |
"Mozilla/5.0 (X11;", | "Mozilla/5.0 (X11;", |
"Mozilla/5.0 (Windows;", | "Mozilla/5.0 (Windows;", |
"Mozilla/5.0 (iP", | "Mozilla/5.0 (iP", |
"Mozilla/5.0 (Linux; U; Android", | "Mozilla/5.0 (Linux; U; Android", |
"Mozilla/4.0 (compatible; MSIE" | "Mozilla/4.0 (compatible; MSIE" |
); | ); |
$slowDevices = Array( | $slowDevices = Array( |
"J2ME", | "J2ME", |
"MIDP", | "MIDP", |
"Opera/", | "Opera/", |
"Mozilla/2.0 (compatible;", | "Mozilla/2.0 (compatible;", |
"Mozilla/3.0 (compatible;" | "Mozilla/3.0 (compatible;" |
); | ); |
return true; | return true; |
} | } |
function array_flatten($a, $f = array()) | function array_flatten($a, $f = array()) |
{ | { |
if (!$a || !is_array($a)) return ''; | if (!$a || !is_array($a)) return ''; |
foreach ($a as $k => $v) { | foreach ($a as $k => $v) { |
if (is_array($v)) $f = array_flatten($v, $f); | if (is_array($v)) $f = array_flatten($v, $f); |
else $f[$k] = $v; | else $f[$k] = $v; |
} | } |
return $f; | return $f; |
} | } |
function remove_spaces($string) | function remove_spaces($string) |
{ | { |
return str_replace(' ', '', $string); | return str_replace(' ', '', $string); |
} | } |
function object2array($object) | function object2array($object) |
{ | { |
if (is_object($object)) { | if (is_object($object)) { |
foreach ($object as $key => $value) { | foreach ($object as $key => $value) { |
$array[$key] = $value; | $array[$key] = $value; |
} | } |
} | } |
else { | else { |
$array = $object; | $array = $object; |
} | } |
return $array; | return $array; |
} | } |
function startsWith($haystack, $needle, $case = true) | function startsWith($haystack, $needle, $case = true) |
{ | { |
if ($case) { | if ($case) { |
return (strcmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); | return (strcmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); |
} | } |
return (strcasecmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); | return (strcasecmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); |
} | } |
function endsWith($haystack, $needle, $case = true) | function endsWith($haystack, $needle, $case = true) |
{ | { |
if ($case) { | if ($case) { |
return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); | return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); |
} | } |
return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); | return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); |
} | } |
function bracketsMeanNewLine($input) | function bracketsMeanNewLine($input) |
{ | { |
return str_replace(")", "</small>", str_replace("(", "<br><small>", $input)); | return str_replace(")", "</small>", str_replace("(", "<br><small>", $input)); |
} | } |
function sksort(&$array, $subkey="id", $sort_ascending=false) { | |
if (count($array)) | |
$temp_array[key($array)] = array_shift($array); | |
foreach($array as $key => $val){ | |
$offset = 0; | |
$found = false; | |
foreach($temp_array as $tmp_key => $tmp_val) | |
{ | |
if(!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) | |
{ | |
$temp_array = array_merge( (array)array_slice($temp_array,0,$offset), | |
array($key => $val), | |
array_slice($temp_array,$offset) | |
); | |
$found = true; | |
} | |
$offset++; | |
} | |
if(!$found) $temp_array = array_merge($temp_array, array($key => $val)); | |
} | |
if ($sort_ascending) $array = array_reverse($temp_array); | |
else $array = $temp_array; | |
} | |
?> | ?> |
<?php | <?php |
include ('common.inc.php'); | include ('common.inc.php'); |
$output = Array(); | $output = Array(); |
$output['hotspots'] = Array(); | $output['hotspots'] = Array(); |
$output['layer'] = "canberrabusstops"; | $output['layer'] = "canberrabusstops"; |
$max_page = 10; | $max_page = 10; |
$max_results = 50; | $max_results = 50; |
$page_start = 0 + filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT); | $page_start = 0 + filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT); |
$page_end = $max_page + filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT); | $page_end = $max_page + filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT); |
$lat = filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | $lat = filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); |
$lon = filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | $lon = filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); |
if (isset($_REQUEST['radius'])) $radius = filter_var($_REQUEST['radius'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | |
$url = $APIurl . "/json/neareststops?lat=$lat&lon=$lon&limit=50"; | $url = $APIurl . "/json/neareststops?lat=$lat&lon=$lon&limit=50"; |
$contents = json_decode(getPage($url)); | $contents = json_decode(getPage($url)); |
debug(print_r($contents, true)); | debug(print_r($contents, true)); |
$stopNum = 0; | $stopNum = 0; |
foreach ($contents as $row) { | foreach ($contents as $row) { |
$stopNum++; | $stopNum++; |
if ($stopNum > $page_start && $stopNum <= $page_end) { | if ($stopNum > $page_start && $stopNum <= $page_end) { |
$hotspot = Array(); | $hotspot = Array(); |
$hotspot['id'] = $row[0]; | $hotspot['id'] = $row[0]; |
$hotspot['title'] = $row[1]; | $hotspot['title'] = $row[1]; |
$hotspot['type'] = 0; | $hotspot['type'] = 0; |
$hotspot['lat'] = floor($row[2] * 1000000); | $hotspot['lat'] = floor($row[2] * 1000000); |
$hotspot['lon'] = floor($row[3] * 1000000); | $hotspot['lon'] = floor($row[3] * 1000000); |
$hotspot['distance'] = distance($row[2], $row[3], $_REQUEST['lat'], $_REQUEST['lon']); | $hotspot['distance'] = distance($row[2], $row[3], $_REQUEST['lat'], $_REQUEST['lon']); |
if (!isset($_REQUEST['radius']) || $hotspot['distance'] < $radius) { | $hotspot['actions'] = Array( |
$hotspot['actions'] = Array( | Array( |
Array( | "label" => 'View more trips/information', |
"label" => 'View more trips/information', | 'uri' => 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $row[0] |
'uri' => 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $row[0] | ) |
) | ); |
); | $url = $APIurl . "/json/stoptrips?stop=" . $row[0] . "&time=" . midnight_seconds() . "&service_period=" . service_period() . "&limit=4&time_range=" . strval(90 * 60); |
$url = $APIurl . "/json/stoptrips?stop=" . $row[0] . "&time=" . midnight_seconds() . "&service_period=" . service_period() . "&limit=4&time_range=" . str(90 * 60); | $trips = json_decode(getPage($url)); |
$trips = json_decode(getPage($url)); | debug(print_r($trips, true)); |
debug(print_r($trips, true)); | foreach ($trips as $key => $row) { |
foreach ($trips as $key => $row) { | if ($key < 3) { |
if ($key < 3) { | $hotspot['line' . strval($key + 2) ] = $row[1][1] . ' @ ' . midnight_seconds_to_time($row[0]); |
$hotspot['line' . strval($key + 2) ] = $row[1][1] . ' @ ' . midnight_seconds_to_time($row[0]); | |
} | |
} | } |
if (sizeof($trips) == 0) $hotspot['line2'] = 'No trips in the near future.'; | |
$output['hotspots'][] = $hotspot; | |
} | } |
if (sizeof($trips) == 0) $hotspot['line2'] = 'No trips in the near future.'; | |
$output['hotspots'][] = $hotspot; | |
} | } |
} | } |
if (sizeof($hotspot) > 0) { | if (sizeof($hotspot) > 0) { |
$output['errorString'] = 'ok'; | $output['errorString'] = 'ok'; |
$output['errorCode'] = 0; | $output['errorCode'] = 0; |
} | } |
else { | else { |
$output['errorString'] = 'no results, try increasing range'; | $output['errorString'] = 'no results, try increasing range'; |
$output['errorCode'] = 21; | $output['errorCode'] = 21; |
} | } |
if ($page_end >= $max_results || sizeof($hotspot) < $max_page) { | if ($page_end >= $max_results || sizeof($hotspot) < $max_page) { |
$output["morePages"] = false; | $output["morePages"] = false; |
$output["nextPageKey"] = null; | $output["nextPageKey"] = null; |
} | } |
else { | else { |
$output["morePages"] = true; | $output["morePages"] = true; |
$output["nextPageKey"] = $page_end; | $output["nextPageKey"] = $page_end; |
} | } |
echo json_encode($output); | echo json_encode($output); |
?> | ?> |
<?php | |
function cleanString($subject) | |
{ | |
$subject = str_replace(" ", " ", $subject); | |
$subject = str_replace("&", "&", $subject); | |
$subject = preg_replace('/[^\r\n\t\x20-\x7E\xA0-\xFF]/', '', $subject); | |
$subject = str_replace(" ", " ", $subject); | |
return trim($subject); | |
} | |
$return = Array(); | |
/*if (file_exists("mywayresponse.txt")) { | |
@$fh = fopen("mywayresponse.txt", 'r'); | |
if ($fh) { | |
$pageHTML = fread($fh, filesize("mywayresponse.txt")); | |
fclose($fh); | |
} | |
}*/ | |
//set POST variables | |
$url = 'https://www.action.act.gov.au/ARTS/use_Funcs.asp'; | |
$field_mapping = Array( | |
"card_number" => "SRNO", | |
"DOBmonth" => "month", | |
"DOBday" => "day", | |
"DOByear" => "year", | |
"secret_answer" => "pwrd", | |
"button" => "button" | |
); | |
foreach (Array( | |
"card_number", | |
"DOBday", | |
"DOBmonth", | |
"DOByear" | |
) as $field_name) { | |
if (isset($_REQUEST[$field_name])) { | |
$fields[$field_name] = filter_var($_REQUEST[$field_name], FILTER_SANITIZE_NUMBER_INT); | |
} | |
else { | |
$return["error"][] = $field_name. " parameter invalid or unspecified"; | |
} | |
} | |
if (isset($_REQUEST['secret_answer'])) { | |
$fields['secret_answer'] = filter_var($_REQUEST['secret_answer'], FILTER_SANITIZE_STRING, Array( | |
FILTER_FLAG_NO_ENCODE_QUOTES, | |
FILTER_FLAG_STRIP_HIGH, | |
FILTER_FLAG_STRIP_LOW | |
)); | |
} | |
else { | |
$return["error"][] = "secret_answer parameter invalid or unspecified"; | |
} | |
$fields['button'] = 'Submit'; | |
$fields_string = ""; | |
//url-ify the data for the POST | |
foreach ($fields as $key => $value) { | |
if (sizeof($value) === 0) $return['error'][] = $key . " parameter invalid or unspecified"; | |
$fields_string.= $field_mapping[$key] . '=' . $value . '&'; | |
} | |
$fields_string = rtrim($fields_string, '&'); | |
if (!isset($return['error'])) { | |
//open connection | |
$ch = curl_init(); | |
//set the url, number of POST vars, POST data | |
curl_setopt($ch, CURLOPT_URL, $url); | |
curl_setopt($ch, CURLOPT_POST, count($fields)); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_HEADER, 0); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 30); | |
//execute post | |
$pageHTML = curl_exec($ch); | |
if (curl_errno($ch)) $return["error"][] = "Network error " . curl_errno($ch) . " " . curl_error($ch) . " " . $url . $fields_string; | |
//close connection | |
curl_close($ch); | |
} | |
if (!isset($return['error'])) { | |
include_once ('simple_html_dom.php'); | |
$page = str_get_html($pageHTML); | |
$pageAlerts = $page->find(".smartCardAlert"); | |
if (sizeof($pageAlerts) > 0) { | |
$return['error'][] = $pageAlerts[0]->plaintext; | |
} | |
if (!isset($return['error'])) { | |
$tableNum = 0; | |
$tableName = Array( | |
1 => "myway_carddetails", | |
2 => "myway_transactions" | |
); | |
foreach ($page->find("table") as $table) { | |
$tableNum++; | |
$tableColumns = Array(); | |
$tableColumnNum = 0; | |
foreach ($table->find("th") as $th) { | |
$tableColumns[$tableColumnNum] = cleanString($th->plaintext); | |
$tableColumnNum++; | |
} | |
$tableRowNum = 0; | |
foreach ($table->find("tr") as $tr) { | |
$tableColumnNum = 0; | |
foreach ($tr->find("td") as $td) { | |
if ($tableNum == 1) $return[$tableName[$tableNum]][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext); | |
else $return[$tableName[$tableNum]][$tableRowNum][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext); | |
$tableColumnNum++; | |
} | |
$tableRowNum++; | |
} | |
} | |
} | |
} | |
if (sizeof($return) == 0) { | |
$return['error'][] = "No data extracted from MyWay website - API may be out of date"; | |
} | |
header('Content-Type: text/javascript; 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 = '(' . json_encode($return) . ');'; //must wrap in parens and end with semicolon | |
print_r($_GET['callback'] . $json); //callback is prepended for json-p | |
} | |
else echo json_encode($return); | |
?> | |
<?php | |
include ('common.inc.php'); | |
include_header("MyWay Balance", "mywayBalance"); | |
$return = Array(); | |
function printBalance($cardNumber, $date, $pwrd) | |
{ | |
global $return; | |
$return = json_decode(getPage(curPageURL() . "/myway_api.json.php?card_number=$cardNumber&DOBday={$date[0]}&DOBmonth={$date[1]}&DOByear={$date[2]}&secret_answer=$pwrd"), true); | |
if (isset($return['error'])) { | |
echo "<font color=red>" . var_dump($return['error']) . "</font>"; | |
} else { | |
echo "<h2>Balance: " . $return['myway_carddetails']['Card Balance'] . "</h2>"; | |
echo '<ul data-role="listview" data-inset="true"><li data-role="list-divider"> Recent Transactions </li>'; | |
foreach ($return['myway_transactions'] as $transaction) { | |
echo "<li><b>" . $transaction["Date / Time"] . "</b>"; | |
echo "<br><small>" . $transaction["TX Reference No / Type"]. "</small>"; | |
echo '<p class="ui-li-aside">'.$transaction["TX Amount"].'</p>'; | |
echo "</li>"; | |
} | |
echo "</ul>"; | |
} | |
} | |
if (isset($_REQUEST['card_number']) && isset($_REQUEST['date']) && isset($_REQUEST['secret_answer'])) { | |
$cardNumber = $_REQUEST['card_number']; | |
$date = explode("/", $_REQUEST['date']); | |
$pwrd = $_REQUEST['secret_answer']; | |
if ($_REQUEST['remember'] == true) { | |
$_COOKIE['card_number'] = $cardNumber; | |
$_COOKIE['date'] = $date; | |
$_COOKIE['secret_answer'] = $pwrd; | |
} | |
printBalance($cardNumber, $date, $pwrd); | |
} | |
else if (isset($_COOKIE['card_number']) && isset($_COOKIE['date']) && isset($_COOKIE['secret_answer'])) { | |
$cardNumber = $_COOKIE['card_number']; | |
$date = explode("/", $_COOKIE['date']); | |
$pwrd = $_COOKIE['secret_answer']; | |
printBalance($cardNumber, $date, $pwrd); | |
} | |
else { | |
$date = (isset($_REQUEST['date']) ? filter_var($_REQUEST['date'], FILTER_SANITIZE_STRING) : date("m/d/Y")); | |
echo '<form action="" method="post"> | |
<div data-role="fieldcontain"> | |
<label for="card_number">Card number</label> | |
<input type="text" name="card_number" id="card_number" value="' . $card_number . '" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="date"> Date of birth </label> | |
<input type="text" name="date" id="date" value="' . $date . '" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="secret_answer"> Secret question answer </label> | |
<input type="text" name="secret_answer" id="secret_answer" value="' . $secret_answer . '" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="remember"> Remember these details? </label> | |
<input type="checkbox" name="remember" id="remember" checked="yes" /> | |
</div> | |
<input type="submit" value="Go!"></form>'; | |
} | |
include_footer(); | |
?> |
<?php | <?php |
include ('common.inc.php'); | include ('common.inc.php'); |
include_header("Routes", "routeList"); | function navbar() |
echo ' | { |
echo ' | |
<div data-role="navbar"> | <div data-role="navbar"> |
<ul> | <ul> |
<li><a href="routeList.php">By Final Destination...</a></li> | <li><a href="routeList.php">By Final Destination...</a></li> |
<li><a href="routeList.php?bynumber=yes">By Number... </a></li> | <li><a href="routeList.php?bynumber=yes">By Number... </a></li> |
<li><a href="routeList.php?bysuburb=yes">By Suburb... </a></li> | <li><a href="routeList.php?bysuburb=yes">By Suburb... </a></li> |
<li><a href="routeList.php?nearby=yes">Nearby... </a></li> | <li><a href="routeList.php?nearby=yes">Nearby... </a></li> |
</ul> | </ul> |
</div> | </div> |
'; | '; |
echo ' <ul data-role="listview" data-inset="true">'; | } |
$url = $APIurl . "/json/routes"; | if ($_REQUEST['bysuburb']) { |
$contents = json_decode(getPage($url)); | include_header("Routes by Suburb", "routeList"); |
function printRoutes($routes) | navbar(); |
{ | echo ' <ul data-role="listview" data-filter="true" data-inset="true" >'; |
foreach ($suburbs as $suburb) { | |
if (!isset($_REQUEST['firstLetter'])) { | |
foreach (range('A', 'Z') as $letter) { | |
echo "<li><a href=\"routeList.php?firstLetter=$letter&bysuburb=yes\">$letter...</a></li>\n"; | |
} | |
} | |
else if (startsWith($suburb, $_REQUEST['firstLetter'])) { | |
echo '<li><a href="routeList.php?suburb=' . urlencode($suburb) . '">' . $suburb . '</a></li>'; | |
} | |
} | |
echo '</ul>'; | |
} | |
else if ($_REQUEST['nearby'] || $_REQUEST['suburb']) { | |
if ($_REQUEST['suburb']) { | |
$suburb = filter_var($_REQUEST['suburb'], FILTER_SANITIZE_STRING); | |
$url = $APIurl . "/json/stopzonesearch?q=" . $suburb; | |
include_header("Routes by Suburb", "routeList"); | |
} | |
if ($_REQUEST['nearby']) { | |
$url = $APIurl . "/json/neareststops?lat={$_SESSION['lat']}&lon={$_SESSION['lon']}&limit=15"; | |
include_header("Routes Nearby", "routeList"); | |
} | |
$stops = json_decode(getPage($url)); | |
$routes = Array(); | |
foreach ($stops as $stop) { | |
$url = $APIurl . "/json/stoproutes?stop=" . $stop[0]; | |
$stoproutes = json_decode(getPage($url)); | |
foreach ($stoproutes as $route) { | |
if (!isset($routes[$route[0]])) $routes[$route[0]] = $route; | |
} | |
} | |
navbar(); | |
echo ' <ul data-role="listview" data-filter="true" data-inset="true" >'; | |
sksort($routes, 1, true); | |
foreach ($routes as $row) { | foreach ($routes as $row) { |
echo '<li>' . $row[1] . ' <a href="trip.php?routeid=' . $row[0] . '">' . $row[2] . " (" . ucwords($row[3]) . ")</a></li>\n"; | echo '<li>' . $row[1] . ' <a href="trip.php?routeid=' . $row[0] . '">' . $row[2] . " (" . ucwords($row[4]) . ")</a></li>\n"; |
} | } |
} | } |
if ($_REQUEST['bynumber']) { | else if ($_REQUEST['bynumber']) { |
include_header("Routes by Number", "routeList"); | |
navbar(); | |
echo ' <ul data-role="listview" data-inset="true">'; | |
$url = $APIurl . "/json/routes"; | |
$contents = json_decode(getPage($url)); | |
$routeSeries = Array(); | $routeSeries = Array(); |
$seriesRange = Array(); | $seriesRange = Array(); |
foreach ($contents as $key => $row) { | foreach ($contents as $key => $row) { |
foreach (explode(" ", $row[1]) as $routeNumber) { | foreach (explode(" ", $row[1]) as $routeNumber) { |
$seriesNum = substr($routeNumber, 0, -1) . "0"; | $seriesNum = substr($routeNumber, 0, -1) . "0"; |
if ($seriesNum == "0") $seriesNum = $routeNumber; | if ($seriesNum == "0") $seriesNum = $routeNumber; |
$finalDigit = substr($routeNumber, sizeof($routeNumber) - 1, 1); | $finalDigit = substr($routeNumber, sizeof($routeNumber) - 1, 1); |
if (isset($seriesRange[$seriesNum])) { | if (isset($seriesRange[$seriesNum])) { |
if ($finalDigit < $seriesRange[$seriesNum]['max']) $seriesRange[$seriesNum]['max'] = $routeNumber; | if ($finalDigit < $seriesRange[$seriesNum]['max']) $seriesRange[$seriesNum]['max'] = $routeNumber; |
if ($finalDigit > $seriesRange[$seriesNum]['min']) $seriesRange[$seriesNum]['min'] = $routeNumber; | if ($finalDigit > $seriesRange[$seriesNum]['min']) $seriesRange[$seriesNum]['min'] = $routeNumber; |
} | } |
else { | else { |
$seriesRange[$seriesNum]['max'] = $routeNumber; | $seriesRange[$seriesNum]['max'] = $routeNumber; |
$seriesRange[$seriesNum]['min'] = $routeNumber; | $seriesRange[$seriesNum]['min'] = $routeNumber; |
} | } |
$routeSeries[$seriesNum][$seriesNum . "-" . $row[1] . "-" . $row[0]] = $row; | $routeSeries[$seriesNum][$seriesNum . "-" . $row[1] . "-" . $row[0]] = $row; |
} | } |
} | } |
ksort($routeSeries); | ksort($routeSeries); |
ksort($seriesRange); | ksort($seriesRange); |
echo '<div class="noscriptnav"> Go to route numbers: '; | echo '<div class="noscriptnav"> Go to route numbers: '; |
foreach ($seriesRange as $series => $range) { | foreach ($seriesRange as $series => $range) { |
if ($range['min'] == $range['max']) echo "<a href=\"#$series\">$series</a> "; | if ($range['min'] == $range['max']) echo "<a href=\"#$series\">$series</a> "; |
else echo "<a href=\"#$series\">{$range['min']}-{$range['max']}</a> "; | else echo "<a href=\"#$series\">{$range['min']}-{$range['max']}</a> "; |
} | } |
echo "</div> | echo "</div> |
<script> | <script> |
$('.noscriptnav').hide(); | $('.noscriptnav').hide(); |
</script>"; | </script>"; |
foreach ($routeSeries as $series => $routes) { | foreach ($routeSeries as $series => $routes) { |
echo '<a name="' . $series . '"></a>'; | echo '<a name="' . $series . '"></a>'; |
if ($series <= 9) echo '<li>' . $series . "<ul>\n"; | if ($series <= 9) echo '<li>' . $series . "<ul>\n"; |
else echo "<li>{$seriesRange[$series]['min']}-{$seriesRange[$series]['max']}<ul>\n"; | else echo "<li>{$seriesRange[$series]['min']}-{$seriesRange[$series]['max']}<ul>\n"; |
printRoutes($routes); | foreach ($routes as $row) { |
echo '<li>' . $row[1] . ' <a href="trip.php?routeid=' . $row[0] . '">' . $row[2] . " (" . ucwords($row[3]) . ")</a></li>\n"; | |
} | |
echo "</ul></li>\n"; | echo "</ul></li>\n"; |
} | } |
} | } |
else { | else { |
include_header("Routes by Destination", "routeList"); | |
navbar(); | |
echo ' <ul data-role="listview" data-inset="true">'; | |
$url = $APIurl . "/json/routes"; | |
$contents = json_decode(getPage($url)); | |
// by destination! | |
foreach ($contents as $key => $row) { | foreach ($contents as $key => $row) { |
$routeDestinations[$row[2]][] = $row; | $routeDestinations[$row[2]][] = $row; |
} | } |
echo '<div class="noscriptnav"> Go to Destination: '; | echo '<div class="noscriptnav"> Go to Destination: '; |
foreach (ksort($routeDestinations) as $destination => $routes) { | foreach (ksort($routeDestinations) as $destination => $routes) { |
echo "<a href=\"#$destination\">$destination</a> "; | echo "<a href=\"#$destination\">$destination</a> "; |
} | } |
echo "</div> | echo "</div> |
<script> | <script> |
$('.noscriptnav').hide(); | $('.noscriptnav').hide(); |
</script>"; | </script>"; |
foreach ($routeDestinations as $destination => $routes) { | foreach ($routeDestinations as $destination => $routes) { |
echo '<a name="' . $destination . '"></a>'; | echo '<a name="' . $destination . '"></a>'; |
echo '<li>' . $destination . "... <ul>\n"; | echo '<li>' . $destination . "... <ul>\n"; |
printRoutes($routes); | foreach ($routes as $row) { |
echo '<li>' . $row[1] . ' <a href="trip.php?routeid=' . $row[0] . '">' . $row[2] . " (" . ucwords($row[3]) . ")</a></li>\n"; | |
} | |
echo "</ul></li>\n"; | echo "</ul></li>\n"; |
} | } |
} | } |
echo "</ul>\n"; | echo "</ul>\n"; |
include_footer(); | include_footer(); |
?> | ?> |
#!/usr/bin/python2.5 | #!/usr/bin/python2.5 |
# Copyright (C) 2007 Google Inc. | # Copyright (C) 2007 Google Inc. |
# | # |
# Licensed under the Apache License, Version 2.0 (the "License"); | # Licensed under the Apache License, Version 2.0 (the "License"); |
# you may not use this file except in compliance with the License. | # you may not use this file except in compliance with the License. |
# You may obtain a copy of the License at | # You may obtain a copy of the License at |
# | # |
# http://www.apache.org/licenses/LICENSE-2.0 | # http://www.apache.org/licenses/LICENSE-2.0 |
# | # |
# Unless required by applicable law or agreed to in writing, software | # Unless required by applicable law or agreed to in writing, software |
# distributed under the License is distributed on an "AS IS" BASIS, | # distributed under the License is distributed on an "AS IS" BASIS, |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
# See the License for the specific language governing permissions and | # See the License for the specific language governing permissions and |
# limitations under the License. | # limitations under the License. |
""" | """ |
An example application that uses the transitfeed module. | An example application that uses the transitfeed module. |
You must provide a Google Maps API key. | You must provide a Google Maps API key. |
""" | """ |
import BaseHTTPServer, sys, urlparse | import BaseHTTPServer, sys, urlparse |
import bisect | import bisect |
from gtfsscheduleviewer.marey_graph import MareyGraph | from gtfsscheduleviewer.marey_graph import MareyGraph |
import gtfsscheduleviewer | import gtfsscheduleviewer |
import mimetypes | import mimetypes |
import os.path | import os.path |
import re | import re |
import signal | import signal |
import simplejson | import simplejson |
import socket | import socket |
import time | import time |
import datetime | import datetime |
import transitfeed | import transitfeed |
from transitfeed import util | from transitfeed import util |
import urllib | import urllib |
# By default Windows kills Python with Ctrl+Break. Instead make Ctrl+Break | # By default Windows kills Python with Ctrl+Break. Instead make Ctrl+Break |
# raise a KeyboardInterrupt. | # raise a KeyboardInterrupt. |
if hasattr(signal, 'SIGBREAK'): | if hasattr(signal, 'SIGBREAK'): |
signal.signal(signal.SIGBREAK, signal.default_int_handler) | signal.signal(signal.SIGBREAK, signal.default_int_handler) |
mimetypes.add_type('text/plain', '.vbs') | mimetypes.add_type('text/plain', '.vbs') |
class ResultEncoder(simplejson.JSONEncoder): | class ResultEncoder(simplejson.JSONEncoder): |
def default(self, obj): | def default(self, obj): |
try: | try: |
iterable = iter(obj) | iterable = iter(obj) |
except TypeError: | except TypeError: |
pass | pass |
else: | else: |
return list(iterable) | return list(iterable) |
return simplejson.JSONEncoder.default(self, obj) | return simplejson.JSONEncoder.default(self, obj) |
# Code taken from | # Code taken from |
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/425210/index_txt | # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/425210/index_txt |
# An alternate approach is shown at | # An alternate approach is shown at |
# http://mail.python.org/pipermail/python-list/2003-July/212751.html | # 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 | # but it requires multiple threads. A sqlite object can only be used from one |
# thread. | # thread. |
class StoppableHTTPServer(BaseHTTPServer.HTTPServer): | class StoppableHTTPServer(BaseHTTPServer.HTTPServer): |
def server_bind(self): | def server_bind(self): |
BaseHTTPServer.HTTPServer.server_bind(self) | BaseHTTPServer.HTTPServer.server_bind(self) |
self.socket.settimeout(1) | self.socket.settimeout(1) |
self._run = True | self._run = True |
def get_request(self): | def get_request(self): |
while self._run: | while self._run: |
try: | try: |
sock, addr = self.socket.accept() | sock, addr = self.socket.accept() |
sock.settimeout(None) | sock.settimeout(None) |
return (sock, addr) | return (sock, addr) |
except socket.timeout: | except socket.timeout: |
pass | pass |
def stop(self): | def stop(self): |
self._run = False | self._run = False |
def serve(self): | def serve(self): |
while self._run: | while self._run: |
self.handle_request() | self.handle_request() |
def StopToTuple(stop): | def StopToTuple(stop): |
"""Return tuple as expected by javascript function addStopMarkerFromList""" | """Return tuple as expected by javascript function addStopMarkerFromList""" |
return (stop.stop_id, stop.stop_name, float(stop.stop_lat), | return (stop.stop_id, stop.stop_name, float(stop.stop_lat), |
float(stop.stop_lon), stop.location_type, stop.stop_code) | float(stop.stop_lon), stop.location_type, stop.stop_code) |
def StopZoneToTuple(stop): | def StopZoneToTuple(stop): |
"""Return tuple as expected by javascript function addStopMarkerFromList""" | """Return tuple as expected by javascript function addStopMarkerFromList""" |
return (stop.stop_id, stop.stop_name, float(stop.stop_lat), | return (stop.stop_id, stop.stop_name, float(stop.stop_lat), |
float(stop.stop_lon), stop.location_type, stop.stop_code, stop.zone_id) | float(stop.stop_lon), stop.location_type, stop.stop_code, stop.zone_id) |
class ScheduleRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | class ScheduleRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
cache = {} | cache = {} |
def do_GET(self): | def do_GET(self): |
scheme, host, path, x, params, fragment = urlparse.urlparse(self.path) | scheme, host, path, x, params, fragment = urlparse.urlparse(self.path) |
parsed_params = {} | parsed_params = {} |
for k in params.split('&'): | for k in params.split('&'): |
k = urllib.unquote(k) | k = urllib.unquote(k) |
if '=' in k: | if '=' in k: |
k, v = k.split('=', 1) | k, v = k.split('=', 1) |
parsed_params[k] = unicode(v, 'utf8') | parsed_params[k] = unicode(v, 'utf8') |
else: | else: |
parsed_params[k] = '' | parsed_params[k] = '' |
if path == '/': | if path == '/': |
return self.handle_GET_home() | return self.handle_GET_home() |
m = re.match(r'/json/([a-z]{1,64})', path) | m = re.match(r'/json/([a-z]{1,64})', path) |
if m: | if m: |
handler_name = 'handle_json_GET_%s' % m.group(1) | handler_name = 'handle_json_GET_%s' % m.group(1) |
handler = getattr(self, handler_name, None) | handler = getattr(self, handler_name, None) |
if callable(handler): | if callable(handler): |
return self.handle_json_wrapper_GET(handler, parsed_params, handler_name) | return self.handle_json_wrapper_GET(handler, parsed_params, handler_name) |
# Restrict allowable file names to prevent relative path attacks etc | # Restrict allowable file names to prevent relative path attacks etc |
m = re.match(r'/file/([a-z0-9_-]{1,64}\.?[a-z0-9_-]{1,64})$', path) | m = re.match(r'/file/([a-z0-9_-]{1,64}\.?[a-z0-9_-]{1,64})$', path) |
if m and m.group(1): | if m and m.group(1): |
try: | try: |
f, mime_type = self.OpenFile(m.group(1)) | f, mime_type = self.OpenFile(m.group(1)) |
return self.handle_static_file_GET(f, mime_type) | return self.handle_static_file_GET(f, mime_type) |
except IOError, e: | except IOError, e: |
print "Error: unable to open %s" % m.group(1) | print "Error: unable to open %s" % m.group(1) |
# Ignore and treat as 404 | # Ignore and treat as 404 |
m = re.match(r'/([a-z]{1,64})', path) | m = re.match(r'/([a-z]{1,64})', path) |
if m: | if m: |
handler_name = 'handle_GET_%s' % m.group(1) | handler_name = 'handle_GET_%s' % m.group(1) |
handler = getattr(self, handler_name, None) | handler = getattr(self, handler_name, None) |
if callable(handler): | if callable(handler): |
return handler(parsed_params) | return handler(parsed_params) |
return self.handle_GET_default(parsed_params, path) | return self.handle_GET_default(parsed_params, path) |
def OpenFile(self, filename): | def OpenFile(self, filename): |
"""Try to open filename in the static files directory of this server. | """Try to open filename in the static files directory of this server. |
Return a tuple (file object, string mime_type) or raise an exception.""" | Return a tuple (file object, string mime_type) or raise an exception.""" |
(mime_type, encoding) = mimetypes.guess_type(filename) | (mime_type, encoding) = mimetypes.guess_type(filename) |
assert mime_type | assert mime_type |
# A crude guess of when we should use binary mode. Without it non-unix | # A crude guess of when we should use binary mode. Without it non-unix |
# platforms may corrupt binary files. | # platforms may corrupt binary files. |
if mime_type.startswith('text/'): | if mime_type.startswith('text/'): |
mode = 'r' | mode = 'r' |
else: | else: |
mode = 'rb' | mode = 'rb' |
return open(os.path.join(self.server.file_dir, filename), mode), mime_type | return open(os.path.join(self.server.file_dir, filename), mode), mime_type |
def handle_GET_default(self, parsed_params, path): | def handle_GET_default(self, parsed_params, path): |
self.send_error(404) | self.send_error(404) |
def handle_static_file_GET(self, fh, mime_type): | def handle_static_file_GET(self, fh, mime_type): |
content = fh.read() | content = fh.read() |
self.send_response(200) | self.send_response(200) |
self.send_header('Content-Type', mime_type) | self.send_header('Content-Type', mime_type) |
self.send_header('Content-Length', str(len(content))) | self.send_header('Content-Length', str(len(content))) |
self.end_headers() | self.end_headers() |
self.wfile.write(content) | self.wfile.write(content) |
def AllowEditMode(self): | def AllowEditMode(self): |
return False | return False |
def handle_GET_home(self): | def handle_GET_home(self): |
schedule = self.server.schedule | schedule = self.server.schedule |
(min_lat, min_lon, max_lat, max_lon) = schedule.GetStopBoundingBox() | (min_lat, min_lon, max_lat, max_lon) = schedule.GetStopBoundingBox() |
forbid_editing = ('true', 'false')[self.AllowEditMode()] | forbid_editing = ('true', 'false')[self.AllowEditMode()] |
agency = ', '.join(a.agency_name for a in schedule.GetAgencyList()).encode('utf-8') | agency = ', '.join(a.agency_name for a in schedule.GetAgencyList()).encode('utf-8') |
key = self.server.key | key = self.server.key |
host = self.server.host | host = self.server.host |
# A very simple template system. For a fixed set of values replace [xxx] | # A very simple template system. For a fixed set of values replace [xxx] |
# with the value of local variable xxx | # with the value of local variable xxx |
f, _ = self.OpenFile('index.html') | f, _ = self.OpenFile('index.html') |
content = f.read() | content = f.read() |
for v in ('agency', 'min_lat', 'min_lon', 'max_lat', 'max_lon', 'key', | for v in ('agency', 'min_lat', 'min_lon', 'max_lat', 'max_lon', 'key', |
'host', 'forbid_editing'): | 'host', 'forbid_editing'): |
content = content.replace('[%s]' % v, str(locals()[v])) | content = content.replace('[%s]' % v, str(locals()[v])) |
self.send_response(200) | self.send_response(200) |
self.send_header('Content-Type', 'text/html') | self.send_header('Content-Type', 'text/html') |
self.send_header('Content-Length', str(len(content))) | self.send_header('Content-Length', str(len(content))) |
self.end_headers() | self.end_headers() |
self.wfile.write(content) | self.wfile.write(content) |
def handle_json_GET_routepatterns(self, params): | def handle_json_GET_routepatterns(self, params): |
"""Given a route_id generate a list of patterns of the route. For each | """Given a route_id generate a list of patterns of the route. For each |
pattern include some basic information and a few sample trips.""" | pattern include some basic information and a few sample trips.""" |
schedule = self.server.schedule | schedule = self.server.schedule |
route = schedule.GetRoute(params.get('route', None)) | route = schedule.GetRoute(params.get('route', None)) |
if not route: | if not route: |
self.send_error(404) | self.send_error(404) |
return | return |
time = int(params.get('time', 0)) | time = int(params.get('time', 0)) |
sample_size = 10 # For each pattern return the start time for this many trips | sample_size = 10 # For each pattern return the start time for this many trips |
pattern_id_trip_dict = route.GetPatternIdTripDict() | pattern_id_trip_dict = route.GetPatternIdTripDict() |
patterns = [] | patterns = [] |
for pattern_id, trips in pattern_id_trip_dict.items(): | for pattern_id, trips in pattern_id_trip_dict.items(): |
time_stops = trips[0].GetTimeStops() | time_stops = trips[0].GetTimeStops() |
if not time_stops: | if not time_stops: |
continue | continue |
has_non_zero_trip_type = False; | has_non_zero_trip_type = False; |
for trip in trips: | for trip in trips: |
if trip['trip_type'] and trip['trip_type'] != '0': | if trip['trip_type'] and trip['trip_type'] != '0': |
has_non_zero_trip_type = True | has_non_zero_trip_type = True |
name = u'%s to %s, %d stops' % (time_stops[0][2].stop_name, time_stops[-1][2].stop_name, len(time_stops)) | name = u'%s to %s, %d stops' % (time_stops[0][2].stop_name, time_stops[-1][2].stop_name, len(time_stops)) |
transitfeed.SortListOfTripByTime(trips) | transitfeed.SortListOfTripByTime(trips) |
num_trips = len(trips) | num_trips = len(trips) |
if num_trips <= sample_size: | if num_trips <= sample_size: |
start_sample_index = 0 | start_sample_index = 0 |
num_after_sample = 0 | num_after_sample = 0 |
else: | else: |
# Will return sample_size trips that start after the 'time' param. | # Will return sample_size trips that start after the 'time' param. |
# Linear search because I couldn't find a built-in way to do a binary | # Linear search because I couldn't find a built-in way to do a binary |
# search with a custom key. | # search with a custom key. |
start_sample_index = len(trips) | start_sample_index = len(trips) |
for i, trip in enumerate(trips): | for i, trip in enumerate(trips): |
if trip.GetStartTime() >= time: | if trip.GetStartTime() >= time: |
start_sample_index = i | start_sample_index = i |
break | break |
num_after_sample = num_trips - (start_sample_index + sample_size) | num_after_sample = num_trips - (start_sample_index + sample_size) |
if num_after_sample < 0: | if num_after_sample < 0: |
# Less than sample_size trips start after 'time' so return all the | # Less than sample_size trips start after 'time' so return all the |
# last sample_size trips. | # last sample_size trips. |
num_after_sample = 0 | num_after_sample = 0 |
start_sample_index = num_trips - sample_size | start_sample_index = num_trips - sample_size |
sample = [] | sample = [] |
for t in trips[start_sample_index:start_sample_index + sample_size]: | for t in trips[start_sample_index:start_sample_index + sample_size]: |
sample.append( (t.GetStartTime(), t.trip_id) ) | sample.append( (t.GetStartTime(), t.trip_id) ) |
patterns.append((name, pattern_id, start_sample_index, sample, | patterns.append((name, pattern_id, start_sample_index, sample, |
num_after_sample, (0,1)[has_non_zero_trip_type])) | num_after_sample, (0,1)[has_non_zero_trip_type])) |
patterns.sort() | patterns.sort() |
return patterns | return patterns |
def handle_json_wrapper_GET(self, handler, parsed_params, handler_name): | def handle_json_wrapper_GET(self, handler, parsed_params, handler_name): |
"""Call handler and output the return value in JSON.""" | """Call handler and output the return value in JSON.""" |
schedule = self.server.schedule | schedule = self.server.schedule |
# round times to nearest 100 seconds | # round times to nearest 100 seconds |
if "time" in parsed_params: | if "time" in parsed_params: |
parsed_params['time'] = int(round(float(parsed_params['time']),-2)) | parsed_params['time'] = int(round(float(parsed_params['time']),-2)) |
paramkey = tuple(sorted(parsed_params.items())) | paramkey = tuple(sorted(parsed_params.items())) |
if handler_name in self.cache and paramkey in self.cache[handler_name] : | if handler_name in self.cache and paramkey in self.cache[handler_name] : |
print ("Cache hit for ",handler_name," params ",parsed_params) | print ("Cache hit for ",handler_name," params ",parsed_params) |
else: | else: |
print ("Cache miss for ",handler_name," params ",parsed_params) | print ("Cache miss for ",handler_name," params ",parsed_params) |
result = handler(parsed_params) | result = handler(parsed_params) |
if not handler_name in self.cache: | if not handler_name in self.cache: |
self.cache[handler_name] = {} | self.cache[handler_name] = {} |
self.cache[handler_name][paramkey] = ResultEncoder().encode(result) | self.cache[handler_name][paramkey] = ResultEncoder().encode(result) |
content = self.cache[handler_name][paramkey] | content = self.cache[handler_name][paramkey] |
self.send_response(200) | self.send_response(200) |
self.send_header('Content-Type', 'text/plain') | self.send_header('Content-Type', 'text/plain') |
self.send_header('Content-Length', str(len(content))) | self.send_header('Content-Length', str(len(content))) |
self.end_headers() | self.end_headers() |
self.wfile.write(content) | self.wfile.write(content) |
def handle_json_GET_routes(self, params): | def handle_json_GET_routes(self, params): |
"""Return a list of all routes.""" | """Return a list of all routes.""" |
schedule = self.server.schedule | schedule = self.server.schedule |
result = [] | result = [] |
for r in schedule.GetRouteList(): | for r in schedule.GetRouteList(): |
servicep = None | servicep = None |
for t in schedule.GetTripList(): | for t in schedule.GetTripList(): |
if t.route_id == r.route_id: | if t.route_id == r.route_id: |
servicep = t.service_period | servicep = t.service_period |
break | break |
result.append( (r.route_id, r.route_short_name, r.route_long_name, servicep.service_id) ) | result.append( (r.route_id, r.route_short_name, r.route_long_name, servicep.service_id) ) |
result.sort(key = lambda x: x[1:3]) | result.sort(key = lambda x: x[1:3]) |
return result | return result |
def handle_json_GET_routesearch(self, params): | |
"""Return a list of routes with matching short name.""" | |
schedule = self.server.schedule | |
routeshortname = params.get('routeshortname', None) | |
result = [] | |
for r in schedule.GetRouteList(): | |
if r.route_short_name == routeshortname: | |
servicep = None | |
for t in schedule.GetTripList(): | |
if t.route_id == r.route_id: | |
servicep = t.service_period | |
break | |
result.append( (r.route_id, r.route_short_name, r.route_long_name, servicep.service_id) ) | |
result.sort(key = lambda x: x[1:3]) | |
return result | |
def handle_json_GET_routerow(self, params): | def handle_json_GET_routerow(self, params): |
schedule = self.server.schedule | schedule = self.server.schedule |
route = schedule.GetRoute(params.get('route', None)) | route = schedule.GetRoute(params.get('route', None)) |
return [transitfeed.Route._FIELD_NAMES, route.GetFieldValuesTuple()] | return [transitfeed.Route._FIELD_NAMES, route.GetFieldValuesTuple()] |
def handle_json_GET_routetrips(self, params): | def handle_json_GET_routetrips(self, params): |
""" Get a trip for a route_id (preferablly the next one) """ | """ Get a trip for a route_id (preferablly the next one) """ |
schedule = self.server.schedule | schedule = self.server.schedule |
query = params.get('route_id', None).lower() | query = params.get('route_id', None).lower() |
result = [] | result = [] |
for t in schedule.GetTripList(): | for t in schedule.GetTripList(): |
if t.route_id == query: | if t.route_id == query: |
try: | try: |
starttime = t.GetStartTime() | starttime = t.GetStartTime() |
except: | except: |
print "Error for GetStartTime of trip #" + t.trip_id + sys.exc_info()[0] | print "Error for GetStartTime of trip #" + t.trip_id + sys.exc_info()[0] |
else: | else: |
result.append ( (starttime, t.trip_id) ) | result.append ( (starttime, t.trip_id) ) |
return sorted(result, key=lambda trip: trip[0]) | return sorted(result, key=lambda trip: trip[0]) |
def handle_json_GET_triprows(self, params): | def handle_json_GET_triprows(self, params): |
"""Return a list of rows from the feed file that are related to this | """Return a list of rows from the feed file that are related to this |
trip.""" | trip.""" |
schedule = self.server.schedule | schedule = self.server.schedule |
try: | try: |
trip = schedule.GetTrip(params.get('trip', None)) | trip = schedule.GetTrip(params.get('trip', None)) |
except KeyError: | except KeyError: |
# if a non-existent trip is searched for, the return nothing | # if a non-existent trip is searched for, the return nothing |
return | return |
route = schedule.GetRoute(trip.route_id) | route = schedule.GetRoute(trip.route_id) |
trip_row = dict(trip.iteritems()) | trip_row = dict(trip.iteritems()) |
route_row = dict(route.iteritems()) | route_row = dict(route.iteritems()) |
return [['trips.txt', trip_row], ['routes.txt', route_row]] | return [['trips.txt', trip_row], ['routes.txt', route_row]] |
def handle_json_GET_tripstoptimes(self, params): | def handle_json_GET_tripstoptimes(self, params): |
schedule = self.server.schedule | schedule = self.server.schedule |
try: | try: |
trip = schedule.GetTrip(params.get('trip')) | trip = schedule.GetTrip(params.get('trip')) |
except KeyError: | except KeyError: |
# if a non-existent trip is searched for, the return nothing | # if a non-existent trip is searched for, the return nothing |
return | return |
time_stops = trip.GetTimeInterpolatedStops() | time_stops = trip.GetTimeInterpolatedStops() |
stops = [] | stops = [] |
times = [] | times = [] |
for arr,ts,is_timingpoint in time_stops: | for arr,ts,is_timingpoint in time_stops: |
stops.append(StopToTuple(ts.stop)) | stops.append(StopToTuple(ts.stop)) |
times.append(arr) | times.append(arr) |
return [stops, times] | return [stops, times] |
def handle_json_GET_tripshape(self, params): | def handle_json_GET_tripshape(self, params): |
schedule = self.server.schedule | schedule = self.server.schedule |
try: | try: |
trip = schedule.GetTrip(params.get('trip')) | trip = schedule.GetTrip(params.get('trip')) |
except KeyError: | except KeyError: |
# if a non-existent trip is searched for, the return nothing | # if a non-existent trip is searched for, the return nothing |
return | return |
points = [] | points = [] |
if trip.shape_id: | if trip.shape_id: |
shape = schedule.GetShape(trip.shape_id) | shape = schedule.GetShape(trip.shape_id) |
for (lat, lon, dist) in shape.points: | for (lat, lon, dist) in shape.points: |
points.append((lat, lon)) | points.append((lat, lon)) |
else: | else: |
time_stops = trip.GetTimeStops() | time_stops = trip.GetTimeStops() |
for arr,dep,stop in time_stops: | for arr,dep,stop in time_stops: |
points.append((stop.stop_lat, stop.stop_lon)) | points.append((stop.stop_lat, stop.stop_lon)) |
return points | return points |
# | |
# GeoPo Encode in Python | |
# @author : Shintaro Inagaki | |
# @param location (Dictionary) [lat (Float), lng (Float), scale(Int)] | |
# @return geopo (String) | |
# | |
def handle_json_GET_neareststops(self, params): | def handle_json_GET_neareststops(self, params): |
"""Return a list of the nearest 'limit' stops to 'lat', 'lon'""" | """Return a list of the nearest 'limit' stops to 'lat', 'lon'""" |
schedule = self.server.schedule | schedule = self.server.schedule |
lat = float(params.get('lat')) | lat = float(params.get('lat')) |
lon = float(params.get('lon')) | lon = float(params.get('lon')) |
limit = int(params.get('limit')) | limit = int(params.get('limit',5)) |
stops = schedule.GetNearestStops(lat=lat, lon=lon, n=limit) | scale = int(params.get('scale',5)) # 5 = neighbourhood ~ 1km, 4= town 5 by 7km |
return [StopToTuple(s) for s in stops] | stops = [] |
# 64characters (number + big and small letter + hyphen + underscore) | |
chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_" | |
geopo = "" | |
# Change a degree measure to a decimal number | |
lat = (lat + 90.0) / 180 * 8 ** 10 # 90.0 is forced FLOAT type when lat is INT | |
lon = (lon + 180.0) / 360 * 8 ** 10 # 180.0 is same | |
# Compute a GeoPo code from head and concatenate | |
for i in range(scale): | |
order = int(lat / (8 ** (9 - i)) % 8) + int(lon / (8 ** (9 - i)) % 8) * 8 | |
geopo = geopo + chars[order] | |
for s in schedule.GetStopList(): | |
if s.stop_code.find(geopo) != -1: | |
stops.append(s) | |
if scale == 5: | |
print stops | |
return [StopToTuple(s) for s in stops] | |
else: | |
dist_stop_list = [] | |
for s in stops: | |
# TODO: Use util.ApproximateDistanceBetweenStops? | |
dist = (s.stop_lat - lat)**2 + (s.stop_lon - lon)**2 | |
if len(dist_stop_list) < limit: | |
bisect.insort(dist_stop_list, (dist, s)) | |
elif dist < dist_stop_list[-1][0]: | |
bisect.insort(dist_stop_list, (dist, s)) | |
dist_stop_list.pop() # Remove stop with greatest distance | |
print dist_stop_list | |
return [StopToTuple(s) for dist, s in dist_stop_list] | |
def handle_json_GET_boundboxstops(self, params): | def handle_json_GET_boundboxstops(self, params): |
"""Return a list of up to 'limit' stops within bounding box with 'n','e' | """Return a list of up to 'limit' stops within bounding box with 'n','e' |
and 's','w' in the NE and SW corners. Does not handle boxes crossing | and 's','w' in the NE and SW corners. Does not handle boxes crossing |
longitude line 180.""" | longitude line 180.""" |
schedule = self.server.schedule | schedule = self.server.schedule |
n = float(params.get('n')) | n = float(params.get('n')) |
e = float(params.get('e')) | e = float(params.get('e')) |
s = float(params.get('s')) | s = float(params.get('s')) |
w = float(params.get('w')) | w = float(params.get('w')) |
limit = int(params.get('limit')) | limit = int(params.get('limit')) |
stops = schedule.GetStopsInBoundingBox(north=n, east=e, south=s, west=w, n=limit) | stops = schedule.GetStopsInBoundingBox(north=n, east=e, south=s, west=w, n=limit) |
return [StopToTuple(s) for s in stops] | return [StopToTuple(s) for s in stops] |
def handle_json_GET_stops(self, params): | def handle_json_GET_stops(self, params): |
schedule = self.server.schedule | schedule = self.server.schedule |
return [StopToTuple(s) for s in schedule.GetStopList()] | return [StopToTuple(s) for s in schedule.GetStopList()] |
def handle_json_GET_timingpoints(self, params): | def handle_json_GET_timingpoints(self, params): |
schedule = self.server.schedule | schedule = self.server.schedule |
matches = [] | matches = [] |
for s in schedule.GetStopList(): | for s in schedule.GetStopList(): |
if s.stop_code.find("Wj") == -1: | if s.stop_code.find("Wj") == -1: |
matches.append(StopToTuple(s)) | matches.append(StopToTuple(s)) |
return matches | return matches |
def handle_json_GET_stopsearch(self, params): | def handle_json_GET_stopsearch(self, params): |
schedule = self.server.schedule | schedule = self.server.schedule |
query = params.get('q', None).lower() | query = params.get('q', None).lower() |
matches = [] | matches = [] |
for s in schedule.GetStopList(): | for s in schedule.GetStopList(): |
if s.stop_name.lower().find(query) != -1 or s.stop_code.lower().find(query) != -1: | if s.stop_name.lower().find(query) != -1 or s.stop_code.lower().find(query) != -1: |
matches.append(StopToTuple(s)) | matches.append(StopToTuple(s)) |
return matches | return matches |
def handle_json_GET_stopnamesearch(self, params): | def handle_json_GET_stopnamesearch(self, params): |
schedule = self.server.schedule | schedule = self.server.schedule |
query = params.get('q', None).lower() | query = params.get('q', None).lower() |
matches = [] | matches = [] |
for s in schedule.GetStopList(): | for s in schedule.GetStopList(): |
if s.stop_name.lower().find(query) != -1: | if s.stop_name.lower().find(query) != -1: |
matches.append(StopToTuple(s)) | matches.append(StopToTuple(s)) |
return matches | return matches |
def handle_json_GET_stopcodesearch(self, params): | def handle_json_GET_stopcodesearch(self, params): |
schedule = self.server.schedule | schedule = self.server.schedule |
query = params.get('q', None).lower() | query = params.get('q', None).lower() |
matches = [] | matches = [] |
for s in schedule.GetStopList(): | for s in schedule.GetStopList(): |
if s.stop_code.lower().find(query) != -1: | if s.stop_code.lower().find(query) != -1: |
matches.append(StopToTuple(s)) | matches.append(StopToTuple(s)) |
return matches | return matches |
def handle_json_GET_stopzonesearch(self, params): | def handle_json_GET_stopzonesearch(self, params): |
schedule = self.server.schedule | schedule = self.server.schedule |
query = params.get('q', None).lower() | query = params.get('q', None).lower() |
matches = [] | matches = [] |
for s in schedule.GetStopList(): | for s in schedule.GetStopList(): |
if s.zone_id != None and s.zone_id.lower().find(query) != -1: | if s.zone_id != None and s.zone_id.lower().find(query) != -1: |
matches.append(StopToTuple(s)) | matches.append(StopToTuple(s)) |
return matches | return matches |
def handle_json_GET_stop(self, params): | def handle_json_GET_stop(self, params): |
schedule = self.server.schedule | schedule = self.server.schedule |
query = params.get('stop_id', None).lower() | query = params.get('stop_id', None).lower() |
for s in schedule.GetStopList(): | for s in schedule.GetStopList(): |
if s.stop_id.lower() == query: | if s.stop_id.lower() == query: |
return StopToTuple(s) | return StopToTuple(s) |
return [] | return [] |
def handle_json_GET_stoproutes(self, params): | def handle_json_GET_stoproutes(self, params): |
"""Given a stop_id return all routes to visit the stop.""" | """Given a stop_id return all routes to visit the stop.""" |
schedule = self.server.schedule | schedule = self.server.schedule |
stop = schedule.GetStop(params.get('stop', None)) | stop = schedule.GetStop(params.get('stop', None)) |
service_period = params.get('service_period', None) | service_period = params.get('service_period', None) |
trips = stop.GetTrips(schedule) | trips = stop.GetTrips(schedule) |
result = {} | result = {} |
for trip in trips: | for trip in trips: |
route = schedule.GetRoute(trip.route_id) | route = schedule.GetRoute(trip.route_id) |
if not trip.route_short_name+route.route_long_name in result: | if not route.route_short_name+route.route_long_name+trip.service_id in result: |
result[trip.route_short_name+route.route_long_name] = (route.route_id, route.route_short_name, route.route_long_name, trip.trip_id) | 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 | return result |
def handle_json_GET_stopalltrips(self, params): | 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.""" |
schedule = self.server.schedule | schedule = self.server.schedule |
stop = schedule.GetStop(params.get('stop', None)) | stop = schedule.GetStop(params.get('stop', None)) |
service_period = params.get('service_period', None) | service_period = params.get('service_period', None) |
time_trips = stop.GetStopTimeTrips(schedule) | time_trips = stop.GetStopTimeTrips(schedule) |
result = [] | result = [] |
for time, (trip, index), tp in time_trips: | for time, (trip, index), tp in time_trips: |
headsign = None | headsign = None |
# Find the most recent headsign from the StopTime objects | # Find the most recent headsign from the StopTime objects |
for stoptime in trip.GetStopTimes()[index::-1]: | for stoptime in trip.GetStopTimes()[index::-1]: |
if stoptime.stop_headsign: | if stoptime.stop_headsign: |
headsign = stoptime.stop_headsign | headsign = stoptime.stop_headsign |
break | break |
# If stop_headsign isn't found, look for a trip_headsign | # If stop_headsign isn't found, look for a trip_headsign |
if not headsign: | if not headsign: |
headsign = trip.trip_headsign | headsign = trip.trip_headsign |
route = schedule.GetRoute(trip.route_id) | route = schedule.GetRoute(trip.route_id) |
trip_name = '' | trip_name = '' |
if route.route_short_name: | if route.route_short_name: |
trip_name += route.route_short_name | trip_name += route.route_short_name |
if route.route_long_name: | if route.route_long_name: |
if len(trip_name): | if len(trip_name): |
trip_name += " - " | trip_name += " - " |
trip_name += route.route_long_name | trip_name += route.route_long_name |
if service_period == None or trip.service_id == service_period: | if service_period == None or trip.service_id == service_period: |
result.append((time, (trip.trip_id, trip_name, trip.service_id), tp)) | result.append((time, (trip.trip_id, trip_name, trip.service_id), tp)) |
return result | return result |
def handle_json_GET_stoptrips(self, params): | def handle_json_GET_stoptrips(self, params): |
"""Given a stop_id and time in seconds since midnight return the next | """Given a stop_id and time in seconds since midnight return the next |
trips to visit the stop.""" | trips to visit the stop.""" |
schedule = self.server.schedule | schedule = self.server.schedule |
stop = schedule.GetStop(params.get('stop', None)) | stop = schedule.GetStop(params.get('stop', None)) |
requested_time = int(params.get('time', 0)) | requested_time = int(params.get('time', 0)) |
limit = int(params.get('limit', 15)) | limit = int(params.get('limit', 15)) |
service_period = params.get('service_period', None) | service_period = params.get('service_period', None) |
time_range = params.get('time_range', 24*60*60) | time_range = int(params.get('time_range', 24*60*60)) |
filtered_time_trips = [] | filtered_time_trips = [] |
for trip, index in stop._GetTripIndex(schedule): | for trip, index in stop._GetTripIndex(schedule): |
tripstarttime = trip.GetStartTime() | tripstarttime = trip.GetStartTime() |
if tripstarttime > requested_time and tripstarttime < (requested_time + time_range): | if tripstarttime > requested_time and tripstarttime < (requested_time + time_range): |
time, stoptime, tp = trip.GetTimeInterpolatedStops()[index] | time, stoptime, tp = trip.GetTimeInterpolatedStops()[index] |
if time > requested_time and time < (requested_time + time_range): | if time > requested_time and time < (requested_time + time_range): |
bisect.insort(filtered_time_trips, (time, (trip, index), tp)) | bisect.insort(filtered_time_trips, (time, (trip, index), tp)) |
result = [] | result = [] |
for time, (trip, index), tp in filtered_time_trips: | for time, (trip, index), tp in filtered_time_trips: |
if len(result) > limit: | if len(result) > limit: |
break | break |
headsign = None | headsign = None |
# Find the most recent headsign from the StopTime objects | # Find the most recent headsign from the StopTime objects |
for stoptime in trip.GetStopTimes()[index::-1]: | for stoptime in trip.GetStopTimes()[index::-1]: |
if stoptime.stop_headsign: | if stoptime.stop_headsign: |
headsign = stoptime.stop_headsign | headsign = stoptime.stop_headsign |
break | break |
# If stop_headsign isn't found, look for a trip_headsign | # If stop_headsign isn't found, look for a trip_headsign |
if not headsign: | if not headsign: |
headsign = trip.trip_headsign | headsign = trip.trip_headsign |
route = schedule.GetRoute(trip.route_id) | route = schedule.GetRoute(trip.route_id) |
trip_name = '' | trip_name = '' |
if route.route_short_name: | if route.route_short_name: |
trip_name += route.route_short_name | trip_name += route.route_short_name |
if route.route_long_name: | if route.route_long_name: |
if len(trip_name): | if len(trip_name): |
trip_name += " - " | trip_name += " - " |
trip_name += route.route_long_name | trip_name += route.route_long_name |
# comment out directions because we already have them in the long name | # comment out directions because we already have them in the long name |
#if headsign: | #if headsign: |
# trip_name += " (Direction: %s)" % headsign | # trip_name += " (Direction: %s)" % headsign |
if service_period == None or trip.service_id == service_period: | if service_period == None or trip.service_id == service_period: |
result.append((time, (trip.trip_id, trip_name, trip.service_id), tp)) | result.append((time, (trip.trip_id, trip_name, trip.service_id), tp)) |
return result | return result |
def handle_GET_ttablegraph(self,params): | def handle_GET_ttablegraph(self,params): |
"""Draw a Marey graph in SVG for a pattern (collection of trips in a route | """Draw a Marey graph in SVG for a pattern (collection of trips in a route |
that visit the same sequence of stops).""" | that visit the same sequence of stops).""" |
schedule = self.server.schedule | schedule = self.server.schedule |
marey = MareyGraph() | marey = MareyGraph() |
trip = schedule.GetTrip(params.get('trip', None)) | trip = schedule.GetTrip(params.get('trip', None)) |
route = schedule.GetRoute(trip.route_id) | route = schedule.GetRoute(trip.route_id) |
height = int(params.get('height', 300)) | height = int(params.get('height', 300)) |
if not route: | if not route: |
print 'no such route' | print 'no such route' |
self.send_error(404) | self.send_error(404) |
return | return |
pattern_id_trip_dict = route.GetPatternIdTripDict() | pattern_id_trip_dict = route.GetPatternIdTripDict() |
pattern_id = trip.pattern_id | pattern_id = trip.pattern_id |
if pattern_id not in pattern_id_trip_dict: | if pattern_id not in pattern_id_trip_dict: |
print 'no pattern %s found in %s' % (pattern_id, pattern_id_trip_dict.keys()) | print 'no pattern %s found in %s' % (pattern_id, pattern_id_trip_dict.keys()) |
self.send_error(404) | self.send_error(404) |
return | return |
triplist = pattern_id_trip_dict[pattern_id] | triplist = pattern_id_trip_dict[pattern_id] |
pattern_start_time = min((t.GetStartTime() for t in triplist)) | pattern_start_time = min((t.GetStartTime() for t in triplist)) |
pattern_end_time = max((t.GetEndTime() for t in triplist)) | pattern_end_time = max((t.GetEndTime() for t in triplist)) |
marey.SetSpan(pattern_start_time,pattern_end_time) | marey.SetSpan(pattern_start_time,pattern_end_time) |
marey.Draw(triplist[0].GetPattern(), triplist, height) | marey.Draw(triplist[0].GetPattern(), triplist, height) |
content = marey.Draw() | content = marey.Draw() |
self.send_response(200) | self.send_response(200) |
self.send_header('Content-Type', 'image/svg+xml') | self.send_header('Content-Type', 'image/svg+xml') |
self.send_header('Content-Length', str(len(content))) | self.send_header('Content-Length', str(len(content))) |
self.end_headers() | self.end_headers() |
self.wfile.write(content) | self.wfile.write(content) |
def FindPy2ExeBase(): | def FindPy2ExeBase(): |
"""If this is running in py2exe return the install directory else return | """If this is running in py2exe return the install directory else return |
None""" | None""" |
# py2exe puts gtfsscheduleviewer in library.zip. For py2exe setup.py is | # py2exe puts gtfsscheduleviewer in library.zip. For py2exe setup.py is |
# configured to put the data next to library.zip. | # configured to put the data next to library.zip. |
windows_ending = gtfsscheduleviewer.__file__.find('\\library.zip\\') | windows_ending = gtfsscheduleviewer.__file__.find('\\library.zip\\') |
if windows_ending != -1: | if windows_ending != -1: |
return transitfeed.__file__[:windows_ending] | return transitfeed.__file__[:windows_ending] |
else: | else: |
return None | return None |
def FindDefaultFileDir(): | def FindDefaultFileDir(): |
"""Return the path of the directory containing the static files. By default | """Return the path of the directory containing the static files. By default |
the directory is called 'files'. The location depends on where setup.py put | the directory is called 'files'. The location depends on where setup.py put |
it.""" | it.""" |
base = FindPy2ExeBase() | base = FindPy2ExeBase() |
if base: | if base: |
return os.path.join(base, 'schedule_viewer_files') | return os.path.join(base, 'schedule_viewer_files') |
else: | else: |
# For all other distributions 'files' is in the gtfsscheduleviewer | # For all other distributions 'files' is in the gtfsscheduleviewer |
# directory. | # directory. |
base = os.path.dirname(gtfsscheduleviewer.__file__) # Strip __init__.py | base = os.path.dirname(gtfsscheduleviewer.__file__) # Strip __init__.py |
return os.path.join(base, 'files') | return os.path.join(base, 'files') |
def GetDefaultKeyFilePath(): | def GetDefaultKeyFilePath(): |
"""In py2exe return absolute path of file in the base directory and in all | """In py2exe return absolute path of file in the base directory and in all |
other distributions return relative path 'key.txt'""" | other distributions return relative path 'key.txt'""" |
windows_base = FindPy2ExeBase() | windows_base = FindPy2ExeBase() |
if windows_base: | if windows_base: |
return os.path.join(windows_base, 'key.txt') | return os.path.join(windows_base, 'key.txt') |
else: | else: |
return 'key.txt' | return 'key.txt' |
def main(RequestHandlerClass = ScheduleRequestHandler): | def main(RequestHandlerClass = ScheduleRequestHandler): |
usage = \ | usage = \ |
'''%prog [options] [<input GTFS.zip>] | '''%prog [options] [<input GTFS.zip>] |
Runs a webserver that lets you explore a <input GTFS.zip> in your browser. | Runs a webserver that lets you explore a <input GTFS.zip> in your browser. |
If <input GTFS.zip> is omited the filename is read from the console. Dragging | If <input GTFS.zip> is omited the filename is read from the console. Dragging |
a file into the console may enter the filename. | a file into the console may enter the filename. |
''' | ''' |
parser = util.OptionParserLongError( | parser = util.OptionParserLongError( |
usage=usage, version='%prog '+transitfeed.__version__) | usage=usage, version='%prog '+transitfeed.__version__) |
parser.add_option('--feed_filename', '--feed', dest='feed_filename', | parser.add_option('--feed_filename', '--feed', dest='feed_filename', |
help='file name of feed to load') | help='file name of feed to load') |
parser.add_option('--key', dest='key', | parser.add_option('--key', dest='key', |
help='Google Maps API key or the name ' | help='Google Maps API key or the name ' |
'of a text file that contains an API key') | 'of a text file that contains an API key') |
parser.add_option('--host', dest='host', help='Host name of Google Maps') | parser.add_option('--host', dest='host', help='Host name of Google Maps') |
parser.add_option('--port', dest='port', type='int', | parser.add_option('--port', dest='port', type='int', |
help='port on which to listen') | help='port on which to listen') |
parser.add_option('--file_dir', dest='file_dir', | parser.add_option('--file_dir', dest='file_dir', |
help='directory containing static files') | help='directory containing static files') |
parser.add_option('-n', '--noprompt', action='store_false', | parser.add_option('-n', '--noprompt', action='store_false', |
dest='manual_entry', | dest='manual_entry', |
help='disable interactive prompts') | help='disable interactive prompts') |
parser.set_defaults(port=8765, | parser.set_defaults(port=8765, |
host='maps.google.com', | host='maps.google.com', |
file_dir=FindDefaultFileDir(), | file_dir=FindDefaultFileDir(), |
manual_entry=True) | manual_entry=True) |
(options, args) = parser.parse_args() | (options, args) = parser.parse_args() |
if not os.path.isfile(os.path.join(options.file_dir, 'index.html')): | if not os.path.isfile(os.path.join(options.file_dir, 'index.html')): |
print "Can't find index.html with --file_dir=%s" % options.file_dir | print "Can't find index.html with --file_dir=%s" % options.file_dir |
exit(1) | exit(1) |
if not options.feed_filename and len(args) == 1: | if not options.feed_filename and len(args) == 1: |
options.feed_filename = args[0] | options.feed_filename = args[0] |
if not options.feed_filename and options.manual_entry: | if not options.feed_filename and options.manual_entry: |
options.feed_filename = raw_input('Enter Feed Location: ').strip('"') | options.feed_filename = raw_input('Enter Feed Location: ').strip('"') |
default_key_file = GetDefaultKeyFilePath() | default_key_file = GetDefaultKeyFilePath() |
if not options.key and os.path.isfile(default_key_file): | if not options.key and os.path.isfile(default_key_file): |
options.key = open(default_key_file).read().strip() | options.key = open(default_key_file).read().strip() |
if options.key and os.path.isfile(options.key): | if options.key and os.path.isfile(options.key): |
options.key = open(options.key).read().strip() | options.key = open(options.key).read().strip() |
schedule = transitfeed.Schedule(problem_reporter=transitfeed.ProblemReporter()) | schedule = transitfeed.Schedule(problem_reporter=transitfeed.ProblemReporter()) |
print 'Loading data from feed "%s"...' % options.feed_filename | print 'Loading data from feed "%s"...' % options.feed_filename |
print '(this may take a few minutes for larger cities)' | print '(this may take a few minutes for larger cities)' |
t0 = datetime.datetime.now() | t0 = datetime.datetime.now() |
schedule.Load(options.feed_filename) | schedule.Load(options.feed_filename) |
print ("Loaded in", (datetime.datetime.now() - t0).seconds , "seconds") | print ("Loaded in", (datetime.datetime.now() - t0).seconds , "seconds") |
server = StoppableHTTPServer(server_address=('', options.port), | server = StoppableHTTPServer(server_address=('', options.port), |
RequestHandlerClass=RequestHandlerClass) | RequestHandlerClass=RequestHandlerClass) |
server.key = options.key | server.key = options.key |
server.schedule = schedule | server.schedule = schedule |
server.file_dir = options.file_dir | server.file_dir = options.file_dir |
server.host = options.host | 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/" % | print ("To view, point your browser at http://localhost:%d/" % |
(server.server_port)) | (server.server_port)) |
server.serve_forever() | server.serve_forever() |
if __name__ == '__main__': | if __name__ == '__main__': |
main() | main() |
<?php | |
/******************************************************************************* | |
Version: 1.11 ($Rev: 175 $) | |
Website: http://sourceforge.net/projects/simplehtmldom/ | |
Author: S.C. Chen <me578022@gmail.com> | |
Acknowledge: Jose Solorzano (https://sourceforge.net/projects/php-html/) | |
Contributions by: | |
Yousuke Kumakura (Attribute filters) | |
Vadim Voituk (Negative indexes supports of "find" method) | |
Antcs (Constructor with automatically load contents either text or file/url) | |
Licensed under The MIT License | |
Redistributions of files must retain the above copyright notice. | |
*******************************************************************************/ | |
define('HDOM_TYPE_ELEMENT', 1); | |
define('HDOM_TYPE_COMMENT', 2); | |
define('HDOM_TYPE_TEXT', 3); | |
define('HDOM_TYPE_ENDTAG', 4); | |
define('HDOM_TYPE_ROOT', 5); | |
define('HDOM_TYPE_UNKNOWN', 6); | |
define('HDOM_QUOTE_DOUBLE', 0); | |
define('HDOM_QUOTE_SINGLE', 1); | |
define('HDOM_QUOTE_NO', 3); | |
define('HDOM_INFO_BEGIN', 0); | |
define('HDOM_INFO_END', 1); | |
define('HDOM_INFO_QUOTE', 2); | |
define('HDOM_INFO_SPACE', 3); | |
define('HDOM_INFO_TEXT', 4); | |
define('HDOM_INFO_INNER', 5); | |
define('HDOM_INFO_OUTER', 6); | |
define('HDOM_INFO_ENDSPACE',7); | |
// helper functions | |
// ----------------------------------------------------------------------------- | |
// get html dom form file | |
function file_get_html() { | |
$dom = new simple_html_dom; | |
$args = func_get_args(); | |
$dom->load(call_user_func_array('file_get_contents', $args), true); | |
return $dom; | |
} | |
// get html dom form string | |
function str_get_html($str, $lowercase=true) { | |
$dom = new simple_html_dom; | |
$dom->load($str, $lowercase); | |
return $dom; | |
} | |
// dump html dom tree | |
function dump_html_tree($node, $show_attr=true, $deep=0) { | |
$lead = str_repeat(' ', $deep); | |
echo $lead.$node->tag; | |
if ($show_attr && count($node->attr)>0) { | |
echo '('; | |
foreach($node->attr as $k=>$v) | |
echo "[$k]=>\"".$node->$k.'", '; | |
echo ')'; | |
} | |
echo "\n"; | |
foreach($node->nodes as $c) | |
dump_html_tree($c, $show_attr, $deep+1); | |
} | |
// get dom form file (deprecated) | |
function file_get_dom() { | |
$dom = new simple_html_dom; | |
$args = func_get_args(); | |
$dom->load(call_user_func_array('file_get_contents', $args), true); | |
return $dom; | |
} | |
// get dom form string (deprecated) | |
function str_get_dom($str, $lowercase=true) { | |
$dom = new simple_html_dom; | |
$dom->load($str, $lowercase); | |
return $dom; | |
} | |
// simple html dom node | |
// ----------------------------------------------------------------------------- | |
class simple_html_dom_node { | |
public $nodetype = HDOM_TYPE_TEXT; | |
public $tag = 'text'; | |
public $attr = array(); | |
public $children = array(); | |
public $nodes = array(); | |
public $parent = null; | |
public $_ = array(); | |
private $dom = null; | |
function __construct($dom) { | |
$this->dom = $dom; | |
$dom->nodes[] = $this; | |
} | |
function __destruct() { | |
$this->clear(); | |
} | |
function __toString() { | |
return $this->outertext(); | |
} | |
// clean up memory due to php5 circular references memory leak... | |
function clear() { | |
$this->dom = null; | |
$this->nodes = null; | |
$this->parent = null; | |
$this->children = null; | |
} | |
// dump node's tree | |
function dump($show_attr=true) { | |
dump_html_tree($this, $show_attr); | |
} | |
// returns the parent of node | |
function parent() { | |
return $this->parent; | |
} | |
// returns children of node | |
function children($idx=-1) { | |
if ($idx===-1) return $this->children; | |
if (isset($this->children[$idx])) return $this->children[$idx]; | |
return null; | |
} | |
// returns the first child of node | |
function first_child() { | |
if (count($this->children)>0) return $this->children[0]; | |
return null; | |
} | |
// returns the last child of node | |
function last_child() { | |
if (($count=count($this->children))>0) return $this->children[$count-1]; | |
return null; | |
} | |
// returns the next sibling of node | |
function next_sibling() { | |
if ($this->parent===null) return null; | |
$idx = 0; | |
$count = count($this->parent->children); | |
while ($idx<$count && $this!==$this->parent->children[$idx]) | |
++$idx; | |
if (++$idx>=$count) return null; | |
return $this->parent->children[$idx]; | |
} | |
// returns the previous sibling of node | |
function prev_sibling() { | |
if ($this->parent===null) return null; | |
$idx = 0; | |
$count = count($this->parent->children); | |
while ($idx<$count && $this!==$this->parent->children[$idx]) | |
++$idx; | |
if (--$idx<0) return null; | |
return $this->parent->children[$idx]; | |
} | |
// get dom node's inner html | |
function innertext() { | |
if (isset($this->_[HDOM_INFO_INNER])) return $this->_[HDOM_INFO_INNER]; | |
if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | |
$ret = ''; | |
foreach($this->nodes as $n) | |
$ret .= $n->outertext(); | |
return $ret; | |
} | |
// get dom node's outer text (with tag) | |
function outertext() { | |
if ($this->tag==='root') return $this->innertext(); | |
// trigger callback | |
if ($this->dom->callback!==null) | |
call_user_func_array($this->dom->callback, array($this)); | |
if (isset($this->_[HDOM_INFO_OUTER])) return $this->_[HDOM_INFO_OUTER]; | |
if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | |
// render begin tag | |
$ret = $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]->makeup(); | |
// render inner text | |
if (isset($this->_[HDOM_INFO_INNER])) | |
$ret .= $this->_[HDOM_INFO_INNER]; | |
else { | |
foreach($this->nodes as $n) | |
$ret .= $n->outertext(); | |
} | |
// render end tag | |
if(isset($this->_[HDOM_INFO_END]) && $this->_[HDOM_INFO_END]!=0) | |
$ret .= '</'.$this->tag.'>'; | |
return $ret; | |
} | |
// get dom node's plain text | |
function text() { | |
if (isset($this->_[HDOM_INFO_INNER])) return $this->_[HDOM_INFO_INNER]; | |
switch ($this->nodetype) { | |
case HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | |
case HDOM_TYPE_COMMENT: return ''; | |
case HDOM_TYPE_UNKNOWN: return ''; | |
} | |
if (strcasecmp($this->tag, 'script')===0) return ''; | |
if (strcasecmp($this->tag, 'style')===0) return ''; | |
$ret = ''; | |
foreach($this->nodes as $n) | |
$ret .= $n->text(); | |
return $ret; | |
} | |
function xmltext() { | |
$ret = $this->innertext(); | |
$ret = str_ireplace('<![CDATA[', '', $ret); | |
$ret = str_replace(']]>', '', $ret); | |
return $ret; | |
} | |
// build node's text with tag | |
function makeup() { | |
// text, comment, unknown | |
if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | |
$ret = '<'.$this->tag; | |
$i = -1; | |
foreach($this->attr as $key=>$val) { | |
++$i; | |
// skip removed attribute | |
if ($val===null || $val===false) | |
continue; | |
$ret .= $this->_[HDOM_INFO_SPACE][$i][0]; | |
//no value attr: nowrap, checked selected... | |
if ($val===true) | |
$ret .= $key; | |
else { | |
switch($this->_[HDOM_INFO_QUOTE][$i]) { | |
case HDOM_QUOTE_DOUBLE: $quote = '"'; break; | |
case HDOM_QUOTE_SINGLE: $quote = '\''; break; | |
default: $quote = ''; | |
} | |
$ret .= $key.$this->_[HDOM_INFO_SPACE][$i][1].'='.$this->_[HDOM_INFO_SPACE][$i][2].$quote.$val.$quote; | |
} | |
} | |
$ret = $this->dom->restore_noise($ret); | |
return $ret . $this->_[HDOM_INFO_ENDSPACE] . '>'; | |
} | |
// find elements by css selector | |
function find($selector, $idx=null) { | |
$selectors = $this->parse_selector($selector); | |
if (($count=count($selectors))===0) return array(); | |
$found_keys = array(); | |
// find each selector | |
for ($c=0; $c<$count; ++$c) { | |
if (($levle=count($selectors[0]))===0) return array(); | |
if (!isset($this->_[HDOM_INFO_BEGIN])) return array(); | |
$head = array($this->_[HDOM_INFO_BEGIN]=>1); | |
// handle descendant selectors, no recursive! | |
for ($l=0; $l<$levle; ++$l) { | |
$ret = array(); | |
foreach($head as $k=>$v) { | |
$n = ($k===-1) ? $this->dom->root : $this->dom->nodes[$k]; | |
$n->seek($selectors[$c][$l], $ret); | |
} | |
$head = $ret; | |
} | |
foreach($head as $k=>$v) { | |
if (!isset($found_keys[$k])) | |
$found_keys[$k] = 1; | |
} | |
} | |
// sort keys | |
ksort($found_keys); | |
$found = array(); | |
foreach($found_keys as $k=>$v) | |
$found[] = $this->dom->nodes[$k]; | |
// return nth-element or array | |
if (is_null($idx)) return $found; | |
else if ($idx<0) $idx = count($found) + $idx; | |
return (isset($found[$idx])) ? $found[$idx] : null; | |
} | |
// seek for given conditions | |
protected function seek($selector, &$ret) { | |
list($tag, $key, $val, $exp, $no_key) = $selector; | |
// xpath index | |
if ($tag && $key && is_numeric($key)) { | |
$count = 0; | |
foreach ($this->children as $c) { | |
if ($tag==='*' || $tag===$c->tag) { | |
if (++$count==$key) { | |
$ret[$c->_[HDOM_INFO_BEGIN]] = 1; | |
return; | |
} | |
} | |
} | |
return; | |
} | |
$end = (!empty($this->_[HDOM_INFO_END])) ? $this->_[HDOM_INFO_END] : 0; | |
if ($end==0) { | |
$parent = $this->parent; | |
while (!isset($parent->_[HDOM_INFO_END]) && $parent!==null) { | |
$end -= 1; | |
$parent = $parent->parent; | |
} | |
$end += $parent->_[HDOM_INFO_END]; | |
} | |
for($i=$this->_[HDOM_INFO_BEGIN]+1; $i<$end; ++$i) { | |
$node = $this->dom->nodes[$i]; | |
$pass = true; | |
if ($tag==='*' && !$key) { | |
if (in_array($node, $this->children, true)) | |
$ret[$i] = 1; | |
continue; | |
} | |
// compare tag | |
if ($tag && $tag!=$node->tag && $tag!=='*') {$pass=false;} | |
// compare key | |
if ($pass && $key) { | |
if ($no_key) { | |
if (isset($node->attr[$key])) $pass=false; | |
} | |
else if (!isset($node->attr[$key])) $pass=false; | |
} | |
// compare value | |
if ($pass && $key && $val && $val!=='*') { | |
$check = $this->match($exp, $val, $node->attr[$key]); | |
// handle multiple class | |
if (!$check && strcasecmp($key, 'class')===0) { | |
foreach(explode(' ',$node->attr[$key]) as $k) { | |
$check = $this->match($exp, $val, $k); | |
if ($check) break; | |
} | |
} | |
if (!$check) $pass = false; | |
} | |
if ($pass) $ret[$i] = 1; | |
unset($node); | |
} | |
} | |
protected function match($exp, $pattern, $value) { | |
switch ($exp) { | |
case '=': | |
return ($value===$pattern); | |
case '!=': | |
return ($value!==$pattern); | |
case '^=': | |
return preg_match("/^".preg_quote($pattern,'/')."/", $value); | |
case '$=': | |
return preg_match("/".preg_quote($pattern,'/')."$/", $value); | |
case '*=': | |
if ($pattern[0]=='/') | |
return preg_match($pattern, $value); | |
return preg_match("/".$pattern."/i", $value); | |
} | |
return false; | |
} | |
protected function parse_selector($selector_string) { | |
// pattern of CSS selectors, modified from mootools | |
$pattern = "/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is"; | |
preg_match_all($pattern, trim($selector_string).' ', $matches, PREG_SET_ORDER); | |
$selectors = array(); | |
$result = array(); | |
//print_r($matches); | |
foreach ($matches as $m) { | |
$m[0] = trim($m[0]); | |
if ($m[0]==='' || $m[0]==='/' || $m[0]==='//') continue; | |
// for borwser grnreated xpath | |
if ($m[1]==='tbody') continue; | |
list($tag, $key, $val, $exp, $no_key) = array($m[1], null, null, '=', false); | |
if(!empty($m[2])) {$key='id'; $val=$m[2];} | |
if(!empty($m[3])) {$key='class'; $val=$m[3];} | |
if(!empty($m[4])) {$key=$m[4];} | |
if(!empty($m[5])) {$exp=$m[5];} | |
if(!empty($m[6])) {$val=$m[6];} | |
// convert to lowercase | |
if ($this->dom->lowercase) {$tag=strtolower($tag); $key=strtolower($key);} | |
//elements that do NOT have the specified attribute | |
if (isset($key[0]) && $key[0]==='!') {$key=substr($key, 1); $no_key=true;} | |
$result[] = array($tag, $key, $val, $exp, $no_key); | |
if (trim($m[7])===',') { | |
$selectors[] = $result; | |
$result = array(); | |
} | |
} | |
if (count($result)>0) | |
$selectors[] = $result; | |
return $selectors; | |
} | |
function __get($name) { | |
if (isset($this->attr[$name])) return $this->attr[$name]; | |
switch($name) { | |
case 'outertext': return $this->outertext(); | |
case 'innertext': return $this->innertext(); | |
case 'plaintext': return $this->text(); | |
case 'xmltext': return $this->xmltext(); | |
default: return array_key_exists($name, $this->attr); | |
} | |
} | |
function __set($name, $value) { | |
switch($name) { | |
case 'outertext': return $this->_[HDOM_INFO_OUTER] = $value; | |
case 'innertext': | |
if (isset($this->_[HDOM_INFO_TEXT])) return $this->_[HDOM_INFO_TEXT] = $value; | |
return $this->_[HDOM_INFO_INNER] = $value; | |
} | |
if (!isset($this->attr[$name])) { | |
$this->_[HDOM_INFO_SPACE][] = array(' ', '', ''); | |
$this->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE; | |
} | |
$this->attr[$name] = $value; | |
} | |
function __isset($name) { | |
switch($name) { | |
case 'outertext': return true; | |
case 'innertext': return true; | |
case 'plaintext': return true; | |
} | |
//no value attr: nowrap, checked selected... | |
return (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]); | |
} | |
function __unset($name) { | |
if (isset($this->attr[$name])) | |
unset($this->attr[$name]); | |
} | |
// camel naming conventions | |
function getAllAttributes() {return $this->attr;} | |
function getAttribute($name) {return $this->__get($name);} | |
function setAttribute($name, $value) {$this->__set($name, $value);} | |
function hasAttribute($name) {return $this->__isset($name);} | |
function removeAttribute($name) {$this->__set($name, null);} | |
function getElementById($id) {return $this->find("#$id", 0);} | |
function getElementsById($id, $idx=null) {return $this->find("#$id", $idx);} | |
function getElementByTagName($name) {return $this->find($name, 0);} | |
function getElementsByTagName($name, $idx=null) {return $this->find($name, $idx);} | |
function parentNode() {return $this->parent();} | |
function childNodes($idx=-1) {return $this->children($idx);} | |
function firstChild() {return $this->first_child();} | |
function lastChild() {return $this->last_child();} | |
function nextSibling() {return $this->next_sibling();} | |
function previousSibling() {return $this->prev_sibling();} | |
} | |
// simple html dom parser | |
// ----------------------------------------------------------------------------- | |
class simple_html_dom { | |
public $root = null; | |
public $nodes = array(); | |
public $callback = null; | |
public $lowercase = false; | |
protected $pos; | |
protected $doc; | |
protected $char; | |
protected $size; | |
protected $cursor; | |
protected $parent; | |
protected $noise = array(); | |
protected $token_blank = " \t\r\n"; | |
protected $token_equal = ' =/>'; | |
protected $token_slash = " />\r\n\t"; | |
protected $token_attr = ' >'; | |
// use isset instead of in_array, performance boost about 30%... | |
protected $self_closing_tags = array('img'=>1, 'br'=>1, 'input'=>1, 'meta'=>1, 'link'=>1, 'hr'=>1, 'base'=>1, 'embed'=>1, 'spacer'=>1); | |
protected $block_tags = array('root'=>1, 'body'=>1, 'form'=>1, 'div'=>1, 'span'=>1, 'table'=>1); | |
protected $optional_closing_tags = array( | |
'tr'=>array('tr'=>1, 'td'=>1, 'th'=>1), | |
'th'=>array('th'=>1), | |
'td'=>array('td'=>1), | |
'li'=>array('li'=>1), | |
'dt'=>array('dt'=>1, 'dd'=>1), | |
'dd'=>array('dd'=>1, 'dt'=>1), | |
'dl'=>array('dd'=>1, 'dt'=>1), | |
'p'=>array('p'=>1), | |
'nobr'=>array('nobr'=>1), | |
); | |
function __construct($str=null) { | |
if ($str) { | |
if (preg_match("/^http:\/\//i",$str) || is_file($str)) | |
$this->load_file($str); | |
else | |
$this->load($str); | |
} | |
} | |
function __destruct() { | |
$this->clear(); | |
} | |
// load html from string | |
function load($str, $lowercase=true) { | |
// prepare | |
$this->prepare($str, $lowercase); | |
// strip out comments | |
$this->remove_noise("'<!--(.*?)-->'is"); | |
// strip out cdata | |
$this->remove_noise("'<!\[CDATA\[(.*?)\]\]>'is", true); | |
// strip out <style> tags | |
$this->remove_noise("'<\s*style[^>]*[^/]>(.*?)<\s*/\s*style\s*>'is"); | |
$this->remove_noise("'<\s*style\s*>(.*?)<\s*/\s*style\s*>'is"); | |
// strip out <script> tags | |
$this->remove_noise("'<\s*script[^>]*[^/]>(.*?)<\s*/\s*script\s*>'is"); | |
$this->remove_noise("'<\s*script\s*>(.*?)<\s*/\s*script\s*>'is"); | |
// strip out preformatted tags | |
$this->remove_noise("'<\s*(?:code)[^>]*>(.*?)<\s*/\s*(?:code)\s*>'is"); | |
// strip out server side scripts | |
$this->remove_noise("'(<\?)(.*?)(\?>)'s", true); | |
// strip smarty scripts | |
$this->remove_noise("'(\{\w)(.*?)(\})'s", true); | |
// parsing | |
while ($this->parse()); | |
// end | |
$this->root->_[HDOM_INFO_END] = $this->cursor; | |
} | |
// load html from file | |
function load_file() { | |
$args = func_get_args(); | |
$this->load(call_user_func_array('file_get_contents', $args), true); | |
} | |
// set callback function | |
function set_callback($function_name) { | |
$this->callback = $function_name; | |
} | |
// remove callback function | |
function remove_callback() { | |
$this->callback = null; | |
} | |
// save dom as string | |
function save($filepath='') { | |
$ret = $this->root->innertext(); | |
if ($filepath!=='') file_put_contents($filepath, $ret); | |
return $ret; | |
} | |
// find dom node by css selector | |
function find($selector, $idx=null) { | |
return $this->root->find($selector, $idx); | |
} | |
// clean up memory due to php5 circular references memory leak... | |
function clear() { | |
foreach($this->nodes as $n) {$n->clear(); $n = null;} | |
if (isset($this->parent)) {$this->parent->clear(); unset($this->parent);} | |
if (isset($this->root)) {$this->root->clear(); unset($this->root);} | |
unset($this->doc); | |
unset($this->noise); | |
} | |
function dump($show_attr=true) { | |
$this->root->dump($show_attr); | |
} | |
// prepare HTML data and init everything | |
protected function prepare($str, $lowercase=true) { | |
$this->clear(); | |
$this->doc = $str; | |
$this->pos = 0; | |
$this->cursor = 1; | |
$this->noise = array(); | |
$this->nodes = array(); | |
$this->lowercase = $lowercase; | |
$this->root = new simple_html_dom_node($this); | |
$this->root->tag = 'root'; | |
$this->root->_[HDOM_INFO_BEGIN] = -1; | |
$this->root->nodetype = HDOM_TYPE_ROOT; | |
$this->parent = $this->root; | |
// set the length of content | |
$this->size = strlen($str); | |
if ($this->size>0) $this->char = $this->doc[0]; | |
} | |
// parse html content | |
protected function parse() { | |
if (($s = $this->copy_until_char('<'))==='') | |
return $this->read_tag(); | |
// text | |
$node = new simple_html_dom_node($this); | |
++$this->cursor; | |
$node->_[HDOM_INFO_TEXT] = $s; | |
$this->link_nodes($node, false); | |
return true; | |
} | |
// read tag info | |
protected function read_tag() { | |
if ($this->char!=='<') { | |
$this->root->_[HDOM_INFO_END] = $this->cursor; | |
return false; | |
} | |
$begin_tag_pos = $this->pos; | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
// end tag | |
if ($this->char==='/') { | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
$this->skip($this->token_blank_t); | |
$tag = $this->copy_until_char('>'); | |
// skip attributes in end tag | |
if (($pos = strpos($tag, ' '))!==false) | |
$tag = substr($tag, 0, $pos); | |
$parent_lower = strtolower($this->parent->tag); | |
$tag_lower = strtolower($tag); | |
if ($parent_lower!==$tag_lower) { | |
if (isset($this->optional_closing_tags[$parent_lower]) && isset($this->block_tags[$tag_lower])) { | |
$this->parent->_[HDOM_INFO_END] = 0; | |
$org_parent = $this->parent; | |
while (($this->parent->parent) && strtolower($this->parent->tag)!==$tag_lower) | |
$this->parent = $this->parent->parent; | |
if (strtolower($this->parent->tag)!==$tag_lower) { | |
$this->parent = $org_parent; // restore origonal parent | |
if ($this->parent->parent) $this->parent = $this->parent->parent; | |
$this->parent->_[HDOM_INFO_END] = $this->cursor; | |
return $this->as_text_node($tag); | |
} | |
} | |
else if (($this->parent->parent) && isset($this->block_tags[$tag_lower])) { | |
$this->parent->_[HDOM_INFO_END] = 0; | |
$org_parent = $this->parent; | |
while (($this->parent->parent) && strtolower($this->parent->tag)!==$tag_lower) | |
$this->parent = $this->parent->parent; | |
if (strtolower($this->parent->tag)!==$tag_lower) { | |
$this->parent = $org_parent; // restore origonal parent | |
$this->parent->_[HDOM_INFO_END] = $this->cursor; | |
return $this->as_text_node($tag); | |
} | |
} | |
else if (($this->parent->parent) && strtolower($this->parent->parent->tag)===$tag_lower) { | |
$this->parent->_[HDOM_INFO_END] = 0; | |
$this->parent = $this->parent->parent; | |
} | |
else | |
return $this->as_text_node($tag); | |
} | |
$this->parent->_[HDOM_INFO_END] = $this->cursor; | |
if ($this->parent->parent) $this->parent = $this->parent->parent; | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
return true; | |
} | |
$node = new simple_html_dom_node($this); | |
$node->_[HDOM_INFO_BEGIN] = $this->cursor; | |
++$this->cursor; | |
$tag = $this->copy_until($this->token_slash); | |
// doctype, cdata & comments... | |
if (isset($tag[0]) && $tag[0]==='!') { | |
$node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until_char('>'); | |
if (isset($tag[2]) && $tag[1]==='-' && $tag[2]==='-') { | |
$node->nodetype = HDOM_TYPE_COMMENT; | |
$node->tag = 'comment'; | |
} else { | |
$node->nodetype = HDOM_TYPE_UNKNOWN; | |
$node->tag = 'unknown'; | |
} | |
if ($this->char==='>') $node->_[HDOM_INFO_TEXT].='>'; | |
$this->link_nodes($node, true); | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
return true; | |
} | |
// text | |
if ($pos=strpos($tag, '<')!==false) { | |
$tag = '<' . substr($tag, 0, -1); | |
$node->_[HDOM_INFO_TEXT] = $tag; | |
$this->link_nodes($node, false); | |
$this->char = $this->doc[--$this->pos]; // prev | |
return true; | |
} | |
if (!preg_match("/^[\w-:]+$/", $tag)) { | |
$node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until('<>'); | |
if ($this->char==='<') { | |
$this->link_nodes($node, false); | |
return true; | |
} | |
if ($this->char==='>') $node->_[HDOM_INFO_TEXT].='>'; | |
$this->link_nodes($node, false); | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
return true; | |
} | |
// begin tag | |
$node->nodetype = HDOM_TYPE_ELEMENT; | |
$tag_lower = strtolower($tag); | |
$node->tag = ($this->lowercase) ? $tag_lower : $tag; | |
// handle optional closing tags | |
if (isset($this->optional_closing_tags[$tag_lower]) ) { | |
while (isset($this->optional_closing_tags[$tag_lower][strtolower($this->parent->tag)])) { | |
$this->parent->_[HDOM_INFO_END] = 0; | |
$this->parent = $this->parent->parent; | |
} | |
$node->parent = $this->parent; | |
} | |
$guard = 0; // prevent infinity loop | |
$space = array($this->copy_skip($this->token_blank), '', ''); | |
// attributes | |
do { | |
if ($this->char!==null && $space[0]==='') break; | |
$name = $this->copy_until($this->token_equal); | |
if($guard===$this->pos) { | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
continue; | |
} | |
$guard = $this->pos; | |
// handle endless '<' | |
if($this->pos>=$this->size-1 && $this->char!=='>') { | |
$node->nodetype = HDOM_TYPE_TEXT; | |
$node->_[HDOM_INFO_END] = 0; | |
$node->_[HDOM_INFO_TEXT] = '<'.$tag . $space[0] . $name; | |
$node->tag = 'text'; | |
$this->link_nodes($node, false); | |
return true; | |
} | |
// handle mismatch '<' | |
if($this->doc[$this->pos-1]=='<') { | |
$node->nodetype = HDOM_TYPE_TEXT; | |
$node->tag = 'text'; | |
$node->attr = array(); | |
$node->_[HDOM_INFO_END] = 0; | |
$node->_[HDOM_INFO_TEXT] = substr($this->doc, $begin_tag_pos, $this->pos-$begin_tag_pos-1); | |
$this->pos -= 2; | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
$this->link_nodes($node, false); | |
return true; | |
} | |
if ($name!=='/' && $name!=='') { | |
$space[1] = $this->copy_skip($this->token_blank); | |
$name = $this->restore_noise($name); | |
if ($this->lowercase) $name = strtolower($name); | |
if ($this->char==='=') { | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
$this->parse_attr($node, $name, $space); | |
} | |
else { | |
//no value attr: nowrap, checked selected... | |
$node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO; | |
$node->attr[$name] = true; | |
if ($this->char!='>') $this->char = $this->doc[--$this->pos]; // prev | |
} | |
$node->_[HDOM_INFO_SPACE][] = $space; | |
$space = array($this->copy_skip($this->token_blank), '', ''); | |
} | |
else | |
break; | |
} while($this->char!=='>' && $this->char!=='/'); | |
$this->link_nodes($node, true); | |
$node->_[HDOM_INFO_ENDSPACE] = $space[0]; | |
// check self closing | |
if ($this->copy_until_char_escape('>')==='/') { | |
$node->_[HDOM_INFO_ENDSPACE] .= '/'; | |
$node->_[HDOM_INFO_END] = 0; | |
} | |
else { | |
// reset parent | |
if (!isset($this->self_closing_tags[strtolower($node->tag)])) $this->parent = $node; | |
} | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
return true; | |
} | |
// parse attributes | |
protected function parse_attr($node, $name, &$space) { | |
$space[2] = $this->copy_skip($this->token_blank); | |
switch($this->char) { | |
case '"': | |
$node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE; | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
$node->attr[$name] = $this->restore_noise($this->copy_until_char_escape('"')); | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
break; | |
case '\'': | |
$node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_SINGLE; | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
$node->attr[$name] = $this->restore_noise($this->copy_until_char_escape('\'')); | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
break; | |
default: | |
$node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO; | |
$node->attr[$name] = $this->restore_noise($this->copy_until($this->token_attr)); | |
} | |
} | |
// link node's parent | |
protected function link_nodes(&$node, $is_child) { | |
$node->parent = $this->parent; | |
$this->parent->nodes[] = $node; | |
if ($is_child) | |
$this->parent->children[] = $node; | |
} | |
// as a text node | |
protected function as_text_node($tag) { | |
$node = new simple_html_dom_node($this); | |
++$this->cursor; | |
$node->_[HDOM_INFO_TEXT] = '</' . $tag . '>'; | |
$this->link_nodes($node, false); | |
$this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
return true; | |
} | |
protected function skip($chars) { | |
$this->pos += strspn($this->doc, $chars, $this->pos); | |
$this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
} | |
protected function copy_skip($chars) { | |
$pos = $this->pos; | |
$len = strspn($this->doc, $chars, $pos); | |
$this->pos += $len; | |
$this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
if ($len===0) return ''; | |
return substr($this->doc, $pos, $len); | |
} | |
protected function copy_until($chars) { | |
$pos = $this->pos; | |
$len = strcspn($this->doc, $chars, $pos); | |
$this->pos += $len; | |
$this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | |
return substr($this->doc, $pos, $len); | |
} | |
protected function copy_until_char($char) { | |
if ($this->char===null) return ''; | |
if (($pos = strpos($this->doc, $char, $this->pos))===false) { | |
$ret = substr($this->doc, $this->pos, $this->size-$this->pos); | |
$this->char = null; | |
$this->pos = $this->size; | |
return $ret; | |
} | |
if ($pos===$this->pos) return ''; | |
$pos_old = $this->pos; | |
$this->char = $this->doc[$pos]; | |
$this->pos = $pos; | |
return substr($this->doc, $pos_old, $pos-$pos_old); | |
} | |
protected function copy_until_char_escape($char) { | |
if ($this->char===null) return ''; | |
$start = $this->pos; | |
while(1) { | |
if (($pos = strpos($this->doc, $char, $start))===false) { | |
$ret = substr($this->doc, $this->pos, $this->size-$this->pos); | |
$this->char = null; | |
$this->pos = $this->size; | |
return $ret; | |
} | |
if ($pos===$this->pos) return ''; | |
if ($this->doc[$pos-1]==='\\') { | |
$start = $pos+1; | |
continue; | |
} | |
$pos_old = $this->pos; | |
$this->char = $this->doc[$pos]; | |
$this->pos = $pos; | |
return substr($this->doc, $pos_old, $pos-$pos_old); | |
} | |
} | |
// remove noise from html content | |
protected function remove_noise($pattern, $remove_tag=false) { | |
$count = preg_match_all($pattern, $this->doc, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE); | |
for ($i=$count-1; $i>-1; --$i) { | |
$key = '___noise___'.sprintf('% 3d', count($this->noise)+100); | |
$idx = ($remove_tag) ? 0 : 1; | |
$this->noise[$key] = $matches[$i][$idx][0]; | |
$this->doc = substr_replace($this->doc, $key, $matches[$i][$idx][1], strlen($matches[$i][$idx][0])); | |
} | |
// reset the length of content | |
$this->size = strlen($this->doc); | |
if ($this->size>0) $this->char = $this->doc[0]; | |
} | |
// restore noise to html content | |
function restore_noise($text) { | |
while(($pos=strpos($text, '___noise___'))!==false) { | |
$key = '___noise___'.$text[$pos+11].$text[$pos+12].$text[$pos+13]; | |
if (isset($this->noise[$key])) | |
$text = substr($text, 0, $pos).$this->noise[$key].substr($text, $pos+14); | |
} | |
return $text; | |
} | |
function __toString() { | |
return $this->root->innertext(); | |
} | |
function __get($name) { | |
switch($name) { | |
case 'outertext': return $this->root->innertext(); | |
case 'innertext': return $this->root->innertext(); | |
case 'plaintext': return $this->root->text(); | |
} | |
} | |
// camel naming conventions | |
function childNodes($idx=-1) {return $this->root->childNodes($idx);} | |
function firstChild() {return $this->root->first_child();} | |
function lastChild() {return $this->root->last_child();} | |
function getElementById($id) {return $this->find("#$id", 0);} | |
function getElementsById($id, $idx=null) {return $this->find("#$id", $idx);} | |
function getElementByTagName($name) {return $this->find($name, 0);} | |
function getElementsByTagName($name, $idx=-1) {return $this->find($name, $idx);} | |
function loadFile() {$args = func_get_args();$this->load(call_user_func_array('file_get_contents', $args), true);} | |
} | |
?> |
<?php | <?php |
include ('common.inc.php'); | include ('common.inc.php'); |
$stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); | $stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); |
$stopcode = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_STRING); | $stopcode = filter_var($_REQUEST['stopcode'], FILTER_SANITIZE_STRING); |
$url = $APIurl . "/json/stop?stop_id=" . $stopid; | $url = $APIurl . "/json/stop?stop_id=" . $stopid; |
$stop = json_decode(getPage($url)); | $stop = json_decode(getPage($url)); |
if ($stop[5] != $stopcode) { | if ($stopcode != "" && $stop[5] != $stopcode) { |
$url = $APIurl . "/json/stopcodesearch?q=" . $stopcode; | $url = $APIurl . "/json/stopcodesearch?q=" . $stopcode; |
$stopsearch = json_decode(getPage($url)); | $stopsearch = json_decode(getPage($url)); |
$stopid = $stopsearch[0][0]; | $stopid = $stopsearch[0][0]; |
$url = $APIurl . "/json/stop?stop_id=" . $stopid; | $url = $APIurl . "/json/stop?stop_id=" . $stopid; |
$stop = json_decode(getPage($url)); | $stop = json_decode(getPage($url)); |
} | |
if (!startsWith($stop[5], "Wj") && strpos($stop[1], "Platform") === false) { | |
// expand out to all platforms | |
} | |
$stops = Array(); | |
$stopPositions = Array(); | |
$stopNames = Array(); | |
$tripStopNumbers = Array(); | |
$allStopsTrips = Array(); | |
$stopLinks = ""; | |
if (isset($_REQUEST['stopids'])) { | |
$stopids = explode(",", filter_var($_REQUEST['stopids'], FILTER_SANITIZE_STRING)); | |
foreach ($stopids as $sub_stopid) { | |
$url = $APIurl . "/json/stop?stop_id=" . $sub_stopid; | |
$stop = json_decode(getPage($url)); | |
$stops[] = $stop; | |
} | |
$stop = $stops[0]; | |
$stopid = $stops[0][0]; | |
$stopLinks.= "Individual stop pages: "; | |
foreach ($stops as $key => $sub_stop) { | |
$stopNames[$key] = $sub_stop[1] . ' Stop #' . ($key + 1); | |
$stopLinks.= '<a href="stop.php?stopid=' . $sub_stop[0] . '&stopcode=' . $sub_stop[5] . '">' . $stopNames[$key] . '</a> '; | |
$stopPositions[$key] = Array( | |
$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)); | |
foreach ($trips as $trip) { | |
if (!isset($allStopsTrips[$trip[1][0]])) $allStopsTrips[$trip[1][0]] = $trip; | |
$tripStopNumbers[$trip[1][0]][] = $key; | |
} | |
} | |
} | } |
include_header($stop[1], "stop"); | include_header($stop[1], "stop"); |
if (isMetricsOn()) { | if (isMetricsOn()) { |
// Create a new Instance of the tracker | // Create a new Instance of the tracker |
$owa = new owa_php(); | $owa = new owa_php(); |
// Set the ID of the site being tracked | // Set the ID of the site being tracked |
$owa->setSiteId($owaSiteID); | $owa->setSiteId($owaSiteID); |
// Create a new event object | // Create a new event object |
$event = $owa->makeEvent(); | $event = $owa->makeEvent(); |
// Set the Event Type, in this case a "video_play" | // Set the Event Type, in this case a "video_play" |
$event->setEventType('view_stop'); | $event->setEventType('view_stop'); |
// Set a property | // Set a property |
$event->set('stop_id', $stopid); | $event->set('stop_id', $stopid); |
// Track the event | // Track the event |
$owa->trackEvent($event); | $owa->trackEvent($event); |
} | } |
timePlaceSettings(); | timePlaceSettings(); |
echo '<div data-role="content" class="ui-content" role="main"><p>' . staticmap(Array( | echo '<div data-role="content" class="ui-content" role="main">'; |
0 => Array( | echo $stopLinks; |
$stop[2], | if (sizeof($stops) > 0) { |
$stop[3] | echo '<p>' . staticmap($stopPositions) . '</p>'; |
) | } |
)) . '</p>'; | else { |
echo '<p>' . staticmap(Array( | |
0 => Array( | |
$stop[2], | |
$stop[3] | |
) | |
)) . '</p>'; | |
} | |
echo ' <ul data-role="listview" data-inset="true">'; | echo ' <ul data-role="listview" data-inset="true">'; |
$url = $APIurl . "/json/stoptrips?stop=" . $stopid . "&time=" . midnight_seconds() . "&service_period=" . service_period(); | if (sizeof($allStopsTrips) > 0) { |
$trips = json_decode(getPage($url)); | $trips = $allStopsTrips; |
} | |
else { | |
$url = $APIurl . "/json/stoptrips?stop=" . $stopid . "&time=" . midnight_seconds() . "&service_period=" . service_period(); | |
$trips = json_decode(getPage($url)); | |
} | |
foreach ($trips as $row) { | foreach ($trips as $row) { |
echo '<li>'; | echo '<li>'; |
echo '<h3><a href="trip.php?stopid=' . $stopid . '&tripid=' . $row[1][0] . '">' . $row[1][1]; | echo '<h3><a href="trip.php?stopid=' . $stopid . '&tripid=' . $row[1][0] . '">' . $row[1][1]; |
if (isFastDevice()) { | if (isFastDevice()) { |
$viaPoints = viaPointNames($row[1][0], $stopid); | $viaPoints = viaPointNames($row[1][0], $stopid); |
if ($viaPoints != "") echo '<br><small>Via: ' . $viaPoints . '</small> </a></h3>'; | if ($viaPoints != "") echo '<br><small>Via: ' . $viaPoints . '</small>'; |
} | } |
if (sizeof($tripStopNumbers) > 0) { | |
echo '<br><small>Boarding At: '; | |
foreach ($tripStopNumbers[$row[1][0]] as $key) { | |
echo $stopNames[$key] .' '; | |
} | |
echo '</small>'; | |
} | |
echo '</a></h3>'; | |
echo '<p class="ui-li-aside"><strong>' . midnight_seconds_to_time($row[0]) . '</strong></p>'; | echo '<p class="ui-li-aside"><strong>' . midnight_seconds_to_time($row[0]) . '</strong></p>'; |
echo '</li>'; | echo '</li>'; |
} | } |
if (sizeof($trips) == 0) echo "<li> <center>No trips in the near future.</center> </li>"; | if (sizeof($trips) == 0) echo "<li> <center>No trips in the near future.</center> </li>"; |
echo '</ul></div>'; | echo '</ul></div>'; |
include_footer(); | include_footer(); |
?> | ?> |
<?php | <?php |
include ('common.inc.php'); | include ('common.inc.php'); |
function filterByFirstLetter($var) { | |
return $var[1][0] == $_REQUEST['firstLetter']; | |
} | |
function navbar() | function navbar() |
{ | { |
echo ' | echo ' |
<div data-role="navbar"> | <div data-role="navbar"> |
<ul> | <ul> |
<li><a href="stopList.php">Timing Points</a></li> | <li><a href="stopList.php">Timing Points</a></li> |
<li><a href="stopList.php?suburbs=yes">By Suburb</a></li> | <li><a href="stopList.php?suburbs=yes">By Suburb</a></li> |
<li><a href="stopList.php?nearby=yes">Nearby Stops</a></li> | <li><a href="stopList.php?nearby=yes">Nearby Stops</a></li> |
<li><a href="stopList.php?allstops=yes">All Stops</a></li> | <li><a href="stopList.php?allstops=yes">All Stops</a></li> |
</ul> | </ul> |
</div> | </div> |
'; | '; |
} | } |
// By suburb | // By suburb |
if (isset($_REQUEST['suburbs'])) { | if (isset($_REQUEST['suburbs'])) { |
include_header("Stops by Suburb", "stopList"); | include_header("Stops by Suburb", "stopList"); |
navbar(); | navbar(); |
echo ' <ul data-role="listview" data-filter="true" data-inset="true" >'; | echo ' <ul data-role="listview" data-filter="true" data-inset="true" >'; |
foreach ($suburbs as $suburb) { | foreach ($suburbs as $suburb) { |
echo '<li><a href="stopList.php?suburb=' . urlencode($suburb) . '">' . $suburb . '</a></li>'; | if (!isset($_REQUEST['firstLetter'])) { |
foreach (range('A', 'Z') as $letter) { | |
echo "<li><a href=\"stopList.php?firstLetter=$letter&suburbs=yes\">$letter...</a></li>\n"; | |
} | |
} | |
else if (startsWith($suburb, $_REQUEST['firstLetter'])) { | |
echo '<li><a href="stopList.php?suburb=' . urlencode($suburb) . '">' . $suburb . '</a></li>'; | |
} | |
} | } |
echo '</ul>'; | echo '</ul>'; |
} | } |
else { | else { |
// Timing Points / All stops | // Timing Points / All stops |
if ($_REQUEST['allstops']) { | if ($_REQUEST['allstops']) { |
$listType = 'allstops=yes'; | |
$url = $APIurl . "/json/stops"; | $url = $APIurl . "/json/stops"; |
include_header("All Stops", "stopList"); | include_header("All Stops", "stopList"); |
navbar(); | navbar(); |
timePlaceSettings(); | timePlaceSettings(); |
} | } |
else if ($_REQUEST['nearby']) { | else if ($_REQUEST['nearby']) { |
$listType = 'nearby=yes'; | |
$url = $APIurl . "/json/neareststops?lat={$_SESSION['lat']}&lon={$_SESSION['lon']}&limit=15"; | $url = $APIurl . "/json/neareststops?lat={$_SESSION['lat']}&lon={$_SESSION['lon']}&limit=15"; |
include_header("Nearby Stops", "stopList"); | include_header("Nearby Stops", "stopList"); |
navbar(); | navbar(); |
timePlaceSettings(true); | timePlaceSettings(true); |
} | } |
else if ($_REQUEST['suburb']) { | else if ($_REQUEST['suburb']) { |
$suburb = filter_var($_REQUEST['suburb'], FILTER_SANITIZE_STRING); | $suburb = filter_var($_REQUEST['suburb'], FILTER_SANITIZE_STRING); |
$listType = "suburb=$suburb"; | |
$url = $APIurl . "/json/stopzonesearch?q=" . $suburb; | $url = $APIurl . "/json/stopzonesearch?q=" . $suburb; |
include_header("Stops in " . ucwords($suburb) , "stopList"); | include_header("Stops in " . ucwords($suburb) , "stopList"); |
if (isMetricsOn()) { | if (isMetricsOn()) { |
// Create a new Instance of the tracker | // Create a new Instance of the tracker |
$owa = new owa_php($config); | $owa = new owa_php($config); |
// Set the ID of the site being tracked | // Set the ID of the site being tracked |
$owa->setSiteId($owaSiteID); | $owa->setSiteId($owaSiteID); |
// Create a new event object | // Create a new event object |
$event = $owa->makeEvent(); | $event = $owa->makeEvent(); |
// Set the Event Type, in this case a "video_play" | // Set the Event Type, in this case a "video_play" |
$event->setEventType('view_stop_list_suburb'); | $event->setEventType('view_stop_list_suburb'); |
// Set a property | // Set a property |
$event->set('stop_list_suburb', $suburb); | $event->set('stop_list_suburb', $suburb); |
// Track the event | // Track the event |
$owa->trackEvent($event); | $owa->trackEvent($event); |
} | } |
navbar(); | navbar(); |
} | } |
else { | else { |
$url = $APIurl . "/json/timingpoints"; | $url = $APIurl . "/json/timingpoints"; |
include_header("Timing Points / Major Stops", "stopList"); | include_header("Timing Points / Major Stops", "stopList"); |
navbar(); | navbar(); |
timePlaceSettings(); | timePlaceSettings(); |
} | } |
echo '<div class="noscriptnav"> Go to letter: '; | echo ' <ul data-role="listview" data-filter="true" data-inset="true" >'; |
foreach (range('A', 'Z') as $letter) { | if (!isset($_REQUEST['firstLetter']) && !$_REQUEST['suburb']) { |
echo "<a href=\"#$letter\">$letter</a> "; | foreach (range('A', 'Z') as $letter) { |
echo "<li><a href=\"stopList.php?firstLetter=$letter&$listType\">$letter...</a></li>\n"; | |
} | |
} | } |
echo "</div> | else { |
<script> | $stops = json_decode(getPage($url)); |
$('.noscriptnav').hide(); | foreach ($stops as $key => $row) { |
</script>"; | $stopName[$key] = $row[1]; |
echo ' <ul data-role="listview" data-filter="true" data-inset="true" >'; | |
$contents = json_decode(getPage($url)); | |
foreach ($contents as $key => $row) { | |
$stopName[$key] = $row[1]; | |
} | |
// Sort the stops by name | |
array_multisort($stopName, SORT_ASC, $contents); | |
$firstletter = ""; | |
foreach ($contents as $row) { | |
if (substr($row[1], 0, 1) != $firstletter) { | |
echo "<a name=$firstletter></a>"; | |
$firstletter = substr($row[1], 0, 1); | |
} | } |
echo '<li>'; | // Sort the stops by name |
if (!startsWith($row[5], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point" class="ui-li-icon">'; | array_multisort($stopName, SORT_ASC, $stops); |
echo '<a href="stop.php?stopid=' . $row[0] . (startsWith($row[5], "Wj") ? '&stopcode=' . $row[5] : "") . '">'; | if (!isset($_REQUEST['suburb'])){ |
if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) { | $stops = array_filter($stops, "filterByFirstLetter"); |
echo '<span class="ui-li-count">' . floor(distance($row[2], $row[3], $_SESSION['lat'], $_SESSION['lon'])) . 'm away</span>'; | |
} | } |
echo bracketsMeanNewLine($row[1]); | $stopsGrouped = Array(); |
echo '</a></li>'; | foreach ($stops as $key => $row) { |
if ((trim(preg_replace("/\(Platform.*/","",$stops[$key][1])) != trim(preg_replace("/\(Platform.*/","",$stops[$key + 1][1]))) || $key + 1 >= sizeof($stops)) { | |
if (sizeof($stopsGrouped) > 0) { | |
// print and empty grouped stops | |
// subsequent duplicates | |
$stopsGrouped["stop_ids"][] = $row[0]; | |
echo '<li>'; | |
if (!startsWith($stopsGrouped['stop_codes'][0], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point" class="ui-li-icon">'; | |
echo '<a href="stop.php?stopids=' . implode(",", $stopsGrouped['stop_ids']) . '">'; | |
if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) { | |
echo '<span class="ui-li-count">' . floor(distance($row[2], $row[3], $_SESSION['lat'], $_SESSION['lon'])) . 'm away</span>'; | |
} | |
echo bracketsMeanNewLine(trim(preg_replace("/\(Platform.*/","",$row[1])) . '(' . sizeof($stopsGrouped["stop_ids"]) . ' stops)'); | |
echo "</a></li>\n"; | |
$stopsGrouped = Array(); | |
} | |
else { | |
// just a normal stop | |
echo '<li>'; | |
if (!startsWith($row[5], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point" class="ui-li-icon">'; | |
echo '<a href="stop.php?stopid=' . $row[0] . (startsWith($row[5], "Wj") ? '&stopcode=' . $row[5] : "") . '">'; | |
if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) { | |
echo '<span class="ui-li-count">' . floor(distance($row[2], $row[3], $_SESSION['lat'], $_SESSION['lon'])) . 'm away</span>'; | |
} | |
echo bracketsMeanNewLine($row[1]); | |
echo "</a></li>\n"; | |
} | |
} else { | |
// this is a duplicated line item | |
if ($key - 1 <= 0 || (trim(preg_replace("/\(Platform.*/","",$stops[$key][1])) != trim(preg_replace("/\(Platform.*/","",$stops[$key - 1][1])))) { | |
// first duplicate | |
$stopsGrouped = Array( | |
"name" => trim(preg_replace("/\(Platform.*/","",$row[1])), | |
"stop_ids" => Array( | |
$row[0] | |
), | |
"stop_codes" => Array( | |
$row[5] | |
) | |
); | |
} | |
else { | |
// subsequent duplicates | |
$stopsGrouped["stop_ids"][] = $row[0]; | |
} | |
} | |
} | |
} | } |
echo '</ul>'; | echo '</ul>'; |
var_dump ($stopsGrouped); | |
} | } |
include_footer(); | include_footer(); |
?> | ?> |
<?php | <?php |
include ('common.inc.php'); | include ('common.inc.php'); |
$tripid = filter_var($_REQUEST['tripid'], FILTER_SANITIZE_NUMBER_INT); | $tripid = filter_var($_REQUEST['tripid'], FILTER_SANITIZE_NUMBER_INT); |
$stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); | $stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); |
$routeid = filter_var($_REQUEST['routeid'], FILTER_SANITIZE_NUMBER_INT); | $routeid = filter_var($_REQUEST['routeid'], FILTER_SANITIZE_NUMBER_INT); |
$routetrips = Array(); | $routetrips = Array(); |
if ($_REQUEST['routeid']) { | if ($_REQUEST['routeid'] && !$_REQUEST['tripid']) { |
$tripid = 0; | |
$url = $APIurl . "/json/routetrips?route_id=" . $routeid; | $url = $APIurl . "/json/routetrips?route_id=" . $routeid; |
$routetrips = json_decode(getPage($url)); | $routetrips = json_decode(getPage($url)); |
foreach ($routetrips as $trip) { | foreach ($routetrips as $trip) { |
if ($trip[0] < midnight_seconds()) { | if ($trip[0] > midnight_seconds()) { |
$tripid = $trip[1]; | $tripid = $trip[1]; |
break; | break; |
} | } |
} | } |
if (!($tripid > 0)) $tripid = $routetrip[0][1]; | if ($tripid == 0) $tripid = $routetrips[0][1]; |
} | } |
$url = $APIurl . "/json/triprows?trip=" . $tripid; | $url = $APIurl . "/json/triprows?trip=" . $tripid; |
$trips = array_flatten(json_decode(getPage($url))); | $trips = array_flatten(json_decode(getPage($url))); |
if (sizeof($routetrips) == 0) { | if (sizeof($routetrips) == 0) { |
$routeid = $trips[1]->route_id; | $routeid = $trips[1]->route_id; |
$url = $APIurl . "/json/routetrips?route_id=" . $trips[1]->route_id; | $url = $APIurl . "/json/routetrips?route_id=" . $trips[1]->route_id; |
$routetrips = json_decode(getPage($url)); | $routetrips = json_decode(getPage($url)); |
} | } |
include_header("Stops on " . $trips[1]->route_short_name . ' ' . $trips[1]->route_long_name, "trip"); | include_header("Stops on " . $trips[1]->route_short_name . ' ' . $trips[1]->route_long_name, "trip"); |
if (isMetricsOn()) { | if (isMetricsOn()) { |
// Create a new Instance of the tracker | // Create a new Instance of the tracker |
$owa = new owa_php(); | $owa = new owa_php(); |
// Set the ID of the site being tracked | // Set the ID of the site being tracked |
$owa->setSiteId($owaSiteID); | $owa->setSiteId($owaSiteID); |
// Create a new event object | // Create a new event object |
$event = $owa->makeEvent(); | $event = $owa->makeEvent(); |
// Set the Event Type, in this case a "video_play" | // Set the Event Type, in this case a "video_play" |
$event->setEventType('view_trip'); | $event->setEventType('view_trip'); |
// Set a property | // Set a property |
$event->set('trip_id', $tripid); | $event->set('trip_id', $tripid); |
$event->set('route_id', $routeid); | $event->set('route_id', $routeid); |
$event->set('stop_id', $stopid); | $event->set('stop_id', $stopid); |
// Track the event | // Track the event |
$owa->trackEvent($event); | $owa->trackEvent($event); |
} | } |
timePlaceSettings(); | $url = $APIurl . "/json/tripstoptimes?trip=" . $tripid; |
$json = json_decode(getPage($url)); | |
$stops = $json[0]; | |
$times = $json[1]; | |
$viaPoints = Array(); | |
foreach ($stops as $stop) { | |
if (!startsWith($stop[5], "Wj")) { | |
$viaPoints[] = $stop[1]; | |
} | |
} | |
echo 'Via: ' . implode(", ",$viaPoints) . '</small>'; | |
echo '<p> Other Trips: '; | echo '<p> Other Trips: '; |
foreach ($routetrips as $othertrip) { | foreach ($routetrips as $othertrip) { |
echo '<a href="trip.php?tripid=' . $othertrip[1] . "&routeid=" . $routeid . '">' . midnight_seconds_to_time($othertrip[0]) . '</a> '; | echo '<a href="trip.php?tripid=' . $othertrip[1] . "&routeid=" . $routeid . '">' . midnight_seconds_to_time($othertrip[0]) . '</a> '; |
} | } |
echo '</p> Other directions/timing periods: '; | echo '</p> Other directions/timing periods: '; |
$url = $APIurl . "/json/routesearch?routeshortname=" . $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> '; | |
} | |
echo ' <ul data-role="listview" data-inset="true">'; | echo ' <ul data-role="listview" data-inset="true">'; |
$url = $APIurl . "/json/tripstoptimes?trip=" . $tripid; | 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>'; |
$json = json_decode(getPage($url)); | |
$stops = $json[0]; | |
$times = $json[1]; | |
echo '<li data-role="list-divider">' . midnight_seconds_to_time($times[0]) . '-' . midnight_seconds_to_time($times[sizeof($times) - 1]) . '</li>'; | |
$stopsGrouped = Array(); | $stopsGrouped = Array(); |
foreach ($stops as $key => $row) { | foreach ($stops as $key => $row) { |
if (($stops[$key][1] != $stops[$key + 1][1]) || $key + 1 >= sizeof($stops)) { | if (($stops[$key][1] != $stops[$key + 1][1]) || $key + 1 >= sizeof($stops)) { |
echo '<li>'; | echo '<li>'; |
if (!startsWith($row[5], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point" class="ui-li-icon">'; | if (!startsWith($row[5], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point" class="ui-li-icon">'; |
if (sizeof($stopsGrouped) > 0) { | if (sizeof($stopsGrouped) > 0) { |
// print and empty grouped stops | // print and empty grouped stops |
// subsequent duplicates | // subsequent duplicates |
$stopsGrouped["stop_ids"][] = $row[0]; | $stopsGrouped["stop_ids"][] = $row[0]; |
$stopsGrouped["endTime"] = $times[$key]; | $stopsGrouped["endTime"] = $times[$key]; |
echo '<a href="stop.php?stopids=' . $stopsGrouped['stop_ids'] . '">'; | echo '<a href="stop.php?stopids=' . implode(",", $stopsGrouped['stop_ids']) . '">'; |
echo '<p class="ui-li-aside">' . midnight_seconds_to_time($stopsGrouped['startTime']) . ' to ' . midnight_seconds_to_time($stopsGrouped['endTime']) . '</p>'; | 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 bracketsMeanNewLine($row[1]); |
echo '</a></li>'; | echo '</a></li>'; |
$stopsGrouped = Array(); | $stopsGrouped = Array(); |
} | } |
else { | else { |
// just a normal stop | // just a normal stop |
echo '<a href="stop.php?stopid=' . $row[0] . (startsWith($row[5], "Wj") ? '&stopcode=' . $row[5] : "") . '">'; | echo '<a href="stop.php?stopid=' . $row[0] . (startsWith($row[5], "Wj") ? '&stopcode=' . $row[5] : "") . '">'; |
echo '<p class="ui-li-aside">' . midnight_seconds_to_time($times[$key]) . '</p>'; | echo '<p class="ui-li-aside">' . midnight_seconds_to_time($times[$key]) . '</p>'; |
echo bracketsMeanNewLine($row[1]); | echo bracketsMeanNewLine($row[1]); |
echo '</a></li>'; | echo '</a></li>'; |
} | } |
} | } |
else { | else { |
// this is a duplicated line item | // this is a duplicated line item |
if ($key - 1 <= 0 || ($stops[$key][1] != $stops[$key - 1][1])) { | if ($key - 1 <= 0 || ($stops[$key][1] != $stops[$key - 1][1])) { |
// first duplicate | // first duplicate |
$stopsGrouped = Array( | $stopsGrouped = Array( |
"name" => $row[1], | "name" => $row[1], |
"startTime" => $times[$key], | "startTime" => $times[$key], |
"stop_ids" => Array( | "stop_ids" => Array( |
$row[0] | $row[0] |
) | ) |
); | ); |
} | } |
else { | else { |
// subsequent duplicates | // subsequent duplicates |
$stopsGrouped["stop_ids"][] = $row[0]; | $stopsGrouped["stop_ids"][] = $row[0]; |
$stopsGrouped["endTime"] = $times[$key]; | $stopsGrouped["endTime"] = $times[$key]; |
} | } |
} | } |
} | } |
echo '</ul>'; | echo '</ul>'; |
include_footer(); | include_footer(); |
?> | ?> |
python schedule_viewer.py --feed=/var/www/cbrfeed.zip \ | #!/bin/sh |
f=`dirname $0` | |
cd $f | |
python schedule_viewer.py --feed=/var/www/cbrfeed.zip \ | |
--key=ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q | --key=ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q |