fontist 1.20.0 → 1.21.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +21 -0
- data/.github/workflows/tebako-pack.yml +2 -2
- data/.github/workflows/test-and-release.yml +22 -16
- data/README.adoc +1 -1
- data/exe/fontist +1 -2
- data/fontist.gemspec +1 -1
- data/lib/fontist/cli/thor_ext.rb +79 -0
- data/lib/fontist/cli.rb +2 -0
- data/lib/fontist/config.rb +2 -1
- data/lib/fontist/font.rb +5 -0
- data/lib/fontist/font_installer.rb +22 -51
- data/lib/fontist/formula.rb +6 -0
- data/lib/fontist/helpers.rb +2 -0
- data/lib/fontist/import/create_formula.rb +77 -35
- data/lib/fontist/import/formula_builder.rb +63 -81
- data/lib/fontist/import/google/api.rb +25 -0
- data/lib/fontist/import/google/create_google_formula.rb +89 -0
- data/lib/fontist/import/google_import.rb +63 -32
- data/lib/fontist/import/recursive_extraction.rb +0 -16
- data/lib/fontist/manifest/locations.rb +2 -0
- data/lib/fontist/resources/archive_resource.rb +55 -0
- data/lib/fontist/resources/google_resource.rb +64 -0
- data/lib/fontist/style_version.rb +4 -0
- data/lib/fontist/utils/cache.rb +16 -0
- data/lib/fontist/utils/downloader.rb +9 -2
- data/lib/fontist/utils/ui.rb +10 -2
- data/lib/fontist/version.rb +1 -1
- data/lib/fontist.rb +5 -1
- metadata +15 -6
- data/lib/fontist/import/google/new_fonts_fetcher.rb +0 -146
- data/lib/fontist/import/google/skiplist.yml +0 -12
- data/lib/fontist/import/google_check.rb +0 -27
@@ -1,49 +1,70 @@
|
|
1
1
|
require "shellwords"
|
2
2
|
require_relative "text_helper"
|
3
|
+
require_relative "helpers/hash_helper"
|
3
4
|
|
4
5
|
module Fontist
|
5
6
|
module Import
|
6
7
|
class FormulaBuilder
|
7
|
-
FORMULA_ATTRIBUTES = %i[platforms description homepage resources
|
8
|
+
FORMULA_ATTRIBUTES = %i[name platforms description homepage resources
|
8
9
|
font_collections fonts extract copyright
|
9
10
|
license_url requires_license_agreement
|
10
11
|
open_license digest command].freeze
|
11
12
|
|
12
|
-
attr_writer :
|
13
|
-
:url,
|
14
|
-
:extractor,
|
13
|
+
attr_writer :resources,
|
15
14
|
:options,
|
16
15
|
:font_files,
|
17
16
|
:font_collection_files,
|
18
17
|
:license_text,
|
19
|
-
:
|
18
|
+
:operations
|
20
19
|
|
21
20
|
def initialize
|
22
21
|
@options = {}
|
22
|
+
@font_files = []
|
23
|
+
@font_collection_files = []
|
23
24
|
end
|
24
25
|
|
25
26
|
def formula
|
26
27
|
formula_attributes.map { |name| [name, send(name)] }.to_h.compact
|
27
28
|
end
|
28
29
|
|
30
|
+
def save
|
31
|
+
path = vacant_path
|
32
|
+
yaml = YAML.dump(Helpers::HashHelper.stringify_keys(formula))
|
33
|
+
File.write(path, yaml)
|
34
|
+
path
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def formula_attributes
|
40
|
+
FORMULA_ATTRIBUTES
|
41
|
+
end
|
42
|
+
|
29
43
|
def name
|
44
|
+
@name ||= generate_name
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_name
|
30
48
|
return @options[:name] if @options[:name]
|
31
49
|
|
32
|
-
common =
|
33
|
-
.map { |attr| both_fonts.map(&attr).uniq }
|
34
|
-
.map { |names| TextHelper.longest_common_prefix(names) }
|
35
|
-
.map { |prefix| prefix unless prefix == "Regular" }
|
36
|
-
.compact
|
37
|
-
.join(" ")
|
50
|
+
common = common_prefix
|
38
51
|
return common unless common.empty?
|
39
52
|
|
40
53
|
both_fonts.map(&:family_name).first
|
41
54
|
end
|
42
55
|
|
43
|
-
|
56
|
+
def common_prefix
|
57
|
+
family_prefix = common_prefix_by_attr(:family_name)
|
58
|
+
style_prefix = common_prefix_by_attr(:type)
|
44
59
|
|
45
|
-
|
46
|
-
|
60
|
+
[family_prefix, style_prefix].compact.join(" ")
|
61
|
+
end
|
62
|
+
|
63
|
+
def common_prefix_by_attr(attr)
|
64
|
+
names = both_fonts.map(&attr).uniq
|
65
|
+
prefix = TextHelper.longest_common_prefix(names)
|
66
|
+
|
67
|
+
prefix unless prefix == "Regular"
|
47
68
|
end
|
48
69
|
|
49
70
|
def both_fonts
|
@@ -70,69 +91,7 @@ module Fontist
|
|
70
91
|
end
|
71
92
|
|
72
93
|
def resources
|
73
|
-
|
74
|
-
|
75
|
-
{ filename => resource_options }
|
76
|
-
end
|
77
|
-
|
78
|
-
def resource_options
|
79
|
-
if @options[:skip_sha]
|
80
|
-
resource_options_without_sha
|
81
|
-
else
|
82
|
-
resource_options_with_sha
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def resource_options_without_sha
|
87
|
-
{ urls: [@url] + mirrors, file_size: file_size }
|
88
|
-
end
|
89
|
-
|
90
|
-
def resource_options_with_sha
|
91
|
-
urls = []
|
92
|
-
sha = []
|
93
|
-
downloads do |url, path|
|
94
|
-
urls << url
|
95
|
-
sha << Digest::SHA256.file(path).to_s
|
96
|
-
end
|
97
|
-
|
98
|
-
sha = prepare_sha256(sha)
|
99
|
-
|
100
|
-
{ urls: urls, sha256: sha, file_size: file_size }
|
101
|
-
end
|
102
|
-
|
103
|
-
def downloads
|
104
|
-
yield @url, @archive
|
105
|
-
|
106
|
-
mirrors.each do |url|
|
107
|
-
path = download(url)
|
108
|
-
next unless path
|
109
|
-
|
110
|
-
yield url, path
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def mirrors
|
115
|
-
@options[:mirror] || []
|
116
|
-
end
|
117
|
-
|
118
|
-
def download(url)
|
119
|
-
Fontist::Utils::Downloader.download(url, progress_bar: true).path
|
120
|
-
rescue Errors::InvalidResourceError
|
121
|
-
Fontist.ui.error("WARN: a mirror is not found '#{url}'")
|
122
|
-
nil
|
123
|
-
end
|
124
|
-
|
125
|
-
def prepare_sha256(input)
|
126
|
-
output = input.uniq
|
127
|
-
return output.first if output.size == 1
|
128
|
-
|
129
|
-
checksums = output.join(", ")
|
130
|
-
Fontist.ui.error("WARN: SHA256 differs (#{checksums})")
|
131
|
-
output
|
132
|
-
end
|
133
|
-
|
134
|
-
def file_size
|
135
|
-
File.size(@archive)
|
94
|
+
@resources || raise("Resources should be set.")
|
136
95
|
end
|
137
96
|
|
138
97
|
def font_collections
|
@@ -175,7 +134,7 @@ module Fontist
|
|
175
134
|
end
|
176
135
|
|
177
136
|
def extract
|
178
|
-
@
|
137
|
+
@operations || {}
|
179
138
|
end
|
180
139
|
|
181
140
|
def copyright
|
@@ -197,9 +156,11 @@ module Fontist
|
|
197
156
|
|
198
157
|
return unless @license_text
|
199
158
|
|
200
|
-
|
201
|
-
|
202
|
-
|
159
|
+
unless @options[:open_license]
|
160
|
+
Fontist.ui.error("WARN: ensure it's an open license, otherwise " \
|
161
|
+
"change the 'open_license' attribute to " \
|
162
|
+
"'requires_license_agreement'")
|
163
|
+
end
|
203
164
|
|
204
165
|
TextHelper.cleanup(@license_text)
|
205
166
|
end
|
@@ -211,6 +172,27 @@ module Fontist
|
|
211
172
|
def command
|
212
173
|
Shellwords.shelljoin(ARGV)
|
213
174
|
end
|
175
|
+
|
176
|
+
def vacant_path
|
177
|
+
path = path_from_name
|
178
|
+
return path unless @options[:keep_existing] && File.exist?(path)
|
179
|
+
|
180
|
+
2.upto(9) do |i|
|
181
|
+
candidate = path.sub(/\.yml$/, "#{i}.yml")
|
182
|
+
return candidate unless File.exist?(candidate)
|
183
|
+
end
|
184
|
+
|
185
|
+
raise Errors::GeneralError, "Formula #{path} already exists."
|
186
|
+
end
|
187
|
+
|
188
|
+
def path_from_name
|
189
|
+
filename = Import.name_to_filename(name)
|
190
|
+
if @options[:formula_dir]
|
191
|
+
File.join(@options[:formula_dir], filename)
|
192
|
+
else
|
193
|
+
filename
|
194
|
+
end
|
195
|
+
end
|
214
196
|
end
|
215
197
|
end
|
216
198
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fontist
|
2
|
+
module Import
|
3
|
+
module Google
|
4
|
+
class Api
|
5
|
+
class << self
|
6
|
+
def items
|
7
|
+
db["items"]
|
8
|
+
end
|
9
|
+
|
10
|
+
def db
|
11
|
+
@db ||= JSON.parse(Net::HTTP.get(URI(url)))
|
12
|
+
end
|
13
|
+
|
14
|
+
def url
|
15
|
+
"https://www.googleapis.com/webfonts/v1/webfonts?key=#{api_key}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def api_key
|
19
|
+
Fontist.google_fonts_key
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require "fontist/import"
|
2
|
+
require "fontist/import/formula_builder"
|
3
|
+
require "fontist/import/otf/font_file"
|
4
|
+
|
5
|
+
module Fontist
|
6
|
+
module Import
|
7
|
+
module Google
|
8
|
+
class CreateGoogleFormula
|
9
|
+
REPO_PATH = Fontist.fontist_path.join("google", "fonts")
|
10
|
+
POSSIBLE_LICENSE_FILES = ["LICENSE.txt",
|
11
|
+
"LICENCE.txt",
|
12
|
+
"OFL.txt",
|
13
|
+
"UFL.txt"].freeze
|
14
|
+
|
15
|
+
def initialize(item, options = {})
|
16
|
+
@item = item
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
builder = FormulaBuilder.new
|
22
|
+
builder.options = options
|
23
|
+
builder.resources = resources
|
24
|
+
builder.font_files = font_files
|
25
|
+
builder.license_text = license_text
|
26
|
+
builder.save
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def options
|
32
|
+
@options.merge(name: formula_name, open_license: true)
|
33
|
+
end
|
34
|
+
|
35
|
+
def formula_name
|
36
|
+
@item["family"]
|
37
|
+
end
|
38
|
+
|
39
|
+
def resources
|
40
|
+
{
|
41
|
+
@item["family"] => {
|
42
|
+
source: "google",
|
43
|
+
family: @item["family"],
|
44
|
+
files: @item["files"].values,
|
45
|
+
},
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def font_files
|
50
|
+
@font_files ||= @item["files"].map do |_key, url|
|
51
|
+
font_file(url)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def license_text
|
56
|
+
@license_text ||= find_license_text
|
57
|
+
end
|
58
|
+
|
59
|
+
def font_file(url)
|
60
|
+
path = Utils::Downloader.download(url, use_content_length: false).path
|
61
|
+
Otf::FontFile.new(path)
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_license_text
|
65
|
+
file = license_file
|
66
|
+
return unless file
|
67
|
+
|
68
|
+
File.read(file)
|
69
|
+
end
|
70
|
+
|
71
|
+
def license_file
|
72
|
+
dir = @item["family"].gsub(" ", "").downcase
|
73
|
+
path = repo_paths(dir).first
|
74
|
+
return unless path
|
75
|
+
|
76
|
+
full_paths = POSSIBLE_LICENSE_FILES.map { |f| File.join(path, f) }
|
77
|
+
|
78
|
+
Dir[*full_paths].first
|
79
|
+
end
|
80
|
+
|
81
|
+
def repo_paths(dir)
|
82
|
+
Dir[File.join(REPO_PATH, "apache", dir),
|
83
|
+
File.join(REPO_PATH, "ofl", dir),
|
84
|
+
File.join(REPO_PATH, "ufl", dir)]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -1,54 +1,92 @@
|
|
1
|
-
require "erb"
|
2
1
|
require_relative "google"
|
3
|
-
require_relative "google/
|
4
|
-
require_relative "
|
2
|
+
require_relative "google/api"
|
3
|
+
require_relative "google/create_google_formula"
|
5
4
|
|
6
5
|
module Fontist
|
7
6
|
module Import
|
8
7
|
class GoogleImport
|
8
|
+
REPO_PATH = Fontist.fontist_path.join("google", "fonts")
|
9
|
+
REPO_URL = "https://github.com/google/fonts.git".freeze
|
10
|
+
|
9
11
|
def initialize(options)
|
10
12
|
@max_count = options[:max_count] || Google::DEFAULT_MAX_COUNT
|
11
13
|
end
|
12
14
|
|
13
15
|
def call
|
14
|
-
|
15
|
-
|
16
|
-
rebuild_index
|
16
|
+
update_repo
|
17
|
+
count = update_formulas
|
18
|
+
rebuild_index if count.positive?
|
17
19
|
end
|
18
20
|
|
19
21
|
private
|
20
22
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
23
|
+
def update_repo
|
24
|
+
if Dir.exist?(REPO_PATH)
|
25
|
+
`cd #{REPO_PATH} && git pull`
|
26
|
+
else
|
27
|
+
FileUtils.mkdir_p(File.dirname(REPO_PATH))
|
28
|
+
`git clone --depth 1 #{REPO_URL} #{REPO_PATH}`
|
29
|
+
end
|
24
30
|
end
|
25
31
|
|
26
|
-
def
|
27
|
-
|
32
|
+
def update_formulas
|
33
|
+
Fontist.ui.say "Updating formulas..."
|
34
|
+
|
35
|
+
items = api_items
|
28
36
|
|
29
|
-
|
30
|
-
|
31
|
-
|
37
|
+
count = 0
|
38
|
+
items.each do |item|
|
39
|
+
break if count >= @max_count
|
40
|
+
|
41
|
+
path = update_formula(item)
|
42
|
+
count += 1 if path
|
32
43
|
end
|
44
|
+
|
45
|
+
count
|
46
|
+
end
|
47
|
+
|
48
|
+
def api_items
|
49
|
+
Google::Api.items
|
50
|
+
end
|
51
|
+
|
52
|
+
def update_formula(item)
|
53
|
+
family = item["family"]
|
54
|
+
Fontist.ui.say "Checking #{family}"
|
55
|
+
unless new_changes?(item)
|
56
|
+
Fontist.ui.say "Skip, no changes"
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
60
|
+
create_formula(item)
|
33
61
|
end
|
34
62
|
|
35
|
-
def
|
36
|
-
|
63
|
+
def new_changes?(item)
|
64
|
+
formula = formula(item["family"])
|
65
|
+
return true unless formula
|
37
66
|
|
38
|
-
|
39
|
-
|
40
|
-
|
67
|
+
item["files"].values != formula.resources.first.files
|
68
|
+
end
|
69
|
+
|
70
|
+
def formula(font_name)
|
71
|
+
path = formula_path(font_name)
|
72
|
+
Formula.new_from_file(path) if File.exist?(path)
|
73
|
+
end
|
74
|
+
|
75
|
+
def formula_path(name)
|
76
|
+
snake_case = name.downcase.gsub(" ", "_")
|
77
|
+
filename = "#{snake_case}.yml"
|
78
|
+
Fontist.formulas_path.join("google", filename)
|
79
|
+
end
|
80
|
+
|
81
|
+
def create_formula(item)
|
82
|
+
path = Google::CreateGoogleFormula.new(
|
83
|
+
item,
|
41
84
|
formula_dir: formula_dir,
|
42
|
-
skip_sha: variable_style?(font_path),
|
43
|
-
digest: Google.digest(font_path),
|
44
85
|
).call
|
45
86
|
|
46
87
|
Fontist.ui.success("Formula has been successfully created: #{path}")
|
47
|
-
end
|
48
88
|
|
49
|
-
|
50
|
-
name = Google.metadata_name(path)
|
51
|
-
"https://fonts.google.com/download?family=#{ERB::Util.url_encode(name)}"
|
89
|
+
path
|
52
90
|
end
|
53
91
|
|
54
92
|
def formula_dir
|
@@ -57,13 +95,6 @@ module Fontist
|
|
57
95
|
end
|
58
96
|
end
|
59
97
|
|
60
|
-
def variable_style?(path)
|
61
|
-
fonts = Dir.glob(File.join(path, "*.{ttf,otf}"))
|
62
|
-
fonts.any? do |font|
|
63
|
-
File.basename(font).match?(/\[(.+,)?(wght|opsz)\]/)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
98
|
def rebuild_index
|
68
99
|
Fontist::Index.rebuild
|
69
100
|
end
|
@@ -19,10 +19,6 @@ module Fontist
|
|
19
19
|
save_operation_subdir
|
20
20
|
end
|
21
21
|
|
22
|
-
def extension
|
23
|
-
fetch_extension(@archive)
|
24
|
-
end
|
25
|
-
|
26
22
|
def font_files
|
27
23
|
ensure_extracted
|
28
24
|
@font_files
|
@@ -52,18 +48,6 @@ module Fontist
|
|
52
48
|
@operations[:options][:fonts_sub_dir] = @subdir
|
53
49
|
end
|
54
50
|
|
55
|
-
def fetch_extension(file)
|
56
|
-
File.extname(filename(file)).sub(/^\./, "")
|
57
|
-
end
|
58
|
-
|
59
|
-
def filename(file)
|
60
|
-
if file.respond_to?(:original_filename)
|
61
|
-
file.original_filename
|
62
|
-
else
|
63
|
-
File.basename(file)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
51
|
def ensure_extracted
|
68
52
|
return if @extracted
|
69
53
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Fontist
|
2
|
+
module Resources
|
3
|
+
class ArchiveResource
|
4
|
+
def initialize(resource, options = {})
|
5
|
+
@resource = resource
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def files(_source_names, &block)
|
10
|
+
excavate.files(recursive_packages: true, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def excavate
|
16
|
+
Excavate::Archive.new(archive.path)
|
17
|
+
end
|
18
|
+
|
19
|
+
def archive
|
20
|
+
download_file(@resource)
|
21
|
+
end
|
22
|
+
|
23
|
+
def download_file(source)
|
24
|
+
errors = []
|
25
|
+
source.urls.each do |request|
|
26
|
+
result = try_download_file(request, source)
|
27
|
+
return result unless result.is_a?(Errors::InvalidResourceError)
|
28
|
+
|
29
|
+
errors << result
|
30
|
+
end
|
31
|
+
|
32
|
+
raise Errors::InvalidResourceError, errors.join(" ")
|
33
|
+
end
|
34
|
+
|
35
|
+
def try_download_file(request, source)
|
36
|
+
info_log(request)
|
37
|
+
|
38
|
+
Fontist::Utils::Downloader.download(
|
39
|
+
request,
|
40
|
+
sha: source.sha256,
|
41
|
+
file_size: source.file_size,
|
42
|
+
progress_bar: !@options[:no_progress],
|
43
|
+
)
|
44
|
+
rescue Errors::InvalidResourceError => e
|
45
|
+
Fontist.ui.say(e.message)
|
46
|
+
e
|
47
|
+
end
|
48
|
+
|
49
|
+
def info_log(request)
|
50
|
+
url = request.respond_to?(:url) ? request.url : request
|
51
|
+
Fontist.ui.say(%(Downloading from #{url}))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Fontist
|
2
|
+
module Resources
|
3
|
+
class GoogleResource
|
4
|
+
def initialize(resource, options = {})
|
5
|
+
@resource = resource
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def files(source_names)
|
10
|
+
cached_paths = download_fonts(source_names)
|
11
|
+
|
12
|
+
cached_paths.map do |path|
|
13
|
+
Dir.mktmpdir do |dir|
|
14
|
+
FileUtils.cp(path, dir)
|
15
|
+
|
16
|
+
yield File.join(dir, File.basename(path))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def download_fonts(source_names)
|
24
|
+
urls = font_urls(source_names)
|
25
|
+
|
26
|
+
urls.map do |url|
|
27
|
+
download(url)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def font_urls(source_names)
|
32
|
+
@resource.files.select do |url|
|
33
|
+
source_names.include?(path_to_source_file(url))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def path_to_source_file(path)
|
38
|
+
format_filename(File.basename(path))
|
39
|
+
end
|
40
|
+
|
41
|
+
# TODO: remove duplication, another in Cache
|
42
|
+
def format_filename(filename)
|
43
|
+
return filename unless filename.length > 255
|
44
|
+
|
45
|
+
ext = File.extname(filename)
|
46
|
+
target_size = 255 - ext.length
|
47
|
+
cut_filename = filename.slice(0, target_size)
|
48
|
+
"#{cut_filename}#{ext}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def download(url)
|
52
|
+
Fontist.ui.say(%(Downloading from #{url}))
|
53
|
+
|
54
|
+
file = Utils::Downloader.download(
|
55
|
+
url,
|
56
|
+
use_content_length: false,
|
57
|
+
progress_bar: !@options[:no_progress],
|
58
|
+
)
|
59
|
+
|
60
|
+
file.path
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/fontist/utils/cache.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Fontist
|
2
2
|
module Utils
|
3
3
|
class Cache
|
4
|
+
MAX_FILENAME_SIZE = 255
|
5
|
+
|
4
6
|
include Locking
|
5
7
|
|
6
8
|
def self.lock_path(path)
|
@@ -110,6 +112,11 @@ module Fontist
|
|
110
112
|
end
|
111
113
|
|
112
114
|
def filename(source)
|
115
|
+
filename = response_to_filename(source)
|
116
|
+
format_filename(filename)
|
117
|
+
end
|
118
|
+
|
119
|
+
def response_to_filename(source)
|
113
120
|
if File.extname(source.original_filename).empty? && source.content_type
|
114
121
|
require "mime/types"
|
115
122
|
ext = MIME::Types[source.content_type].first&.preferred_extension
|
@@ -119,6 +126,15 @@ module Fontist
|
|
119
126
|
source.original_filename
|
120
127
|
end
|
121
128
|
|
129
|
+
def format_filename(filename)
|
130
|
+
return filename unless filename.length > MAX_FILENAME_SIZE
|
131
|
+
|
132
|
+
ext = File.extname(filename)
|
133
|
+
target_size = MAX_FILENAME_SIZE - ext.length
|
134
|
+
cut_filename = filename.slice(0, target_size)
|
135
|
+
"#{cut_filename}#{ext}"
|
136
|
+
end
|
137
|
+
|
122
138
|
def move(source_file, target_path)
|
123
139
|
# Windows requires file descriptors to be closed before files are moved
|
124
140
|
source_file.close
|
@@ -10,12 +10,17 @@ module Fontist
|
|
10
10
|
ruby2_keywords :download if respond_to?(:ruby2_keywords, true)
|
11
11
|
end
|
12
12
|
|
13
|
-
def initialize(file,
|
13
|
+
def initialize(file,
|
14
|
+
file_size: nil,
|
15
|
+
sha: nil,
|
16
|
+
progress_bar: nil,
|
17
|
+
use_content_length: true)
|
14
18
|
# TODO: If the first mirror fails, try the second one
|
15
19
|
@file = file
|
16
20
|
@sha = [sha].flatten.compact
|
17
21
|
@file_size = file_size.to_i if file_size
|
18
22
|
@progress_bar = progress_bar
|
23
|
+
@use_content_length = use_content_length
|
19
24
|
@cache = Cache.new
|
20
25
|
end
|
21
26
|
|
@@ -85,7 +90,9 @@ module Fontist
|
|
85
90
|
max_redirects: 10,
|
86
91
|
headers: headers,
|
87
92
|
content_length_proc: ->(content_length) {
|
88
|
-
|
93
|
+
if @use_content_length && content_length
|
94
|
+
progress_bar.total = content_length
|
95
|
+
end
|
89
96
|
},
|
90
97
|
progress_proc: -> (progress) {
|
91
98
|
progress_bar.increment(progress)
|