vatsim_online_redux 1.0.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/vatsim_online/callsign_parser.rb +13 -7
- data/lib/vatsim_online/data_downloader.rb +131 -127
- data/lib/vatsim_online/station.rb +37 -16
- data/lib/vatsim_online/station_parser.rb +28 -19
- data/lib/vatsim_online/version.rb +3 -3
- data/spec/callsign_parser_spec.rb +13 -7
- data/spec/data_downloader_spec.rb +16 -9
- data/spec/data_downloader_spec_helper.rb +6 -4
- data/spec/spec_helper.rb +1 -0
- data/spec/station_parser_spec.rb +51 -53
- data/spec/support/vatsim_data.json +796 -0
- data/spec/support/vatsim_status.json +13 -0
- data/spec/vatsim_online_spec.rb +106 -101
- data/vatsim_online_redux.gemspec +1 -0
- metadata +21 -9
- data/spec/callsign_parser_spec_helper.rb +0 -10
- data/spec/station_parser_spec_helper.rb +0 -10
- data/spec/vatsim_online_spec_helper.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b68e83fc9b674c716b6bc39a5c49ca70a9d111eb0222bc344d0dd60df8582e9
|
4
|
+
data.tar.gz: 22751c268f529366bd591a6b1d7ce6bd020390c521aacf6d1a72417ae90c59df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f7e76e654c1f4c87c58f33c84ac13b115e5811571b9f07fedb08804867d3a6ff591b993d56ae0d2d054b8ac8d9e0e7b7ffc8b854d7b682ce9941b15e79a43e9
|
7
|
+
data.tar.gz: f8a65ee499723d787f6c25c26ab9d4dcabc7d764c3c18441bd2a78bbec92ed385f9fd6718724193ef76901e62b28643a181c978e29b2c350cfbd08eb2e0f93e4
|
@@ -9,7 +9,7 @@ module VatsimTools
|
|
9
9
|
attributes = %w{role callsign gcmap_width gcmap_height}
|
10
10
|
attributes.each {|attribute| attr_accessor attribute.to_sym }
|
11
11
|
|
12
|
-
LOCAL_DATA = "#{Dir.tmpdir}/vatsim_online/vatsim_data.
|
12
|
+
LOCAL_DATA = "#{Dir.tmpdir}/vatsim_online/vatsim_data.json"
|
13
13
|
|
14
14
|
def initialize(callsign, args = nil)
|
15
15
|
VatsimTools::DataDownloader.new
|
@@ -29,15 +29,21 @@ module VatsimTools
|
|
29
29
|
|
30
30
|
|
31
31
|
def stations
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
matching_stations = []
|
33
|
+
raw_data = File.read(LOCAL_DATA)
|
34
|
+
data = JSON.parse(raw_data)
|
35
|
+
pilots = data['pilots'].each {|p| p['role'] = 'pilot'}
|
36
|
+
controllers = data['controllers'].each {|p| p['role'] = 'controller'}
|
37
|
+
atis = data['atis'].each {|p| p['role'] = 'atis'}
|
38
|
+
stations = pilots + controllers + atis
|
39
|
+
stations.each do |station|
|
40
|
+
callsign = station['callsign']
|
41
|
+
@callsign.each do |cs|
|
42
|
+
matching_stations << station if callsign[0...cs.length] == cs # && client == "ATC") unless @role == "pilot"
|
37
43
|
# stations << row if (origin[0...icao.length] == icao || destination[0...icao.length] == icao) unless @role == "atc"
|
38
44
|
end
|
39
45
|
end
|
40
|
-
|
46
|
+
matching_stations
|
41
47
|
end
|
42
48
|
|
43
49
|
def station_objects
|
@@ -1,127 +1,131 @@
|
|
1
|
-
module VatsimTools
|
2
|
-
require 'tempfile'
|
3
|
-
require 'time_diff'
|
4
|
-
require 'tmpdir'
|
5
|
-
require 'net/http'
|
6
|
-
require 'fileutils'
|
7
|
-
class DataDownloader
|
8
|
-
|
9
|
-
STATUS_URL = "
|
10
|
-
TEMP_DIR = "#{Dir.tmpdir}/vatsim_online"
|
11
|
-
LOCAL_STATUS = "#{Dir.tmpdir}/vatsim_online/vatsim_status.
|
12
|
-
LOCAL_STATUS_BAK = "#{Dir.tmpdir}/vatsim_online/vatsim_status_bak.
|
13
|
-
LOCAL_DATA = "#{Dir.tmpdir}/vatsim_online/vatsim_data.
|
14
|
-
LOCAL_DATA_BAK = "#{Dir.tmpdir}/vatsim_online/vatsim_data_bak.
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
FileUtils.mkdir(TEMP_DIR) unless File.exist? TEMP_DIR
|
18
|
-
data_file
|
19
|
-
end
|
20
|
-
|
21
|
-
def create_status_tempfile
|
22
|
-
uri = URI(STATUS_URL)
|
23
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
24
|
-
request = Net::HTTP::Get.new(uri.path)
|
25
|
-
|
26
|
-
|
27
|
-
File.
|
28
|
-
File.
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
File.
|
75
|
-
File.
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
file.
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
125
|
-
|
126
|
-
|
127
|
-
|
1
|
+
module VatsimTools
|
2
|
+
require 'tempfile'
|
3
|
+
require 'time_diff'
|
4
|
+
require 'tmpdir'
|
5
|
+
require 'net/http'
|
6
|
+
require 'fileutils'
|
7
|
+
class DataDownloader
|
8
|
+
|
9
|
+
STATUS_URL = "https://status.vatsim.net/status.json"
|
10
|
+
TEMP_DIR = "#{Dir.tmpdir}/vatsim_online"
|
11
|
+
LOCAL_STATUS = "#{Dir.tmpdir}/vatsim_online/vatsim_status.json"
|
12
|
+
LOCAL_STATUS_BAK = "#{Dir.tmpdir}/vatsim_online/vatsim_status_bak.json"
|
13
|
+
LOCAL_DATA = "#{Dir.tmpdir}/vatsim_online/vatsim_data.json"
|
14
|
+
LOCAL_DATA_BAK = "#{Dir.tmpdir}/vatsim_online/vatsim_data_bak.json"
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
FileUtils.mkdir(TEMP_DIR) unless File.exist? TEMP_DIR
|
18
|
+
data_file
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_status_tempfile
|
22
|
+
uri = URI(STATUS_URL)
|
23
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
24
|
+
request = Net::HTTP::Get.new(uri.path)
|
25
|
+
http.use_ssl = (uri.scheme == 'https')
|
26
|
+
data = http.request(request).body.gsub("\n", '')
|
27
|
+
create_status_backup if File.exists?(LOCAL_STATUS)
|
28
|
+
File.write(LOCAL_STATUS, data)
|
29
|
+
File.chmod(0777, LOCAL_STATUS)
|
30
|
+
dummy_status if data.include? "<html><head>"
|
31
|
+
rescue Exception => e
|
32
|
+
if e.class == WebMock::NetConnectNotAllowedError
|
33
|
+
raise e
|
34
|
+
end
|
35
|
+
dummy_status
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_status_backup
|
39
|
+
source = LOCAL_STATUS
|
40
|
+
target = LOCAL_STATUS_BAK
|
41
|
+
FileUtils.cp_r source, target
|
42
|
+
File.chmod(0777, LOCAL_STATUS_BAK)
|
43
|
+
end
|
44
|
+
|
45
|
+
def read_status_tempfile
|
46
|
+
status = File.open(LOCAL_STATUS)
|
47
|
+
difference = Time.diff(status.ctime, Time.now)[:hour]
|
48
|
+
if difference > 3
|
49
|
+
data = create_status_tempfile
|
50
|
+
else
|
51
|
+
data = status.read
|
52
|
+
end
|
53
|
+
status.close
|
54
|
+
data
|
55
|
+
end
|
56
|
+
|
57
|
+
def status_file
|
58
|
+
File.exists?(LOCAL_STATUS) ? read_status_tempfile : create_status_tempfile
|
59
|
+
LOCAL_STATUS
|
60
|
+
end
|
61
|
+
|
62
|
+
def servers
|
63
|
+
raw_data = File.read(status_file)
|
64
|
+
data = JSON.parse(raw_data)
|
65
|
+
data['data']['v3']
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_local_data_file
|
69
|
+
uri = URI(servers.sample)
|
70
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
71
|
+
request = Net::HTTP::Get.new(uri.path)
|
72
|
+
http.use_ssl = (uri.scheme == 'https')
|
73
|
+
req_data = http.request(request).body
|
74
|
+
create_data_backup if File.exists?(LOCAL_DATA)
|
75
|
+
File.open(LOCAL_DATA, "w+") {|f| f.write(req_data.force_encoding('UTF-8'))}
|
76
|
+
File.chmod(0777, LOCAL_DATA)
|
77
|
+
gem_data_file if req_data.include? "<html><head>"
|
78
|
+
file = File.open(LOCAL_DATA)
|
79
|
+
gem_data_file if file.size == 0
|
80
|
+
file.close
|
81
|
+
rescue Exception => e
|
82
|
+
if e.class == WebMock::NetConnectNotAllowedError
|
83
|
+
raise e
|
84
|
+
end
|
85
|
+
gem_data_file
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_data_backup
|
89
|
+
source = LOCAL_DATA
|
90
|
+
target = LOCAL_DATA_BAK
|
91
|
+
FileUtils.cp_r source, target
|
92
|
+
File.chmod(0777, LOCAL_DATA_BAK)
|
93
|
+
end
|
94
|
+
|
95
|
+
def read_local_datafile
|
96
|
+
data = File.open(LOCAL_DATA)
|
97
|
+
difference = Time.diff(data.ctime, Time.now)[:minute]
|
98
|
+
if difference > 2
|
99
|
+
d = create_local_data_file
|
100
|
+
else
|
101
|
+
d = data.read
|
102
|
+
end
|
103
|
+
data.close
|
104
|
+
d
|
105
|
+
end
|
106
|
+
|
107
|
+
def data_file
|
108
|
+
File.exists?(LOCAL_DATA) ? read_local_datafile : create_local_data_file
|
109
|
+
LOCAL_DATA
|
110
|
+
end
|
111
|
+
|
112
|
+
def gem_data_file
|
113
|
+
source = LOCAL_DATA_BAK
|
114
|
+
target = LOCAL_DATA
|
115
|
+
FileUtils.cp_r source, target
|
116
|
+
File.chmod(0777, LOCAL_DATA)
|
117
|
+
end
|
118
|
+
|
119
|
+
def dummy_status
|
120
|
+
source = LOCAL_STATUS_BAK
|
121
|
+
target = LOCAL_STATUS
|
122
|
+
FileUtils.cp_r source, target
|
123
|
+
File.chmod(0777, LOCAL_STATUS)
|
124
|
+
end
|
125
|
+
def get_data(url)
|
126
|
+
uri = URI(url)
|
127
|
+
Net::HTTP.get(uri)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
@@ -12,27 +12,44 @@ module VatsimTools
|
|
12
12
|
|
13
13
|
def initialize(station, args = nil)
|
14
14
|
|
15
|
-
@callsign
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
@callsign = station['callsign']
|
16
|
+
@cid = station['cid'].to_s
|
17
|
+
@name = station['name']
|
18
|
+
@role = station['role']
|
19
|
+
@frequency = station['frequency']
|
20
|
+
@latitude = station['latitude'].to_s
|
21
|
+
@longitude = station['longitude'].to_s
|
22
|
+
@altitude = station['altitude']
|
23
|
+
@groundspeed = station['groundspeed']
|
24
|
+
@aircraft = station['flight_plan']['aircraft'] rescue ''
|
25
|
+
@origin = station['flight_plan']['departure'] rescue ''
|
26
|
+
@planned_altitude = station['flight_plan']['altitude'] rescue ''
|
27
|
+
@destination = station['flight_plan']['arrival'] rescue ''
|
28
|
+
@transponder = station['transponder']
|
29
|
+
@facility = station['facility'].to_s
|
30
|
+
@flight_type = station['flight_plan']['flight_rules'] rescue ''
|
31
|
+
@remarks = station['flight_plan']['remarks'] rescue ''
|
32
|
+
@route = station['flight_plan']['route'] rescue ''
|
33
|
+
@logon = station['logon_time']
|
34
|
+
@heading = station['heading'].to_s
|
35
|
+
@qnh_in = station['qnh_i_hg'].to_s
|
36
|
+
@qnh_mb = station['qnh_mb'].to_s
|
20
37
|
|
21
|
-
@atis = atis_cleaner(station[
|
22
|
-
@rating = humanized_rating(station[
|
23
|
-
@latitude_humanized = latitude_parser(station[
|
24
|
-
@longitude_humanized = longitude_parser(station[
|
38
|
+
@atis = atis_cleaner(station['text_atis']) if station['text_atis']
|
39
|
+
@rating = humanized_rating(station['rating'].to_s)
|
40
|
+
@latitude_humanized = latitude_parser(station['latitude'])
|
41
|
+
@longitude_humanized = longitude_parser(station['longitude'])
|
25
42
|
@online_since = utc_logon_time if @logon
|
26
43
|
@gcmap_width = args[:gcmap_width].to_i if args && args[:gcmap_width]
|
27
44
|
@gcmap_height = args[:gcmap_height].to_i if args && args[:gcmap_height]
|
28
45
|
@gcmap = gcmap_generator
|
29
|
-
@atis_message = construct_atis_message(station[
|
46
|
+
@atis_message = construct_atis_message(station['text_atis']) if station['text_atis']
|
30
47
|
end
|
31
48
|
|
32
49
|
private
|
33
50
|
|
34
51
|
def gcmap_generator
|
35
|
-
return "No map for ATC stations" if @role != "
|
52
|
+
return "No map for ATC stations" if @role != "pilot"
|
36
53
|
construct_gcmap_url.gcmap(:width => @gcmap_width, :height => @gcmap_height)
|
37
54
|
end
|
38
55
|
|
@@ -47,22 +64,26 @@ module VatsimTools
|
|
47
64
|
route
|
48
65
|
end
|
49
66
|
|
50
|
-
def latitude_parser(
|
67
|
+
def latitude_parser(lat_s)
|
68
|
+
return nil if lat_s == nil
|
69
|
+
lat = lat_s.to_f
|
51
70
|
lat > 0 ? hemisphere = "N" : hemisphere = "S"
|
52
71
|
hemisphere + lat.abs.to_s
|
53
72
|
end
|
54
73
|
|
55
|
-
def longitude_parser(
|
74
|
+
def longitude_parser(lon_s)
|
75
|
+
return nil if lon_s == nil
|
76
|
+
lon = lon_s.to_f
|
56
77
|
lon > 0 ? hemisphere = "E" : hemisphere = "W"
|
57
78
|
hemisphere + lon.abs.to_s
|
58
79
|
end
|
59
80
|
|
60
81
|
def atis_cleaner(raw_atis)
|
61
|
-
raw_atis.gsub(/[\^]/, '. ')
|
82
|
+
raw_atis.join(' ').gsub(/[\^]/, '. ')
|
62
83
|
end
|
63
84
|
|
64
85
|
def utc_logon_time
|
65
|
-
Time.parse
|
86
|
+
Time.parse(@logon)
|
66
87
|
end
|
67
88
|
|
68
89
|
def humanized_rating(rating_number)
|
@@ -84,7 +105,7 @@ module VatsimTools
|
|
84
105
|
end
|
85
106
|
|
86
107
|
def construct_atis_message(raw_atis)
|
87
|
-
message = raw_atis.gsub(/[\^]/, '<br />')
|
108
|
+
message = raw_atis.join(' ').gsub(/[\^]/, '<br />')
|
88
109
|
message.index('>') ? message = message[message.index('>')+1...message.length] : message = "No published remark"
|
89
110
|
end
|
90
111
|
|
@@ -7,9 +7,9 @@ module VatsimTools
|
|
7
7
|
require_relative "station"
|
8
8
|
|
9
9
|
attributes = %w{role icao excluded gcmap_width gcmap_height}
|
10
|
-
attributes.each {|attribute| attr_accessor attribute.to_sym }
|
10
|
+
attributes.each { |attribute| attr_accessor attribute.to_sym }
|
11
11
|
|
12
|
-
LOCAL_DATA = "#{Dir.tmpdir}/vatsim_online/vatsim_data.
|
12
|
+
LOCAL_DATA = "#{Dir.tmpdir}/vatsim_online/vatsim_data.json"
|
13
13
|
|
14
14
|
def initialize(icao, args = nil)
|
15
15
|
VatsimTools::DataDownloader.new
|
@@ -17,7 +17,7 @@ module VatsimTools
|
|
17
17
|
if icao == "ALL"
|
18
18
|
@icao = nil
|
19
19
|
else
|
20
|
-
@icao = icao.upcase.split(',').each {|s| s.strip!}
|
20
|
+
@icao = icao.upcase.split(',').each { |s| s.strip! }
|
21
21
|
end
|
22
22
|
@excluded = args[:exclude].upcase if args && args[:exclude]
|
23
23
|
@gcmap_width = args[:gcmap_width] if args && args[:gcmap_width]
|
@@ -32,44 +32,53 @@ module VatsimTools
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def stations
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
matching_stations = []
|
36
|
+
raw_data = File.read(LOCAL_DATA)
|
37
|
+
data = JSON.parse(raw_data)
|
38
|
+
pilots = data['pilots'].each { |p| p['role'] = 'pilot' }
|
39
|
+
controllers = data['controllers'].each { |p| p['role'] = 'controller' }
|
40
|
+
atis = data['atis'].each { |p| p['role'] = 'atis' }
|
41
|
+
stations = pilots + controllers + atis
|
42
|
+
stations.each do |station|
|
43
|
+
callsign = station['callsign']
|
44
|
+
destination = station['flight_plan']['arrival'] rescue ''
|
45
|
+
origin = station['flight_plan']['departure'] rescue ''
|
46
|
+
client = station['role']
|
38
47
|
unless @icao
|
39
|
-
|
40
|
-
|
48
|
+
matching_stations << station if (client == "controller") unless @role == "pilot"
|
49
|
+
matching_stations << station if (client == "pilot") unless @role == "atc"
|
41
50
|
else
|
42
|
-
|
43
|
-
|
44
|
-
|
51
|
+
@icao.each do |icao|
|
52
|
+
matching_stations << station if (callsign[0...icao.length] == icao && client == "controller") unless @role == "pilot"
|
53
|
+
matching_stations << station if (origin[0...icao.length] == icao || destination[0...icao.length] == icao) unless @role == "atc"
|
45
54
|
end
|
46
55
|
end
|
47
56
|
end
|
48
|
-
|
57
|
+
matching_stations
|
49
58
|
end
|
50
59
|
|
51
60
|
def station_objects
|
52
|
-
station_objects= []
|
61
|
+
station_objects = []
|
53
62
|
args = {}
|
54
63
|
args[:gcmap_width] = @gcmap_width if @gcmap_width
|
55
64
|
args[:gcmap_height] = @gcmap_height if @gcmap_height
|
56
|
-
stations.each {|station| station_objects << VatsimTools::Station.new(station, args) }
|
65
|
+
stations.each { |station| station_objects << VatsimTools::Station.new(station, args) }
|
57
66
|
station_objects
|
58
67
|
end
|
59
68
|
|
60
69
|
def sorted_station_objects
|
61
70
|
atc = []; pilots = []; arrivals = []; departures = []
|
62
|
-
station_objects.each {|sobj| sobj.role == "
|
71
|
+
station_objects.each { |sobj| sobj.role == "controller" ? atc << sobj : pilots << sobj }
|
63
72
|
if @icao
|
64
|
-
|
65
|
-
|
73
|
+
@icao.each do |icao|
|
74
|
+
pilots.each do |pilot|
|
66
75
|
departures << pilot if pilot.origin[0...icao.length] == icao
|
67
76
|
arrivals << pilot if pilot.destination[0...icao.length] == icao
|
68
77
|
end
|
69
78
|
end
|
70
79
|
end
|
71
|
-
atc.delete_if {|a| @excluded && a.callsign[0...@excluded.length] == @excluded }
|
72
|
-
{:atc => atc, :pilots => pilots, :arrivals => arrivals, :departures => departures}
|
80
|
+
atc.delete_if { |a| @excluded && a.callsign[0...@excluded.length] == @excluded }
|
81
|
+
{ :atc => atc, :pilots => pilots, :arrivals => arrivals, :departures => departures }
|
73
82
|
end
|
74
83
|
|
75
84
|
end
|