Last active
December 3, 2015 20:00
-
-
Save ajosanchez/1029e3de6a628554c037 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'socket' # Get sockets from stdlib | |
require 'json' | |
require 'active_support/all' | |
require 'active_record' | |
ActiveRecord::Base.logger = Logger.new(STDERR) | |
ActiveRecord::Base.establish_connection( | |
:adapter => 'sqlite3', | |
:database => 'project_db' | |
) | |
ActiveRecord::Schema.define do | |
unless ActiveRecord::Base.connection.tables.include? 'flights' | |
create_table :flights do |t| | |
t.string :name | |
t.integer :speed | |
t.datetime :enter_time | |
t.string :divert | |
t.integer :altitude | |
end | |
end | |
end | |
class Flight < ActiveRecord::Base | |
end | |
class FlightTracker | |
MINSPEED = 105 | |
MAXSPEED = 128 | |
DESC_LENGTH = 65291 | |
FA_LENGTH = 15021 | |
DISTANCE = 5200 | |
def make_record_live input | |
Flight.create( | |
:name => input[:name], | |
:speed => set_speed(input), | |
:enter_time => input[:toe], | |
:divert => divert(input), | |
:altitude => input[:altitude] | |
) | |
end | |
def set_speed flight | |
if Flight.exists?(1) | |
safe_speed = ( (DESC_LENGTH-DISTANCE) / ( prev_FA - flight[:toe] ).ceil ) | |
safe_speed = MAXSPEED if ( safe_speed > MAXSPEED || safe_speed < 0) | |
return safe_speed | |
else | |
return MAXSPEED | |
end | |
end | |
def prev_FA | |
prev_flight = Flight.where(divert: 'no').last | |
dur = DESC_LENGTH / prev_flight.speed | |
prev_flight.enter_time + dur | |
end | |
def calc_FA_time flight | |
speed = calc_speed flight | |
DESC_LENGTH.div( speed ) | |
end | |
def divert flight | |
set_speed(flight) < MINSPEED ? "yes" : "no" | |
end | |
def tracking_info | |
aircrafts = [] | |
Flight.all.each do |flight| | |
unless (flight.divert == 'yes') || complete?(flight) | |
aircrafts << { "flight" => flight.name, | |
"altitude" => altitude(flight), | |
"x" => xcoord(distance(flight)), | |
"y" => ycoord(distance(flight)), | |
"status" => status(flight) } | |
end | |
end | |
return { 'aircrafts' => aircrafts } | |
end | |
def complete? flight | |
(Time.now - flight.enter_time) > ((DESC_LENGTH+FA_LENGTH)/flight.speed) + 121 ? true : false | |
end | |
def altitude flight | |
if distance(flight) > DESC_LENGTH+FA_LENGTH | |
0 | |
else | |
10000 - (10000 * ((Time.now - flight.enter_time)/((DESC_LENGTH+FA_LENGTH).div(flight.speed)))) | |
end | |
end | |
def distance flight | |
dist = (Time.now - flight.enter_time) * flight.speed | |
if dist > DESC_LENGTH+FA_LENGTH + 1 | |
(return (DESC_LENGTH + FA_LENGTH + 1)) | |
else | |
(return dist) | |
end | |
end | |
def xcoord distance | |
if distance > DESC_LENGTH+FA_LENGTH | |
0 | |
else | |
( 2.1e-12 * distance**3 ) - | |
( 4.41e-6 * distance**2 ) + | |
( 0.047 * distance ) + 16000 | |
end | |
end | |
def ycoord distance | |
if distance > DESC_LENGTH+FA_LENGTH | |
1000 | |
else | |
( 2.23e-14 * distance**4 ) - | |
( 2e-9 * distance**3 ) + | |
( 1.02e-4 * distance**2 ) - | |
( 5 * distance ) + 47000 | |
end | |
end | |
def status flight | |
if flight.divert == "yes" | |
"diverted" | |
elsif distance(flight) < DESC_LENGTH | |
"descending" | |
elsif distance(flight).between?(DESC_LENGTH, DESC_LENGTH + FA_LENGTH) | |
"final approach" | |
elsif distance(flight) > DESC_LENGTH+FA_LENGTH | |
"landed" | |
end | |
end | |
end | |
def url_parse request | |
route = request.match /\s\/\w*\?/ | |
route = route.to_s.gsub!(/\s|\?|\//, '') | |
header_param = /\s*[\w.]+=(?:[\w.]+|"(?:[^"\\]|\\.)*")?\s*/ | |
params = request.scan(header_param).map! do |s| | |
key, value = s.strip.split('=', 2) | |
value = value[1..-2].gsub(/\\(.)/, '\1') if value.start_with?('"') | |
[key, value] | |
end | |
return {:route => route, :params => params} | |
end | |
def get_req values | |
route = values[:route].to_s | |
params = values[:params].to_h | |
if route.empty? | |
text = "<h1>*** Welcome to the Flight Tracker API ***</h1>" | |
text << "<p>To input a flight: localhost:4567/entry?flight=KS4567&altitude=10000</p>" | |
text << "<p>To get info on all flights: localhost:4567/tracking_info</p>" | |
return text | |
elsif route == 'entry' | |
plane = { :name => params['flight'], :altitude => params['altitude'], :toe => Time.now } | |
$t.make_record_live(plane) | |
return plane | |
elsif route == 'tracking_info' | |
results = $t.tracking_info | |
return results.to_json | |
else | |
return "error" | |
end | |
end | |
server = TCPServer.open(2000) # Socket to listen on port 2000 | |
$t = FlightTracker.new | |
loop { # Servers run forever | |
Thread.start(server.accept) do |client| | |
request = client.gets | |
if request.match /^GET/ | |
values = url_parse(request) | |
client.puts get_req(values) | |
else | |
client.puts "Sorry, we don't recognize that request." | |
end | |
client.close # Disconnect from the client | |
end | |
} ##### END OF LOOP ##### |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hardcore! 👍