Class: Fontist::Import::Google::FontDatabase

Inherits:
Object
  • Object
show all
Defined in:
lib/fontist/import/google/font_database.rb

Overview

Database for merged font data from API sources

Generates v4 formulas (TTF static only) or v5 formulas (all formats)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ttf_data:, vf_data: nil, woff2_data: nil, github_data: nil, version: 4, source_path: nil) ⇒ FontDatabase

Initialize database with API data

Parameters:

  • ttf_data (Array)

    TTF endpoint data

  • vf_data (Array, nil) (defaults to: nil)

    VF endpoint data (optional, for v5)

  • woff2_data (Array, nil) (defaults to: nil)

    WOFF2 endpoint data (optional, for v5)

  • github_data (Array, nil) (defaults to: nil)

    GitHub repository data (optional)

  • version (Integer) (defaults to: 4)

    Formula version (4 or 5)

  • source_path (String, nil) (defaults to: nil)

    Path to google/fonts repository (optional)



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/fontist/import/google/font_database.rb', line 88

def initialize(ttf_data:, vf_data: nil, woff2_data: nil,
github_data: nil, version: 4, source_path: nil)
  @ttf_data = Array(ttf_data)
  @vf_data = Array(vf_data)
  @woff2_data = Array(woff2_data)
  @github_data_raw = Array(github_data)
  @version = version
  @source_path = source_path
  @ttf_files = {}
  @woff2_files = {}
  @github_index = index_github_data
  @github_data = @github_index # Expose indexed version
  @fonts = merge_data
end

Instance Attribute Details

#fontsObject (readonly)

Returns the value of attribute fonts.



11
12
13
# File 'lib/fontist/import/google/font_database.rb', line 11

def fonts
  @fonts
end

#github_dataObject (readonly)

Returns the value of attribute github_data.



11
12
13
# File 'lib/fontist/import/google/font_database.rb', line 11

def github_data
  @github_data
end

#ttf_filesObject (readonly)

Returns the value of attribute ttf_files.



11
12
13
# File 'lib/fontist/import/google/font_database.rb', line 11

def ttf_files
  @ttf_files
end

#versionObject (readonly)

Returns the value of attribute version.



11
12
13
# File 'lib/fontist/import/google/font_database.rb', line 11

def version
  @version
end

#woff2_filesObject (readonly)

Returns the value of attribute woff2_files.



11
12
13
# File 'lib/fontist/import/google/font_database.rb', line 11

def woff2_files
  @woff2_files
end

Class Method Details

.build(api_key:, source_path: nil) ⇒ FontDatabase

Generic build method for backward compatibility Delegates to build_v4 by default

Parameters:

  • api_key (String)

    Google Fonts API key

  • source_path (String, nil) (defaults to: nil)

    Path to google/fonts repository (optional)

Returns:



70
71
72
73
74
75
76
77
78
# File 'lib/fontist/import/google/font_database.rb', line 70

def self.build(api_key:, source_path: nil)
  if source_path
    build_v4(api_key: api_key, source_path: source_path)
  else
    # Build without GitHub data
    ttf_data = DataSources::Ttf.new(api_key: api_key).fetch
    new(ttf_data: ttf_data, version: 4, source_path: nil)
  end
end

.build_v4(api_key:, source_path:) ⇒ FontDatabase

Build database for v4 formulas (production)

V4 Requirements:

  • TTF format ONLY (no WOFF2)

  • Static fonts ONLY (exclude variable fonts)

  • OFL.txt license from GitHub repository

  • Complete metadata from Fontisan

Parameters:

  • api_key (String)

    Google Fonts API key

  • source_path (String)

    Path to google/fonts repository

Returns:



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/fontist/import/google/font_database.rb', line 24

def self.build_v4(api_key:, source_path:)
  ttf_data = DataSources::Ttf.new(api_key: api_key).fetch
  # NO VF endpoint, NO WOFF2 endpoint for v4
  github_data = DataSources::Github.new(source_path: source_path).fetch

  new(
    ttf_data: ttf_data,
    github_data: github_data,
    version: 4,
    source_path: source_path,
  )
end

.build_v5(api_key:, source_path:) ⇒ FontDatabase

Build database for v5 formulas (future)

