aipp 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/aipp.gemspec +1 -1
- data/exe/aip2aixm +2 -2
- data/lib/aipp/loader.rb +16 -6
- data/lib/aipp/parsers/LF/ENR-4.1.rb +102 -0
- data/lib/aipp/parsers/LF/ENR-4.3.rb +31 -0
- data/lib/aipp/{parser → parsers}/LF/ENR-5.1.rb +9 -17
- data/lib/aipp/parsers/LF/helpers/url.rb +15 -0
- data/lib/aipp/version.rb +1 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0897562e048a1f5eae251b19e4059ce16a319761acff603a0679e8688aad8a7a'
|
4
|
+
data.tar.gz: d83c038edceaab6eb9d996eba589e3aa277e702be8974d80a22c7f45b0e7f8bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1df374cfd53eaa0a5d767018996b6b62df24b7641d0755346b01c7846b4eaa40c307d777c684663335676f6003db0313e84d2ff379c74b2e0503cee5a4600e9
|
7
|
+
data.tar.gz: a3cb46a7fb3d6e43ff1f030fdd361b0a764eea73431e9880a896aae87fc101d3f91d45e084940797633f2e5f5eb6fe27c9771f1c9e14931df40e8a2c4194fe28
|
data/CHANGELOG.md
CHANGED
data/aipp.gemspec
CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_development_dependency 'guard'
|
31
31
|
spec.add_development_dependency 'guard-minitest'
|
32
32
|
|
33
|
-
spec.add_runtime_dependency 'aixm', '~> 0', '>= 0.2.
|
33
|
+
spec.add_runtime_dependency 'aixm', '~> 0', '>= 0.2.2'
|
34
34
|
spec.add_runtime_dependency 'nokogiri', '~> 1'
|
35
35
|
spec.add_runtime_dependency 'nokogumbo', '~> 1'
|
36
36
|
spec.add_runtime_dependency 'pry', '~> 0'
|
data/exe/aip2aixm
CHANGED
@@ -42,7 +42,7 @@ class Executable
|
|
42
42
|
extensions = [(:ofm if ofm)].compact
|
43
43
|
filename = [fir, aip, airac].join('_') + '.aixm'
|
44
44
|
loader = AIPP::Loader.new(fir: fir, aip: aip, airac: airac, limit: limit)
|
45
|
-
aixm = loader.aixm.
|
45
|
+
aixm = loader.aixm.to_aixm(*extensions)
|
46
46
|
File.write(Pathname.new(Dir.pwd).join(filename), aixm)
|
47
47
|
end
|
48
48
|
end
|
@@ -51,7 +51,7 @@ begin
|
|
51
51
|
executable = Executable.new
|
52
52
|
executable.run
|
53
53
|
rescue => exception
|
54
|
-
if executable
|
54
|
+
if executable&.verbose
|
55
55
|
raise exception
|
56
56
|
else
|
57
57
|
puts "#{File.basename($0)}: #{exception.message}"
|
data/lib/aipp/loader.rb
CHANGED
@@ -4,19 +4,21 @@ module AIPP
|
|
4
4
|
|
5
5
|
attr_accessor :aixm
|
6
6
|
|
7
|
+
def self.parsers_path
|
8
|
+
Pathname(__dir__).join('parsers')
|
9
|
+
end
|
10
|
+
|
7
11
|
def self.list
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
File.basename(aip_file, '.rb')
|
12
|
+
parsers_path.each_child.each.with_object({}) do |fir, hash|
|
13
|
+
hash[fir.basename.to_s] = fir.glob('*.rb').map do |aip|
|
14
|
+
aip.basename('.rb').to_s
|
12
15
|
end
|
13
16
|
end
|
14
17
|
end
|
15
18
|
|
16
19
|
def initialize(fir:, aip:, airac:, limit:)
|
17
20
|
@fir, @aip, @airac, @limit = fir.upcase, aip.upcase, airac, limit
|
18
|
-
|
19
|
-
self.singleton_class.send(:include, AIPP::Parser)
|
21
|
+
load_parser
|
20
22
|
@aixm = AIXM.document(effective_at: @airac)
|
21
23
|
convert!
|
22
24
|
warn "WARNING: document is not complete" unless aixm.complete?
|
@@ -27,6 +29,14 @@ module AIPP
|
|
27
29
|
|
28
30
|
private
|
29
31
|
|
32
|
+
def load_parser
|
33
|
+
self.class.parsers_path.join(@fir, 'helpers').glob('*.rb').each do |helper|
|
34
|
+
require helper
|
35
|
+
end
|
36
|
+
require_relative "parsers/#{@fir}/#{@aip}"
|
37
|
+
self.singleton_class.send(:include, AIPP::Parsers)
|
38
|
+
end
|
39
|
+
|
30
40
|
def file
|
31
41
|
file_name = "#{@fir}_#{@aip}_#{@airac}.html"
|
32
42
|
Pathname.new(Dir.tmpdir).join(file_name).tap do |file_path|
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module AIPP
|
2
|
+
module Parsers
|
3
|
+
include Helpers::URL
|
4
|
+
using AIPP::Refinements
|
5
|
+
|
6
|
+
def convert!
|
7
|
+
html.css('tbody').each do |tbody|
|
8
|
+
tbody.css('tr').to_enum.with_index(1).each do |tr, index|
|
9
|
+
break if index >= @limit
|
10
|
+
tds = tr.css('td')
|
11
|
+
master, slave = tds[1].text.strip.downcase.gsub(/[^\w-]/, '').downcase.split('-')
|
12
|
+
navaid = AIXM.send(master, base_from(tds).merge(send("#{master}_from", tds)))
|
13
|
+
navaid.schedule = schedule_from(tds[4])
|
14
|
+
navaid.remarks = remarks_from(tds[5], tds[7], tds[9])
|
15
|
+
navaid.send("associate_#{slave}", channel: channel_from(tds[3])) if slave
|
16
|
+
aixm.features << navaid
|
17
|
+
rescue => exception
|
18
|
+
warn("WARNING: error parsing navigational aid at ##{index}: #{exception.message}", binding)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def base_from(tds)
|
27
|
+
{
|
28
|
+
id: tds[2].text.strip,
|
29
|
+
name: tds[0].text.strip,
|
30
|
+
xy: xy_from(tds[5]),
|
31
|
+
z: z_from(tds[6])
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def vor_from(tds)
|
36
|
+
{
|
37
|
+
type: :vor,
|
38
|
+
f: frequency_from(tds[3]),
|
39
|
+
north: :geographic,
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def dme_from(tds)
|
44
|
+
{
|
45
|
+
channel: channel_from(tds[3])
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def ndb_from(tds)
|
50
|
+
{
|
51
|
+
f: frequency_from(tds[3])
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def tacan_from(tds)
|
56
|
+
{
|
57
|
+
channel: channel_from(tds[3])
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def xy_from(td)
|
62
|
+
parts = td.text.strip.split(/\s+/)
|
63
|
+
AIXM.xy(lat: parts[0], long: parts[1])
|
64
|
+
end
|
65
|
+
|
66
|
+
def z_from(td)
|
67
|
+
parts = td.text.strip.split(/\s+/)
|
68
|
+
AIXM.z(parts[0].to_i, :qnh) if parts[1] == 'ft'
|
69
|
+
end
|
70
|
+
|
71
|
+
def frequency_from(td)
|
72
|
+
parts = td.text.strip.split(/\s+/)
|
73
|
+
AIXM.f(parts[0], parts[1]) if parts[1] =~ /hz$/i
|
74
|
+
end
|
75
|
+
|
76
|
+
def channel_from(td)
|
77
|
+
parts = td.text.strip.split(/\s+/)
|
78
|
+
parts.last if parts[-2].downcase == 'ch'
|
79
|
+
end
|
80
|
+
|
81
|
+
def schedule_from(td)
|
82
|
+
code = td.text.strip
|
83
|
+
AIXM.schedule(code: code) unless code.empty?
|
84
|
+
end
|
85
|
+
|
86
|
+
def remarks_from(*parts)
|
87
|
+
part_titles = ['RANGE', 'SITUATION', 'OBSERVATIONS']
|
88
|
+
[].tap do |remarks|
|
89
|
+
parts.each.with_index do |part, index|
|
90
|
+
text = if index == 0
|
91
|
+
part = part.text.strip.split(/\s+/)
|
92
|
+
part.shift(2)
|
93
|
+
part.join(' ').blank_to_nil
|
94
|
+
else
|
95
|
+
part.text.strip.blank_to_nil
|
96
|
+
end
|
97
|
+
remarks << "#{part_titles[index]}:\n#{text}" if text
|
98
|
+
end
|
99
|
+
end.join("\n\n").blank_to_nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module AIPP
|
2
|
+
module Parsers
|
3
|
+
include Helpers::URL
|
4
|
+
# using AIPP::Refinements
|
5
|
+
|
6
|
+
def convert!
|
7
|
+
html.css('tbody').each do |tbody|
|
8
|
+
tbody.css('tr').to_enum.with_index(1).each do |tr, index|
|
9
|
+
break if index >= @limit
|
10
|
+
tds = tr.css('td')
|
11
|
+
designated_point = AIXM.designated_point(
|
12
|
+
type: :icao,
|
13
|
+
id: tds[0].text.strip,
|
14
|
+
xy: xy_from(tds[1])
|
15
|
+
)
|
16
|
+
aixm.features << designated_point
|
17
|
+
rescue => exception
|
18
|
+
warn("WARNING: error parsing designated point at ##{index}: #{exception.message}", binding)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def xy_from(td)
|
27
|
+
parts = td.text.strip.split(/\s+/)
|
28
|
+
AIXM.xy(lat: parts[0], long: parts[1])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
module AIPP
|
2
|
-
module
|
2
|
+
module Parsers
|
3
|
+
include Helpers::URL
|
3
4
|
using AIPP::Refinements
|
4
5
|
using AIXM::Refinements
|
5
6
|
|
6
7
|
TYPES = {
|
7
|
-
'D' =>
|
8
|
-
'P' =>
|
9
|
-
'R' =>
|
10
|
-
'ZIT' =>
|
8
|
+
'D' => 'D',
|
9
|
+
'P' => 'P',
|
10
|
+
'R' => 'R',
|
11
|
+
'ZIT' => 'P'
|
11
12
|
}.freeze
|
12
13
|
|
13
14
|
BORDERS = {
|
@@ -19,18 +20,10 @@ module AIPP
|
|
19
20
|
'franco-belge' => 'BELGIUM_FRANCE'
|
20
21
|
}.freeze
|
21
22
|
|
22
|
-
def url
|
23
|
-
"https://www.sia.aviation-civile.gouv.fr/dvd/eAIP_%s/FRANCE/AIRAC-%s/html/eAIP/FR-%s-fr-FR.html" % [
|
24
|
-
aixm.effective_at.strftime('%d_%^b_%Y'), # 04_JAN_2018
|
25
|
-
aixm.effective_at.to_date.xmlschema, # 2018-01-04
|
26
|
-
@aip # ENR-5.1
|
27
|
-
]
|
28
|
-
end
|
29
|
-
|
30
23
|
def convert!
|
31
24
|
html.css('tbody:has(tr[id^=mid])').each do |tbody|
|
32
25
|
airspace = nil
|
33
|
-
tbody.css('tr').
|
26
|
+
tbody.css('tr').to_enum.with_index(1).each do |tr, index|
|
34
27
|
if tr.attr(:class) =~ /keep-with-next-row/
|
35
28
|
airspace = airspace_from tr
|
36
29
|
else
|
@@ -42,9 +35,9 @@ module AIPP
|
|
42
35
|
airspace.remarks = remarks_from(tds[2], tds[3], tds[4])
|
43
36
|
fail "airspace `#{airspace.name}' is not complete" unless airspace.complete?
|
44
37
|
aixm.features << airspace
|
45
|
-
break if index / 2
|
38
|
+
break if index / 2 >= @limit
|
46
39
|
rescue => exception
|
47
|
-
warn("WARNING: error parsing airspace `#{airspace.name}': #{exception.message}", binding)
|
40
|
+
warn("WARNING: error parsing airspace `#{airspace.name}' at ##{index}: #{exception.message}", binding)
|
48
41
|
end
|
49
42
|
end
|
50
43
|
end
|
@@ -135,6 +128,5 @@ module AIPP
|
|
135
128
|
end
|
136
129
|
end.join("\n\n")
|
137
130
|
end
|
138
|
-
|
139
131
|
end
|
140
132
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module AIPP
|
2
|
+
module Helpers
|
3
|
+
module URL
|
4
|
+
|
5
|
+
def url
|
6
|
+
"https://www.sia.aviation-civile.gouv.fr/dvd/eAIP_%s/FRANCE/AIRAC-%s/html/eAIP/FR-%s-fr-FR.html" % [
|
7
|
+
aixm.effective_at.strftime('%d_%^b_%Y'), # 04_JAN_2018
|
8
|
+
aixm.effective_at.to_date.xmlschema, # 2018-01-04
|
9
|
+
@aip # ENR-5.1
|
10
|
+
]
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/aipp/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aipp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Schwyn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -131,7 +131,7 @@ dependencies:
|
|
131
131
|
version: '0'
|
132
132
|
- - ">="
|
133
133
|
- !ruby/object:Gem::Version
|
134
|
-
version: 0.2.
|
134
|
+
version: 0.2.2
|
135
135
|
type: :runtime
|
136
136
|
prerelease: false
|
137
137
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -141,7 +141,7 @@ dependencies:
|
|
141
141
|
version: '0'
|
142
142
|
- - ">="
|
143
143
|
- !ruby/object:Gem::Version
|
144
|
-
version: 0.2.
|
144
|
+
version: 0.2.2
|
145
145
|
- !ruby/object:Gem::Dependency
|
146
146
|
name: nokogiri
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,7 +206,10 @@ files:
|
|
206
206
|
- lib/aipp.rb
|
207
207
|
- lib/aipp/airac.rb
|
208
208
|
- lib/aipp/loader.rb
|
209
|
-
- lib/aipp/
|
209
|
+
- lib/aipp/parsers/LF/ENR-4.1.rb
|
210
|
+
- lib/aipp/parsers/LF/ENR-4.3.rb
|
211
|
+
- lib/aipp/parsers/LF/ENR-5.1.rb
|
212
|
+
- lib/aipp/parsers/LF/helpers/url.rb
|
210
213
|
- lib/aipp/refinements.rb
|
211
214
|
- lib/aipp/version.rb
|
212
215
|
- spec/lib/aipp/airac_spec.rb
|