aipp 0.1.0 → 0.1.2
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/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
|