fontist 0.3.0 → 0.4.0
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/README.md +25 -1
- data/lib/fontist.rb +1 -0
- data/lib/fontist/data/formulas/courier.yml +26 -0
- data/lib/fontist/data/formulas/ms_system.yml +68 -0
- data/lib/fontist/data/formulas/ms_vista.yml +105 -26
- data/lib/fontist/data/formulas/source_font.yml +154 -42
- data/lib/fontist/data/source.yml +2 -0
- data/lib/fontist/downloader.rb +1 -1
- data/lib/fontist/finder.rb +2 -4
- data/lib/fontist/formula_finder.rb +94 -0
- data/lib/fontist/formulas.rb +2 -0
- data/lib/fontist/formulas/base.rb +48 -1
- data/lib/fontist/formulas/courier_font.rb +25 -0
- data/lib/fontist/formulas/helpers/exe_extractor.rb +45 -0
- data/lib/fontist/formulas/helpers/zip_extractor.rb +36 -0
- data/lib/fontist/formulas/ms_system.rb +29 -0
- data/lib/fontist/formulas/ms_vista.rb +18 -50
- data/lib/fontist/formulas/source_font.rb +8 -31
- data/lib/fontist/installer.rb +11 -16
- data/lib/fontist/system_font.rb +11 -0
- data/lib/fontist/version.rb +1 -1
- data/spec/fontist/finder_spec.rb +1 -1
- data/spec/fontist/formula_finder_spec.rb +54 -0
- data/spec/fontist/formulas/courier_font_spec.rb +30 -0
- data/spec/fontist/formulas/ms_system_spec.rb +31 -0
- data/spec/fontist/formulas/ms_vista_spec.rb +3 -3
- data/spec/fontist/installer_spec.rb +4 -4
- data/spec/fontist/source_spec.rb +1 -1
- data/spec/fontist/system_font_spec.rb +11 -0
- metadata +12 -2
data/lib/fontist/data/source.yml
CHANGED
data/lib/fontist/downloader.rb
CHANGED
data/lib/fontist/finder.rb
CHANGED
@@ -21,13 +21,11 @@ module Fontist
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def remote_source
|
24
|
-
Fontist::
|
25
|
-
!value.fonts.grep(/#{name}/i).empty?
|
26
|
-
end
|
24
|
+
Fontist::FormulaFinder.find(name)
|
27
25
|
end
|
28
26
|
|
29
27
|
def downloadable_font
|
30
|
-
unless remote_source.
|
28
|
+
unless remote_source.nil?
|
31
29
|
raise(
|
32
30
|
Fontist::Errors::MissingFontError,
|
33
31
|
"Fonts are missing, please run" \
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Fontist
|
2
|
+
class FormulaFinder
|
3
|
+
def initialize(font_name)
|
4
|
+
@font_name = font_name
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.find(font_name)
|
8
|
+
new(font_name).find
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.find_fonts(name)
|
12
|
+
new(name).find_fonts
|
13
|
+
end
|
14
|
+
|
15
|
+
def find
|
16
|
+
formulas = find_formula
|
17
|
+
build_formulas_array(formulas)
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_fonts
|
21
|
+
matched_fonts = find_formula.map do |key, _value|
|
22
|
+
formulas[key].fonts.select do |font|
|
23
|
+
font.name == font_name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
matched_fonts.empty? ? nil : matched_fonts.flatten
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :font_name
|
33
|
+
|
34
|
+
def build_formulas_array(formulas)
|
35
|
+
unless formulas.empty?
|
36
|
+
Array.new.tap do |formula_array|
|
37
|
+
formulas.each do |key|
|
38
|
+
formula_array.push(
|
39
|
+
key: key.to_s,
|
40
|
+
installer: formula_installers[key]
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_formula
|
48
|
+
find_by_font_name || find_by_font || []
|
49
|
+
end
|
50
|
+
|
51
|
+
def formulas
|
52
|
+
@formulas ||= Fontist::Source.formulas.to_h
|
53
|
+
end
|
54
|
+
|
55
|
+
def formula_installers
|
56
|
+
{
|
57
|
+
msvista: Fontist::Formulas::MsVista,
|
58
|
+
ms_system: Fontist::Formulas::MsSystem,
|
59
|
+
courier: Fontist::Formulas::CourierFont,
|
60
|
+
source_front: Fontist::Formulas::SourceFont,
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_by_font_name
|
65
|
+
formula_names = formulas.select do |key, value|
|
66
|
+
!value.fonts.map(&:name).grep(/#{font_name}/i).empty?
|
67
|
+
end.keys
|
68
|
+
|
69
|
+
formula_names.empty? ? nil : formula_names
|
70
|
+
end
|
71
|
+
|
72
|
+
# Note
|
73
|
+
#
|
74
|
+
# These interface recursively look into every single font styles,
|
75
|
+
# so ideally try to avoid using it when possible, and that's why
|
76
|
+
# we've added it as last option in formula finder.
|
77
|
+
#
|
78
|
+
def find_by_font
|
79
|
+
formula_names = formulas.select do |key, value|
|
80
|
+
match_in_font_styles?(value.fonts)
|
81
|
+
end.keys
|
82
|
+
|
83
|
+
formula_names.empty? ? nil : formula_names
|
84
|
+
end
|
85
|
+
|
86
|
+
def match_in_font_styles?(fonts)
|
87
|
+
styles = fonts.select do |font|
|
88
|
+
!font.styles.map(&:font).grep(/#{font_name}/i).empty?
|
89
|
+
end
|
90
|
+
|
91
|
+
styles.empty? ? false : true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/fontist/formulas.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
+
require "fontist/downloader"
|
2
|
+
require "fontist/formulas/helpers/exe_extractor"
|
3
|
+
require "fontist/formulas/helpers/zip_extractor"
|
4
|
+
|
1
5
|
module Fontist
|
2
6
|
module Formulas
|
3
7
|
class Base
|
4
8
|
def initialize(font_name, confirmation:, **options)
|
9
|
+
@matched_fonts = []
|
5
10
|
@font_name = font_name
|
6
11
|
@confirmation = confirmation || "no"
|
7
12
|
@force_download = options.fetch(:force_download, false)
|
@@ -14,12 +19,54 @@ module Fontist
|
|
14
19
|
new(font_name, options.merge(confirmation: confirmation)).fetch
|
15
20
|
end
|
16
21
|
|
22
|
+
def fetch
|
23
|
+
extract_fonts(map_names_to_fonts(font_name))
|
24
|
+
|
25
|
+
matched_fonts_uniq = matched_fonts.flatten.uniq
|
26
|
+
matched_fonts_uniq.empty? ? nil : matched_fonts_uniq
|
27
|
+
end
|
28
|
+
|
17
29
|
private
|
18
30
|
|
19
|
-
attr_reader
|
31
|
+
attr_reader(
|
32
|
+
:font_name,
|
33
|
+
:fonts_path,
|
34
|
+
:confirmation,
|
35
|
+
:matched_fonts,
|
36
|
+
:force_download,
|
37
|
+
)
|
20
38
|
|
21
39
|
def check_user_license_agreement
|
22
40
|
end
|
41
|
+
|
42
|
+
def resources(name, &block)
|
43
|
+
source = formulas[name]
|
44
|
+
block_given? ? yield(source) : source
|
45
|
+
end
|
46
|
+
|
47
|
+
def formulas
|
48
|
+
@formulas ||= Fontist::Source.formulas
|
49
|
+
end
|
50
|
+
|
51
|
+
def match_fonts(fonts_dir, font_name)
|
52
|
+
font = fonts_dir.grep(/#{font_name}/i)
|
53
|
+
@matched_fonts.push(font) if font
|
54
|
+
|
55
|
+
font
|
56
|
+
end
|
57
|
+
|
58
|
+
def map_names_to_fonts(font_name)
|
59
|
+
fonts = FormulaFinder.find_fonts(font_name)
|
60
|
+
fonts = fonts.map { |font| font.styles.map(&:font) }.flatten if fonts
|
61
|
+
|
62
|
+
fonts || []
|
63
|
+
end
|
64
|
+
|
65
|
+
def download_file(source)
|
66
|
+
Fontist::Downloader.download(
|
67
|
+
source.urls.first, sha: source.sha, file_size: source.file_size,
|
68
|
+
)
|
69
|
+
end
|
23
70
|
end
|
24
71
|
end
|
25
72
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fontist
|
2
|
+
module Formulas
|
3
|
+
class CourierFont < Base
|
4
|
+
include Formulas::Helpers::ExeExtractor
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def extract_fonts(font_names)
|
9
|
+
resources("courier") do |resource|
|
10
|
+
cab_extract(resource) do |fonts_dir|
|
11
|
+
font_names.each do |font_name|
|
12
|
+
match_fonts(fonts_dir, font_name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def check_user_license_agreement
|
19
|
+
unless resources("courier").agreement === confirmation
|
20
|
+
raise(Fontist::Errors::LicensingError)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Fontist
|
2
|
+
module Formulas
|
3
|
+
module Helpers
|
4
|
+
module ExeExtractor
|
5
|
+
def cab_extract(exe_file, download: true, font_ext: /.tt|.ttc/i)
|
6
|
+
exe_file = download_file(exe_file).path if download
|
7
|
+
cab_file = decompressor.search(exe_file)
|
8
|
+
cabbed_fonts = grep_fonts(cab_file.files, font_ext) || []
|
9
|
+
fonts_paths = extract_cabbed_fonts_to_assets(cabbed_fonts)
|
10
|
+
|
11
|
+
yield(fonts_paths) if block_given?
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def decompressor
|
17
|
+
@decompressor ||= (
|
18
|
+
require "libmspack"
|
19
|
+
LibMsPack::CabDecompressor.new
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def grep_fonts(file, font_ext)
|
24
|
+
Array.new.tap do |fonts|
|
25
|
+
while file
|
26
|
+
fonts.push(file) if file.filename.match(font_ext)
|
27
|
+
file = file.next
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def extract_cabbed_fonts_to_assets(cabbed_fonts)
|
33
|
+
Array.new.tap do |fonts|
|
34
|
+
cabbed_fonts.each do |font|
|
35
|
+
font_path = fonts_path.join(font.filename).to_s
|
36
|
+
decompressor.extract(font, font_path)
|
37
|
+
|
38
|
+
fonts.push(font_path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Fontist
|
2
|
+
module Formulas
|
3
|
+
module Helpers
|
4
|
+
module ZipExtractor
|
5
|
+
def zip_extract(resource, download: true, fonts_sub_dir: "/")
|
6
|
+
zip_file = download_file(resource) if download
|
7
|
+
zip_file ||= resource.urls.first
|
8
|
+
|
9
|
+
fonts_paths = unzip_fonts(zip_file, fonts_sub_dir)
|
10
|
+
block_given? ? yield(fonts_paths) : fonts_paths
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def unzip_fonts(file, fonts_sub_dir = "/")
|
16
|
+
Zip.on_exists_proc = true
|
17
|
+
|
18
|
+
Array.new.tap do |fonts|
|
19
|
+
Zip::File.open(file) do |zip_file|
|
20
|
+
zip_file.glob("#{fonts_sub_dir}*.{ttf,ttc}").each do |entry|
|
21
|
+
filename = entry.name.gsub("#{fonts_sub_dir}", "")
|
22
|
+
|
23
|
+
if filename
|
24
|
+
font_path = fonts_path.join(filename)
|
25
|
+
fonts.push(font_path.to_s)
|
26
|
+
|
27
|
+
entry.extract(font_path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Fontist
|
2
|
+
module Formulas
|
3
|
+
class MsSystem < Base
|
4
|
+
include Formulas::Helpers::ExeExtractor
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def data_node
|
9
|
+
@data_node ||= "ms_system"
|
10
|
+
end
|
11
|
+
|
12
|
+
def check_user_license_agreement
|
13
|
+
unless resources(data_node).agreement === confirmation
|
14
|
+
raise(Fontist::Errors::LicensingError)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def extract_fonts(font_names)
|
19
|
+
resources(data_node) do |resource|
|
20
|
+
cab_extract(resource) do |fonts_dir|
|
21
|
+
font_names.each do |font_name|
|
22
|
+
match_fonts(fonts_dir, font_name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,69 +1,37 @@
|
|
1
|
-
require "fontist/downloader"
|
2
|
-
|
3
1
|
module Fontist
|
4
2
|
module Formulas
|
5
3
|
class MsVista < Base
|
6
|
-
|
7
|
-
fonts = extract_ppviewer_fonts
|
8
|
-
paths = fonts.grep(/#{font_name}/i)
|
9
|
-
paths.empty? ? nil : paths
|
10
|
-
end
|
4
|
+
include Formulas::Helpers::ExeExtractor
|
11
5
|
|
12
6
|
private
|
13
7
|
|
14
|
-
def
|
15
|
-
|
16
|
-
raise(Fontist::Errors::LicensingError)
|
17
|
-
end
|
8
|
+
def data_node
|
9
|
+
@data_node ||= "msvista"
|
18
10
|
end
|
19
11
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
LibMsPack::CabDecompressor.new
|
24
|
-
)
|
25
|
-
end
|
26
|
-
|
27
|
-
def extract_ppviewer_fonts
|
28
|
-
Array.new.tap do |fonts|
|
29
|
-
cabbed_fonts.each do |font|
|
30
|
-
font_path = fonts_path.join(font.filename).to_s
|
31
|
-
decompressor.extract(font, font_path)
|
32
|
-
|
33
|
-
fonts.push(font_path)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def extract_ppviewer_cab_file
|
39
|
-
if !File.exists?(ppviewer_cab) || force_download
|
40
|
-
exe_file = decompressor.search(download_exe_file.path)
|
41
|
-
decompressor.extract(exe_file.files.next, ppviewer_cab)
|
12
|
+
def check_user_license_agreement
|
13
|
+
unless resources(data_node).agreement === confirmation
|
14
|
+
raise(Fontist::Errors::LicensingError)
|
42
15
|
end
|
43
16
|
end
|
44
17
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
fonts.push(file) if file.filename.match(/.tt|.TT/)
|
54
|
-
file = file.next
|
18
|
+
def extract_fonts(font_names)
|
19
|
+
resources(data_node) do |resource|
|
20
|
+
exe_extract(resource) do |cab_file|
|
21
|
+
cab_extract(cab_file, download: false) do |fonts_dir|
|
22
|
+
font_names.each do |font_name|
|
23
|
+
match_fonts(fonts_dir, font_name)
|
24
|
+
end
|
25
|
+
end
|
55
26
|
end
|
56
27
|
end
|
57
28
|
end
|
58
29
|
|
59
|
-
def source
|
60
|
-
|
61
|
-
|
30
|
+
def exe_extract(source)
|
31
|
+
cab_files = decompressor.search(download_file(source).path)
|
32
|
+
decompressor.extract(cab_files.files.next, ppviewer_cab)
|
62
33
|
|
63
|
-
|
64
|
-
Fontist::Downloader.download(
|
65
|
-
source.urls.first, file_size: source.file_size.to_i, sha: source.sha
|
66
|
-
)
|
34
|
+
yield(ppviewer_cab) if block_given?
|
67
35
|
end
|
68
36
|
|
69
37
|
def ppviewer_cab
|
@@ -3,46 +3,23 @@ require "zip"
|
|
3
3
|
module Fontist
|
4
4
|
module Formulas
|
5
5
|
class SourceFont < Formulas::Base
|
6
|
-
|
7
|
-
paths = extract_fonts.grep(/#{font_name}/i)
|
8
|
-
paths.empty? ? nil : paths
|
9
|
-
end
|
6
|
+
include Formulas::Helpers::ZipExtractor
|
10
7
|
|
11
8
|
private
|
12
9
|
|
13
|
-
def
|
14
|
-
@
|
15
|
-
end
|
16
|
-
|
17
|
-
def extract_fonts
|
18
|
-
zip_file = download_file
|
19
|
-
unzip_fonts(zip_file)
|
10
|
+
def data_node
|
11
|
+
@data_node ||= "source_font"
|
20
12
|
end
|
21
13
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
zip_file.glob("fonts/*.ttf").each do |entry|
|
28
|
-
filename = entry.name.gsub("fonts/", "")
|
29
|
-
|
30
|
-
if filename
|
31
|
-
font_path = fonts_path.join(filename)
|
32
|
-
fonts.push(font_path.to_s)
|
33
|
-
|
34
|
-
entry.extract(font_path)
|
35
|
-
end
|
14
|
+
def extract_fonts(font_names)
|
15
|
+
resources(data_node) do |resource|
|
16
|
+
zip_extract(resource, fonts_sub_dir: "fonts/") do |fonts_paths|
|
17
|
+
font_names.each do |font_name|
|
18
|
+
match_fonts(fonts_paths, font_name)
|
36
19
|
end
|
37
20
|
end
|
38
21
|
end
|
39
22
|
end
|
40
|
-
|
41
|
-
def download_file
|
42
|
-
Fontist::Downloader.download(
|
43
|
-
source.urls.first, file_size: source.file_size.to_i, sha: source.sha
|
44
|
-
)
|
45
|
-
end
|
46
23
|
end
|
47
24
|
end
|
48
25
|
end
|