You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.8 KiB

  1. <?php
  2. namespace App\Http\Controllers;
  3. use Laravel\Lumen\Routing\Controller as BaseController;
  4. use Illuminate\Http\Request;
  5. use DB;
  6. use Quartz;
  7. use Log;
  8. use DateTime, DateTimeZone;
  9. class Api extends BaseController
  10. {
  11. public function account(Request $request) {
  12. $token = $request->input('token');
  13. if(!$token)
  14. return response(json_encode(['error' => 'no token provided']))->header('Content-Type', 'application/json');
  15. $db = DB::table('databases')->where('write_token','=',$token)->first();
  16. if(!$db)
  17. return response(json_encode(['error' => 'invalid token']))->header('Content-Type', 'application/json');
  18. return response(json_encode(['name' => $db->name]))->header('Content-Type', 'application/json');
  19. }
  20. public function query(Request $request) {
  21. $token = $request->input('token');
  22. if(!$token)
  23. return response(json_encode(['error' => 'no token provided']))->header('Content-Type', 'application/json');
  24. $db = DB::table('databases')->where('read_token','=',$token)->first();
  25. if(!$db)
  26. return response(json_encode(['error' => 'invalid token']))->header('Content-Type', 'application/json');
  27. $qz = new Quartz\DB(env('STORAGE_DIR').$db->name, 'r');
  28. if($request->input('tz')) {
  29. $tz = $request->input('tz');
  30. } else {
  31. $tz = 'America/Los_Angeles';
  32. }
  33. if($date=$request->input('date')) {
  34. $start = DateTime::createFromFormat('Y-m-d H:i:s', $date.' 00:00:00', new DateTimeZone($tz));
  35. $end = DateTime::createFromFormat('Y-m-d H:i:s', $date.' 23:59:59', new DateTimeZone($tz));
  36. } else {
  37. return response(json_encode(['error' => 'no date provided']))->header('Content-Type', 'application/json');
  38. }
  39. $results = $qz->queryRange($start, $end);
  40. $locations = [];
  41. $properties = [];
  42. $events = [];
  43. foreach($results as $id=>$record) {
  44. if(property_exists($record->data->properties, 'action')) {
  45. $rec = $record->data;
  46. $date = $record->date;
  47. $rec->properties->unixtime = (int)$date->format('U');
  48. $events[] = $rec;
  49. } else {
  50. #$record->date->format('U.u');
  51. $locations[] = $record->data;
  52. $props = $record->data->properties;
  53. $date = $record->date;
  54. $date->setTimeZone(new DateTimeZone($tz));
  55. $props->timestamp = $date->format('c');
  56. $props->unixtime = (int)$date->format('U');
  57. $properties[] = $props;
  58. }
  59. }
  60. if($request->input('format') == 'linestring') {
  61. $linestring = array(
  62. 'type' => 'LineString',
  63. 'coordinates' => array(),
  64. 'properties' => $properties
  65. );
  66. foreach($locations as $loc) {
  67. if(property_exists($loc, 'geometry'))
  68. $linestring['coordinates'][] = $loc->geometry->coordinates;
  69. else
  70. $linestring['coordinates'][] = null;
  71. }
  72. $response = array(
  73. 'linestring' => $linestring,
  74. 'events' => $events
  75. );
  76. } else {
  77. $response = [
  78. 'locations' => $locations
  79. ];
  80. }
  81. return response(json_encode($response))->header('Content-Type', 'application/json');
  82. }
  83. public function input(Request $request) {
  84. $token = $request->input('token');
  85. if(!$token)
  86. return response(json_encode(['error' => 'no token provided']))->header('Content-Type', 'application/json');
  87. $db = DB::table('databases')->where('write_token','=',$token)->first();
  88. if(!$db)
  89. return response(json_encode(['error' => 'invalid token']))->header('Content-Type', 'application/json');
  90. if(!is_array($request->input('locations')))
  91. 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');
  92. $qz = new Quartz\DB(env('STORAGE_DIR').$db->name, 'w');
  93. $num = 0;
  94. foreach($request->input('locations') as $loc) {
  95. if(array_key_exists('properties', $loc) && array_key_exists('timestamp', $loc['properties'])) {
  96. try {
  97. if(preg_match('/^\d+\.\d+$/', $loc['properties']['timestamp']))
  98. $date = DateTime::createFromFormat('U.u', $loc['properties']['timestamp']);
  99. elseif(preg_match('/^\d+$/', $loc['properties']['timestamp']))
  100. $date = DateTime::createFromFormat('U', $loc['properties']['timestamp']);
  101. else
  102. $date = new DateTime($loc['properties']['timestamp']);
  103. if($date) {
  104. $num++;
  105. $qz->add($date, $loc);
  106. } else {
  107. Log::warning('Received invalid date: ' . $loc['properties']['timestamp']);
  108. }
  109. } catch(Exception $e) {
  110. Log::warning('Received invalid date: ' . $loc['properties']['timestamp']);
  111. }
  112. }
  113. }
  114. return response(json_encode(['result' => 'ok', 'saved' => $num]))->header('Content-Type', 'application/json');
  115. }
  116. }