Skip to content

Instantly share code, notes, and snippets.

@ajosanchez
Last active December 3, 2015 20:00
Show Gist options
  • Save ajosanchez/1029e3de6a628554c037 to your computer and use it in GitHub Desktop.
Save ajosanchez/1029e3de6a628554c037 to your computer and use it in GitHub Desktop.
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 #####
@crteal
Copy link

crteal commented Dec 3, 2015

Hardcore! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment