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)