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.
- #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.
146 147 148 |
# File 'lib/fontist/system_index.rb', line 146 def path @path end |
#paths_loader ⇒ Object
Returns the value of attribute paths_loader.
146 147 148 |
# File 'lib/fontist/system_index.rb', line 146 def paths_loader @paths_loader end |
Class Method Details
.from_file(path:, paths_loader:) ⇒ Object
169 170 171 172 173 174 |
# File 'lib/fontist/system_index.rb', line 169 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
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/fontist/system_index.rb', line 320 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
189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/fontist/system_index.rb', line 189 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 |
#find(font, style, format_spec: nil) ⇒ Object
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/fontist/system_index.rb', line 206 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
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/fontist/system_index.rb', line 231 def index # Fast path: if read_only mode is set, skip index_changed? check entirely # But we still need to build if fonts is nil (first time access) if @read_only_mode && !fonts.nil? return fonts # Fall through to build the index on first access 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
260 261 262 263 264 265 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 |
# File 'lib/fontist/system_index.rb', line 260 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
301 302 303 304 |
# File 'lib/fontist/system_index.rb', line 301 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
255 256 257 258 |
# File 'lib/fontist/system_index.rb', line 255 def read_only_mode @read_only_mode = true self end |
#rebuild(verbose: false, stats: nil) ⇒ Object
337 338 339 |
# File 'lib/fontist/system_index.rb', line 337 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)
307 308 309 310 311 |
# File 'lib/fontist/system_index.rb', line 307 def reset_verification! @index_check_done = false @cached_current_paths = nil self end |
#set_content(path, paths_loader) ⇒ Object
176 177 178 179 180 181 |
# File 'lib/fontist/system_index.rb', line 176 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
161 162 163 |
# File 'lib/fontist/system_index.rb', line 161 def set_path(path) @path = path end |
#set_path_loader(paths_loader) ⇒ Object
165 166 167 |
# File 'lib/fontist/system_index.rb', line 165 def set_path_loader(paths_loader) @paths_loader = paths_loader end |
#to_file(path) ⇒ Object
201 202 203 204 |
# File 'lib/fontist/system_index.rb', line 201 def to_file(path) FileUtils.mkdir_p(File.dirname(path)) File.write(path, to_yaml) end |
#update(verbose: false, stats: nil) ⇒ Object
313 314 315 316 317 318 |
# File 'lib/fontist/system_index.rb', line 313 def update(verbose: false, stats: nil) tap do |col| col.fonts = detect_paths(@paths_loader&.call || [], verbose: verbose, stats: stats) end end |