ad_localize 3.6.0 → 4.0.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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -1
  3. data/Gemfile.lock +34 -11
  4. data/README.md +148 -145
  5. data/ad_localize.gemspec +2 -0
  6. data/bin/console +1 -0
  7. data/exe/ad_localize +1 -1
  8. data/lib/ad_localize.rb +52 -11
  9. data/lib/ad_localize/ad_logger.rb +22 -9
  10. data/lib/ad_localize/cli.rb +10 -0
  11. data/lib/ad_localize/constant.rb +2 -21
  12. data/lib/ad_localize/entities/key.rb +74 -0
  13. data/lib/ad_localize/entities/locale_wording.rb +60 -0
  14. data/lib/ad_localize/entities/translation.rb +20 -0
  15. data/lib/ad_localize/entities/wording.rb +24 -0
  16. data/lib/ad_localize/interactors/execute_export_request.rb +43 -0
  17. data/lib/ad_localize/interactors/export_csv_files.rb +17 -0
  18. data/lib/ad_localize/interactors/export_g_spreadsheet.rb +55 -0
  19. data/lib/ad_localize/interactors/export_wording.rb +27 -0
  20. data/lib/ad_localize/interactors/merge_wordings.rb +43 -0
  21. data/lib/ad_localize/interactors/platforms/export_android_locale_wording.rb +39 -0
  22. data/lib/ad_localize/interactors/platforms/export_ios_locale_wording.rb +62 -0
  23. data/lib/ad_localize/interactors/platforms/export_json_locale_wording.rb +23 -0
  24. data/lib/ad_localize/interactors/platforms/export_platform_factory.rb +44 -0
  25. data/lib/ad_localize/interactors/platforms/export_properties_locale_wording.rb +29 -0
  26. data/lib/ad_localize/interactors/platforms/export_yaml_locale_wording.rb +23 -0
  27. data/lib/ad_localize/mappers/android_translation_mapper.rb +18 -0
  28. data/lib/ad_localize/mappers/csv_path_to_wording.rb +76 -0
  29. data/lib/ad_localize/mappers/ios_translation_mapper.rb +12 -0
  30. data/lib/ad_localize/mappers/locale_wording_to_hash.rb +25 -0
  31. data/lib/ad_localize/mappers/options_to_export_request.rb +28 -0
  32. data/lib/ad_localize/mappers/translation_group_mapper.rb +14 -0
  33. data/lib/ad_localize/mappers/translation_mapper.rb +30 -0
  34. data/lib/ad_localize/mappers/value_range_to_wording.rb +69 -0
  35. data/lib/ad_localize/option_handler.rb +30 -57
  36. data/lib/ad_localize/repositories/file_system_repository.rb +13 -0
  37. data/lib/ad_localize/repositories/g_sheets_repository.rb +44 -0
  38. data/lib/ad_localize/requests/export_request.rb +77 -0
  39. data/lib/ad_localize/requests/g_spreadsheet_options.rb +47 -0
  40. data/lib/ad_localize/requests/merge_policy.rb +28 -0
  41. data/lib/ad_localize/serializers/info_plist_serializer.rb +27 -0
  42. data/lib/ad_localize/serializers/json_serializer.rb +13 -0
  43. data/lib/ad_localize/serializers/localizable_strings_serializer.rb +27 -0
  44. data/lib/ad_localize/serializers/localizable_stringsdict_serializer.rb +35 -0
  45. data/lib/ad_localize/serializers/properties_serializer.rb +25 -0
  46. data/lib/ad_localize/serializers/strings_serializer.rb +33 -0
  47. data/lib/ad_localize/serializers/with_template.rb +19 -0
  48. data/lib/ad_localize/serializers/yaml_serializer.rb +13 -0
  49. data/lib/ad_localize/templates/android/strings.xml.erb +19 -0
  50. data/lib/ad_localize/templates/ios/InfoPlist.strings.erb +3 -0
  51. data/lib/ad_localize/templates/ios/Localizable.strings.erb +3 -0
  52. data/lib/ad_localize/templates/ios/Localizable.stringsdict.erb +41 -0
  53. data/lib/ad_localize/templates/properties/template.properties.erb +3 -0
  54. data/lib/ad_localize/version.rb +1 -1
  55. data/lib/ad_localize/view_models/translation_group_view_model.rb +15 -0
  56. data/lib/ad_localize/view_models/translation_view_model.rb +19 -0
  57. metadata +74 -11
  58. data/Makefile +0 -11
  59. data/lib/ad_localize/csv_file_manager.rb +0 -64
  60. data/lib/ad_localize/csv_parser.rb +0 -165
  61. data/lib/ad_localize/platform/android_formatter.rb +0 -70
  62. data/lib/ad_localize/platform/ios_formatter.rb +0 -143
  63. data/lib/ad_localize/platform/json_formatter.rb +0 -17
  64. data/lib/ad_localize/platform/platform_formatter.rb +0 -109
  65. data/lib/ad_localize/platform/yml_formatter.rb +0 -19
  66. data/lib/ad_localize/runner.rb +0 -55
