admiral-tools-figma 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +1 -0
- data/admiral-tools-figma.gemspec +9 -0
- data/admiraltools/actions/figma_download_images.rb +116 -0
- data/admiraltools/actions/figma_generate_styles.rb +77 -0
- data/admiraltools/actions/figma_get_image_links.rb +139 -0
- data/admiraltools/actions/figma_get_styles.rb +90 -0
- data/admiraltools/helper/admiraltools_helper.rb +18 -0
- data/admiraltools/helper/figma/figma_client/figma_client.rb +193 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_color.rb +35 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_component.rb +58 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_components_styles_meta.rb +30 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_frame_info.rb +46 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_node.rb +43 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_paint.rb +32 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_style.rb +48 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_type_style.rb +56 -0
- data/admiraltools/helper/figma/figma_client/models/api/results/figma_components_styles_result.rb +36 -0
- data/admiraltools/helper/figma/figma_client/models/api/results/figma_images_result.rb +25 -0
- data/admiraltools/helper/figma/figma_client/models/api/results/figma_nodes_result.rb +52 -0
- data/admiraltools/helper/figma/figma_client/models/domain/converters/figma_to_domain_converter.rb +98 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/color.rb +44 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/component.rb +86 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/components_list.rb +29 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/font.rb +56 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/frame_info.rb +46 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/image_link.rb +33 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/style.rb +113 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/styles_group.rb +22 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/styles_list.rb +29 -0
- data/admiraltools/helper/figma/figma_client/models/models.rb +25 -0
- data/admiraltools/helper/figma/figma_image_downloader/bin/svg2vectordrawable.jar +0 -0
- data/admiraltools/helper/figma/figma_image_downloader/figma_image_downloader.rb +65 -0
- data/admiraltools/helper/figma/figma_image_downloader/generators/folder_generator.rb +47 -0
- data/admiraltools/helper/figma/figma_image_downloader/generators/folder_generator_raw.rb +32 -0
- data/admiraltools/helper/figma/figma_image_downloader/generators/folder_generator_res.rb +38 -0
- data/admiraltools/helper/figma/figma_image_downloader/generators/folder_generator_xcassets.rb +180 -0
- data/admiraltools/helper/figma/figma_image_downloader/generators/generators.rb +6 -0
- data/admiraltools/helper/figma/figma_image_downloader/helpers/image_name_formatter.rb +72 -0
- data/admiraltools/helper/figma/figma_image_downloader/helpers/progress_tasks_logger.rb +22 -0
- data/admiraltools/helper/figma/figma_image_downloader/helpers/scale_formatter.rb +96 -0
- data/admiraltools/helper/figma/figma_image_downloader/helpers/svg_to_vector_converter.rb +12 -0
- data/admiraltools/helper/figma/figma_image_downloader/models/download_image_params.rb +31 -0
- data/admiraltools/helper/figma/figma_image_downloader/models/image_name_components.rb +10 -0
- data/admiraltools/helper/figma/figma_image_downloader/models/image_ref.rb +12 -0
- data/admiraltools/helper/figma/figma_image_downloader/models/image_set_ref.rb +14 -0
- data/admiraltools/helper/figma/figma_image_downloader/models/models.rb +5 -0
- data/admiraltools/helper/figma/figma_template_generator/figma_template_generator.rb +22 -0
- data/admiraltools/helper/figma/figma_template_generator/models/styles_template.rb +34 -0
- data/admiraltools/helper/figma/helpers/file_folder.rb +30 -0
- data/admiraltools/helper/figma/helpers/hash_access.rb +18 -0
- data/admiraltools/helper/figma/helpers/string_filters.rb +63 -0
- data/admiraltools/helper/figma/helpers/string_format.rb +60 -0
- data/admiraltools/helper/system/system.rb +17 -0
- data/admiraltools/version.rb +7 -0
- data/admiraltools.rb +18 -0
- metadata +96 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Font
|
4
|
+
attr_accessor \
|
5
|
+
:font_family,
|
6
|
+
:font_postscript_name,
|
7
|
+
:font_size,
|
8
|
+
:font_weight,
|
9
|
+
:letter_spacing
|
10
|
+
|
11
|
+
def initialize(
|
12
|
+
font_family:,
|
13
|
+
font_postscript_name:,
|
14
|
+
font_size:,
|
15
|
+
font_weight:,
|
16
|
+
letter_spacing:
|
17
|
+
)
|
18
|
+
@font_family = font_family
|
19
|
+
@font_postscript_name = font_postscript_name
|
20
|
+
@font_size = font_size
|
21
|
+
@font_weight = font_weight
|
22
|
+
@letter_spacing = letter_spacing
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_hash(hash)
|
26
|
+
return nil if hash.nil?
|
27
|
+
|
28
|
+
font_family = hash['font_family']
|
29
|
+
font_postscript_name = hash['font_postscript_name']
|
30
|
+
font_size = hash['font_size']
|
31
|
+
font_weight = hash['font_weight']
|
32
|
+
letter_spacing = hash['letter_spacing']
|
33
|
+
|
34
|
+
if !font_family.nil? && !font_postscript_name.nil? && !font_size.nil? && !font_weight.nil? && !letter_spacing.nil?
|
35
|
+
return Font.new(
|
36
|
+
font_family: font_family,
|
37
|
+
font_postscript_name: font_postscript_name,
|
38
|
+
font_size: font_size,
|
39
|
+
font_weight: font_weight,
|
40
|
+
letter_spacing: letter_spacing
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_hash
|
48
|
+
hash = {}
|
49
|
+
hash['font_family'] = font_family
|
50
|
+
hash['font_postscript_name'] = font_postscript_name
|
51
|
+
hash['font_size'] = font_size
|
52
|
+
hash['font_weight'] = font_weight
|
53
|
+
hash['letter_spacing'] = letter_spacing
|
54
|
+
hash
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FrameInfo
|
4
|
+
attr_accessor \
|
5
|
+
:node_id,
|
6
|
+
:name,
|
7
|
+
:background_color,
|
8
|
+
:page_id,
|
9
|
+
:page_name
|
10
|
+
|
11
|
+
def initialize(
|
12
|
+
node_id:,
|
13
|
+
name:,
|
14
|
+
background_color:,
|
15
|
+
page_id:,
|
16
|
+
page_name:
|
17
|
+
)
|
18
|
+
@node_id = node_id
|
19
|
+
@name = name
|
20
|
+
@background_color = background_color
|
21
|
+
@page_id = page_id
|
22
|
+
@page_name = page_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_hash(hash)
|
26
|
+
return nil if hash.nil?
|
27
|
+
|
28
|
+
node_id = hash['node_id']
|
29
|
+
name = hash['name']
|
30
|
+
background_color = hash['background_color']
|
31
|
+
page_id = hash['page_id']
|
32
|
+
page_name = hash['page_name']
|
33
|
+
FigmaFrameInfo.new(node_id: node_id, name: name, background_color: background_color, page_id: page_id,
|
34
|
+
page_name: page_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_hash
|
38
|
+
hash = {}
|
39
|
+
hash['node_id'] = node_id
|
40
|
+
hash['name'] = name
|
41
|
+
hash['background_color'] = background_color
|
42
|
+
hash['page_id'] = page_id
|
43
|
+
hash['page_name'] = page_name
|
44
|
+
hash
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ImageLink
|
4
|
+
attr_accessor :link, :scale, :image_format
|
5
|
+
|
6
|
+
def initialize(link:, scale:, image_format:)
|
7
|
+
@link = link
|
8
|
+
@scale = scale
|
9
|
+
@image_format = image_format
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.from_hash(hash)
|
13
|
+
return nil if hash.nil?
|
14
|
+
|
15
|
+
scale = hash['scale']
|
16
|
+
link = hash['link']
|
17
|
+
image_format = hash['image_format']
|
18
|
+
|
19
|
+
if !scale.nil? && !link.nil? && !image_format.nil?
|
20
|
+
return ImageLink.new(scale: scale, link: link, image_format: image_format)
|
21
|
+
end
|
22
|
+
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_hash
|
27
|
+
hash = {}
|
28
|
+
hash['scale'] = scale
|
29
|
+
hash['link'] = link
|
30
|
+
hash['image_format'] = image_format
|
31
|
+
hash
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class StyleNameInfo
|
4
|
+
attr_accessor :full_name, :group_name, :style_name
|
5
|
+
|
6
|
+
def initialize(
|
7
|
+
full_name:,
|
8
|
+
group_name:,
|
9
|
+
style_name:
|
10
|
+
)
|
11
|
+
@full_name = full_name
|
12
|
+
@group_name = group_name
|
13
|
+
@style_name = style_name
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.create_from(name:)
|
17
|
+
name ||= ''
|
18
|
+
full_name = name
|
19
|
+
name_array = name.split('/')
|
20
|
+
|
21
|
+
if name_array.count > 1
|
22
|
+
group_name = name_array[0]
|
23
|
+
name_array.shift
|
24
|
+
style_name = name_array.join('/')
|
25
|
+
else
|
26
|
+
group_name = 'Default'
|
27
|
+
style_name = name_array[0] || 'unknown'
|
28
|
+
end
|
29
|
+
|
30
|
+
StyleNameInfo.new(
|
31
|
+
full_name: full_name,
|
32
|
+
group_name: group_name,
|
33
|
+
style_name: style_name
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_hash
|
38
|
+
hash = {}
|
39
|
+
hash['full_name'] = full_name
|
40
|
+
hash['group_name'] = group_name
|
41
|
+
hash['style_name'] = style_name
|
42
|
+
hash
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Style
|
47
|
+
attr_accessor :name, :node_id, :style_type, :description, :color, :font
|
48
|
+
|
49
|
+
def description_params
|
50
|
+
JSON.parse(description)
|
51
|
+
rescue StandardError
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize(
|
56
|
+
name:,
|
57
|
+
node_id:,
|
58
|
+
style_type:,
|
59
|
+
description:,
|
60
|
+
color: nil,
|
61
|
+
font: nil
|
62
|
+
)
|
63
|
+
@name = name
|
64
|
+
@node_id = node_id
|
65
|
+
@style_type = style_type
|
66
|
+
@description = description
|
67
|
+
@color = color
|
68
|
+
@font = font
|
69
|
+
end
|
70
|
+
|
71
|
+
def name_info
|
72
|
+
StyleNameInfo.create_from(name: name)
|
73
|
+
end
|
74
|
+
|
75
|
+
def is_dark
|
76
|
+
name.downcase.include?('dark') || false
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.from_hash(hash)
|
80
|
+
return nil if hash.nil?
|
81
|
+
|
82
|
+
name = hash['name']
|
83
|
+
node_id = hash['node_id']
|
84
|
+
style_type = hash['style_type']
|
85
|
+
description = hash['description']
|
86
|
+
color_hash = hash['color']
|
87
|
+
font_hash = hash['font']
|
88
|
+
|
89
|
+
color = !color_hash.nil? ? Color.from_hash(color_hash) : nil
|
90
|
+
font = !font_hash.nil? ? Font.from_hash(font_hash) : nil
|
91
|
+
|
92
|
+
if !name.nil? && !node_id.nil? && style_type
|
93
|
+
return Style.new(name: name, node_id: node_id, style_type: style_type, description: description,
|
94
|
+
color: color, font: font)
|
95
|
+
end
|
96
|
+
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
|
100
|
+
def to_hash
|
101
|
+
hash = {}
|
102
|
+
hash['name'] = name
|
103
|
+
hash['node_id'] = node_id
|
104
|
+
hash['style_type'] = style_type
|
105
|
+
hash['description'] = description
|
106
|
+
hash['color'] = color&.to_hash unless color.nil?
|
107
|
+
hash['font'] = font&.to_hash unless font.nil?
|
108
|
+
hash['name_info'] = name_info.to_hash unless name_info.nil?
|
109
|
+
hash['description_params'] = description_params unless description_params.nil?
|
110
|
+
hash['is_dark'] = is_dark
|
111
|
+
hash
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class StylesGroup
|
4
|
+
attr_accessor :name, :styles
|
5
|
+
|
6
|
+
def initialize(name:, styles:)
|
7
|
+
@name = name
|
8
|
+
@styles = styles
|
9
|
+
end
|
10
|
+
|
11
|
+
def is_dark
|
12
|
+
name.downcase.include?('dark') || false
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_hash
|
16
|
+
hash = {}
|
17
|
+
hash['name'] = name
|
18
|
+
hash['styles'] = styles&.map { |s| s.to_hash }
|
19
|
+
hash['is_dark'] = is_dark
|
20
|
+
hash
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require_relative 'style'
|
5
|
+
|
6
|
+
class StylesList
|
7
|
+
attr_accessor :styles
|
8
|
+
|
9
|
+
def initialize(styles:)
|
10
|
+
@styles = styles
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.from_hash(hash)
|
14
|
+
hash.map { |s| Style.from_hash(s) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
styles.map(&:to_hash)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.from_json(json)
|
22
|
+
styles = (JSON.parse(json) || []).map { |s| Style.from_hash(s) }
|
23
|
+
StylesList.new(styles: styles)
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_json(*_args)
|
27
|
+
styles.map(&:to_hash).to_json
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'api/primitives/figma_color'
|
4
|
+
require_relative 'api/primitives/figma_component'
|
5
|
+
require_relative 'api/primitives/figma_components_styles_meta'
|
6
|
+
require_relative 'api/primitives/figma_node'
|
7
|
+
require_relative 'api/primitives/figma_paint'
|
8
|
+
require_relative 'api/primitives/figma_style'
|
9
|
+
require_relative 'api/primitives/figma_type_style'
|
10
|
+
require_relative 'api/primitives/figma_color'
|
11
|
+
|
12
|
+
require_relative 'api/results/figma_components_styles_result'
|
13
|
+
require_relative 'api/results/figma_images_result'
|
14
|
+
require_relative 'api/results/figma_nodes_result'
|
15
|
+
|
16
|
+
require_relative 'domain/primitives/color'
|
17
|
+
require_relative 'domain/primitives/component'
|
18
|
+
require_relative 'domain/primitives/components_list'
|
19
|
+
require_relative 'domain/primitives/font'
|
20
|
+
require_relative 'domain/primitives/image_link'
|
21
|
+
require_relative 'domain/primitives/style'
|
22
|
+
require_relative 'domain/primitives/styles_group'
|
23
|
+
require_relative 'domain/primitives/styles_list'
|
24
|
+
|
25
|
+
require_relative 'domain/converters/figma_to_domain_converter'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'models/models'
|
4
|
+
require_relative 'generators/generators'
|
5
|
+
require_relative 'helpers/progress_tasks_logger'
|
6
|
+
|
7
|
+
class FigmaImageDownloader
|
8
|
+
OUTPUT_FORMAT_RAW = 'raw'
|
9
|
+
OUTPUT_FORMAT_RES = 'res'
|
10
|
+
OUTPUT_FORMAT_XCASSETS = 'xcassets'
|
11
|
+
OUTPUT_FORMAT_XCASSETS_SYMOBLS = 'xcassets-symbols'
|
12
|
+
|
13
|
+
XCASSETS_TEMPLATE_RENDERING_INTENT_ORIGINAL = 'original'
|
14
|
+
XCASSETS_TEMPLATE_RENDERING_INTENT_TEMPLATE = 'template'
|
15
|
+
|
16
|
+
def download_images(params:)
|
17
|
+
generator = generator(params: params)
|
18
|
+
|
19
|
+
image_set_refs = params.image_components.map { |c| generator.create_image_sets(image_component: c) }
|
20
|
+
total_count = image_set_refs.map(&:image_refs).flatten.length
|
21
|
+
|
22
|
+
logger = ProgressTasksLogger.new(total_count: total_count)
|
23
|
+
puts("Start downloading #{total_count}")
|
24
|
+
generator.start_download(image_sets: image_set_refs)
|
25
|
+
image_set_refs.each do |image_set|
|
26
|
+
puts("Image set: #{image_set.name}")
|
27
|
+
generator.image_set_start_download(image_set: image_set)
|
28
|
+
image_set.image_refs.each do |image|
|
29
|
+
generator.image_start_download(image: image)
|
30
|
+
download_task(task: image, output_folder: params.output_folder)
|
31
|
+
logger.increment
|
32
|
+
puts("#{logger.progress_string} #{image.path} #{image.image_link.link}")
|
33
|
+
generator.image_end_download(image: image)
|
34
|
+
end
|
35
|
+
generator.image_set_end_download(image_set: image_set)
|
36
|
+
end
|
37
|
+
puts("\nDownloading complete! #{logger.progress_string}")
|
38
|
+
generator.end_download(image_sets: image_set_refs)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def generator(params:)
|
44
|
+
case params.output_format
|
45
|
+
when OUTPUT_FORMAT_RAW
|
46
|
+
FolderGeneratorRaw.new(params: params)
|
47
|
+
when OUTPUT_FORMAT_RES
|
48
|
+
FolderGeneratorRes.new(params: params)
|
49
|
+
when OUTPUT_FORMAT_XCASSETS
|
50
|
+
FolderGeneratorXcassets.new(params: params, symbols: false)
|
51
|
+
when OUTPUT_FORMAT_XCASSETS_SYMOBLS
|
52
|
+
FolderGeneratorXcassets.new(params: params, symbols: true)
|
53
|
+
else
|
54
|
+
raise 'Unknown output format'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def download_task(task:, output_folder:)
|
59
|
+
data = open(task.image_link.link)
|
60
|
+
path = File.join(output_folder, task.path)
|
61
|
+
file = File.open_file(file_name: path, mode: 'w', create_directories: true)
|
62
|
+
file.write(data.read)
|
63
|
+
file.close
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FolderGenerator
|
4
|
+
attr_accessor :params
|
5
|
+
|
6
|
+
def initialize(params:)
|
7
|
+
@params = params
|
8
|
+
end
|
9
|
+
|
10
|
+
def start_download(image_sets:); end
|
11
|
+
|
12
|
+
def end_download(image_sets:); end
|
13
|
+
|
14
|
+
def create_image_sets(image_component:); end
|
15
|
+
|
16
|
+
def image_set_start_download(image_set:); end
|
17
|
+
|
18
|
+
def image_set_end_download(image_set:); end
|
19
|
+
|
20
|
+
def image_start_download(image:); end
|
21
|
+
|
22
|
+
def image_end_download(image:); end
|
23
|
+
|
24
|
+
def format_name(image_component:)
|
25
|
+
formatter = ImageNameFormatter.new
|
26
|
+
page_name = params.include_page_name ? image_component.containing_frame.page_name : nil
|
27
|
+
frame_name = params.include_frame_name ? image_component.containing_frame.name : nil
|
28
|
+
|
29
|
+
formatter.separate(
|
30
|
+
name: image_component.name,
|
31
|
+
page_name: page_name,
|
32
|
+
frame_name: frame_name,
|
33
|
+
naming_style: params.naming_style,
|
34
|
+
folder_depth: params.folder_depth
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def image_path(group_name:, image_link:, single_scale:)
|
39
|
+
formatter = ImageNameFormatter.new
|
40
|
+
formatter.image_path(
|
41
|
+
group_name: group_name,
|
42
|
+
image_link: image_link,
|
43
|
+
single_scale: single_scale,
|
44
|
+
convert_to_dpi: params.convert_scales_to_dpi
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'folder_generator'
|
4
|
+
require_relative '../helpers/scale_formatter'
|
5
|
+
require_relative '../helpers/image_name_formatter'
|
6
|
+
require_relative '../models/image_set_ref'
|
7
|
+
|
8
|
+
class FolderGeneratorRaw < FolderGenerator
|
9
|
+
def create_image_sets(image_component:)
|
10
|
+
name_components = format_name(image_component: image_component)
|
11
|
+
name = name_components.name
|
12
|
+
folder = name_components.folder
|
13
|
+
|
14
|
+
image_links = image_component.image_links
|
15
|
+
single_scale = image_component.single_scale?
|
16
|
+
|
17
|
+
image_refs = image_links.map do |i|
|
18
|
+
file_name = image_path(group_name: name, image_link: i, single_scale: single_scale)
|
19
|
+
item_path = File.join(folder, file_name)
|
20
|
+
ImageRef.new(path: item_path, image_link: i)
|
21
|
+
end
|
22
|
+
|
23
|
+
ImageSetRef.new(name: name, folder: folder, image_refs: image_refs, single_scale: single_scale)
|
24
|
+
end
|
25
|
+
|
26
|
+
def image_end_download(image:)
|
27
|
+
return unless params.convert_svg_to_vector
|
28
|
+
|
29
|
+
input_file = File.join(params.output_folder, image.path)
|
30
|
+
SvtToVectorConverter.new.convert(input_file: input_file)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'folder_generator'
|
4
|
+
require_relative '../helpers/scale_formatter'
|
5
|
+
require_relative '../helpers/image_name_formatter'
|
6
|
+
require_relative '../models/image_set_ref'
|
7
|
+
|
8
|
+
class FolderGeneratorRes < FolderGenerator
|
9
|
+
def create_image_sets(image_component:)
|
10
|
+
name_components = format_name(image_component: image_component)
|
11
|
+
name = name_components.name
|
12
|
+
folder = name_components.folder
|
13
|
+
|
14
|
+
image_links = image_component.image_links
|
15
|
+
single_scale = image_component.single_scale?
|
16
|
+
|
17
|
+
image_refs = image_links.map do |i|
|
18
|
+
file_name = "#{name}.#{i.image_format}"
|
19
|
+
scale_folder = folder_for_scale(scale: i.scale, single_scale: single_scale)
|
20
|
+
item_path = File.join(folder, scale_folder, file_name)
|
21
|
+
ImageRef.new(path: item_path, image_link: i)
|
22
|
+
end
|
23
|
+
|
24
|
+
ImageSetRef.new(name: name, folder: folder, image_refs: image_refs, single_scale: single_scale)
|
25
|
+
end
|
26
|
+
|
27
|
+
def folder_for_scale(scale:, single_scale:)
|
28
|
+
dpi = ScaleFormatter.new.dpi_from_scale(scale)
|
29
|
+
!single_scale && !dpi.nil? ? "drawable-#{dpi}" : 'drawable'
|
30
|
+
end
|
31
|
+
|
32
|
+
def image_end_download(image:)
|
33
|
+
return unless params.convert_svg_to_vector
|
34
|
+
|
35
|
+
input_file = File.join(params.output_folder, image.path)
|
36
|
+
SvtToVectorConverter.new.convert(input_file: input_file)
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require_relative 'folder_generator'
|
5
|
+
require_relative '../../helpers/hash_access'
|
6
|
+
require_relative '../helpers/scale_formatter'
|
7
|
+
require_relative '../helpers/image_name_formatter'
|
8
|
+
require_relative '../models/image_set_ref'
|
9
|
+
|
10
|
+
class FolderGeneratorXcassets < FolderGenerator
|
11
|
+
|
12
|
+
attr_accessor :symbols
|
13
|
+
|
14
|
+
def initialize(symbols:, params:)
|
15
|
+
@symbols = symbols
|
16
|
+
super(params: params)
|
17
|
+
end
|
18
|
+
|
19
|
+
def start_download(image_sets:)
|
20
|
+
create_root_content_json(folder: params.output_folder)
|
21
|
+
end
|
22
|
+
|
23
|
+
def image_set_start_download(image_set:)
|
24
|
+
create_recursive_asset_contnet_json(folder: image_set.folder)
|
25
|
+
|
26
|
+
if symbols
|
27
|
+
create_symbolset_content_json(image_set: image_set)
|
28
|
+
else
|
29
|
+
create_imageset_content_json(image_set: image_set)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def image_end_download(image:)
|
34
|
+
return unless params.convert_svg_to_vector
|
35
|
+
|
36
|
+
input_file = File.join(params.output_folder, image.path)
|
37
|
+
SvtToVectorConverter.new.convert(input_file: input_file)
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_image_sets(image_component:)
|
41
|
+
name_components = format_name(image_component: image_component)
|
42
|
+
name = name_components.name
|
43
|
+
extension = symbols ? 'symbolset' : 'imageset'
|
44
|
+
folder = File.join(name_components.folder, "#{name}.#{extension}")
|
45
|
+
|
46
|
+
image_links = image_component.image_links
|
47
|
+
single_scale = image_component.single_scale?
|
48
|
+
|
49
|
+
image_refs = image_links.map do |i|
|
50
|
+
file_name = image_path(group_name: name, image_link: i, single_scale: single_scale)
|
51
|
+
item_path = File.join(folder, file_name)
|
52
|
+
ImageRef.new(path: item_path, image_link: i)
|
53
|
+
end
|
54
|
+
|
55
|
+
ImageSetRef.new(name: name, folder: folder, image_refs: image_refs, single_scale: single_scale)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def create_root_content_json(folder:)
|
61
|
+
file_path = File.join(folder, 'Contents.json')
|
62
|
+
return if File.exist?(file_path)
|
63
|
+
|
64
|
+
content = content_template
|
65
|
+
File.write_file_json(path: file_path, hash: content)
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_recursive_asset_contnet_json(folder:)
|
69
|
+
folder_root = params.output_folder
|
70
|
+
|
71
|
+
folders = folder.split('/')[0...-1].map do |f|
|
72
|
+
folder_root = File.join(folder_root, f)
|
73
|
+
folder_root
|
74
|
+
end
|
75
|
+
|
76
|
+
folders.each { |f| create_asset_contnet_json(folder: f) }
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_content_property(content:, key:, value:)
|
80
|
+
if content.dig('properties', key).nil? && !value.nil?
|
81
|
+
properties = content['properties'] || {}
|
82
|
+
properties[key] = value
|
83
|
+
content['properties'] = properties
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_asset_contnet_json(folder:)
|
88
|
+
file_path = File.join(folder, 'Contents.json')
|
89
|
+
content = File.read_file_json(path: file_path) || content_template
|
90
|
+
xcassets_params = params.xcassets_params || {}
|
91
|
+
provides_namespace = xcassets_params[:provides_namespace]
|
92
|
+
|
93
|
+
add_content_property(content: content, key: 'provides-namespace', value: provides_namespace)
|
94
|
+
|
95
|
+
File.write_file_json(path: file_path, hash: content)
|
96
|
+
end
|
97
|
+
|
98
|
+
def content_template
|
99
|
+
content = {}
|
100
|
+
content['info'] = {}
|
101
|
+
content['info']['version'] = 1
|
102
|
+
content['info']['author'] = 'xcode'
|
103
|
+
content
|
104
|
+
end
|
105
|
+
|
106
|
+
def create_symbolset_content_json(image_set:)
|
107
|
+
image_refs = image_set&.image_refs || []
|
108
|
+
|
109
|
+
if image_refs.empty?
|
110
|
+
return
|
111
|
+
end
|
112
|
+
|
113
|
+
folder = File.join(params.output_folder, image_set.folder)
|
114
|
+
file_path = File.join(folder, 'Contents.json')
|
115
|
+
content = File.read_file_json(path: file_path) || content_template
|
116
|
+
symbols = content['symbols'] || []
|
117
|
+
|
118
|
+
ref = image_refs[0]
|
119
|
+
filename = File.basename(ref.path)
|
120
|
+
|
121
|
+
symbol = symbols.first || {}
|
122
|
+
symbol['filename'] = filename
|
123
|
+
symbol['idiom'] = 'universal' if symbol['idiom'].nil?
|
124
|
+
|
125
|
+
symbols = [symbol]
|
126
|
+
content['symbols'] = symbols
|
127
|
+
|
128
|
+
xcassets_params = params.xcassets_params || {}
|
129
|
+
language_direction = xcassets_params[:language_direction]
|
130
|
+
add_content_property(content: content, key: 'language-direction', value: language_direction)
|
131
|
+
|
132
|
+
File.write_file_json(path: file_path, hash: content)
|
133
|
+
end
|
134
|
+
|
135
|
+
def create_imageset_content_json(image_set:)
|
136
|
+
folder = File.join(params.output_folder, image_set.folder)
|
137
|
+
file_path = File.join(folder, 'Contents.json')
|
138
|
+
content = File.read_file_json(path: file_path) || content_template
|
139
|
+
images = content['images'] || []
|
140
|
+
|
141
|
+
image_set&.image_refs&.each do |task|
|
142
|
+
filename = File.basename(task.path)
|
143
|
+
image_names = images.map { |i| i['filename'] }.compact
|
144
|
+
image_index = image_names.find_index(filename)
|
145
|
+
|
146
|
+
if image_index.nil?
|
147
|
+
images.push({})
|
148
|
+
image_index = images.length - 1
|
149
|
+
end
|
150
|
+
|
151
|
+
image = images[image_index]
|
152
|
+
|
153
|
+
image['filename'] = filename
|
154
|
+
image['idiom'] = 'universal' if image['idiom'].nil?
|
155
|
+
|
156
|
+
scale = task.image_link.scale
|
157
|
+
scale_enabled = !scale.nil? && !image_set.single_scale
|
158
|
+
|
159
|
+
if scale_enabled
|
160
|
+
image['scale'] = ScaleFormatter.new.formatted_scale(scale: scale)
|
161
|
+
else
|
162
|
+
image.delete('scale')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
content['images'] = images
|
167
|
+
xcassets_params = params.xcassets_params || {}
|
168
|
+
template_rendering_intent = xcassets_params[:template_rendering_intent]
|
169
|
+
preserves_vector_representation = xcassets_params[:preserves_vector_representation]
|
170
|
+
|
171
|
+
add_content_property(content: content, key: 'template-rendering-intent', value: template_rendering_intent)
|
172
|
+
add_content_property(content: content, key: 'preserves-vector-representation', value: preserves_vector_representation)
|
173
|
+
|
174
|
+
File.write_file_json(path: file_path, hash: content)
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
|