V5 will support:

  • TTF + WOFF2 formats

  • Static + Variable fonts

  • Enhanced ‘provides` attribute

  • Per-file resources

Parameters:

  • api_key (String)

    Google Fonts API key

  • source_path (String)

    Path to google/fonts repository

Returns:



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/fontist/import/google/font_database.rb', line 48

def self.build_v5(api_key:, source_path:)
  ttf_data = DataSources::Ttf.new(api_key: api_key).fetch
  vf_data = DataSources::Vf.new(api_key: api_key).fetch
  woff2_data = DataSources::Woff2.new(api_key: api_key).fetch
  github_data = DataSources::Github.new(source_path: source_path).fetch

  new(
    ttf_data: ttf_data,
    vf_data: vf_data,
    woff2_data: woff2_data,
    github_data: github_data,
    version: 5,
    source_path: source_path,
  )
end

Instance Method Details

#all_fontsObject

Get all font families



104
105
106
# File 'lib/fontist/import/google/font_database.rb', line 104

def all_fonts
  @fonts.values
end

#by_category(category) ⇒ Object

Filter fonts by category



114
115
116
# File 'lib/fontist/import/google/font_database.rb', line 114

def by_category(category)
  all_fonts.select { |font| font.category == category }
end

#categoriesObject

Get all unique categories



138
139
140
# File 'lib/fontist/import/google/font_database.rb', line 138

def categories
  all_fonts.map(&:category).compact.uniq.sort
end

#create_import_source(family) ⇒ GoogleImportSource?

Create GoogleImportSource for a font family

Parameters:

Returns:



293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/fontist/import/google/font_database.rb', line 293

def create_import_source(family)
  # Only create import_source if we have a commit_id
  commit = current_commit_id
  return nil unless commit

  Fontist::GoogleImportSource.new(
    commit_id: commit,
    api_version: "v1",
    last_modified: last_modified_for(family),
    family_id: family.family.downcase.tr(" ", "_"),
  )
end

#current_commit_idString?

Get current git commit from google/fonts repository

Returns:

  • (String, nil)

    Git commit SHA or nil if not available



270
271
272
273
274
275
276
277
278
# File 'lib/fontist/import/google/font_database.rb', line 270

def current_commit_id
  return @commit_id if defined?(@commit_id)

  @commit_id = if @source_path && File.directory?(@source_path)
                 get_git_commit(@source_path)
               end

  @commit_id
end

#default_description(family) ⇒ Object

Generate default description



239
240
241
# File 'lib/fontist/import/google/font_database.rb', line 239

def default_description(family)
  "#{family.family} font family"
end

#default_homepage(family) ⇒ Object

Generate default homepage



244
245
246
# File 'lib/fontist/import/google/font_database.rb', line 244

def default_homepage(family)
  "https://fonts.google.com/specimen/#{family.family.gsub(/\s+/, '+')}"
end

#find_font_filename_for_variant(family, variant) ⇒ Object

Find filename for a variant



210
211
212
213
214
215
216
217
218
219
220
# File 'lib/fontist/import/google/font_database.rb', line 210

def find_font_filename_for_variant(family, variant)
  # Try TTF first
  url = @ttf_files[family.family]&.[](variant)
  return url.split("/").last if url

  # Try WOFF2
  url = @woff2_files[family.family]&.[](variant)
  return url.split("/").last if url

  nil
end

#font_by_name(family_name) ⇒ Object

Find a specific font family by name



109
110
111
# File 'lib/fontist/import/google/font_database.rb', line 109

def font_by_name(family_name)
  @fonts[family_name]
end

#fonts_countObject

Get count of fonts by type



129
130
131
132
133
134
135
# File 'lib/fontist/import/google/font_database.rb', line 129

def fonts_count
  {
    total: all_fonts.count,
    variable: variable_fonts_only.count,
    static: static_fonts_only.count,
  }
end

#fonts_with_both_formatsObject

Get fonts available in both formats



153
154
155
156
157
# File 'lib/fontist/import/google/font_database.rb', line 153

def fonts_with_both_formats
  all_fonts.select do |font|
    @ttf_files.key?(font.family) && @woff2_files.key?(font.family)
  end
end

#fonts_with_ttfObject

Get fonts available in TTF format



143
144
145
# File 'lib/fontist/import/google/font_database.rb', line 143

def fonts_with_ttf
  all_fonts.select { |font| @ttf_files.key?(font.family) }
end

#fonts_with_woff2Object

Get fonts available in WOFF2 format



148
149
150
# File 'lib/fontist/import/google/font_database.rb', line 148

def fonts_with_woff2
  all_fonts.select { |font| @woff2_files.key?(font.family) }
end

#formula_name(family) ⇒ Object

Generate formula name from family name



234
235
236
# File 'lib/fontist/import/google/font_database.rb', line 234

def formula_name(family)
  family.family.downcase.gsub(/\s+/, "_")
end

#last_modified_for(family) ⇒ String

Get last modified timestamp for a font family

Parameters:

Returns:

  • (String)

    ISO 8601 timestamp



284
285
286
287
# File 'lib/fontist/import/google/font_database.rb', line 284

def last_modified_for(family)
  # Use last_modified from API metadata if available
  family.last_modified || Time.now.utc.iso8601
end

#save_formula(formula_hash, family_name, output_dir) ⇒ Object

Save formula to disk



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/fontist/import/google/font_database.rb', line 249

def save_formula(formula_hash, family_name, output_dir)
  FileUtils.mkdir_p(output_dir)

  # Google Fonts formulas always use simple filenames
  # (Google Fonts is a live service, always pointing to latest version)
  base_name = family_name.downcase.gsub(/\s+/, "_")
  filename = "#{base_name}.yml"

  path = File.join(output_dir, filename)

  # Use HashHelper to convert keys to strings (preserves import_source object)
  formula_with_string_keys = Helpers::HashHelper.stringify_keys(formula_hash)

  File.write(path, YAML.dump(formula_with_string_keys))

  path
end

#save_formulas(output_dir, family_name: nil) ⇒ Object

Save formulas to disk



197
198
199
200
201
202
203
204
205
206
207
# File 'lib/fontist/import/google/font_database.rb', line 197

def save_formulas(output_dir, family_name: nil)
  families = family_name ? [font_by_name(family_name)] : all_fonts
  families = families.compact

  families.map do |family|
    formula = to_formula(family.family)
    next unless formula

    save_formula(formula, family.family, output_dir)
  end.compact
end

#static_fonts_onlyObject

Get only static fonts (fonts without axes)



124
125
126
# File 'lib/fontist/import/google/font_database.rb', line 124

def static_fonts_only
  all_fonts.reject(&:variable_font?)
end

#to_formula(family_name) ⇒ Object

Generate formula for a font family



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/fontist/import/google/font_database.rb', line 170

def to_formula(family_name)
  family = font_by_name(family_name)
  return nil unless family

  # Use FormulaBuilder class for version-aware building
  require_relative "formula_builder"
  formula = FormulaBuilder.build(
    family,
    version: @version,
    github_index: @github_index,
    ttf_files: @ttf_files,
    woff2_files: @woff2_files,
  )

  # Add import_source if available (requires commit_id from source_path)
  import_source = create_import_source(family)
  formula[:import_source] = import_source if import_source

  formula
end

#to_formulasObject

Generate formulas for all fonts



192
193
194
# File 'lib/fontist/import/google/font_database.rb', line 192

def to_formulas
  all_fonts.map { |f| to_formula(f.family) }.compact
end

#ttf_files_for(family_name) ⇒ Object

Get TTF files for a specific font family



160
161
162
# File 'lib/fontist/import/google/font_database.rb', line 160

def ttf_files_for(family_name)
  @ttf_files[family_name]
end

#variable_fonts_onlyObject

Get only variable fonts (fonts with axes)



119
120
121
# File 'lib/fontist/import/google/font_database.rb', line 119

def variable_fonts_only
  all_fonts.select(&:variable_font?)
end

#variant_to_type(variant) ⇒ Object

Convert API variant to style type



223
224
225
226
227
228
229
230
231
# File 'lib/fontist/import/google/font_database.rb', line 223

def variant_to_type(variant)
  case variant
  when "regular" then "Regular"
  when "italic" then "Italic"
  when /^(\d+)italic$/ then "#{$1} Italic"
  when /^(\d+)$/ then variant
  else variant.capitalize
  end
end

#woff2_files_for(family_name) ⇒ Object

Get WOFF2 files for a specific font family



165
166
167
# File 'lib/fontist/import/google/font_database.rb', line 165

def woff2_files_for(family_name)
  @woff2_files[family_name]
end