Module: Fontist::Indexes::IncrementalScanner
- Defined in:
- lib/fontist/indexes/incremental_scanner.rb
Class Method Summary collapse
-
.compute_signature(path) ⇒ Object
Compute SHA256 signature of first 1KB for quick change detection.
-
.detect_format(path) ⇒ Object
Detect font format from file header.
-
.scan_batch(paths, cache: {}) ⇒ Object
Scan multiple font files in batch cache: Optional hash of path => cached_version Returns: Array of font metadata hashes.
-
.scan_directory(directory) ⇒ Object
Scan a single directory and return font metadata Returns: Array of hashes with path, filename, file_size, file_mtime, signature.
-
.scan_font_file(path) ⇒ Object
Scan a single font file and extract metadata Returns: Hash with path, filename, file_size, file_mtime, signature, format.
-
.scan_with_cache(path, cached_version) ⇒ Object
Scan with cache - reuse cached metadata if file unchanged Returns: Hash if file exists and unchanged, nil otherwise.
Class Method Details
.compute_signature(path) ⇒ Object
Compute SHA256 signature of first 1KB for quick change detection
67 68 69 70 71 72 73 |
# File 'lib/fontist/indexes/incremental_scanner.rb', line 67 def self.compute_signature(path) return nil unless File.exist?(path) # Read first 1KB for fast signature header = File.read(path, 1024) Digest::SHA256.hexdigest(header) end |
.detect_format(path) ⇒ Object
Detect font format from file header
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/fontist/indexes/incremental_scanner.rb', line 76 def self.detect_format(path) return :unknown unless File.exist?(path) header = File.read(path, 4) # Debug output # puts "detect_format: path=#{path}, header=#{header.bytes.inspect}" case header when /^\x00\x01\x00\x00/ :truetype when /^OTTO/ :opentype when /^wOFF/ :woff when /^wOF2/ :woff2 else :unknown end end |
.scan_batch(paths, cache: {}) ⇒ Object
Scan multiple font files in batch cache: Optional hash of path => cached_version Returns: Array of font metadata hashes
55 56 57 58 59 60 61 62 63 64 |
# File 'lib/fontist/indexes/incremental_scanner.rb', line 55 def self.scan_batch(paths, cache: {}) paths.map do |path| cached = cache[path] if cached scan_with_cache(path, cached) else scan_font_file(path) end end.compact end |
.scan_directory(directory) ⇒ Object
Scan a single directory and return font metadata Returns: Array of hashes with path, filename, file_size, file_mtime, signature
8 9 10 11 12 13 14 |
# File 'lib/fontist/indexes/incremental_scanner.rb', line 8 def self.scan_directory(directory) return [] unless Dir.exist?(directory) PathScanning.list_font_directory(directory).map do |path| scan_font_file(path) end end |
.scan_font_file(path) ⇒ Object
Scan a single font file and extract metadata Returns: Hash with path, filename, file_size, file_mtime, signature, format
18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/fontist/indexes/incremental_scanner.rb', line 18 def self.scan_font_file(path) return nil unless File.exist?(path) stat = File.stat(path) { path: path, filename: File.basename(path), file_size: stat.size, file_mtime: stat.mtime.to_i, signature: compute_signature(path), format: detect_format(path), } end |
.scan_with_cache(path, cached_version) ⇒ Object
Scan with cache - reuse cached metadata if file unchanged Returns: Hash if file exists and unchanged, nil otherwise
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/fontist/indexes/incremental_scanner.rb', line 35 def self.scan_with_cache(path, cached_version) return nil unless File.exist?(path) current_stat = File.stat(path) # Check if file changed if cached_version && cached_version[:file_size] == current_stat.size && cached_version[:file_mtime] == current_stat.mtime.to_i # Could also check signature here for extra certainty return cached_version end # File changed or no cache - rescan scan_font_file(path) end |