From 4ef172eeb74ac8add23983b4214c43147614aa30 Mon Sep 17 00:00:00 2001 From: Aaron Parecki Date: Sun, 10 Jan 2016 12:23:12 -0800 Subject: [PATCH] adds API method to return the latest record before a given date also can optionally reverse geocode the record using Atlas --- README.md | 18 ++++-- compass/.env.example | 3 +- compass/app/Http/Controllers/Api.php | 83 +++++++++++++++++++++++++++- compass/app/Http/routes.php | 2 +- 4 files changed, 98 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 44195f3..34419b6 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,22 @@ The open source iOS [GPS Logger](https://github.com/esripdx/GPS-Logger-iOS) will ### Reading -To read a database, make a GET request with the following keys: +To read a database, make a GET request as follows: `GET /api/query` -* token - the read token for the database -* date - specify a date to return all data on that day -* tz - timezone string (e.g. America/Los_Angeles) which will be used to determine the absolute start/end times for the day - +* token - (required) the read token for the database +* tz - (optional, default UTC) timezone string (e.g. America/Los_Angeles) which will be used to determine the absolute start/end times for the day +* format - (optional, default "full") either "full" or "linestring" + * full - return one JSON record for each result in the database + * linestring - combine all the returned results into a GeoJSON linestring +* date - specify a date to return all data on that day (YYYY-mm-dd format) + +`GET /api/last` +* token - (required) the read token for the database +* tz - (optional, default UTC) timezone string (e.g. America/Los_Angeles) which will be used to determine the absolute start/end times for the day +* date - (optional) specify a full timestamp to return a single record before this date (the point returned will be no more than 24 hours before the given date) +* geocode - (optional) if "true", then the location found will be reverse geocoded using [Atlas](https://atlas.p3k.io) to find the city and timezone at the location ## Credits diff --git a/compass/.env.example b/compass/.env.example index 67c64b9..f557d04 100644 --- a/compass/.env.example +++ b/compass/.env.example @@ -1,5 +1,6 @@ -BASE_URL=http://compass.dev/ +BASE_URL=http://compass.p3k.io/ DEFAULT_AUTH_ENDPOINT=https://indieauth.com/auth +ATLAS_BASE=http://atlas.p3k.io/ STORAGE_DIR=/var/compass/data diff --git a/compass/app/Http/Controllers/Api.php b/compass/app/Http/Controllers/Api.php index 89ceceb..059c720 100644 --- a/compass/app/Http/Controllers/Api.php +++ b/compass/app/Http/Controllers/Api.php @@ -7,7 +7,7 @@ use Illuminate\Http\Request; use DB; use Quartz; use Log; -use DateTime, DateTimeZone; +use DateTime, DateTimeZone, DateInterval; use App\Jobs\TripComplete; class Api extends BaseController @@ -106,6 +106,87 @@ class Api extends BaseController return response(json_encode($response))->header('Content-Type', 'application/json'); } + public function last(Request $request) { + $token = $request->input('token'); + if(!$token) + return response(json_encode(['error' => 'no token provided']))->header('Content-Type', 'application/json'); + + $db = DB::table('databases')->where('read_token','=',$token)->first(); + if(!$db) + return response(json_encode(['error' => 'invalid token']))->header('Content-Type', 'application/json'); + + $qz = new Quartz\DB(env('STORAGE_DIR').$db->name, 'r'); + + if($request->input('tz')) { + $tz = $request->input('tz'); + } else { + $tz = 'UTC'; + } + + if($input=$request->input('before')) { + if(preg_match('/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $input)) { + // If the input date is given in YYYY-mm-dd HH:mm:ss format, interpret it in the timezone given + $date = DateTime::createFromFormat('Y-m-d H:i:s', $input, new DateTimeZone($tz)); + } else { + // Otherwise, parse the string and use the timezone in the input + $date = new DateTime($input); + $date->setTimeZone(new DateTimeZone($tz)); + } + + if(!$date) { + return response(json_encode(['error' => 'invalid date provided']))->header('Content-Type', 'application/json'); + } + } else { + return response(json_encode(['error' => 'no date provided']))->header('Content-Type', 'application/json'); + } + + // TODO: move this logic into QuartzDB + + // Load the shard for the given date + $shard = $qz->shardForDate($date); + // If the shard doesn't exist, check one day before + if(!$shard->exists()) { + $date = $date->sub(new DateInterval('PT86400S')); + $shard = $qz->shardForDate($date); + } + // Now if the shard doesn't exist, return an empty result + if(!$shard->exists()) { + return response(json_encode([ + 'data'=>null + ])); + } + + // Start iterating through the shard and look for the last line that is before the given date + $shard->init(); + $record = false; + foreach($shard as $r) { + if($r->date > $date) + break; + $record = $r; + } + + $response = [ + 'data' => $record->data + ]; + + if($request->input('geocode') && property_exists($record->data, 'geometry') && property_exists($record->data->geometry, 'coordinates')) { + $coords = $record->data->geometry->coordinates; + $params = [ + 'latitude' => $coords[1], + 'longitude' => $coords[0] + ]; + $ch = curl_init(env('ATLAS_BASE').'api/geocode?'.http_build_query($params)); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 8); + $geocode = json_decode(curl_exec($ch)); + if($geocode) { + $response['geocode'] = $geocode; + } + } + + return response(json_encode($response)); + } + public function input(Request $request) { $token = $request->input('token'); if(!$token) diff --git a/compass/app/Http/routes.php b/compass/app/Http/routes.php index 5394aba..7ac1e44 100644 --- a/compass/app/Http/routes.php +++ b/compass/app/Http/routes.php @@ -24,10 +24,10 @@ $app->post('/settings/{name:[A-Za-z0-9]+}', 'Controller@updateSettings'); $app->post('/database/create', 'Controller@createDatabase'); $app->get('/api/query', 'Api@query'); +$app->get('/api/last', 'Api@last'); $app->get('/api/input', 'Api@account'); $app->post('/api/input', 'Api@input'); // Event::listen('illuminate.query', function($query){ // Log::debug($query); // }); -