Class: Fontist::SystemIndexFontCollection
- Inherits:
-
Lutaml::Model::Collection
- Object
- Lutaml::Model::Collection
- Fontist::SystemIndexFontCollection
- Includes:
- Utils::Locking
- Defined in:
- lib/fontist/system_index.rb
Constant Summary collapse
- INDEX_REBUILD_THRESHOLD =
Don’t rebuild index more frequently than this (in seconds)
30 * 60
- ALLOWED_KEYS =
%i[path full_name family_name type].freeze
- OPTIONAL_KEYS =
Optional metadata keys for optimization (not required for validity)
%i[file_size file_mtime].freeze
Instance Attribute Summary collapse
-
#path ⇒ Object
Returns the value of attribute path.
-
#paths_loader ⇒ Object
Returns the value of attribute paths_loader.
Class Method Summary collapse
Instance Method Summary collapse
- #build(forced: false, verbose: false, stats: nil) ⇒ Object
-
#check_index ⇒ Object
Check if the content has all required keys.
-
#disable_read_only_mode ⇒ Object
Disable read-only mode so future ‘index` calls go through `index_changed?` again.
- #find(font, style, format_spec: nil) ⇒ Object
- #index ⇒ Object
- #index_changed? ⇒ Boolean
-
#mark_verified! ⇒ Object
Mark this index as verified, skipping future index_changed? checks Used after successfully loading the index from file.
-
#read_only_mode ⇒ Object
Enable read-only mode for operations that don’t need index rebuilding This is used during manifest compilation to avoid expensive index checks.
- #rebuild(verbose: false, stats: nil) ⇒ Object
-
#reset_verification! ⇒ Object
Reset verification flag (for testing or forcing re-check).
- #set_content(path, paths_loader) ⇒ Object
-
#set_path(path) ⇒ Object
30 minutes.
- #set_path_loader(paths_loader) ⇒ Object
- #to_file(path) ⇒ Object
- #update(verbose: false, stats: nil) ⇒ Object
Methods included from Utils::Locking
Instance Attribute Details
#path ⇒ Object
Returns the value of attribute path.
147 148 149 |
# File 'lib/fontist/system_index.rb', line 147 def path @path end |
#paths_loader ⇒ Object
Returns the value of attribute paths_loader.
147 148 149 |
# File 'lib/fontist/system_index.rb', line 147 def paths_loader @paths_loader end |
Class Method Details
.from_file(path:, paths_loader:) ⇒ Object
170 171 172 173 174 175 |
# File 'lib/fontist/system_index.rb', line 170 def self.from_file(path:, paths_loader:) # If the file does not exist, return a new collection return new.set_content(path, paths_loader) unless File.exist?(path) from_yaml(File.read(path)).set_content(path, paths_loader) end |
Instance Method Details
#build(forced: false, verbose: false, stats: nil) ⇒ Object
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/fontist/system_index.rb', line 326 def build(forced: false, verbose: false, stats: nil) if forced return rebuild_with_lock(verbose: verbose, stats: stats) end previous_index = load_index updated_fonts = update if changed?(updated_fonts, previous_index.fonts || []) # Store the updated fonts so we don't need to call update again @pending_fonts = updated_fonts.fonts rebuild_with_lock(verbose: verbose, stats: stats) end self end |
#check_index ⇒ Object
Check if the content has all required keys
190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/fontist/system_index.rb', line 190 def check_index Fontist.formulas_repo_path_exists! Array(fonts).each do |font| missing_keys = ALLOWED_KEYS.reject do |key| font.send(key) end raise_font_index_corrupted(font, missing_keys) if missing_keys.any? end end |
#disable_read_only_mode ⇒ Object
Disable read-only mode so future ‘index` calls go through `index_changed?` again. Paired with `read_only_mode` to scope the optimization to a single block (see Manifest.with_performance_optimizations).
261 262 263 264 |
# File 'lib/fontist/system_index.rb', line 261 def disable_read_only_mode @read_only_mode = false self end |
#find(font, style, format_spec: nil) ⇒ Object
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/fontist/system_index.rb', line 207 def find(font, style, format_spec: nil) current_fonts = index return nil if current_fonts.nil? || current_fonts.empty? if style.nil? found_fonts = current_fonts.select do |file| file.family_name&.casecmp?(font) end else found_fonts = current_fonts.select do |file| file.family_name&.casecmp?(font) && file.type&.casecmp?(style) end end # Apply format filtering if specified if format_spec&.has_constraints? && found_fonts require_relative "format_matcher" matcher = FormatMatcher.new(format_spec) found_fonts = matcher.filter_indexed_fonts(found_fonts) end found_fonts.empty? ? nil : found_fonts end |
#index ⇒ Object
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/fontist/system_index.rb', line 232 def index if @read_only_mode && !fonts.nil? return fonts end return fonts unless index_changed? # Notify user about index rebuild for large collections paths = @paths_loader&.call || [] if (paths.size > 100) && !@verbose Fontist.ui.say("Building font index (#{paths.size} fonts found, this may take a while...)") end build check_index fonts end |
#index_changed? ⇒ Boolean
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
# File 'lib/fontist/system_index.rb', line 266 def index_changed? return true if fonts.nil? || fonts.empty? return false if @index_check_done # Skip if already verified in this session # Quick check: if index was scanned recently, trust it if recently_scanned? Fontist.ui.debug("System index scanned #{time_since_scan} seconds ago, skipping check") @index_check_done = true return false end # Quick check: if directories haven't changed, trust the index if directories_unchanged? Fontist.ui.debug("Font directories unchanged, skipping full scan") @index_check_done = true # Update last scan time to extend validity self.last_scan_time = Time.now.to_i return false end # At this point we need to do a full scan Fontist.ui.debug("Font directories changed or stale, performing full scan") # Cache the paths loader results to avoid repeated Dir.glob calls @cached_current_paths ||= @paths_loader&.call&.sort&.uniq || [] excluded_paths_in_current = @cached_current_paths.select do |path| excluded?(path) end changed = @cached_current_paths != (font_paths + excluded_paths_in_current).uniq.sort # Mark as verified if unchanged, so we don't check again in this session @index_check_done = true unless changed changed end |
#mark_verified! ⇒ Object
Mark this index as verified, skipping future index_changed? checks Used after successfully loading the index from file
307 308 309 310 |
# File 'lib/fontist/system_index.rb', line 307 def mark_verified! @index_check_done = true self end |
#read_only_mode ⇒ Object
Enable read-only mode for operations that don’t need index rebuilding This is used during manifest compilation to avoid expensive index checks
253 254 255 256 |
# File 'lib/fontist/system_index.rb', line 253 def read_only_mode @read_only_mode = true self end |
#rebuild(verbose: false, stats: nil) ⇒ Object
343 344 345 |
# File 'lib/fontist/system_index.rb', line 343 def rebuild(verbose: false, stats: nil) build(forced: true, verbose: verbose, stats: stats) end |
#reset_verification! ⇒ Object
Reset verification flag (for testing or forcing re-check)
313 314 315 316 317 |
# File 'lib/fontist/system_index.rb', line 313 def reset_verification! @index_check_done = false @cached_current_paths = nil self end |
#set_content(path, paths_loader) ⇒ Object
177 178 179 180 181 182 |
# File 'lib/fontist/system_index.rb', line 177 def set_content(path, paths_loader) tap do |content| content.set_path(path) content.set_path_loader(paths_loader) end end |
#set_path(path) ⇒ Object
30 minutes
162 163 164 |
# File 'lib/fontist/system_index.rb', line 162 def set_path(path) @path = path end |
#set_path_loader(paths_loader) ⇒ Object
166 167 168 |
# File 'lib/fontist/system_index.rb', line 166 def set_path_loader(paths_loader) @paths_loader = paths_loader end |
#to_file(path) ⇒ Object
202 203 204 205 |
# File 'lib/fontist/system_index.rb', line 202 def to_file(path) FileUtils.mkdir_p(File.dirname(path)) File.write(path, to_yaml) end |
#update(verbose: false, stats: nil) ⇒ Object
319 320 321 322 323 324 |
# File 'lib/fontist/system_index.rb', line 319 def update(verbose: false, stats: nil) tap do |col| col.fonts = detect_paths(@paths_loader&.call || [], verbose: verbose, stats: stats) end end |