summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Parecki <aaron@parecki.com>2017-05-11 19:19:07 -0700
committerAaron Parecki <aaron@parecki.com>2017-05-11 19:19:07 -0700
commitb1b4aaa4d02ba2cf4c0bb07a95afcb0035dac3cf (patch)
treec7bf18e62395def018326e61d97de2bf48ffbe5d
parent34afa1f5f220af14c055e5eb5e0844be0b5120aa (diff)
add interface for checking in to flights
let's give this a shot
-rw-r--r--controllers/controllers.php99
-rw-r--r--schema/migrations/0005.sql5
-rw-r--r--scripts/flights.php156
-rw-r--r--views/new-flight.php54
-rw-r--r--views/new-post.php2
5 files changed, 315 insertions, 1 deletions
diff --git a/controllers/controllers.php b/controllers/controllers.php
index fe4d89c..ecc3a9e 100644
--- a/controllers/controllers.php
+++ b/controllers/controllers.php
@@ -191,6 +191,105 @@ $app->get('/itinerary', function() use($app) {
}
});
+$app->get('/flight', function() use($app) {
+ if($user=require_login($app)) {
+ $params = $app->request()->params();
+
+ render('new-flight', array(
+ 'title' => 'Flight',
+ 'authorizing' => false
+ ));
+ }
+});
+
+$app->post('/flight', function() use($app) {
+ if($user=require_login($app)) {
+ $params = $app->request()->params();
+
+ $location = false;
+
+ if($params['action'] == 'find') {
+
+ } elseif($params['action'] == 'checkin') {
+
+ $payload = [
+ 'type' => ['h-entry'],
+ 'properties' => [
+ 'checkin' => [
+ [
+ 'type' => ['h-card'],
+ 'properties' => [
+ 'name' => [$params['flight']],
+ 'url' => ['http://flightaware.com/live/flight/'.$params['flight']],
+ ]
+ ]
+ ]
+ ]
+ ];
+
+ $r = micropub_post_for_user($user, $payload, null, true);
+
+ $location = $r['location'];
+
+ if($location) {
+ // Store the checkin in the database to enable the cron job tracking the flight
+ $flight = ORM::for_table('flights')->create();
+ $flight->user_id = $_SESSION['user_id'];
+ $flight->date_created = date('Y-m-d H:i:s');
+ $flight->active = 1;
+ $flight->url = $location;
+ $flight->flight = $params['flight'];
+ $flight->save();
+ }
+ }
+
+ $app->response()['Content-type'] = 'application/json';
+ $app->response()->body(json_encode(array(
+ 'result' => 'ok',
+ 'location' => $location
+ )));
+ }
+});
+
+$app->get('/flight/:id/:flightID/route.json', function($id, $flightID) use($app) {
+ $route = false;
+
+ $flight = ORM::for_table('flights')->where('id', $id)->find_one();
+ if($flight) {
+ $lastPosition = json_decode($flight->lastposition, true);
+ if($lastPosition['InFlightInfoResult']['faFlightID'] == $flightID) {
+
+ // {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-122.638351,45.52217]},"properties":{"date":"2016-01-02T23:13:49Z","altitude":42.666666666667}}
+
+ $route = [
+ 'type' => 'FeatureCollection',
+ 'features' => []
+ ];
+
+ $positions = json_decode($flight->positions, true);
+ foreach($positions as $p) {
+ $route['features'][] = [
+ 'type' => 'Feature',
+ 'geometry' => [
+ 'type' => 'Point',
+ 'coordinates' => [$p['lng'], $p['lat']]
+ ],
+ 'properties' => [
+ 'date' => $p['date'],
+ 'altitude' => $p['altitude'],
+ 'heading' => $p['heading'],
+ 'speed' => $p['speed']
+ ]
+ ];
+ }
+
+ }
+ }
+
+ $app->response()['Content-type'] = 'application/json';
+ $app->response()->body(json_encode($route));
+});
+
$app->get('/photo', function() use($app) {
if($user=require_login($app)) {
$params = $app->request()->params();
diff --git a/schema/migrations/0005.sql b/schema/migrations/0005.sql
new file mode 100644
index 0000000..d94cb8d
--- /dev/null
+++ b/schema/migrations/0005.sql
@@ -0,0 +1,5 @@
+
+
+ALTER TABLE users
+ADD COLUMN `flightaware_username` VARCHAR(255) NOT NULL DEFAULT '',
+ADD COLUMN `flightaware_apikey` VARCHAR(255) NOT NULL DEFAULT '';
diff --git a/scripts/flights.php b/scripts/flights.php
new file mode 100644
index 0000000..565732a
--- /dev/null
+++ b/scripts/flights.php
@@ -0,0 +1,156 @@
+<?php
+chdir(dirname(__FILE__).'/..');
+require 'vendor/autoload.php';
+
+$flights = ORM::for_table('flights')
+ ->where('active', 1)
+ ->find_many();
+foreach($flights as $flight) {
+
+ $user = ORM::for_table('users')
+ ->where('id', $flight->user_id)
+ ->where_not_equal('flightaware_apikey', '')
+ ->find_one();
+ if($user) {
+ echo date('Y-m-d H:i:s')."\n";
+ echo "Processing flight ".$flight->flight." for ".$user->url."\n";
+
+ $ch = curl_init('http://flightxml.flightaware.com/json/FlightXML2/InFlightInfo?ident='.$flight->flight);
+ curl_setopt($ch, CURLOPT_USERPWD, $user->flightaware_username.':'.$user->flightaware_apikey);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $json = curl_exec($ch);
+ $data = json_decode($json, true);
+ #$data = json_decode($flight->lastposition, true);
+ $flightData = $data['InFlightInfoResult'];
+
+ $flight->lastposition = $json;
+ $flight->save();
+
+ if($flightData['departureTime']) {
+
+ if($flightData['departureTime'] < strtotime($flight->date_created)) {
+ echo "This flight departed before the checkin was made so this is probably the wrong flight\n";
+ } else {
+
+ $has_new_location = false;
+ $flight_ended = false;
+
+ // Add this point to the list
+ if($flight->positions)
+ $positions = json_decode($flight->positions, true);
+ else
+ $positions = [];
+
+ if($flightData['latitude']) {
+ $positions[] = [
+ 'date' => date('Y-m-d H:i:s'),
+ 'lat' => $flightData['latitude'],
+ 'lng' => $flightData['longitude'],
+ 'altitude' => $flightData['altitude'],
+ 'heading' => $flightData['heading'],
+ 'speed' => $flightData['groundspeed'],
+ ];
+ $flight->positions = json_encode($positions);
+
+ $has_new_location = true;
+ }
+
+ if($has_new_location) {
+ $latitude = $flightData['latitude'];
+ $longitude = $flightData['longitude'];
+ } else {
+ $latitude = $positions[count($positions)-1]['lat'];
+ $longitude = $positions[count($positions)-1]['lng'];
+ }
+
+ if($flightData['arrivalTime']) {
+ $flight->arrival_time = date('Y-m-d H:i:s', $flightData['arrivalTime']);
+ $flight->active = 0;
+ $flight_ended = true;
+ }
+
+ if($flight_ended || $has_new_location) {
+
+ $flight->departure_time = date('Y-m-d H:i:s', $flightData['departureTime']);
+ $flight->save();
+
+ $checkin = [
+ 'type' => ['h-card'],
+ 'properties' => [
+ 'name' => [$flight->flight],
+ 'url' => ['http://flightaware.com/live/flight/'.$flight->flight],
+ 'latitude' => [$latitude],
+ 'longitude' => [$longitude],
+ ]
+ ];
+
+ // Geocode the location
+ $geocode = json_decode(file_get_contents('https://atlas.p3k.io/api/geocode?latitude='.$latitude.'&longitude='.$longitude), true);
+ if($geocode) {
+ $checkin['properties']['locality'] = [$geocode['locality']];
+ $checkin['properties']['region'] = [$geocode['region']];
+ $checkin['properties']['country-name'] = [$geocode['country']];
+ $tz = new DateTimeZone($geocode['timezone']);
+ } else {
+ $tz = new DateTimeZone('UTC');
+ }
+
+ $departure = new DateTime($flight->departure_time);
+ $departure->setTimeZone($tz);
+
+ $trip = [
+ 'type' => ['h-trip'],
+ 'properties' => [
+ 'mode-of-transport' => ['plane'],
+ 'start' => [$departure->format('c')],
+ 'flight' => [$flightData['ident']],
+ 'flight-id' => [$flightData['faFlightID']],
+ 'aircraft' => [$flightData['type']],
+ 'origin' => [$flightData['origin']],
+ 'destination' => [$flightData['destination']],
+ 'speed' => [
+ [
+ 'type' => ['h-measure'],
+ 'properties' => [
+ 'num' => [$flightData['groundspeed']],
+ 'unit' => ['mph'],
+ ]
+ ]
+ ],
+ 'route' => ['http://quill.dev/flight/'.$flight->id.'/'.$flightData['faFlightID'].'/route.json']
+ ]
+ ];
+
+ if($flight->arrival_time) {
+ $arrival = new DateTime($flight->arrival_time);
+ $arrival->setTimeZone($tz);
+ $trip['properties']['end'] = [$arrival->format('c')];
+ }
+
+ // Convert this to a Micropub request
+ $micropub = [
+ 'action' => 'update',
+ 'url' => $flight->url,
+ 'replace' => [
+ 'checkin' => $checkin,
+ 'trip' => $trip,
+ ]
+ ];
+ $r = micropub_post_for_user($user, $micropub, null, true);
+ print_r($r['response']);
+
+ }
+ }
+
+ } else {
+ echo "It looks like the flight has not yet departed\n";
+ }
+
+ print_r($data);
+
+ } else {
+ echo "User ".$user->url." has no FlightAware credentials\n";
+ }
+
+}
+
diff --git a/views/new-flight.php b/views/new-flight.php
new file mode 100644
index 0000000..031b86f
--- /dev/null
+++ b/views/new-flight.php
@@ -0,0 +1,54 @@
+<div class="narrow">
+ <?= partial('partials/header') ?>
+
+ <div style="clear: both;" class="notice-pad">
+ <div class="alert alert-success hidden" id="test_success"><strong>Success!</strong><br>Your checkin should be on your website now!<br><a href="" id="post_href">View your post</a></div>
+ <div class="alert alert-danger hidden" id="test_error"><strong>Your endpoint did not return a Location header.</strong><br>See <a href="/creating-a-micropub-endpoint">Creating a Micropub Endpoint</a> for more information.</div>
+ </div>
+
+ <form role="form" style="margin-top: 20px;" id="note_form">
+
+ <div class="form-group">
+ <label>Flight Number (e.g. <code>AS387</code>)</label>
+ <input type="text" id="flight" class="form-control" value="AS387">
+ </div>
+
+ <div style="float: right; margin-top: 6px;">
+ <button class="btn btn-success" id="btn_post">Check In</button>
+ </div>
+
+ </form>
+
+</div>
+<script>
+$(function(){
+ $("#btn_post").click(function(){
+ if($(this).text() == "Find Flight") {
+ $.post("/flight", {
+ action: "find",
+ flight: $("#flight").val()
+ }, function(data){
+
+ });
+ } else {
+ $("#btn_post").addClass("loading disabled").text("Working...");
+ $.post("/flight", {
+ action: "checkin",
+ flight: $("#flight").val()
+ }, function(response){
+ if(response.location != false) {
+ $("#test_success").removeClass('hidden');
+ $("#test_error").addClass('hidden');
+ $("#post_href").attr("href", response.location);
+ $("#note_form").addClass("hidden");
+ } else {
+ $("#test_success").addClass('hidden');
+ $("#test_error").removeClass('hidden');
+ $("#btn_post").removeClass("loading disabled").text("Check In");
+ }
+ });
+ }
+ return false;
+ });
+});
+</script>
diff --git a/views/new-post.php b/views/new-post.php
index 6e6eb0f..2e523b8 100644
--- a/views/new-post.php
+++ b/views/new-post.php
@@ -85,7 +85,7 @@
<input type="checkbox" id="note_location_chk" value="">
<img src="/images/spinner.gif" id="note_location_loading" style="display: none;">
- <input type="text" id="note_location_msg" value="" class="form-control" placeholder="" readonly="readonly">
+ <input type="text" name="note_location_msg" id="note_location_msg" value="" class="form-control" placeholder="" readonly="readonly">
<input type="hidden" id="note_location">
<input type="hidden" id="location_enabled" value="<?= $this->location_enabled ?>">