@@ -1,165 +0,0 @@
1
- module AdLocalize
2
- class CsvParser
3
- CSV_WORDING_KEYS_COLUMN = "key"
4
- PLURAL_KEY_REGEXP = /\#\#\{([A-Za-z]+)\}/
5
- ADAPTIVE_KEY_REGEXP = /\#\#\{(\d+)\}/
6
- INFO_PLIST_KEY_REGEXP = /(NS.+UsageDescription)|(CF.+Name)/ # see https://developer.apple.com/documentation/bundleresources/information_property_list
7
-
8
- attr_accessor :locales
9
-
10
- def initialize
11
- @locales = []
12
- end
13
-
14
- # Raise a StandardError if no locale is detected in the csv
15
- def extract_data(file_name)
16
- data = {}
17
- CSV.foreach(file_name, headers: true, skip_blanks: true) do |row|
18
- validity_status = check_row(row)
19
- if validity_status.zero?
20
- keys_column_index = row.index(CSV_WORDING_KEYS_COLUMN)
21
- fields = row.fields
22
- LOGGER.log(:warn, :yellow, "Missing key in line #{$.}") unless fields[keys_column_index...fields.count].all?(&:nil?)
23
- next
24
- elsif validity_status == -1
25
- LOGGER.log(:error, :red, "[CSV FORMAT] #{file_name} is not a valid file")
26
- exit
27
- else
28
- find_locales(row) if locales.empty?
29
- row_data = parse_row(row)
30
- data.deep_merge!(row_data) unless row_data.nil?
31
- end
32
- end
33
- remove_numeral_conflicts!(data)
34
- data
35
- end
36
-
37
- private
38
-
39
- # Returns 1 if row is ok, 0 if row there are missing information and -1 if row is not a csv row
40
- def check_row(row)
41
- valid_row = 1
42
- # Check non empty row
43
- if row.field(CSV_WORDING_KEYS_COLUMN).nil?
44
- valid_row = 0
45
- elsif not row.headers.include?(CSV_WORDING_KEYS_COLUMN)
46
- valid_row = -1
47
- end
48
- return valid_row
49
- end
50
-
51
- def find_locales(row)
52
- wording_key_column_index = row.index(CSV_WORDING_KEYS_COLUMN)
53
- if row.length > wording_key_column_index
54
- self.locales = row.headers.slice((wording_key_column_index+1)..-1).compact.reject do |header|
55
- header.to_s.include? Constant::COMMENT_KEY_COLUMN_IDENTIFIER
56
- end
57
- end
58
- if locales.empty?
59
- raise 'NO DETECTED LOCALES'
60
- else
61
- LOGGER.log(:debug, :green, "DETECTED LOCALES : #{locales.join(', ')}")
62
- end
63
- end
64
-
65
- def parse_row(row)
66
- key_infos = parse_key(row)
67
- return nil if key_infos.nil?
68
-
69
- locales.each_with_object({ key_infos.dig(:key) => {} }) do |locale, output|
70
- current_key = key_infos.dig(:key)
71
- current_key_already_has_wording_for_locale = output[current_key].key? locale.to_sym
72
- output[current_key][locale.to_sym] = { key_infos.dig(:numeral_key) => {} } unless current_key_already_has_wording_for_locale
73
-
74
- if key_infos.dig(:numeral_key) == Constant::SINGULAR_KEY_SYMBOL
75
- trace_wording(row[locale], "[#{locale.upcase}] Singular key ---> #{current_key}", "[#{locale.upcase}] Missing translation for #{current_key}")
76
- value = row[locale] || default_wording(locale, current_key)
77
- elsif key_infos.dig(:numeral_key) == Constant::PLURAL_KEY_SYMBOL
78
- trace_wording(row[locale],
79
- "[#{locale.upcase}] Plural key ---> plural_identifier : #{key_infos.dig(:plural_identifier)}, key : #{current_key}",
80
- "[#{locale.upcase}] Missing translation for #{current_key} (#{key_infos.dig(:plural_identifier)})")
81
- value = { key_infos.dig(:plural_identifier) => row[locale] || default_wording(locale, "#{current_key} (#{key_infos.dig(:plural_identifier)})") }
82
- elsif key_infos.dig(:numeral_key) == Constant::ADAPTIVE_KEY_SYMBOL
83
- trace_wording(row[locale],
84
- "[#{locale.upcase}] Adaptive key ---> adaptive_identifier : #{key_infos.dig(:adaptive_identifier)}, key : #{current_key}",
85
- "[#{locale.upcase}] Missing translation for #{current_key} (#{key_infos.dig(:adaptive_identifier)})")
86
- value = { key_infos.dig(:adaptive_identifier) => row[locale] || default_wording(locale, "#{current_key} (#{key_infos.dig(:adaptive_identifier)})") }
87
- elsif key_infos.dig(:numeral_key) == Constant::INFO_PLIST_KEY_SYMBOL
88
- trace_wording(row[locale], "[#{locale.upcase}] Info.plist key ---> #{current_key}", "[#{locale.upcase}] Missing translation for #{current_key}")
89
- value = row[locale] || default_wording(locale, current_key)
90
- else
91
- raise "Unknown numeral key #{key_infos.dig(:numeral_key)}"
92
- end
93
-
94
- check_wording_parameters(row[locale], locale, current_key)
95
- output[current_key][locale.to_sym][key_infos.dig(:numeral_key)] = value
96
- locale_comment_column = "#{Constant::COMMENT_KEY_COLUMN_IDENTIFIER} #{locale}"
97
- output[current_key][locale.to_sym][Constant::COMMENT_KEY_SYMBOL] = row[locale_comment_column] unless locale_comment_column.blank? and row[locale_comment_column].blank?
98
- end
99
- end
100
-
101
- def parse_key(row)
102
- key = row.field(CSV_WORDING_KEYS_COLUMN).strip
103
- plural_prefix = key.match(PLURAL_KEY_REGEXP)
104
- plural_identifier = nil
105
- invalid_plural = false
106
-
107
- adaptive_prefix = key.match(ADAPTIVE_KEY_REGEXP)
108
- adaptive_identifier = nil
109
- invalid_adaptive = false
110
-
111
- if plural_prefix != nil
112
- numeral_key = Constant::PLURAL_KEY_SYMBOL
113
- key = plural_prefix.pre_match
114
- plural_identifier = plural_prefix.captures&.first
115
- LOGGER.log(:debug, :red, "Invalid key #{key}") if key.nil?
116
- LOGGER.log(:debug, :red, "Empty plural prefix!") if plural_identifier.nil?
117
- invalid_plural = plural_identifier.nil?
118
- elsif adaptive_prefix != nil
119
- numeral_key = Constant::ADAPTIVE_KEY_SYMBOL
120
- key = adaptive_prefix.pre_match
121
- adaptive_identifier = adaptive_prefix.captures&.first
122
- LOGGER.log(:debug, :red, "Invalid key #{key}") if key.nil?
123
- LOGGER.log(:debug, :red, "Empty adaptive prefix!") if adaptive_identifier.nil?
124
- invalid_adaptive = adaptive_identifier.nil?
125
- elsif key.match(INFO_PLIST_KEY_REGEXP) != nil
126
- numeral_key = Constant::INFO_PLIST_KEY_SYMBOL
127
- else
128
- numeral_key = Constant::SINGULAR_KEY_SYMBOL
129
- end
130
-
131
- (key.nil? or invalid_plural or invalid_adaptive) ? nil : { key: key.to_sym, numeral_key: numeral_key, plural_identifier: plural_identifier&.to_sym, adaptive_identifier: adaptive_identifier&.to_sym }
132
- end
133
-
134
- def default_wording(locale, key)
135
- LOGGER.debug? ? "<[#{locale.upcase}] Missing translation for #{key}>" : ""
136
- end
137
-
138
- def trace_wording(wording, present_message, missing_message)
139
- if wording
140
- LOGGER.log(:debug, :green, present_message)
141
- else
142
- LOGGER.log(:debug, :yellow, missing_message)
143
- end
144
- end
145
-
146
- def check_wording_parameters(value, locale, key)
147
- formatted_arguments = value&.scan(/%(\d$)?@/) || []
148
- if formatted_arguments.size >= 2
149
- is_all_ordered = formatted_arguments.inject(true){ |is_ordered, match| is_ordered &&= !match.join.empty? }
150
- LOGGER.log(:warn, :red, "[#{locale.upcase}] Multiple arguments for #{key} but no order") unless is_all_ordered
151
- end
152
- end
153
-
154
- def remove_numeral_conflicts!(data)
155
- data.select do |_, wording|
156
- wording.values.any? { |translation| (translation.keys & [:plural, :singular]).size == 2 }
157
- end.keys.each do |key|
158
- AdLocalize::LOGGER.log(:warn, :yellow, "Key \"#{key}\" is duplicated in singular and plural." \
159
- "The singular wording will be ignored. You should keep one version of the key (singular or plural)"
160
- )
161
- data[key].values.each { |wording| wording.delete(:singular) }
162
- end
163
- end
164
- end
165
- end
@@ -1,70 +0,0 @@
1
- module AdLocalize::Platform
2
- class AndroidFormatter < PlatformFormatter
3
- def platform
4
- :android
5
- end
6
-
7
- def export(locale, data, export_extension = nil, substitution_format = nil)
8
- locale = locale.to_sym
9
- export_dir_suffix = (locale == default_locale) ? "" : "-#{locale.downcase}"
10
- create_locale_dir(export_dir_suffix)
11
-
12
- xml_doc = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
13
- xml.resources {
14
- data.each do |key, wording|
15
- singular_wording = wording.dig(locale, AdLocalize::Constant::SINGULAR_KEY_SYMBOL)
16
- unless singular_wording.blank?
17
- comment = wording.dig(locale, AdLocalize::Constant::COMMENT_KEY_SYMBOL)
18
- add_singular_wording_to_xml(key, singular_wording, xml, comment: comment)
19
- end
20
-
21
- plural_wording = wording.dig(locale, AdLocalize::Constant::PLURAL_KEY_SYMBOL)
22
- add_plural_wording_to_xml(key, plural_wording, xml) unless plural_wording.blank?
23
- end
24
- }
25
- end
26
-
27
- export_dir(export_dir_suffix).join(AdLocalize::Constant::ANDROID_EXPORT_FILENAME).open("w") do |file|
28
- file.puts xml_doc.to_xml(indent: 4)
29
- end
30
- AdLocalize::LOGGER.log(:debug, :black, "Android [#{locale}] ---> DONE!")
31
- end
32
-
33
- private
34
-
35
- def ios_converter(value)
36
- processedValue = value.gsub(/(?<!\\)'/, "\\\\'") # match ' unless there is a \ before
37
- processedValue = processedValue.gsub(/(?<!\\)\"/, "\\\"") # match " unless there is a \ before
38
- processedValue = processedValue.gsub(/(%(\d+\$)?@)/, '%\2s') # should match values like %1$s and %s
39
- processedValue = processedValue.gsub(/(%((\d+\$)?(\d+)?)i)/, '%\2d') # should match values like %i, %3$i, %01i, %1$02i
40
- processedValue = processedValue.gsub(/%(?!((\d+\$)?(s|(\d+)?d)))/, '%%') # negative lookahead: identifies when user really wants to display a %
41
- processedValue = processedValue.gsub("\\U", "\\u")
42
- "\"#{processedValue}\""
43
- end
44
-
45
- def add_singular_wording_to_xml(key, text, xml, comment: nil)
46
- xml.comment(comment) unless comment.blank?
47
- xml.string(name: key) {
48
- add_wording_text_to_xml(text, xml)
49
- }
50
- end
51
-
52
- def add_plural_wording_to_xml(key, plural_hash, xml)
53
- xml.plurals(name: key) {
54
- plural_hash.each do |plural_type, plural_text|
55
- next if plural_text.blank?
56
- xml.item(quantity: plural_type) {
57
- add_wording_text_to_xml(plural_text, xml)
58
- }
59
- end
60
- } unless plural_hash.values.all? &:empty?
61
- end
62
-
63
- def add_wording_text_to_xml(wording_text, xml)
64
- raise 'Wording text should not be empty' if wording_text.blank?
65
- xml.text(
66
- ios_converter(wording_text)
67
- )
68
- end
69
- end
70
- end
@@ -1,143 +0,0 @@
1
- module AdLocalize::Platform
2
- class IosFormatter < PlatformFormatter
3
- def platform
4
- :ios
5
- end
6
-
7
- def export(locale, data, export_extension = nil, substitution_format = nil)
8
- create_locale_dir(locale)
9
- all_symbols = [
10
- AdLocalize::Constant::PLURAL_KEY_SYMBOL,
11
- AdLocalize::Constant::ADAPTIVE_KEY_SYMBOL,
12
- AdLocalize::Constant::SINGULAR_KEY_SYMBOL,
13
- AdLocalize::Constant::INFO_PLIST_KEY_SYMBOL
14
- ]
15
- all_symbols.each do |numeral_key|
16
- numeral_data = data.select {|key, wording| wording.dig(locale.to_sym)&.key? numeral_key}
17
- if numeral_data.empty?
18
- AdLocalize::LOGGER.log(:info, :green, "[#{locale.upcase}] no #{numeral_key.to_s} keys were found to generate the file")
19
- else
20
- send("write_#{numeral_key}", locale, numeral_data)
21
- end
22
- end
23
- end
24
-
25
- protected
26
-
27
- def write_singular(locale, singulars)
28
- write_localizable(
29
- locale: locale,
30
- singulars: singulars,
31
- wording_type: AdLocalize::Constant::SINGULAR_KEY_SYMBOL,
32
- filename: AdLocalize::Constant::IOS_SINGULAR_EXPORT_FILENAME
33
- )
34
- end
35
-
36
- def write_info_plist(locale, singulars)
37
- write_localizable(
38
- locale: locale,
39
- singulars: singulars,
40
- wording_type: AdLocalize::Constant::INFO_PLIST_KEY_SYMBOL,
41
- filename: AdLocalize::Constant::IOS_INFO_PLIST_EXPORT_FILENAME
42
- )
43
- end
44
-
45
- def write_plural(locale, plurals)
46
- locale = locale.to_sym
47
-
48
- append_to_localizable_plist(locale) do |xml|
49
- plurals.each do |wording_key, translations|
50
- xml.key wording_key
51
- xml.dict {
52
- xml.key "NSStringLocalizedFormatKey"
53
- xml.string "%\#@key@"
54
- xml.key "key"
55
- xml.dict {
56
- xml.key "NSStringFormatSpecTypeKey"
57
- xml.string "NSStringPluralRuleType"
58
- xml.key "NSStringFormatValueTypeKey"
59
- xml.string "d"
60
- translations[locale][AdLocalize::Constant::PLURAL_KEY_SYMBOL].each do |wording_type, wording_value|
61
- xml.key wording_type
62
- xml.string wording_value
63
- end
64
- }
65
- }
66
- end
67
- end
68
- AdLocalize::LOGGER.log(:debug, :green, "iOS plural [#{locale}] ---> DONE!")
69
- end
70
-
71
- def write_adaptive(locale, adaptives)
72
- locale = locale.to_sym
73
-
74
- append_to_localizable_plist(locale) do |xml|
75
- adaptives.each do |wording_key, translations|
76
- xml.key wording_key
77
- xml.dict {
78
- xml.key "NSStringVariableWidthRuleType"
79
- xml.dict {
80
- translations[locale][AdLocalize::Constant::ADAPTIVE_KEY_SYMBOL].each do |wording_type, wording_value|
81
- xml.key wording_type
82
- xml.string wording_value
83
- end
84
- }
85
- }
86
- end
87
- end
88
- AdLocalize::LOGGER.log(:debug, :black, "iOS adaptive [#{locale}] ---> DONE!")
89
- end
90
-
91
- private
92
-
93
- def escape_quotes_if_needed(value)
94
- value.gsub(/(?<!\\)\"/, "\\\"") # match " unless there is a \ before
95
- end
96
-
97
- def write_localizable(locale:, singulars:, wording_type:, filename:)
98
- locale = locale.to_sym
99
-
100
- singulars.each do |key, locales_wording|
101
- value = locales_wording.dig(locale, wording_type)
102
- value = escape_quotes_if_needed(value)
103
- comment = locales_wording.dig(locale, AdLocalize::Constant::COMMENT_KEY_SYMBOL)
104
- export_dir(locale).join(filename).open("a") do |file|
105
- line = ""
106
- if wording_type == AdLocalize::Constant::INFO_PLIST_KEY_SYMBOL
107
- line = %(#{key} = "#{value}";)
108
- else
109
- line = %("#{key}" = "#{value}";)
110
- end
111
- line << " // #{comment}" unless comment.nil?
112
- line << "\n"
113
- file.puts line
114
- end
115
- end
116
- AdLocalize::LOGGER.log(:debug, :green, "iOS #{wording_type} [#{locale}] ---> DONE!")
117
- end
118
-
119
- def append_to_localizable_plist(locale)
120
- filename = export_dir(locale).join(AdLocalize::Constant::IOS_PLURAL_EXPORT_FILENAME)
121
- xml_doc = nil
122
- if File.exist?(filename)
123
- xml_content = Nokogiri::XML(open(filename)) do |config|
124
- config.default_xml.noblanks # minimify xml
125
- end
126
- xml_doc = Nokogiri::XML::Builder.with(xml_content.css('plist>dict').first) do |xml|
127
- yield(xml)
128
- end
129
- else
130
- xml_doc = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
131
- xml.plist {
132
- xml.dict {
133
- yield(xml)
134
- }
135
- }
136
- end
137
- end
138
- filename.open("w") do |file|
139
- file.puts xml_doc.to_xml(indent: 4)
140
- end
141
- end
142
- end
143
- end
@@ -1,17 +0,0 @@
1
- module AdLocalize::Platform
2
- class JsonFormatter < PlatformFormatter
3
- def platform
4
- :json
5
- end
6
-
7
- def export(locale, data, export_extension = "json", substitution_format = "react")
8
- locale = locale.to_sym
9
- json_data = build_platform_data_splitting_on_dots(locale, data)
10
- platform_dir.join("#{locale.to_s}.#{export_extension}").open("w") do |file|
11
- file.puts json_data.to_json
12
- end
13
-
14
- AdLocalize::LOGGER.log(:debug, :green, "JSON [#{locale}] ---> DONE!")
15
- end
16
- end
17
- end
@@ -1,109 +0,0 @@
1
- module AdLocalize::Platform
2
- class PlatformFormatter
3
- PLURAL_KEY_SYMBOL = :plural
4
- SINGULAR_KEY_SYMBOL = :singular
5
- OPTIONS = {output_path: ".."}
6
-
7
- attr_accessor :platform_dir
8
- attr_reader :default_locale, :output_path, :add_intermediate_platform_dir
9
-
10
- def initialize(default_locale, output_path, add_intermediate_platform_dir)
11
- @default_locale = default_locale.to_sym
12
- @output_path = output_path # Must be set before platform_dir
13
- @platform_dir = add_intermediate_platform_dir ? export_base_directory.join(platform.to_s) : export_base_directory
14
- @add_intermediate_platform_dir = add_intermediate_platform_dir
15
- create_platform_dir
16
- end
17
-
18
- def platform
19
- raise 'Please override me!'
20
- end
21
-
22
- def export(locale, data, export_extension, substitution_format)
23
- locale = locale.to_sym
24
- formatted_data = data.each_with_object({}) do |(key, wording), hash_acc|
25
- hash_acc[locale.to_s] = {} unless hash_acc.key? locale.to_s
26
- if wording.dig(locale)&.key? :singular
27
- value = ios_converter(wording.dig(locale, :singular))
28
- hash_acc[locale.to_s][key.to_s] = value
29
- end
30
- if wording.dig(locale)&.key? :plural
31
- hash_acc[locale.to_s][key.to_s] = {}
32
- wording.dig(locale, :plural).each do |plural_type, plural_text|
33
- value = ios_converter(plural_text)
34
- hash_acc[locale.to_s][key.to_s][plural_type.to_s] = value
35
- end
36
- end
37
- end
38
-
39
- platform_dir.join("#{locale.to_s}.#{export_extension}").open("w") do |file|
40
- yield(formatted_data, file)
41
- end
42
-
43
- AdLocalize::LOGGER.log(:debug, :green, "#{platform.to_s.upcase} [#{locale}] ---> DONE!")
44
- end
45
-
46
- protected
47
- def export_base_directory
48
- if output_path
49
- Pathname.new(output_path)
50
- else
51
- Pathname::pwd.join(AdLocalize::Constant::EXPORT_FOLDER)
52
- end
53
- end
54
-
55
- def create_platform_dir
56
- if platform_dir.directory? && add_intermediate_platform_dir
57
- FileUtils.rm_rf("#{platform_dir}/.", secure: true)
58
- else
59
- platform_dir.mkpath
60
- end
61
- end
62
-
63
- def export_dir(locale)
64
- platform_dir + AdLocalize::Constant::CONFIG.dig(:platforms, :export_directory_names, platform.to_sym) % { locale: locale.downcase }
65
- end
66
-
67
- def create_locale_dir(locale)
68
- raise 'Locale needed' unless locale
69
-
70
- if export_dir(locale).directory?
71
- FileUtils.rm_rf("#{export_dir(locale)}/.", secure: true)
72
- else
73
- export_dir(locale).mkdir
74
- end
75
- end
76
-
77
- def build_platform_data_splitting_on_dots(locale, data)
78
- data.each_with_object({}) do |(key, wording), hash_acc|
79
- hash_acc[locale.to_s] = {} unless hash_acc.key? locale.to_s
80
- keys = key.to_s.split('.')
81
- hash = hash_acc[locale.to_s]
82
- keys.each_with_index do |inner_key, index|
83
- if index === keys.count - 1
84
- fill_hash(wording, locale, hash, inner_key)
85
- else
86
- if hash[inner_key].nil?
87
- hash[inner_key] = {}
88
- end
89
- hash = hash[inner_key]
90
- end
91
- end
92
- end
93
- end
94
-
95
- def fill_hash(wording, locale, hash, key)
96
- if wording.dig(locale)&.key? :singular
97
- value = wording.dig(locale, :singular)
98
- hash[key.to_s] = value
99
- end
100
- if wording.dig(locale)&.key? :plural
101
- hash[key.to_s] = {}
102
- wording.dig(locale, :plural).each do |plural_type, plural_text|
103
- value = plural_text
104
- hash[key.to_s][plural_type.to_s] = value
105
- end
106
- end
107
- end
108
- end
109
- end