lib/fontist/import/recursive_extraction.rb in fontist-1.6.0 vs lib/fontist/import/recursive_extraction.rb in fontist-1.7.0

- old
+ new

@@ -1,32 +1,44 @@ require "find" require_relative "extractors" +require_relative "files/font_detector" module Fontist module Import class RecursiveExtraction - BOTH_FONTS_PATTERN = "**/*.{ttf,otf,ttc}*".freeze + FONTS_PATTERN = "**/*.{ttf,otf,ttc}".freeze ARCHIVE_EXTENSIONS = %w[zip msi exe cab].freeze + LICENSE_PATTERN = /(OFL\.txt|UFL\.txt|LICENSE\.txt|COPYING)$/i.freeze - def initialize(archive, subarchive: nil) + def initialize(archive, subarchive: nil, subdir: nil) @archive = archive @subarchive = subarchive + @subdir = subdir @operations = [] + @font_files = [] + @collection_files = [] end def extension File.extname(filename(@archive)).sub(/^\./, "") end - def extract(pattern) - Array.new.tap do |results| - Find.find(extracted_path) do |path| # rubocop:disable Style/CollectionMethods, Metrics/LineLength - results << yield(path) if path.match(pattern) - end - end + def font_files + ensure_extracted + @font_files end + def font_collection_files + ensure_extracted + @collection_files + end + + def license_text + ensure_extracted + @license_text + end + def operations ensure_extracted @operations.size == 1 ? @operations.first : @operations end @@ -48,11 +60,15 @@ @extracted_path ||= extract_recursively(@archive) end def extract_recursively(archive) path = operate_on_archive(archive) - return path if fonts_exist?(path) + match_files(path) + if matched? + save_operation_subdir + return path + end next_archive = find_archive(path) extract_recursively(next_archive) end @@ -82,12 +98,53 @@ def save_operation(extractor) @operations << { format: extractor.format } end - def fonts_exist?(path) - fonts = Dir.glob(File.join(path, BOTH_FONTS_PATTERN)) - !fonts.empty? + def match_files(dir_path) + Find.find(dir_path) do |entry_path| # rubocop:disable Style/CollectionMethods + match_license(entry_path) + match_font(entry_path) if font_directory?(entry_path, dir_path) + end + end + + def match_license(path) + @license_text ||= File.read(path) if license?(path) + end + + def license?(file) + file.match?(LICENSE_PATTERN) + end + + def font_directory?(path, base_path) + return true unless @subdir + + relative_path = Pathname.new(path).relative_path_from(base_path).to_s + dirname = File.dirname(relative_path) + normalized_pattern = @subdir.chomp("/") + File.fnmatch?(normalized_pattern, dirname) + end + + def match_font(path) + case Files::FontDetector.detect(path) + when :font + @font_files << Otf::FontFile.new(path) + when :collection + @collection_files << Files::CollectionFile.new(path) + end + end + + def matched? + [@font_files, @collection_files].any? do |files| + files.size.positive? + end + end + + def save_operation_subdir + return unless @subdir + + @operations.last[:options] ||= {} + @operations.last[:options][:fonts_sub_dir] = @subdir end def find_archive(path) paths = Dir.children(path).map { |file| File.join(path, file) } by_subarchive(paths) || by_size(paths)