Browse Source

adds API method to return the latest record before a given date

also can optionally reverse geocode the record using Atlas
pull/5/head
Aaron Parecki 8 years ago
parent
commit
4ef172eeb7
4 changed files with 98 additions and 8 deletions
  1. +13
    -5
      README.md
  2. +2
    -1
      compass/.env.example
  3. +82
    -1
      compass/app/Http/Controllers/Api.php
  4. +1
    -1
      compass/app/Http/routes.php

+ 13
- 5
README.md View File

@ -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

+ 2
- 1
compass/.env.example View File

@ -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

+ 82
- 1
compass/app/Http/Controllers/Api.php View File

@ -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)

+ 1
- 1
compass/app/Http/routes.php View File

@ -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);
// });

Loading…
Cancel
Save