first commit
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
|
||||
require('../lock.php');
|
||||
$lock_file = lock_pid_file();
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$member_id = 0;
|
||||
$country = 'SG';
|
||||
$timezone = 'UTC';
|
||||
$distance = 1.2; // km
|
||||
$city_id = 1; // Singapore
|
||||
$pool = 1; // Main pool - does not matter (we do not have pools here...)
|
||||
$areas_count = 28;
|
||||
|
||||
$transport_providers = [3,4,5];
|
||||
|
||||
CONST SELECT_DISTINCT_AREAS = <<< EOS
|
||||
WITH whole_hours AS (
|
||||
SELECT hour, area_start_id, area_end_id, transport_provider_id
|
||||
FROM generate_series(0, 23) hour,
|
||||
generate_series(1, $1) area_start_id,
|
||||
generate_series(1, $1) area_end_id,
|
||||
unnest(ARRAY[3,4,5]) transport_provider_id
|
||||
ORDER BY transport_provider_id, area_start_id, area_end_id, hour
|
||||
)
|
||||
SELECT DISTINCT ah.area_start_id as area_id FROM whole_hours ah
|
||||
LEFT JOIN geofence_area_average_quotes gaaq ON ah.hour = gaaq.hour
|
||||
AND ah.area_start_id = gaaq.area_start_id AND ah.area_end_id = gaaq.area_end_id AND ah.transport_provider_id =gaaq.transport_provider_id
|
||||
WHERE gaaq.hour IS NULL
|
||||
AND ah.hour = date_part('hour', timezone($2, now()))
|
||||
UNION
|
||||
SELECT DISTINCT ah.area_end_id as area_id FROM whole_hours ah
|
||||
LEFT JOIN geofence_area_average_quotes gaaq ON ah.hour = gaaq.hour
|
||||
AND ah.area_start_id = gaaq.area_start_id AND ah.area_end_id = gaaq.area_end_id AND ah.transport_provider_id =gaaq.transport_provider_id
|
||||
WHERE gaaq.hour IS NULL
|
||||
AND ah.hour = date_part('hour', timezone($2, now()))
|
||||
ORDER BY area_id
|
||||
EOS;
|
||||
|
||||
CONST SELECT_MISSED_AREAS = <<< EOS
|
||||
WITH whole_hours AS (
|
||||
SELECT hour, area_start_id, area_end_id, transport_provider_id
|
||||
FROM generate_series(0, 23) hour,
|
||||
generate_series(1, $1) area_start_id,
|
||||
generate_series(1, $1) area_end_id,
|
||||
unnest(ARRAY[3,4,5]) transport_provider_id
|
||||
ORDER BY transport_provider_id, area_start_id, area_end_id, hour
|
||||
)
|
||||
SELECT DISTINCT ah.* FROM whole_hours ah
|
||||
LEFT JOIN geofence_area_average_quotes gaaq ON ah.hour = gaaq.hour
|
||||
AND ah.area_start_id = gaaq.area_start_id AND ah.area_end_id = gaaq.area_end_id AND ah.transport_provider_id =gaaq.transport_provider_id
|
||||
WHERE gaaq.hour IS NULL
|
||||
AND ah.hour = date_part('hour', timezone($2, now()))
|
||||
ORDER BY ah.transport_provider_id, ah.area_start_id, ah.area_end_id, ah.hour
|
||||
EOS;
|
||||
|
||||
$transport_providers_param = "{".implode(",", $transport_providers). "}";
|
||||
$area_ids = [];
|
||||
$resp = pg_query_params($conn, SELECT_DISTINCT_AREAS, [
|
||||
$areas_count,
|
||||
$timezone,
|
||||
// $transport_providers_param
|
||||
]);
|
||||
if ($resp && pg_num_rows($resp)) {
|
||||
while ($row=pg_fetch_row($resp)) {
|
||||
$area_ids[] = $row[0];
|
||||
}
|
||||
}
|
||||
QuoteApi::$job_name=$job_name;
|
||||
if (count($area_ids)) {
|
||||
// Step 1 & 2: area locations
|
||||
$locations_start = [];
|
||||
$locations_end = [];
|
||||
$area_locations = [];
|
||||
$q = "SELECT id, latitude, longitude, name, boundaries FROM geofence_area WHERE country='${country}' AND city_id=${city_id} AND district='t' AND id IN (".implode (", ", $area_ids).") ORDER BY id";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$q1 = "select * from address where country='${country}' AND (%s) order by random() limit 2";
|
||||
while ($f=pg_fetch_row($r)) {
|
||||
// Singapore areas are postal!
|
||||
$b = json_decode($f[4],true); // {"postal_code":["60","61","62","63","64"]}
|
||||
$q2 = [];
|
||||
foreach ($b["postal_code"] as $code) {
|
||||
$q2[] = "LEFT(postal,".strlen($code).")='${code}'";
|
||||
}
|
||||
$r1 = pg_query($conn, sprintf($q1,implode(" OR ",$q2)));
|
||||
if ($r1 && pg_num_rows($r1)>1 && $f1=pg_fetch_assoc($r1)) {
|
||||
$locations_start[$f[0]] = $f1;
|
||||
$f1 = pg_fetch_assoc($r1);
|
||||
$locations_end[$f[0]] = $f1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$providers_areas = [];
|
||||
$resp = pg_query_params($conn, SELECT_MISSED_AREAS, [
|
||||
$areas_count,
|
||||
$timezone,
|
||||
]);
|
||||
if ($resp && pg_num_rows($resp)) {
|
||||
while ($row=pg_fetch_row($resp)) {
|
||||
|
||||
$star_area_id = $row[1];
|
||||
$end_area_id = $row[2];
|
||||
$transport_provider = $row[3];
|
||||
|
||||
if (!array_key_exists($transport_provider,$providers_areas)) {
|
||||
$providers_areas[$transport_provider] = [];
|
||||
}
|
||||
$d = distanceBetweenTwoGpsCoordinates(
|
||||
$locations_start[$star_area_id]["latitude"], $locations_start[$star_area_id]["longitude"],
|
||||
$locations_end[$end_area_id]["latitude"], $locations_end[$end_area_id]["longitude"],
|
||||
"K"
|
||||
);
|
||||
if ($locations_start[$star_area_id]["id"] != $locations_end[$end_area_id]["id"]
|
||||
&& $d > $distance || $star_area_id == $end_area_id ) {
|
||||
array_push($providers_areas[$transport_provider],
|
||||
[
|
||||
"start_area" => $locations_start[$star_area_id],
|
||||
"end_area" => $locations_end[$end_area_id]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
// echo json_encode($providers_areas, JSON_PRETTY_PRINT) .PHP_EOL;
|
||||
}
|
||||
|
||||
if (count($providers_areas) > 0) {
|
||||
// Step 4: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
foreach ($providers_areas as $provider_id => $provider_areas) {
|
||||
foreach ($provider_areas as $areas) {
|
||||
$origin_id = $areas["start_area"]["id"];
|
||||
$destination_id = $areas["end_area"]["id"];
|
||||
$origin = $areas["start_area"]["address"];
|
||||
$destination = $areas["end_area"]["address"];
|
||||
|
||||
$pool = $provider_id == 3 ? 2 : 1;
|
||||
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} ";
|
||||
$q.= " AND transport_provider_id=${provider_id} AND cost>0 AND pool=${pool} ";
|
||||
$q.= " AND completed > (now() - '1 hour'::interval) ";
|
||||
$q.= " ORDER BY completed DESC LIMIT 1";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$provider_id, 0,'t', $pool);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$provider_id\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
// Step 5: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit) {
|
||||
//error_log("public function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit)");
|
||||
if (($lat1 == $lat2) && ($lon1 == $lon2)) {
|
||||
return 0;
|
||||
}
|
||||
$theta = $lon1 - $lon2;
|
||||
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
|
||||
$dist = acos($dist);
|
||||
$dist = rad2deg($dist);
|
||||
$miles = $dist * 60 * 1.1515;
|
||||
$unit = strtoupper($unit);
|
||||
if ($unit == "K") {
|
||||
return ($miles * 1.609344);
|
||||
}
|
||||
if ($unit == "N") {
|
||||
($miles * 0.8684);
|
||||
}
|
||||
return $miles;
|
||||
}
|
||||
|
||||
unlock_pid_file($lock_file);
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$country = 'SG';
|
||||
$member_id = 0;
|
||||
|
||||
// ComfortDelGro & Gojek
|
||||
$transport_providers = [4,5];
|
||||
// Grab
|
||||
//$transport_providers = [3];
|
||||
|
||||
// Step 1: Load batch files
|
||||
$origins = load_batch_file("batch_quote_file_origins.txt");
|
||||
$destinations = load_batch_file("batch_quote_file_destinations.txt");
|
||||
|
||||
// Step 2: Geocode addresses
|
||||
$newOrigins = geocode_addresses($origins);
|
||||
$newDestinations = geocode_addresses($destinations);
|
||||
|
||||
// Step 3: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
QuoteApi::$job_name = $job_name;
|
||||
foreach ($newOrigins as $origin_id=>$origin) {
|
||||
foreach ($newDestinations as $destination_id=>$destination) {
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 ";
|
||||
$q.= " ORDER BY completed DESC LIMIT 1";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$transport_provider);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
function load_batch_file($filename) {
|
||||
$results = [];
|
||||
$fn = fopen($filename,"r");
|
||||
while(! feof($fn)) {
|
||||
$result = fgets($fn);
|
||||
$results[] = trim($result);
|
||||
}
|
||||
fclose($fn);
|
||||
return $results;
|
||||
}
|
||||
|
||||
function geocode_addresses($addresses) {
|
||||
$geocodedAddresses = [];
|
||||
foreach ($addresses as $address) {
|
||||
$params = [
|
||||
"address" => $address,
|
||||
"member_id" => 0,
|
||||
"country" => "SG"
|
||||
];
|
||||
$input = http_build_query($params);
|
||||
list($payload,$decrypted,$result,$body) = main_api_get('/trips/api/geocode/?',$input);
|
||||
if (is_array($payload) && array_key_exists('geocode',$payload) && is_array($payload['geocode'])
|
||||
&& array_key_exists('id',$payload['geocode']) && $payload['geocode']['id']>0) {
|
||||
$geocodedAddresses[$payload['geocode']['id']] = $payload['geocode']['address'];
|
||||
}
|
||||
}
|
||||
return $geocodedAddresses;
|
||||
}
|
||||
|
||||
function main_api_get($endpoint,$input) {
|
||||
global $baseURL, $encryptionAlg, $encryptionKey, $encryptionIV, $httpAuthToken;
|
||||
if ($endpoint!="" && $input!="") { // minimal sanity
|
||||
sleep(1);
|
||||
$url = $baseURL . $endpoint . $input;
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Server-Token ' . $httpAuthToken,
|
||||
"client_id: BATCH"
|
||||
)
|
||||
);
|
||||
|
||||
$body = curl_exec($ch);
|
||||
$result = json_decode($body,true);
|
||||
|
||||
$decrypted = openssl_decrypt(
|
||||
hex2bin(
|
||||
$result['payload']
|
||||
),
|
||||
$encryptionAlg,
|
||||
$encryptionKey,
|
||||
OPENSSL_RAW_DATA,
|
||||
$encryptionIV
|
||||
);
|
||||
$payload = json_decode($decrypted, true);
|
||||
return [$payload,$decrypted,$result,$body];
|
||||
}
|
||||
return [NULL,NULL,NULL,NULL];
|
||||
}
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$country = 'SG';
|
||||
$member_id = 0;
|
||||
|
||||
// ComfortDelGro & Gojek
|
||||
$transport_providers = [4,5];
|
||||
// Grab
|
||||
$transport_providers = [3];
|
||||
QuoteApi::$job_name = $job_name;
|
||||
$q = "select id,automation_id from quotes where id>=11462 and id<=13761 and (cost<1 or cost is null)";
|
||||
$q = "select id,automation_id from quotes where id>=11462 and id<=13761 and (cost<1 or cost is null)";
|
||||
$r = pg_query($conn,$q);
|
||||
|
||||
while ($f=pg_fetch_assoc($r)) {
|
||||
list($res,$cost) = QuoteApi::check_quote($f["id"]);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$f["id"]."/".$f["automation_id"]." => ".$cost."\n";
|
||||
}
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
Dempsey Hill, Dempsey Rd, #03-01 Blk 8D, Singapore 249679
|
||||
Botanic Gardens Mansion, 18 Taman Serasi, Singapore 257722
|
||||
Bandstand - Singapore Botanic Gardens, 6 Cluny Rd, Singapore 259573
|
||||
Palm Valley Gate, Tyersall Rd, Singapore
|
||||
Botanic Gardens Nassim Gate, 1B Cluny Rd, Singapore 259598
|
||||
IKEA Alexandra, 317 Alexandra Rd, Singapore 159965
|
||||
Anchorpoint Shopping Centre, 370 Alexandra Rd, Singapore 159953
|
||||
ABC Brickworks, 6 Jalan Bukit Merah, Singapore 150006
|
||||
Depot Road Zhen Shan Mei Claypot Laksa, 119 Bukit Merah Lane 1, #01-75 Fine Taste Eating House, Singapore 151119
|
||||
Alexandra Village, 1009 Bukit Merah Lane 3, Singapore 159723
|
||||
Haw Par Villa, 262 Pasir Panjang Rd, Singapore 118628
|
||||
TeleTech Park, 20 Science Park Rd, Singapore 117674
|
||||
Kopitiam, 1 Wholesale Centre #01-02 Blk, 1 Pasir Panjang Rd, Singapore 110001
|
||||
Zenxin Organic Food Singapore @ Pasir Panjang, 14 Pasir Panjang, #01-25, Wholesale Centre, Singapore 110014
|
||||
Queenstown MRT, 301 Commonwealth Ave, Singapore 149729
|
||||
Mr Bean, 301 Commonwealth Ave, #02-05, Singapore 149729
|
||||
Mei Ling Market & Food Centre, 159 Mei Ling St, Singapore 140159
|
||||
Vivarch Enrichment Group, Cendex Centre, 120 Lower Delta Rd, #12-13, Singapore 169208
|
||||
Connection One, 169 Bukit Merah Central, Singapore
|
||||
Redhill Market, 81 Redhill Ln, Singapore 150081
|
||||
Tiong Bahru MRT Station, 300 Tiong Bahru Rd, Singapore 168731
|
||||
SAFRA Mount Faber, 2 Telok Blangah Way, Singapore 098803
|
||||
LifestyleMart, 2 Telok Blangah Way, #02-07 SAFRA Mount Faber, Singapore 098803
|
||||
Giant Express Telok Blangah 8, #01-171 Telok Blangah Cres, Block 8, Singapore 090008
|
||||
Vivo City, 1 Harbourfront Walk, Singapore 098585
|
||||
HarbourFront Centre, 2 Maritime Square, Singapore 099255
|
||||
Seah Im Food Centre, 2 Seah Im Rd, Singapore 099114
|
||||
Harbourlights, 66 Telok Blangah Rd, Singapore 098830
|
||||
85 Redhill Ln, Singapore 150085
|
||||
SIME DARBY BUSINESS CENTRE, 315 Alexandra Rd
|
||||
Alexandra Hospital, 378 Alexandra Rd, Singapore 159964
|
||||
Everlast @ Queensway Shopping Centre, Queensway Shopping Center #01-23, 1 Queensway, Singapore 149053
|
||||
Block 79, 79 Ayer Rajah Crescent
|
||||
MDIS Campus, 501 Stirling Rd, Singapore 148951
|
||||
The Cheese Ark, 49 Stirling Rd, #01-489, Singapore 141049
|
||||
Tanglin Halt Neighbourhood Centre Historical Marker
|
||||
Sheng Siong, 88 Tanglin Halt Rd, Singapore 141088
|
||||
One North Station, 9 Ayer Rajah Avenue Singapore 138647 Ayer Rajah Ave, Singapore 138647
|
||||
Timbre+, 73A Ayer Rajah Crescent, JTC Launchpad, Singapore 139957
|
||||
Two Chefs Eating Place, 116 Commonwealth Cres, #01-129
|
||||
Dempsey Hill, Dempsey Rd, #03-01 Blk 8D, Singapore 249679
|
||||
Morsels, 25, #01-04 Dempsey Rd, Singapore 249670
|
||||
Huber's Butchery, 22 Dempsey Rd, Singapore 249679
|
||||
Raffles Holland V Mall, 118 Holland Ave, Singapore 278973
|
||||
The Nailist - Holland Road Shopping Centre, 211 Holland Avenue, Holland Rd, #03-31/32 Shopping centre, Singapore 278967
|
||||
Holland Village MRT Station, 200 Holland Avenue Singapore 278995 Holland Avenue, Singapore 278995
|
||||
Kai Life, Holland Avenue, 211 Holland Rd, #02-04 Shopping Centre, Singapore 278967
|
||||
Sunday Folks, 44 Jln Merah Saga, #01-52 Chip Bee Gardens, Singapore 278116
|
||||
Daily Scoop @ Chip Bee Garden, 70 Jln Merah Saga, 80, Singapore 278129
|
||||
Holland Drive Market and Food Centre, 44 Holland Dr, Singapore 270044
|
||||
Chip Bee Gardens, 43 Jln Merah Saga, Singapore 278115
|
||||
My Cosy Corner, 587 Bukit Timah Rd, #02-02 Coronation Plaza, Singapore 269707
|
||||
Singapore University of Social Sciences, 463 Clementi Rd, Blk C, Singapore 599494
|
||||
The Grandstand, 200 Turf Club Rd, Singapore 287994
|
||||
Premier Pitch Indoor, 200 Turf Club Road, Plot 9, Singapore 287994
|
||||
SkyPark Arena @ King Albert Park, 896 Dunearn Rd, #05-03 Tuan Sing Holdings, Singapore 589472
|
||||
Watsons Singapore, 1 Jalan Anak Bukit, Bukit Timah West, #B1-57, Singapore 588996
|
||||
Anytime Fitness Bukit Timah, Upper Bukit Timah Rd, #B1-01 Shopping Centre, Singapore 588179
|
||||
EQUIP, 78 Rifle Range Rd, Singapore 588384
|
||||
Sime Darby Centre, 896 Dunearn Rd, Singapore 589472
|
||||
Chin Huat, #01 Clementi Street 12, 30 zhizu massage centre, Singapore 120105
|
||||
West Coast Plaza, 154 West Coast Rd, Singapore 127371
|
||||
Sheng Siong, #01-144 Clementi West Street 2, Blk 720, Singapore 120720
|
||||
McDonald’s West Coast Park, 71 W Coast Ave, Singapore 126844
|
||||
Ayer Rajah Food Centre, W Coast Dr, Blk 503, Singapore 120503
|
||||
West Bowl Bowling, 12 W Coast Walk, Singapore 127157
|
||||
The Clementi Mall, 3155 Commonwealth Ave W, Singapore 129588
|
||||
Popular Bookstore, 2 Jurong East Street 21, #02-36 IMM Building, Singapore 609601
|
||||
Books Kinokuniya Jurong Store, 50 Jurong Gateway Rd, #04-23 JEM, Singapore 608549
|
||||
Westgate, 3 Gateway Dr, Singapore 608532
|
||||
Beng Hiang Restaurant, 135 Jurong Gateway Rd, #02-337, Singapore 600135
|
||||
Science Centre Singapore, 15 Science Centre Rd, Singapore 609081
|
||||
IMM, 2 Jurong East Street 21, Singapore 609601
|
||||
Sofzsleep, 21 Bukit Batok Cres, #24-82 Wecga Tower, Singapore 658065
|
||||
1345 Mookata, 25 Bukit Batok Crescent, Singapore 658077
|
||||
CopyPrinter Pte Ltd, Bukit Batok Cres, #09-04 Enterprise Center, No 20, Singapore 658080
|
||||
Unity Centre, 51 Bukit Batok Cres, Singapore 658077
|
||||
Acacia Lodge, 530-540 Bukit Batok Street 23, Singapore 659548
|
||||
West Mall, 1 Bukit Batok Central Link, Singapore 658713
|
||||
Bukit Batok MRT, 10 Bukit Batok Central, Singapore 659958
|
||||
Singapore Pools (Bukit Batok Central Branch), 642 Bukit Batok Central, #01-56, Singapore 188994
|
||||
McDonald's, 256 Jurong East Street 24, Singapore 600256
|
||||
Yuhua Village Market and Food Centre, 254 Jurong East Street 24, Singapore 600254
|
||||
Zai Shun Curry Fish Head, 253 Jurong East Street 24, #01-205, Singapore 600253
|
||||
@@ -0,0 +1,30 @@
|
||||
3 Conservatory Drive, Singapore 117376
|
||||
9 Engineering Drive 1, #07-26 EA, Singapore 117575
|
||||
4 Engineering Drive 3, Singapore 117583
|
||||
2 Engineering Drive 4, NUS Information Technology, Singapore 117584
|
||||
4 Architecture Dr, Singapore 117566 Architecture Dr, Singapore 117566
|
||||
4 Engineering Drive 4, Blk E5 #02-09, Singapore 117585 Engineering Drive 4, Singapore 117585
|
||||
12 Kent Ridge Cres, Singapore 119275
|
||||
11 Arts Link, #03-06 AS1, Singapore 117573
|
||||
3 Arts Link, Level 4 AS3, Singapore 117569
|
||||
5 Arts Link Block AS7, Level 5 The, Shaw Foundation Building, Singapore 117570
|
||||
9 Kent Ridge Dr, Singapore 119241
|
||||
15 Computing Dr, Singapore 117418
|
||||
3 Research Link, Singapore 117602
|
||||
15 Kent Ridge Dr, Singapore 119245
|
||||
21 Heng Mui Keng Terrace, Singapore 119613
|
||||
30 Heng Mui Keng Terrace, Singapore 119614
|
||||
29 Heng Mui Keng Terrace, Block D & E, Singapore 119620
|
||||
11 Science Park Rd, Singapore 117685
|
||||
27 Prince George's Park, National University of Singapore, Singapore 118425
|
||||
15 Prince George's Park, Singapore 118414
|
||||
1 Research Link, Singapore 117604
|
||||
31 Lower Kent Ridge Rd, Singapore 119078
|
||||
50 Kent Ridge Cres, Singapore 119279
|
||||
30 Lower Kent Ridge Rd, Singapore 119075
|
||||
21 Lower Kent Ridge Rd, Singapore 119077
|
||||
12 Science Drive 2, Singapore 117549
|
||||
10 Lower Kent Ridge Rd, Singapore 119076
|
||||
28 Medical Dr, Singapore 117456
|
||||
1E Kent Ridge Rd, Singapore 119228
|
||||
70 South Buona Vista Rd, Singapore 118176
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$member_id = 0;
|
||||
$country = 'SG';
|
||||
$timezone = 1; // Asia/Singapore
|
||||
$distance = 2; // km
|
||||
$top_count = 15;
|
||||
|
||||
#Grab, ComfortDelGro, GOJEK
|
||||
$transport_providers = [3,4,5];
|
||||
$transport_providers = [4,5];
|
||||
|
||||
// Step 1: top 15 start locations
|
||||
$locations_start = [];
|
||||
$q = "SELECT COUNT(*) AS num, ROUND(b.latitude,2) AS lat, ROUND(b.longitude,2) AS lng ";
|
||||
$q.= " FROM parsedemail_item a LEFT JOIN address b ON b.id=a.location_start_id ";
|
||||
$q.= " WHERE b.timezone=${timezone} AND a.private='f' AND dup_id IS NULL ";
|
||||
$q.= " GROUP BY b.latitude, b.longitude ORDER BY num DESC LIMIT ${top_count}";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$q1 = "select * from address where round(latitude,2)=%0.02f and round(longitude,2)=%0.02f order by random() limit 1";
|
||||
while ($f=pg_fetch_row($r)) {
|
||||
$r1 = pg_query($conn, sprintf($q1,$f[1],$f[2]));
|
||||
if ($r1 && pg_num_rows($r1) && $f1=pg_fetch_assoc($r1)) {
|
||||
$locations_start[] = $f1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: top 15 end locations
|
||||
$locations_end = [];
|
||||
$q = "SELECT COUNT(*) AS num, ROUND(b.latitude,2) AS lat, ROUND(b.longitude,2) AS lng ";
|
||||
$q.= " FROM parsedemail_item a LEFT JOIN address b ON b.id=a.location_end_id ";
|
||||
$q.= " WHERE b.timezone=${timezone} AND a.private='f' AND dup_id IS NULL ";
|
||||
$q.= " GROUP BY b.latitude, b.longitude ORDER BY num DESC LIMIT ${top_count}";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$q1 = "select * from address where round(latitude,2)=%0.02f and round(longitude,2)=%0.02f order by random() limit 1";
|
||||
while ($f=pg_fetch_row($r)) {
|
||||
$r1 = pg_query($conn, sprintf($q1,$f[1],$f[2]));
|
||||
if ($r1 && pg_num_rows($r1) && $f1=pg_fetch_assoc($r1)) {
|
||||
$locations_end[] = $f1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Step 3: distance between locations (if makes sense to quote)
|
||||
$pairs = [];
|
||||
foreach ($locations_start as $location_start) {
|
||||
foreach ($locations_end as $location_end) {
|
||||
// Spheroid function in PHP to speed up
|
||||
$d = distanceBetweenTwoGpsCoordinates(
|
||||
$location_start["latitude"], $location_start["longitude"],
|
||||
$location_end["latitude"], $location_end["longitude"],
|
||||
"K"
|
||||
);
|
||||
if ($d>$distance) {
|
||||
$pairs[] = [$location_start, $location_end];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
QuoteApi::$job_name = $job_name;
|
||||
foreach ($pairs as list($location_start, $location_end)) {
|
||||
$origin_id = $location_start["id"];
|
||||
$destination_id = $location_end["id"];
|
||||
$origin = $location_start["address"];
|
||||
$destination = $location_end["address"];
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 ";
|
||||
$q.= " AND completed>(current_date-1) ";
|
||||
$q.= " ORDER BY completed DESC LIMIT 1";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$transport_provider);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 5: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit) {
|
||||
//error_log("public function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit)");
|
||||
if (($lat1 == $lat2) && ($lon1 == $lon2)) {
|
||||
return 0;
|
||||
}
|
||||
$theta = $lon1 - $lon2;
|
||||
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
|
||||
$dist = acos($dist);
|
||||
$dist = rad2deg($dist);
|
||||
$miles = $dist * 60 * 1.1515;
|
||||
$unit = strtoupper($unit);
|
||||
if ($unit == "K") {
|
||||
return ($miles * 1.609344);
|
||||
}
|
||||
if ($unit == "N") {
|
||||
($miles * 0.8684);
|
||||
}
|
||||
return $miles;
|
||||
}
|
||||
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
require('../lock.php');
|
||||
$lock_file = lock_pid_file();
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$member_id = 0;
|
||||
$country = 'US';
|
||||
$timezone = 2; // America/Los_Angeles
|
||||
$distance = 2; // km
|
||||
$city_id = 1096; // San Francisco
|
||||
$pool = 2; // Dedicated pool
|
||||
|
||||
$transport_providers = [1,2]; // Uber, Lyft
|
||||
|
||||
// Step 1: start locations
|
||||
$locations_start = [];
|
||||
$q = "SELECT id,latitude,longitude,name FROM geofence_area WHERE country='${country}' AND city_id=${city_id} AND district='t' ORDER BY id";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$q1 = "select * from address where round(latitude,2)=%0.02f and round(longitude,2)=%0.02f order by random() limit 1";
|
||||
while ($f=pg_fetch_row($r)) {
|
||||
$r1 = pg_query($conn, sprintf($q1,$f[1],$f[2]));
|
||||
if ($r1 && pg_num_rows($r1) && $f1=pg_fetch_assoc($r1)) {
|
||||
$locations_start[$f[0].'_'.$f[3]] = $f1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: end locations
|
||||
$locations_end = $locations_start;
|
||||
|
||||
// Step 3: distance between locations (if makes sense to quote)
|
||||
$pairs = [];
|
||||
foreach ($locations_start as $location_start) {
|
||||
foreach ($locations_end as $location_end) {
|
||||
// Spheroid function in PHP to speed up
|
||||
$d = distanceBetweenTwoGpsCoordinates(
|
||||
$location_start["latitude"], $location_start["longitude"],
|
||||
$location_end["latitude"], $location_end["longitude"],
|
||||
"K"
|
||||
);
|
||||
/* if ($d>$distance) {
|
||||
$pairs[] = [$location_start, $location_end];
|
||||
}//*/
|
||||
if ($location_start["id"]!=$location_end["id"]) {
|
||||
$pairs[] = [$location_start, $location_end];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
QuoteApi::$job_name=$job_name;
|
||||
foreach ($pairs as list($location_start, $location_end)) {
|
||||
$origin_id = $location_start["id"];
|
||||
$destination_id = $location_end["id"];
|
||||
$origin = $location_start["address"];
|
||||
$destination = $location_end["address"];
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 AND pool=${pool}";
|
||||
//$q.= " AND completed>(current_date-1) ";
|
||||
$q.= " AND completed>(now() - '1 hour'::interval) ";
|
||||
$q.= " ORDER BY completed DESC LIMIT 1";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$transport_provider, 0,'t',$pool);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 5: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit) {
|
||||
//error_log("public function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit)");
|
||||
if (($lat1 == $lat2) && ($lon1 == $lon2)) {
|
||||
return 0;
|
||||
}
|
||||
$theta = $lon1 - $lon2;
|
||||
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
|
||||
$dist = acos($dist);
|
||||
$dist = rad2deg($dist);
|
||||
$miles = $dist * 60 * 1.1515;
|
||||
$unit = strtoupper($unit);
|
||||
if ($unit == "K") {
|
||||
return ($miles * 1.609344);
|
||||
}
|
||||
if ($unit == "N") {
|
||||
($miles * 0.8684);
|
||||
}
|
||||
return $miles;
|
||||
}
|
||||
|
||||
|
||||
unlock_pid_file($lock_file);
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
require('../lock.php');
|
||||
$lock_file = lock_pid_file();
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$member_id = 0;
|
||||
$country = 'US';
|
||||
$timezone = 2; // America/Los_Angeles
|
||||
$distance = 2; // km
|
||||
$city_id = 1096; // San Francisco
|
||||
$pool = 2; // Dedicated pool
|
||||
|
||||
$transport_providers = [8]; // Autocab
|
||||
|
||||
// Step 1: start locations
|
||||
$locations_start = [];
|
||||
$q = "SELECT id,latitude,longitude,name FROM geofence_area WHERE country='${country}' AND city_id=${city_id} AND district='t' ORDER BY id";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$q1 = "select * from address where round(latitude,2)=%0.02f and round(longitude,2)=%0.02f order by random() limit 1";
|
||||
while ($f=pg_fetch_row($r)) {
|
||||
$r1 = pg_query($conn, sprintf($q1,$f[1],$f[2]));
|
||||
if ($r1 && pg_num_rows($r1) && $f1=pg_fetch_assoc($r1)) {
|
||||
$locations_start[$f[0].'_'.$f[3]] = $f1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: end locations
|
||||
$locations_end = $locations_start;
|
||||
|
||||
// Step 3: distance between locations (if makes sense to quote)
|
||||
$pairs = [];
|
||||
foreach ($locations_start as $location_start) {
|
||||
foreach ($locations_end as $location_end) {
|
||||
// Spheroid function in PHP to speed up
|
||||
$d = distanceBetweenTwoGpsCoordinates(
|
||||
$location_start["latitude"], $location_start["longitude"],
|
||||
$location_end["latitude"], $location_end["longitude"],
|
||||
"K"
|
||||
);
|
||||
/* if ($d>$distance) {
|
||||
$pairs[] = [$location_start, $location_end];
|
||||
}//*/
|
||||
if ($location_start["id"]!=$location_end["id"]) {
|
||||
$pairs[] = [$location_start, $location_end];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
QuoteApi::$job_name=$job_name;
|
||||
foreach ($pairs as list($location_start, $location_end)) {
|
||||
$origin_id = $location_start["id"];
|
||||
$destination_id = $location_end["id"];
|
||||
$origin = $location_start["address"];
|
||||
$destination = $location_end["address"];
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 AND pool=${pool}";
|
||||
//$q.= " AND completed>(current_date-1) ";
|
||||
$q.= " AND completed>(now() - '1 hour'::interval) ";
|
||||
$q.= " ORDER BY completed DESC LIMIT 1";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$transport_provider, 0,'t',$pool);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 5: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit) {
|
||||
//error_log("public function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit)");
|
||||
if (($lat1 == $lat2) && ($lon1 == $lon2)) {
|
||||
return 0;
|
||||
}
|
||||
$theta = $lon1 - $lon2;
|
||||
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
|
||||
$dist = acos($dist);
|
||||
$dist = rad2deg($dist);
|
||||
$miles = $dist * 60 * 1.1515;
|
||||
$unit = strtoupper($unit);
|
||||
if ($unit == "K") {
|
||||
return ($miles * 1.609344);
|
||||
}
|
||||
if ($unit == "N") {
|
||||
($miles * 0.8684);
|
||||
}
|
||||
return $miles;
|
||||
}
|
||||
|
||||
|
||||
unlock_pid_file($lock_file);
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
|
||||
require('../lock.php');
|
||||
$lock_file = lock_pid_file();
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
$member_id = 0;
|
||||
$country = 'SG';
|
||||
$timezone = 1; // Asia/Singapore
|
||||
$distance = 1.2; // km
|
||||
$city_id = 1; // Singapore
|
||||
$pool = 1; // Main pool - does not matter (we do not have pools here...)
|
||||
|
||||
//$transport_providers = [3,4,5]; // Grab, ComfortDelGro, Gojek
|
||||
$transport_providers = [4,5]; // ComfortDelGro, Gojek
|
||||
|
||||
// Step 1 & 2: start & end locations
|
||||
$locations_start = [];
|
||||
$locations_end = [];
|
||||
$q = "SELECT id,latitude,longitude,name,boundaries FROM geofence_area WHERE country='${country}' AND city_id=${city_id} AND district='t' ORDER BY id";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$q1 = "select * from address where country='${country}' AND (%s) order by random() limit 2";
|
||||
while ($f=pg_fetch_row($r)) {
|
||||
// Singapore areas are postal!
|
||||
$b = json_decode($f[4],true); // {"postal_code":["60","61","62","63","64"]}
|
||||
$q2 = [];
|
||||
foreach ($b["postal_code"] as $code) {
|
||||
$q2[] = "LEFT(postal,".strlen($code).")='${code}'";
|
||||
}
|
||||
$r1 = pg_query($conn, sprintf($q1,implode(" OR ",$q2)));
|
||||
if ($r1 && pg_num_rows($r1)>1 && $f1=pg_fetch_assoc($r1)) {
|
||||
$locations_start[$f[0].'_'.$f[3]] = $f1;
|
||||
$f1 = pg_fetch_assoc($r1);
|
||||
$locations_end[$f[0].'_'.$f[3]] = $f1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: distance between locations (if makes sense to quote)
|
||||
$pairs = [];
|
||||
foreach ($locations_start as $location_start) {
|
||||
foreach ($locations_end as $location_end) {
|
||||
// Spheroid function in PHP to speed up
|
||||
$d = distanceBetweenTwoGpsCoordinates(
|
||||
$location_start["latitude"], $location_start["longitude"],
|
||||
$location_end["latitude"], $location_end["longitude"],
|
||||
"K"
|
||||
);
|
||||
/* if ($d>$distance) {
|
||||
$pairs[] = [$location_start, $location_end];
|
||||
}//*/
|
||||
if ($location_start["id"]!=$location_end["id"] && $d>$distance) {
|
||||
$pairs[] = [$location_start, $location_end];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
QuoteApi::$job_name = $job_name;
|
||||
foreach ($pairs as list($location_start, $location_end)) {
|
||||
$origin_id = $location_start["id"];
|
||||
$destination_id = $location_end["id"];
|
||||
$origin = $location_start["address"];
|
||||
$destination = $location_end["address"];
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 AND pool=${pool}";
|
||||
//$q.= " AND completed>(current_date-1) ";
|
||||
$q.= " AND completed>(now() - '1 hour'::interval) ";
|
||||
$q.= " ORDER BY completed DESC LIMIT 1";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$transport_provider, 0,'t', $pool);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 5: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit) {
|
||||
//error_log("public function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit)");
|
||||
if (($lat1 == $lat2) && ($lon1 == $lon2)) {
|
||||
return 0;
|
||||
}
|
||||
$theta = $lon1 - $lon2;
|
||||
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
|
||||
$dist = acos($dist);
|
||||
$dist = rad2deg($dist);
|
||||
$miles = $dist * 60 * 1.1515;
|
||||
$unit = strtoupper($unit);
|
||||
if ($unit == "K") {
|
||||
return ($miles * 1.609344);
|
||||
}
|
||||
if ($unit == "N") {
|
||||
($miles * 0.8684);
|
||||
}
|
||||
return $miles;
|
||||
}
|
||||
|
||||
unlock_pid_file($lock_file);
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
|
||||
require('../lock.php');
|
||||
$lock_file = lock_pid_file();
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$member_id = 0;
|
||||
$country = 'SG';
|
||||
$timezone = 1; // Asia/Singapore
|
||||
$distance = 1.2; // km
|
||||
$city_id = 1; // Singapore
|
||||
$pool = 2; // Second pool
|
||||
|
||||
$transport_providers = [3]; // Grab
|
||||
|
||||
// Step 1 & 2: start & end locations
|
||||
$locations_start = [];
|
||||
$locations_end = [];
|
||||
$q = "SELECT id,latitude,longitude,name,boundaries FROM geofence_area WHERE country='${country}' AND city_id=${city_id} AND district='t' ORDER BY id";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$q1 = "select * from address where country='${country}' AND (%s) order by random() limit 2";
|
||||
while ($f=pg_fetch_row($r)) {
|
||||
// Singapore areas are postal!
|
||||
$b = json_decode($f[4],true); // {"postal_code":["60","61","62","63","64"]}
|
||||
$q2 = [];
|
||||
foreach ($b["postal_code"] as $code) {
|
||||
$q2[] = "LEFT(postal,".strlen($code).")='${code}'";
|
||||
}
|
||||
$r1 = pg_query($conn, sprintf($q1,implode(" OR ",$q2)));
|
||||
if ($r1 && pg_num_rows($r1)>1 && $f1=pg_fetch_assoc($r1)) {
|
||||
$locations_start[$f[0].'_'.$f[3]] = $f1;
|
||||
$f1 = pg_fetch_assoc($r1);
|
||||
$locations_end[$f[0].'_'.$f[3]] = $f1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: distance between locations (if makes sense to quote)
|
||||
$pairs = [];
|
||||
foreach ($locations_start as $location_start) {
|
||||
foreach ($locations_end as $location_end) {
|
||||
// Spheroid function in PHP to speed up
|
||||
$d = distanceBetweenTwoGpsCoordinates(
|
||||
$location_start["latitude"], $location_start["longitude"],
|
||||
$location_end["latitude"], $location_end["longitude"],
|
||||
"K"
|
||||
);
|
||||
/* if ($d>$distance) {
|
||||
$pairs[] = [$location_start, $location_end];
|
||||
}//*/
|
||||
if ($location_start["id"]!=$location_end["id"] && $d>$distance) {
|
||||
$pairs[] = [$location_start, $location_end];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
QuoteApi::$job_name=$job_name;
|
||||
foreach ($pairs as list($location_start, $location_end)) {
|
||||
$origin_id = $location_start["id"];
|
||||
$destination_id = $location_end["id"];
|
||||
$origin = $location_start["address"];
|
||||
$destination = $location_end["address"];
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 AND pool=${pool}";
|
||||
//$q.= " AND completed>(current_date-1) ";
|
||||
$q.= " AND completed>(now() - '1 hour'::interval) ";
|
||||
$q.= " ORDER BY completed DESC LIMIT 1";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$transport_provider,0,'t',$pool);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 5: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit) {
|
||||
//error_log("public function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit)");
|
||||
if (($lat1 == $lat2) && ($lon1 == $lon2)) {
|
||||
return 0;
|
||||
}
|
||||
$theta = $lon1 - $lon2;
|
||||
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
|
||||
$dist = acos($dist);
|
||||
$dist = rad2deg($dist);
|
||||
$miles = $dist * 60 * 1.1515;
|
||||
$unit = strtoupper($unit);
|
||||
if ($unit == "K") {
|
||||
return ($miles * 1.609344);
|
||||
}
|
||||
if ($unit == "N") {
|
||||
($miles * 0.8684);
|
||||
}
|
||||
return $miles;
|
||||
}
|
||||
|
||||
|
||||
unlock_pid_file($lock_file);
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] batch_quote_singapore_districts job complete.\n";
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$country = 'SG';
|
||||
$member_id = 0;
|
||||
|
||||
// Grab, ComfortDelGro & Gojek
|
||||
$transport_providers = [/*3,*/4,5];
|
||||
|
||||
// Step 1: Load trips
|
||||
$q = "select b.*,c.address AS origin, d.address AS destination ";
|
||||
$q.= " from (select root_id,count(*) as count from trip_price_comparison where root_type=1 group by root_id) as a, ";
|
||||
$q.= " parsedemail_item b, address c, address d ";
|
||||
$q.= " where a.count=1 and b.id=a.root_id and b.private='f' and c.id=b.location_start_id and d.id=b.location_end_id and c.country='${country}' ";
|
||||
$q.= " and b.dup_id is null ";
|
||||
$q.= " order by b.travel_date desc";
|
||||
echo $q."\n";
|
||||
//exit();
|
||||
$r = pg_query($conn, $q);
|
||||
|
||||
// Step 3: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
|
||||
QuoteApi::$job_name=$job_name;
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$n = pg_num_rows($r);
|
||||
echo "[".date("Y-m-d H:i:s")."] Processing ".$n." trips.\n";
|
||||
$i = 0;
|
||||
while ($f = pg_fetch_assoc($r)) {
|
||||
$i++;
|
||||
echo "[".date("Y-m-d H:i:s")."] Processing ${i}/${n} (".sprintf("%0.02f",100.0*$i/$n).") trip id=".$f["id"].".\n";
|
||||
if ($f["location_start_id"]==$f["location_end_id"]) continue;
|
||||
$location_start_id=$f["location_start_id"];
|
||||
$location_end_id=$f["location_end_id"];
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${location_start_id} AND location_end_id=${location_end_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 ";
|
||||
$q.= " AND completed>(current_date-1) ORDER BY completed DESC LIMIT 1";
|
||||
$quotes = pg_query($conn, $q);
|
||||
if ($quotes && pg_num_rows($quotes) && $quote=pg_fetch_assoc($quotes)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$quote["cost"]." already exists ID #".$quote["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($f["origin"],$f["destination"],$country,$member_id,$transport_provider);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$country = 'US';
|
||||
$member_id = 0;
|
||||
|
||||
// Uber & Lyft
|
||||
$transport_providers = [1,2];
|
||||
|
||||
// Step 1: Load trips
|
||||
$q = "select b.*,c.address AS origin, d.address AS destination ";
|
||||
$q.= " from (select root_id,count(*) as count from trip_price_comparison where root_type=1 group by root_id) as a, ";
|
||||
$q.= " parsedemail_item b, address c, address d ";
|
||||
$q.= " where a.count=1 and b.id=a.root_id and b.private='f' and c.id=b.location_start_id and d.id=b.location_end_id and c.country='${country}' ";
|
||||
$q.= " and b.dup_id is null ";
|
||||
$q.= " order by b.travel_date desc";
|
||||
$r = pg_query($conn, $q);
|
||||
|
||||
// Step 3: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
QuoteApi::$job_name = $job_name;
|
||||
if ($r && pg_num_rows($r)) {
|
||||
$n = pg_num_rows($r);
|
||||
echo "[".date("Y-m-d H:i:s")."] Processing ".$n." trips.\n";
|
||||
$i = 0;
|
||||
while ($f = pg_fetch_assoc($r)) {
|
||||
$i++;
|
||||
echo "[".date("Y-m-d H:i:s")."] Processing ${i}/${n} (".sprintf("%0.02f",100.0*$i/$n).") trip id=".$f["id"].".\n";
|
||||
if ($f["location_start_id"]==$f["location_end_id"]) continue;
|
||||
$location_start_id=$f["location_start_id"];
|
||||
$location_end_id=$f["location_end_id"];
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${location_start_id} AND location_end_id=${location_end_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 ";
|
||||
$q.= " AND completed>(current_date-1) ORDER BY completed DESC LIMIT 1";
|
||||
$quotes = pg_query($conn, $q);
|
||||
if ($quotes && pg_num_rows($quotes) && $quote=pg_fetch_assoc($quotes)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$quote["cost"]." already exists ID #".$quote["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($f["origin"],$f["destination"],$country,$member_id,$transport_provider);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$country = 'SG';
|
||||
$member_id = 0;
|
||||
|
||||
// Grab, ComfortDelGro & Gojek
|
||||
$transport_providers = [/*3,*/4,5];
|
||||
|
||||
// Step 1: Load batch file
|
||||
$attractions = load_batch_file("batch_quote_tourist_attractions.txt");
|
||||
|
||||
// Step 2: Geocode addresses
|
||||
$newOrigins = geocode_addresses($attractions);
|
||||
|
||||
// Step 3: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
QuoteApi::$job_name = $job_name;
|
||||
foreach ($newOrigins as $origin_id=>$origin) {
|
||||
foreach ($newOrigins as $destination_id=>$destination) {
|
||||
if ($origin_id==$destination_id) continue;
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 ";
|
||||
$q.= " AND completed>(current_date-1) ORDER BY completed DESC LIMIT 1";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$transport_provider);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
function load_batch_file($filename) {
|
||||
$results = [];
|
||||
$fn = fopen($filename,"r");
|
||||
while(! feof($fn)) {
|
||||
$result = fgets($fn);
|
||||
$results[strtok($result,"\t")] = trim(strtok("\t"));
|
||||
}
|
||||
fclose($fn);
|
||||
return $results;
|
||||
}
|
||||
|
||||
function geocode_addresses($addresses) {
|
||||
global $conn;
|
||||
$geocodedAddresses = [];
|
||||
foreach ($addresses as $desc=>$address) {
|
||||
$params = [
|
||||
"address" => $address,
|
||||
"member_id" => 0,
|
||||
"country" => "SG"
|
||||
];
|
||||
$input = http_build_query($params);
|
||||
list($payload,$decrypted,$result,$body) = main_api_get('/trips/api/geocode/?',$input);
|
||||
if (is_array($payload) && array_key_exists('geocode',$payload) && is_array($payload['geocode'])
|
||||
&& array_key_exists('id',$payload['geocode']) && $payload['geocode']['id']>0) {
|
||||
$geocodedAddresses[$payload['geocode']['id']] = $payload['geocode']['address'];
|
||||
$q = "INSERT INTO tourist_attraction (attraction,address_id) VALUES('".pg_escape_string($desc)."',".$payload["geocode"]["id"].")";
|
||||
$r = pg_query($conn,$q);
|
||||
}
|
||||
}
|
||||
return $geocodedAddresses;
|
||||
}
|
||||
|
||||
function main_api_get($endpoint,$input) {
|
||||
global $baseURL, $encryptionAlg, $encryptionKey, $encryptionIV, $httpAuthToken;
|
||||
if ($endpoint!="" && $input!="") { // minimal sanity
|
||||
sleep(1);
|
||||
$url = $baseURL . $endpoint . $input;
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Server-Token ' . $httpAuthToken,
|
||||
"client_id: BATCH"
|
||||
)
|
||||
);
|
||||
|
||||
$body = curl_exec($ch);
|
||||
$result = json_decode($body,true);
|
||||
|
||||
$decrypted = openssl_decrypt(
|
||||
hex2bin(
|
||||
$result['payload']
|
||||
),
|
||||
$encryptionAlg,
|
||||
$encryptionKey,
|
||||
OPENSSL_RAW_DATA,
|
||||
$encryptionIV
|
||||
);
|
||||
$payload = json_decode($decrypted, true);
|
||||
return [$payload,$decrypted,$result,$body];
|
||||
}
|
||||
return [NULL,NULL,NULL,NULL];
|
||||
}
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,18 @@
|
||||
ArtScience Museum 6 Bayfront Ave, Singapore, 18974
|
||||
National Gallery Singapore 1 St Andrew's Rd, Singapore, 178957
|
||||
National Museum of Singapore 93 Stamford Rd, Singapore, 178897
|
||||
Haw Par Villa 262 Pasir Panjang Rd, Singapore, 118628
|
||||
Singapore Botanic Gardens 1 Cluny Rd, Singapore, 259569
|
||||
Chinese and Japanese Gardens 1 Chinese Garden Rd, Singapore, 619795
|
||||
Gardens by the Bay 18 Marina Gardens Dr, Singapore, 018953
|
||||
Fort Canning River Valley Rd, Singapore, 179037
|
||||
Singapore Zoo 80 Mandai Lake Rd, 729826
|
||||
River Safari 80 Mandai Lake Rd, Singapore, 729826
|
||||
Little India #02, 48 Serangoon Rd, 16, Little India Arcade, 217959
|
||||
Chinatown 133 New Bridge Rd, Singapore 059413
|
||||
Kampong Glam 18 Kandahar St, Singapore 198884
|
||||
Universal Studios Singapore 8 Sentosa Gateway, 098269
|
||||
Siloso Beach Siloso Beach 7R47+42 Southern Islands, SingaporeWalk, Singapore
|
||||
Adventure Cove Waterpark 8 Sentosa Gateway, 098269
|
||||
Marina Bay Sands Rooftop 10 Bayfront Ave, Singapore 018956
|
||||
1-Altitude 1 Raffles Place, #B1-12, Singapore, 048616
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$country = 'US';
|
||||
$member_id = 0;
|
||||
|
||||
// Uber, Lyft
|
||||
$transport_providers = [1,2];
|
||||
|
||||
// Step 1: Load batch file
|
||||
$attractions = load_batch_file("batch_quote_tourist_attractions_atl.txt");
|
||||
|
||||
// Step 2: Geocode addresses
|
||||
$newOrigins = geocode_addresses($attractions);
|
||||
|
||||
QuoteApi::$job_name=$job_name;
|
||||
// Step 3: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
foreach ($newOrigins as $origin_id=>$origin) {
|
||||
foreach ($newOrigins as $destination_id=>$destination) {
|
||||
if ($origin_id==$destination_id) continue;
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 ";
|
||||
$q.= " AND completed>(current_date-1) ORDER BY completed DESC LIMIT 1";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$transport_provider);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
function load_batch_file($filename) {
|
||||
$results = [];
|
||||
$fn = fopen($filename,"r");
|
||||
while(! feof($fn)) {
|
||||
$result = fgets($fn);
|
||||
$results[strtok($result,"\t")] = trim(strtok("\t"));
|
||||
}
|
||||
fclose($fn);
|
||||
return $results;
|
||||
}
|
||||
|
||||
function geocode_addresses($addresses) {
|
||||
global $conn;
|
||||
$geocodedAddresses = [];
|
||||
foreach ($addresses as $desc=>$address) {
|
||||
$params = [
|
||||
"address" => $address,
|
||||
"member_id" => 0,
|
||||
"country" => "US"
|
||||
];
|
||||
$input = http_build_query($params);
|
||||
list($payload,$decrypted,$result,$body) = main_api_get('/trips/api/geocode/?',$input);
|
||||
if (is_array($payload) && array_key_exists('geocode',$payload) && is_array($payload['geocode'])
|
||||
&& array_key_exists('id',$payload['geocode']) && $payload['geocode']['id']>0) {
|
||||
$geocodedAddresses[$payload['geocode']['id']] = $payload['geocode']['address'];
|
||||
$q = "INSERT INTO tourist_attraction (attraction,address_id) VALUES('".pg_escape_string($desc)."',".$payload["geocode"]["id"].")";
|
||||
$r = pg_query($conn,$q);
|
||||
}
|
||||
}
|
||||
return $geocodedAddresses;
|
||||
}
|
||||
|
||||
function main_api_get($endpoint,$input) {
|
||||
global $baseURL, $encryptionAlg, $encryptionKey, $encryptionIV, $httpAuthToken;
|
||||
if ($endpoint!="" && $input!="") { // minimal sanity
|
||||
sleep(1);
|
||||
$url = $baseURL . $endpoint . $input;
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Server-Token ' . $httpAuthToken,
|
||||
"client_id: BATCH"
|
||||
)
|
||||
);
|
||||
|
||||
$body = curl_exec($ch);
|
||||
$result = json_decode($body,true);
|
||||
|
||||
$decrypted = openssl_decrypt(
|
||||
hex2bin(
|
||||
$result['payload']
|
||||
),
|
||||
$encryptionAlg,
|
||||
$encryptionKey,
|
||||
OPENSSL_RAW_DATA,
|
||||
$encryptionIV
|
||||
);
|
||||
$payload = json_decode($decrypted, true);
|
||||
return [$payload,$decrypted,$result,$body];
|
||||
}
|
||||
return [NULL,NULL,NULL,NULL];
|
||||
}
|
||||
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,5 @@
|
||||
Mercedes-Benz Stadium 1 AMB Dr NW, Atlanta, GA 30313
|
||||
Cumberland Mall 2860 Cumberland Mall, Atlanta, GA 30339
|
||||
SunTrust Park 755 Battery Ave SE, Atlanta, GA 30339
|
||||
Georgia Aquarium 225 Baker St NW, Atlanta, GA 30313
|
||||
CNN Studio 190 Marietta St NW, Atlanta, GA 30303
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
$job_name = pathinfo(__FILE__, PATHINFO_FILENAME);
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job is starting.\n";
|
||||
|
||||
set_time_limit(0); // No limit!
|
||||
|
||||
require('../../backend.php');
|
||||
require('../common/QuoteApi.php');
|
||||
|
||||
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
||||
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
|
||||
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
|
||||
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
|
||||
|
||||
$baseURL = $savvyext->cfgReadChar('system.api_url');
|
||||
|
||||
$db_host = $savvyext->cfgReadChar('database.host');
|
||||
$db_name = $savvyext->cfgReadChar('database.name');
|
||||
$db_user = $savvyext->cfgReadChar('database.user');
|
||||
$db_pass = $savvyext->cfgReadChar('database.pass');
|
||||
$db_port = $savvyext->cfgReadLong('database.port');
|
||||
$connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}";
|
||||
$conn = pg_connect($connstr);
|
||||
|
||||
$country = 'US';
|
||||
$member_id = 0;
|
||||
|
||||
// Uber, Lyft
|
||||
$transport_providers = [1,2];
|
||||
|
||||
// Step 1: Load batch file
|
||||
$attractions = load_batch_file("batch_quote_tourist_attractions_sf.txt");
|
||||
|
||||
// Step 2: Geocode addresses
|
||||
$newOrigins = geocode_addresses($attractions);
|
||||
|
||||
// Step 3: Schedule quotes
|
||||
$checkQuotes = [];
|
||||
QuoteApi::$job_name = $job_name;
|
||||
foreach ($newOrigins as $origin_id=>$origin) {
|
||||
foreach ($newOrigins as $destination_id=>$destination) {
|
||||
if ($origin_id==$destination_id) continue;
|
||||
foreach ($transport_providers as $transport_provider) {
|
||||
$q = "SELECT * FROM quotes ";
|
||||
$q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} ";
|
||||
$q.= " AND transport_provider_id=${transport_provider} AND cost>0 ";
|
||||
$q.= " AND completed>(current_date-1) ORDER BY completed DESC LIMIT 1";
|
||||
$r = pg_query($conn, $q);
|
||||
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n";
|
||||
continue;
|
||||
}
|
||||
list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$transport_provider);
|
||||
if ($res>0) {
|
||||
if ($res==2) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n";
|
||||
} else if ($res==1) {
|
||||
echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n";
|
||||
$checkQuotes[] = $id;
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n";
|
||||
}
|
||||
} else {
|
||||
echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n";
|
||||
echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Check quotes
|
||||
foreach ($checkQuotes as $id) {
|
||||
list($res,$cost) = QuoteApi::check_quote($id);
|
||||
echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n";
|
||||
}
|
||||
|
||||
function load_batch_file($filename) {
|
||||
$results = [];
|
||||
$fn = fopen($filename,"r");
|
||||
while(! feof($fn)) {
|
||||
$result = fgets($fn);
|
||||
$results[strtok($result,"\t")] = trim(strtok("\t"));
|
||||
}
|
||||
fclose($fn);
|
||||
return $results;
|
||||
}
|
||||
|
||||
function geocode_addresses($addresses) {
|
||||
global $conn;
|
||||
$geocodedAddresses = [];
|
||||
foreach ($addresses as $desc=>$address) {
|
||||
$params = [
|
||||
"address" => $address,
|
||||
"member_id" => 0,
|
||||
"country" => "US"
|
||||
];
|
||||
$input = http_build_query($params);
|
||||
list($payload,$decrypted,$result,$body) = main_api_get('/trips/api/geocode/?',$input);
|
||||
if (is_array($payload) && array_key_exists('geocode',$payload) && is_array($payload['geocode'])
|
||||
&& array_key_exists('id',$payload['geocode']) && $payload['geocode']['id']>0) {
|
||||
$geocodedAddresses[$payload['geocode']['id']] = $payload['geocode']['address'];
|
||||
$q = "INSERT INTO tourist_attraction (attraction,address_id) VALUES('".pg_escape_string($desc)."',".$payload["geocode"]["id"].")";
|
||||
$r = pg_query($conn,$q);
|
||||
}
|
||||
}
|
||||
return $geocodedAddresses;
|
||||
}
|
||||
|
||||
function main_api_get($endpoint,$input) {
|
||||
global $baseURL, $encryptionAlg, $encryptionKey, $encryptionIV, $httpAuthToken;
|
||||
if ($endpoint!="" && $input!="") { // minimal sanity
|
||||
sleep(1);
|
||||
$url = $baseURL . $endpoint . $input;
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Server-Token ' . $httpAuthToken,
|
||||
"client_id: BATCH"
|
||||
)
|
||||
);
|
||||
|
||||
$body = curl_exec($ch);
|
||||
$result = json_decode($body,true);
|
||||
|
||||
$decrypted = openssl_decrypt(
|
||||
hex2bin(
|
||||
$result['payload']
|
||||
),
|
||||
$encryptionAlg,
|
||||
$encryptionKey,
|
||||
OPENSSL_RAW_DATA,
|
||||
$encryptionIV
|
||||
);
|
||||
$payload = json_decode($decrypted, true);
|
||||
return [$payload,$decrypted,$result,$body];
|
||||
}
|
||||
return [NULL,NULL,NULL,NULL];
|
||||
}
|
||||
echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";
|
||||
@@ -0,0 +1,27 @@
|
||||
Golden Gate Post Card Viewpoint Golden Gate Bridge, Coastal Trail, San Francisco, CA 94129, USA
|
||||
Battery Spencer RGH7+FH Sausalito, California, USA
|
||||
Madame Tussauds San Francisco 145 Jefferson St, San Francisco, CA 94133, USA
|
||||
Ghirardelli Square 900 North Point St Suite 52, San Francisco, CA 94109, USA
|
||||
Ferry Building 1 Ferry Building, San Francisco, CA 94111, USA
|
||||
Nob Hill 1621 Polk St, San Francisco, CA 94109, USA
|
||||
Lombard Street 2139 Lombard St, San Francisco, CA 94123, USA
|
||||
Chinatown 826 Grant Ave, San Francisco, CA 94108, USA
|
||||
Golden Gate Park 50 Stow Lake Dr E, San Francisco, CA 94118, USA
|
||||
San Francisco Botanical Garden 1199 9th Ave, San Francisco, CA 94122, USA
|
||||
California Palace of the Legion of Honor 100 34th Ave, San Francisco, CA 94121, USA
|
||||
The Palace Of Fine Arts 3601 Lyon St, San Francisco, CA 94123, USA
|
||||
California Academy of Sciences 55 Music Concourse Dr, San Francisco, CA 94118, USA
|
||||
San Francisco Museum of Modern Art 151 3rd St, San Francisco, CA 94103, USA
|
||||
de Young Fine Arts Museum of San Francisco 50 Hagiwara Tea Garden Dr, San Francisco, CA 94118, USA
|
||||
Twin Peaks 501 Twin Peaks Blvd, San Francisco, CA 94114, USA
|
||||
Asian Art Museum 200 Larkin St, San Francisco, CA 94102, USA
|
||||
Exploratorium Pier 15, The Embarcadero, San Francisco, CA 94111, USA
|
||||
High Tea at a Historic Hotel 2 New Montgomery St, San Francisco, CA 94105, USA
|
||||
AT&T Park 24 Willie Mays Plaza, San Francisco, CA 94107, USA
|
||||
Walt Disney Family Museum 104 Montgomery St, San Francisco, CA 94129, USA
|
||||
Yerba Buena Gardens 750 Howard St, San Francisco, CA 94103, USA
|
||||
San Francisco Symphony 201 Van Ness Ave, San Francisco, CA 94102, USA
|
||||
San Francisco Zoo and Gardens Sloat Blvd & Great Highway, San Francisco, CA 94132, USA
|
||||
Union Square 333 Post St, San Francisco, CA 94108, USA
|
||||
Baker Beach Gibson Rd, San Francisco, CA 94129, USA
|
||||
Japantown 1610 Geary Blvd, San Francisco, CA 94115, USA
|
||||
Reference in New Issue
Block a user