<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Laravel\Lumen\Routing\Controller as BaseController;
|
|
use Illuminate\Http\Request;
|
|
use DB;
|
|
use Quartz;
|
|
use Log;
|
|
use DateTime, DateTimeZone;
|
|
use App\Jobs\TripComplete;
|
|
|
|
class Api extends BaseController
|
|
{
|
|
|
|
public function account(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('write_token','=',$token)->first();
|
|
if(!$db)
|
|
return response(json_encode(['error' => 'invalid token']))->header('Content-Type', 'application/json');
|
|
|
|
return response(json_encode(['name' => $db->name]))->header('Content-Type', 'application/json');
|
|
}
|
|
|
|
public function query(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($date=$request->input('date')) {
|
|
$start = DateTime::createFromFormat('Y-m-d H:i:s', $date.' 00:00:00', new DateTimeZone($tz));
|
|
$end = DateTime::createFromFormat('Y-m-d H:i:s', $date.' 23:59:59', new DateTimeZone($tz));
|
|
} else {
|
|
return response(json_encode(['error' => 'no date provided']))->header('Content-Type', 'application/json');
|
|
}
|
|
|
|
$results = $qz->queryRange($start, $end);
|
|
|
|
$locations = [];
|
|
$properties = [];
|
|
$events = [];
|
|
|
|
if($request->input('format') == 'linestring') {
|
|
|
|
foreach($results as $id=>$record) {
|
|
// When returning a linestring, separate out the "event" records from the "location" records
|
|
if(property_exists($record->data->properties, 'action')) {
|
|
$rec = $record->data;
|
|
# add a unixtime property
|
|
$rec->properties->unixtime = (int)$record->date->format('U');
|
|
$events[] = $rec;
|
|
} else {
|
|
#$record->date->format('U.u');
|
|
$locations[] = $record->data;
|
|
$props = $record->data->properties;
|
|
$date = $record->date;
|
|
$date->setTimeZone(new DateTimeZone($tz));
|
|
$props->timestamp = $date->format('c');
|
|
$props->unixtime = (int)$date->format('U');
|
|
$properties[] = $props;
|
|
}
|
|
}
|
|
|
|
$linestring = array(
|
|
'type' => 'LineString',
|
|
'coordinates' => [],
|
|
'properties' => $properties
|
|
);
|
|
foreach($locations as $loc) {
|
|
if(property_exists($loc, 'geometry'))
|
|
$linestring['coordinates'][] = $loc->geometry->coordinates;
|
|
else
|
|
$linestring['coordinates'][] = null;
|
|
}
|
|
|
|
$response = array(
|
|
'linestring' => $linestring,
|
|
'events' => $events
|
|
);
|
|
|
|
} else {
|
|
foreach($results as $id=>$record) {
|
|
$locations[] = $record->data;
|
|
}
|
|
|
|
$response = [
|
|
'locations' => $locations
|
|
];
|
|
}
|
|
|
|
return response(json_encode($response))->header('Content-Type', 'application/json');
|
|
}
|
|
|
|
public function input(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('write_token','=',$token)->first();
|
|
if(!$db)
|
|
return response(json_encode(['error' => 'invalid token']))->header('Content-Type', 'application/json');
|
|
|
|
if(!is_array($request->input('locations')))
|
|
return response(json_encode(['error' => 'invalid input', 'error_description' => 'parameter "locations" must be an array of GeoJSON data with a "timestamp" property']))->header('Content-Type', 'application/json');
|
|
|
|
$qz = new Quartz\DB(env('STORAGE_DIR').$db->name, 'w');
|
|
|
|
$num = 0;
|
|
$trips = 0;
|
|
foreach($request->input('locations') as $loc) {
|
|
if(array_key_exists('properties', $loc)) {
|
|
if(array_key_exists('timestamp', $loc['properties'])) {
|
|
try {
|
|
if(preg_match('/^\d+\.\d+$/', $loc['properties']['timestamp']))
|
|
$date = DateTime::createFromFormat('U.u', $loc['properties']['timestamp']);
|
|
elseif(preg_match('/^\d+$/', $loc['properties']['timestamp']))
|
|
$date = DateTime::createFromFormat('U', $loc['properties']['timestamp']);
|
|
else
|
|
$date = new DateTime($loc['properties']['timestamp']);
|
|
|
|
if($date) {
|
|
$num++;
|
|
$qz->add($date, $loc);
|
|
|
|
if(array_key_exists('type', $loc['properties']) && $loc['properties']['type'] == 'trip') {
|
|
try {
|
|
$job = (new TripComplete($db->id, $loc))->onQueue('compass');
|
|
$this->dispatch($job);
|
|
$trips++;
|
|
} catch(Exception $e) {
|
|
Log::warning('Received invalid trip');
|
|
}
|
|
}
|
|
|
|
} else {
|
|
Log::warning('Received invalid date: ' . $loc['properties']['timestamp']);
|
|
}
|
|
} catch(Exception $e) {
|
|
Log::warning('Received invalid date: ' . $loc['properties']['timestamp']);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return response(json_encode(['result' => 'ok', 'saved' => $num, 'trips' => $trips]))->header('Content-Type', 'application/json');
|
|
}
|
|
|
|
}
|