flightstats 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/flightstats/data_feed.rb +1 -48
- data/lib/flightstats/data_feed/file.rb +4 -3
- data/lib/flightstats/data_feed/file/sax_parser.rb +9 -2
- data/lib/flightstats/data_feed/sax_parser.rb +1 -0
- data/test/flightstats/data_feed/file_test.rb +124 -3
- data/test/responses/feed_file_list_tz_fallback.xml +2 -0
- data/test/responses/test_tz_fallback1.gz +0 -0
- data/test/responses/test_tz_fallback2.gz +0 -0
- metadata +4 -1
@@ -22,52 +22,5 @@ class FlightStats::DataFeed
|
|
22
22
|
files
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
26
|
-
# def self.get_gz_file(id)
|
27
|
-
# id = id['id'] if id.class == Hash
|
28
|
-
# FlightStats::raw_query({:file=>id}, '/development/feed')
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
# def self.get_file(id)
|
32
|
-
# Zlib::GzipReader.new(FlightStats::DataFeed.get_gz_file(id))
|
33
|
-
# end
|
34
|
-
#
|
35
|
-
# # passes each file to a block,
|
36
|
-
# # each file is the raw gzipped file from flightstats, StringIO object
|
37
|
-
# def each_gz_file(&block)
|
38
|
-
# if block.arity == 1
|
39
|
-
# @files.each{ |f| block.call(FlightStats::DataFeed.get_gz_file(f)) }
|
40
|
-
# elsif block.arity == 2
|
41
|
-
# @files.each { |f|
|
42
|
-
# block.call(FlightStats::DataFeed.get_gz_file(f), f['timestamp'])
|
43
|
-
# }
|
44
|
-
# end
|
45
|
-
# end
|
46
|
-
#
|
47
|
-
# # passes each file to a block, each file is a Zlib::GzipReader instance
|
48
|
-
# def each_file(&block)
|
49
|
-
# if block.arity == 1
|
50
|
-
# @files.each{ |f| block.call(FlightStats::DataFeed.get_file(f)) }
|
51
|
-
# elsif block.arity == 2
|
52
|
-
# @files.each { |f|
|
53
|
-
# block.call(FlightStats::DataFeed.get_file(f), f['timestamp'])
|
54
|
-
# }
|
55
|
-
# end
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
# # passes each update to a block, each update is an instance of FlightStats::Flight
|
59
|
-
# def each(&block)
|
60
|
-
# each_file { |file| FlightStats::DataFeed.process_file(file, &block) }
|
61
|
-
# end
|
62
|
-
#
|
63
|
-
# def self.process_file(file, &block)
|
64
|
-
# xml = LibXML::XML::Parser.string(file.read, PARSER_OPTIONS).parse.root
|
65
|
-
# xml.children.each do |node|
|
66
|
-
# flight = FlightStats::Flight.new(node.children[0])
|
67
|
-
# time_updated = Time.parse(node.attributes['DateTimeRecorded'][0..18] + ' PT')
|
68
|
-
# flight.attributes['updated_at'] = time_updated.utc
|
69
|
-
# block.call(flight)
|
70
|
-
# end
|
71
|
-
# end
|
72
|
-
#
|
25
|
+
|
73
26
|
end
|
@@ -3,8 +3,9 @@ class FlightStats::DataFeed::File
|
|
3
3
|
attr_accessor :id, :message_count, :bytes, :timestamp
|
4
4
|
alias :size :bytes
|
5
5
|
|
6
|
-
def initialize(content = nil)
|
6
|
+
def initialize(content = nil, timestamp = nil)
|
7
7
|
@content = content if content.is_a?(StringIO) or content.is_a?(File)
|
8
|
+
@timestamp = timestamp
|
8
9
|
end
|
9
10
|
|
10
11
|
def content
|
@@ -18,11 +19,11 @@ class FlightStats::DataFeed::File
|
|
18
19
|
parser = LibXML::XML::SaxParser.io(Zlib::GzipReader.new(content))
|
19
20
|
|
20
21
|
if block_given?
|
21
|
-
parser.callbacks = SaxParser.new(&block)
|
22
|
+
parser.callbacks = SaxParser.new(@timestamp, &block)
|
22
23
|
parser.parse
|
23
24
|
else
|
24
25
|
updates = []
|
25
|
-
parser.callbacks = SaxParser.new { |update| updates << update }
|
26
|
+
parser.callbacks = SaxParser.new(@timestamp) { |update| updates << update }
|
26
27
|
parser.parse
|
27
28
|
updates
|
28
29
|
end
|
@@ -2,8 +2,9 @@ class FlightStats::DataFeed::File::SaxParser
|
|
2
2
|
|
3
3
|
include LibXML::XML::SaxParser::Callbacks
|
4
4
|
|
5
|
-
def initialize(&on_update_block)
|
5
|
+
def initialize(file_timestamp_utc, &on_update_block)
|
6
6
|
@stack = []
|
7
|
+
@file_timestamp_utc = file_timestamp_utc
|
7
8
|
@on_update_block = on_update_block
|
8
9
|
end
|
9
10
|
|
@@ -24,7 +25,13 @@ class FlightStats::DataFeed::File::SaxParser
|
|
24
25
|
@update.event = attributes['Event']
|
25
26
|
@update.data_updated = attributes['DataUpdated']
|
26
27
|
tz = TZInfo::Timezone.get('America/Los_Angeles')
|
27
|
-
@update.timestamp = tz.local_to_utc(to_time(attributes['DateTimeRecorded']))
|
28
|
+
@update.timestamp = tz.local_to_utc(to_time(attributes['DateTimeRecorded'])) do |periods|
|
29
|
+
if @file_timestamp_utc
|
30
|
+
periods.select{ |period|
|
31
|
+
period.to_utc(to_time(attributes['DateTimeRecorded'])).hour == @file_timestamp_utc.utc.hour
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
28
35
|
when 'FlightHistory'
|
29
36
|
@flight = FlightStats::Flight.new
|
30
37
|
@flight.id = attributes['FlightHistoryId']
|
@@ -11,10 +11,14 @@ class FlightStats::DataFeed::FileTest < Test::Unit::TestCase
|
|
11
11
|
:body => File.read("#{File.dirname(__FILE__)}/../../responses/test2.gz"))
|
12
12
|
|
13
13
|
count = 0
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
begin
|
15
|
+
FlightStats::DataFeed.new.files do |file|
|
16
|
+
file.updates do |update|
|
17
|
+
count += 1
|
18
|
+
end
|
17
19
|
end
|
20
|
+
rescue
|
21
|
+
GC.start
|
18
22
|
end
|
19
23
|
assert_equal 11, count
|
20
24
|
end
|
@@ -43,6 +47,7 @@ class FlightStats::DataFeed::FileTest < Test::Unit::TestCase
|
|
43
47
|
changes << update
|
44
48
|
end
|
45
49
|
end
|
50
|
+
|
46
51
|
update = changes[0]
|
47
52
|
assert_equal(Time.utc(2009,6,8,20,30,0,43), update.timestamp)
|
48
53
|
assert_equal('ASDI', update.source)
|
@@ -143,4 +148,120 @@ class FlightStats::DataFeed::FileTest < Test::Unit::TestCase
|
|
143
148
|
assert_equal('CM', update.flight.codeshares.first.airline.code)
|
144
149
|
assert_equal('CM', update.flight.codeshares.first.airline.iata_code)
|
145
150
|
end
|
151
|
+
|
152
|
+
def test_convert_local_time_to_correct_utc_time_when_is_an_ambiguous_local_time
|
153
|
+
FakeWeb.register_uri(:get, "https://www.pathfinder-xml.com/development/feed?login.guid=test&useUTC=true&lastAccessed=#{Time.now.utc.strftime("%Y-%m-%dT%H:%M")}",
|
154
|
+
:body => File.read("#{File.dirname(__FILE__)}/../../responses/feed_file_list_tz_fallback.xml"))
|
155
|
+
FakeWeb.register_uri(:get, "https://www.pathfinder-xml.com/development/feed?login.guid=test&file=4551477",
|
156
|
+
:body => File.read("#{File.dirname(__FILE__)}/../../responses/test_tz_fallback1.gz"))
|
157
|
+
FakeWeb.register_uri(:get, "https://www.pathfinder-xml.com/development/feed?login.guid=test&file=4551480",
|
158
|
+
:body => File.read("#{File.dirname(__FILE__)}/../../responses/test_tz_fallback2.gz"))
|
159
|
+
|
160
|
+
changes = Array.new
|
161
|
+
FlightStats::DataFeed.new.files do |file|
|
162
|
+
file.updates do |update|
|
163
|
+
changes << update
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
update = changes[0]
|
168
|
+
assert_equal(Time.utc(2009,11,1,8,37,0,43), update.timestamp)
|
169
|
+
assert_equal('ASDI', update.source)
|
170
|
+
assert_equal('STATUS-Active', update.event)
|
171
|
+
assert_equal('ARD- New=06/08/09 16:24, ERD- Old=06/08/09 16:26 New=06/08/09 16:24, ERA- Old=06/08/09 17:45 New=06/08/09 17:42, STATUS- Old=S New=A', update.data_updated)
|
172
|
+
|
173
|
+
assert_equal('162197049', update.flight.id)
|
174
|
+
assert_equal('753', update.flight.number)
|
175
|
+
assert_equal(Time.utc(2009,6,8,16,26), update.flight.scheduled_local_runway_departure_time)
|
176
|
+
assert_equal(Time.utc(2009,6,8,16,24), update.flight.estimated_local_runway_departure_time)
|
177
|
+
assert_equal(Time.utc(2009,6,8,16,24,52), update.flight.actual_local_runway_departure_time)
|
178
|
+
assert_equal(Time.utc(2009,6,8,17,45), update.flight.scheduled_local_runway_arrival_time)
|
179
|
+
assert_equal(Time.utc(2009,6,8,17,42), update.flight.estimated_local_runway_arrival_time)
|
180
|
+
assert_equal('A', update.flight.creator_code)
|
181
|
+
assert_equal('A', update.flight.status_code)
|
182
|
+
assert_equal(79, update.flight.scheduled_air_time)
|
183
|
+
assert_equal(-4, update.flight.departure_airport_timezone_offset)
|
184
|
+
assert_equal(-4, update.flight.arrival_airport_timezone_offset)
|
185
|
+
assert_equal(Time.utc(2009,6,8,16,26), update.flight.local_departure_time)
|
186
|
+
assert_equal(Time.utc(2009,6,8,17,45), update.flight.local_arrival_time)
|
187
|
+
|
188
|
+
assert_equal('G4', update.flight.airline.code)
|
189
|
+
assert_equal('AAY', update.flight.airline.icao_code)
|
190
|
+
assert_nil(update.flight.airline.iata_code)
|
191
|
+
assert_nil(update.flight.airline.faa_code)
|
192
|
+
assert_nil(update.flight.airline.name)
|
193
|
+
|
194
|
+
assert_equal('SFB', update.flight.origin.code)
|
195
|
+
assert_equal('KSFB', update.flight.origin.icao_code)
|
196
|
+
assert_nil(update.flight.origin.iata_code)
|
197
|
+
assert_nil(update.flight.origin.faa_code)
|
198
|
+
assert_nil(update.flight.origin.name)
|
199
|
+
|
200
|
+
assert_equal('GSO', update.flight.destination.code)
|
201
|
+
assert_equal('KGSO', update.flight.destination.icao_code)
|
202
|
+
assert_nil(update.flight.destination.iata_code)
|
203
|
+
assert_nil(update.flight.destination.faa_code)
|
204
|
+
assert_nil(update.flight.destination.name)
|
205
|
+
|
206
|
+
assert_equal([], update.flight.codeshares)
|
207
|
+
|
208
|
+
update = changes[6]
|
209
|
+
assert_equal(Time.utc(2009,11,1,9,37,1,110), update.timestamp)
|
210
|
+
assert_equal('Airline (CO)', update.source)
|
211
|
+
assert_equal('Time Adjustment', update.event)
|
212
|
+
assert_equal('EGD- New=06/08/09 19:35, EGA- New=06/08/09 23:35, DGATE- New=C-30', update.data_updated)
|
213
|
+
|
214
|
+
assert_equal('161861862', update.flight.id)
|
215
|
+
assert_equal('1417', update.flight.number)
|
216
|
+
assert_equal(Time.utc(2009,6,8,19,35), update.flight.published_local_departure_time)
|
217
|
+
assert_equal(Time.utc(2009,6,8,23,35), update.flight.published_local_arrival_time)
|
218
|
+
assert_equal(Time.utc(2009,6,8,19,35), update.flight.scheduled_local_gate_departure_time)
|
219
|
+
assert_equal(Time.utc(2009,6,8,19,35), update.flight.estimated_local_gate_departure_time)
|
220
|
+
assert_equal(Time.utc(2009,6,8,23,35), update.flight.scheduled_local_gate_arrival_time)
|
221
|
+
assert_equal(Time.utc(2009,6,8,23,35), update.flight.estimated_local_gate_arrival_time)
|
222
|
+
assert_equal(Time.utc(2009,6,8,19,56), update.flight.scheduled_local_runway_departure_time)
|
223
|
+
assert_equal(Time.utc(2009,6,8,19,56), update.flight.estimated_local_runway_departure_time)
|
224
|
+
assert_equal(Time.utc(2009,6,8,23,21), update.flight.scheduled_local_runway_arrival_time)
|
225
|
+
assert_equal(Time.utc(2009,6,8,23,21), update.flight.estimated_local_runway_arrival_time)
|
226
|
+
assert_nil(update.flight.actual_local_runway_departure_time)
|
227
|
+
assert_equal('O', update.flight.creator_code)
|
228
|
+
assert_equal('S', update.flight.status_code)
|
229
|
+
assert_equal(145, update.flight.scheduled_air_time)
|
230
|
+
assert_equal(180, update.flight.scheduled_block_time)
|
231
|
+
assert_equal(-5, update.flight.departure_airport_timezone_offset)
|
232
|
+
assert_equal(-4, update.flight.arrival_airport_timezone_offset)
|
233
|
+
assert_equal(Time.utc(2009,6,8,19,35), update.flight.local_departure_time)
|
234
|
+
assert_equal(Time.utc(2009,6,8,23,35), update.flight.local_arrival_time)
|
235
|
+
assert_equal('735', update.flight.scheduled_aircraft_type)
|
236
|
+
assert_equal('C-30', update.flight.departure_gate)
|
237
|
+
assert_equal('C', update.flight.departure_terminal)
|
238
|
+
assert_nil(update.flight.arrival_terminal)
|
239
|
+
|
240
|
+
assert_equal('CO', update.flight.airline.code)
|
241
|
+
assert_equal('COA', update.flight.airline.icao_code)
|
242
|
+
assert_nil(update.flight.airline.iata_code)
|
243
|
+
assert_nil(update.flight.airline.faa_code)
|
244
|
+
assert_nil(update.flight.airline.name)
|
245
|
+
|
246
|
+
assert_equal('IAH', update.flight.origin.code)
|
247
|
+
assert_equal('KIAH', update.flight.origin.icao_code)
|
248
|
+
assert_nil(update.flight.origin.iata_code)
|
249
|
+
assert_nil(update.flight.origin.faa_code)
|
250
|
+
assert_nil(update.flight.origin.name)
|
251
|
+
|
252
|
+
assert_equal('PIT', update.flight.destination.code)
|
253
|
+
assert_equal('KPIT', update.flight.destination.icao_code)
|
254
|
+
assert_nil(update.flight.destination.iata_code)
|
255
|
+
assert_nil(update.flight.destination.faa_code)
|
256
|
+
assert_nil(update.flight.destination.name)
|
257
|
+
|
258
|
+
assert_equal(1, update.flight.codeshares.size)
|
259
|
+
assert_equal('109977276', update.flight.codeshares.first.id)
|
260
|
+
assert_equal('2317', update.flight.codeshares.first.number)
|
261
|
+
assert_equal('L', update.flight.codeshares.first.designator)
|
262
|
+
assert_equal(Time.utc(2009,6,8,19,35), update.flight.codeshares.first.published_local_departure_time)
|
263
|
+
assert_equal(Time.utc(2009,6,8,23,35), update.flight.codeshares.first.published_local_arrival_time)
|
264
|
+
assert_equal('CM', update.flight.codeshares.first.airline.code)
|
265
|
+
assert_equal('CM', update.flight.codeshares.first.airline.iata_code)
|
266
|
+
end
|
146
267
|
end
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<FlightHistoryEventFeedResponse xmlns="http://pathfinder-xml/FlightHistoryEventFeedService.xsd"><File Bytes="265293" DateTime="2009-11-01T01:37:00.000" DateTimeUTC="2009-11-01T08:37:00.000" ID="4551477" Messages="1760"/><File Bytes="231618" DateTime="2009-11-01T01:37:00.000" DateTimeUTC="2009-11-01T09:37:00.000" ID="4551480" Messages="1505"/></FlightHistoryEventFeedResponse>
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flightstats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- FlightCaster
|
@@ -60,8 +60,11 @@ files:
|
|
60
60
|
- test/test_helper.rb
|
61
61
|
- test/responses/test1.gz
|
62
62
|
- test/responses/test2.gz
|
63
|
+
- test/responses/test_tz_fallback1.gz
|
64
|
+
- test/responses/test_tz_fallback2.gz
|
63
65
|
- test/responses/error.xml
|
64
66
|
- test/responses/feed_file_list.xml
|
67
|
+
- test/responses/feed_file_list_tz_fallback.xml
|
65
68
|
has_rdoc: true
|
66
69
|
homepage: http://flightcaster.com/
|
67
70
|
licenses: []
|