lib/aipp/parser.rb in aipp-0.2.6 vs lib/aipp/parser.rb in aipp-1.0.0

- old
+ new

@@ -1,10 +1,11 @@ module AIPP # AIP parser infrastructure class Parser - + extend Forwardable + include AIPP::Debugger using AIXM::Refinements # @return [Hash] passed command line arguments attr_reader :options @@ -35,92 +36,97 @@ @cache = OpenStruct.new AIXM.send("#{options[:schema]}!") AIXM.config.region = options[:region] end + # @return [String] + def inspect + "#<AIPP::Parser>" + end + # Read the configuration from config.yml. def read_config - info("Reading config.yml") - @config = YAML.load_file(config_file, fallback: {}).transform_keys(&:to_sym) if config_file.exist? + info("reading config.yml") + @config = YAML.load_file(config_file, symbolize_names: true, fallback: {}) if config_file.exist? @config[:namespace] ||= SecureRandom.uuid @aixm.namespace = @config[:namespace] end # Read the region directory and build the dependency list. def read_region - info("Reading region #{options[:region]}") + info("reading region #{options[:region]}") dir = Pathname(__FILE__).dirname.join('regions', options[:region]) fail("unknown region `#{options[:region]}'") unless dir.exist? # Fixtures dir.glob('fixtures/*.yml').each do |file| - verbose_info "Reading fixture fixtures/#{file.basename}" + verbose_info "reading fixture fixtures/#{file.basename}" fixture = YAML.load_file(file) @fixtures[file.basename('.yml').to_s] = fixture end # Borders dir.glob('borders/*.geojson').each do |file| - verbose_info "Reading border borders/#{file.basename}" - border = AIPP::Border.new(file) - @borders[border.name] = border + verbose_info "reading border borders/#{file.basename}" + border = AIPP::Border.from_file(file) + @borders[file.basename] = border end # Helpers dir.glob('helpers/*.rb').each do |file| - verbose_info "Reading helper helpers/#{file.basename}" + verbose_info "reading helper helpers/#{file.basename}" require file end # Parsers dir.glob('*.rb').each do |file| - verbose_info "Requiring #{file.basename}" + verbose_info "requiring #{file.basename}" require file aip = file.basename('.*').to_s - @dependencies[aip] = ("AIPP::%s::%s::DEPENDS" % [options[:region], aip.remove(/\W/).classify]).constantize + @dependencies[aip] = ("AIPP::%s::%s::DEPENDS" % [options[:region], aip.remove(/\W/).camelcase]).constantize end end # Parse AIP by invoking the parser classes for the current region. def parse_aip info("AIRAC #{options[:airac].id} effective #{options[:airac].date}", color: :green) AIPP::Downloader.new(storage: options[:storage], source: options[:airac].date.xmlschema) do |downloader| @dependencies.tsort(options[:aip]).each do |aip| - info("Parsing #{aip}") - ("AIPP::%s::%s" % [options[:region], aip.remove(/\W/).classify]).constantize.new( + info("parsing #{aip}") + ("AIPP::%s::%s" % [options[:region], aip.remove(/\W/).camelcase]).constantize.new( aip: aip, downloader: downloader, fixture: @fixtures[aip], parser: self ).attach_patches.tap(&:parse).detach_patches end end if options[:grouped_obstacles] - info("Grouping obstacles") + info("grouping obstacles") aixm.group_obstacles! end - info("Counting #{aixm.features.count} features") + info("counting #{aixm.features.count} features") end # Validate the AIXM document. # # @raise [RuntimeError] if the document is not valid def validate_aixm - info("Detecting duplicates") + info("detecting duplicates") if (duplicates = aixm.features.duplicates).any? message = "duplicates found:\n" + duplicates.map { "#{_1.inspect} from #{_1.source}" }.join("\n") - @options[:force] ? warn(message, pry: binding) : fail(message) + @options[:force] ? warn(message) : fail(message) end - info("Validating #{options[:schema].upcase}") + info("validating #{options[:schema].upcase}") unless aixm.valid? message = "invalid #{options[:schema].upcase} document:\n" + aixm.errors.map(&:message).join("\n") - @options[:force] ? warn(message, pry: binding) : fail(message) + @options[:force] ? warn(message) : fail(message) end end # Write the AIXM document and context information. def write_build if @options[:aip] - info ("Skipping build") + info ("skipping build") else - info("Writing build") + info("writing build") builds_path.mkpath build_file = builds_path.join("#{@options[:airac].date.xmlschema}.zip") Dir.mktmpdir do |tmp_dir| tmp_dir = Pathname(tmp_dir) # AIXM/OFMX file @@ -133,24 +139,23 @@ config: @config, options: @options }.to_yaml ) # Manifest - manifest, buffer, feature, aip, uid, comment = [], '', '', '', '', '' - File.open(tmp_dir.join(aixm_file)).each do |line| - buffer << line - case line - when /^ {2}<(\w{3}).*source=".*?\|.*?\|(.*?)\|/ then buffer, feature, aip = line, $1, $2 - when /^ {4}<#{feature}Uid[^>]+?mid="(.*?)"/ then uid = $1 - when /^ {2}<!-- (.*) -->/ then comment = $1 - when /^ {2}<\/#{feature}>/ - manifest << [aip, feature, uid[0,8], AIXM::PayloadHash.new(buffer).to_uuid[0,8], comment].to_csv - feature, aip, uid = '', '', '' - end - end - manifest = manifest.sort.prepend "AIP,Feature,Short Uid Hash,Short Feature Hash,Comment\n" - File.write(tmp_dir.join('manifest.csv'), manifest.join) + manifest = ['AIP','Feature', 'Comment', 'Short Uid Hash', 'Short Feature Hash'].to_csv + manifest += aixm.features.map do |feature| + xml = feature.to_xml + element = xml.first_match(/<(\w{3})\s/) + [ + feature.source.split('|')[2], + element, + xml.match(/<!-- (.*?) -->/)[1], + AIXM::PayloadHash.new(xml.match(%r(<#{element}Uid\s.*?</#{element}Uid>)m).to_s).to_uuid[0,8], + AIXM::PayloadHash.new(xml).to_uuid[0,8] + ].to_csv + end.sort.join + File.write(tmp_dir.join('manifest.csv'), manifest) # Zip it build_file.delete if build_file.exist? Zip::File.open(build_file, Zip::File::CREATE) do |zip| tmp_dir.children.each do |entry| zip.add(entry.basename.to_s, entry) unless entry.basename.to_s[0] == '.' @@ -160,17 +165,17 @@ end end # Write the AIXM document. def write_aixm - info("Writing #{aixm_file}") + info("writing #{aixm_file}") AIXM.config.mid = options[:mid] File.write(aixm_file, aixm.to_xml) end # Write the configuration to config.yml. def write_config - info("Writing config.yml") + info("writing config.yml") File.write(config_file, config.to_yaml) end private