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) ⇒ 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.
140 141 142 |
# File 'lib/fontist/system_index.rb', line 140 def path @path end |
#paths_loader ⇒ Object
Returns the value of attribute paths_loader.
140 141 142 |
# File 'lib/fontist/system_index.rb', line 140 def paths_loader @paths_loader end |
Class Method Details
.from_file(path:, paths_loader:) ⇒ Object
163 164 165 166 167 168 |
# File 'lib/fontist/system_index.rb', line 163 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
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/fontist/system_index.rb', line 313 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
183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/fontist/system_index.rb', line 183 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) ⇒ Object
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/fontist/system_index.rb', line 200 def find(font, style) 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 found_fonts.empty? ? nil : found_fonts end |
#index ⇒ Object
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/fontist/system_index.rb', line 218 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
247 248 249 250 251 252 253 254 255 256 257 258 259 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 |
# File 'lib/fontist/system_index.rb', line 247 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
288 289 290 291 |
# File 'lib/fontist/system_index.rb', line 288 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
242 243 244 245 |
# File 'lib/fontist/system_index.rb', line 242 def read_only_mode @read_only_mode = true self end |
#rebuild(verbose: false, stats: nil) ⇒ Object
330 331 332 |
# File 'lib/fontist/system_index.rb', line 330 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)
294 295 296 297 298 |
# File 'lib/fontist/system_index.rb', line 294 def reset_verification! @index_check_done = false @cached_current_paths = nil self end |
#set_content(path, paths_loader) ⇒ Object
170 171 172 173 174 175 |
# File 'lib/fontist/system_index.rb', line 170 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
155 156 157 |
# File 'lib/fontist/system_index.rb', line 155 def set_path(path) @path = path end |
#set_path_loader(paths_loader) ⇒ Object
159 160 161 |
# File 'lib/fontist/system_index.rb', line 159 def set_path_loader(paths_loader) @paths_loader = paths_loader end |
#to_file(path) ⇒ Object
195 196 197 198 |
# File 'lib/fontist/system_index.rb', line 195 def to_file(path) FileUtils.mkdir_p(File.dirname(path)) File.write(path, to_yaml) end |
#update(verbose: false, stats: nil) ⇒ Object
300 301 302 303 304 |
# File 'lib/fontist/system_index.rb', line 300 def update tap do |col| col.fonts = detect_paths(@paths_loader&.call || []) end end |