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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -1
- data/Gemfile.lock +34 -11
- data/README.md +148 -145
- data/ad_localize.gemspec +2 -0
- data/bin/console +1 -0
- data/exe/ad_localize +1 -1
- data/lib/ad_localize.rb +52 -11
- data/lib/ad_localize/ad_logger.rb +22 -9
- data/lib/ad_localize/cli.rb +10 -0
- data/lib/ad_localize/constant.rb +2 -21
- data/lib/ad_localize/entities/key.rb +74 -0
- data/lib/ad_localize/entities/locale_wording.rb +60 -0
- data/lib/ad_localize/entities/translation.rb +20 -0
- data/lib/ad_localize/entities/wording.rb +24 -0
- data/lib/ad_localize/interactors/execute_export_request.rb +43 -0
- data/lib/ad_localize/interactors/export_csv_files.rb +17 -0
- data/lib/ad_localize/interactors/export_g_spreadsheet.rb +55 -0
- data/lib/ad_localize/interactors/export_wording.rb +27 -0
- data/lib/ad_localize/interactors/merge_wordings.rb +43 -0
- data/lib/ad_localize/interactors/platforms/export_android_locale_wording.rb +39 -0
- data/lib/ad_localize/interactors/platforms/export_ios_locale_wording.rb +62 -0
- data/lib/ad_localize/interactors/platforms/export_json_locale_wording.rb +23 -0
- data/lib/ad_localize/interactors/platforms/export_platform_factory.rb +44 -0
- data/lib/ad_localize/interactors/platforms/export_properties_locale_wording.rb +29 -0
- data/lib/ad_localize/interactors/platforms/export_yaml_locale_wording.rb +23 -0
- data/lib/ad_localize/mappers/android_translation_mapper.rb +18 -0
- data/lib/ad_localize/mappers/csv_path_to_wording.rb +76 -0
- data/lib/ad_localize/mappers/ios_translation_mapper.rb +12 -0
- data/lib/ad_localize/mappers/locale_wording_to_hash.rb +25 -0
- data/lib/ad_localize/mappers/options_to_export_request.rb +28 -0
- data/lib/ad_localize/mappers/translation_group_mapper.rb +14 -0
- data/lib/ad_localize/mappers/translation_mapper.rb +30 -0
- data/lib/ad_localize/mappers/value_range_to_wording.rb +69 -0
- data/lib/ad_localize/option_handler.rb +30 -57
- data/lib/ad_localize/repositories/file_system_repository.rb +13 -0
- data/lib/ad_localize/repositories/g_sheets_repository.rb +44 -0
- data/lib/ad_localize/requests/export_request.rb +77 -0
- data/lib/ad_localize/requests/g_spreadsheet_options.rb +47 -0
- data/lib/ad_localize/requests/merge_policy.rb +28 -0
- data/lib/ad_localize/serializers/info_plist_serializer.rb +27 -0
- data/lib/ad_localize/serializers/json_serializer.rb +13 -0
- data/lib/ad_localize/serializers/localizable_strings_serializer.rb +27 -0
- data/lib/ad_localize/serializers/localizable_stringsdict_serializer.rb +35 -0
- data/lib/ad_localize/serializers/properties_serializer.rb +25 -0
- data/lib/ad_localize/serializers/strings_serializer.rb +33 -0
- data/lib/ad_localize/serializers/with_template.rb +19 -0
- data/lib/ad_localize/serializers/yaml_serializer.rb +13 -0
- data/lib/ad_localize/templates/android/strings.xml.erb +19 -0
- data/lib/ad_localize/templates/ios/InfoPlist.strings.erb +3 -0
- data/lib/ad_localize/templates/ios/Localizable.strings.erb +3 -0
- data/lib/ad_localize/templates/ios/Localizable.stringsdict.erb +41 -0
- data/lib/ad_localize/templates/properties/template.properties.erb +3 -0
- data/lib/ad_localize/version.rb +1 -1
- data/lib/ad_localize/view_models/translation_group_view_model.rb +15 -0
- data/lib/ad_localize/view_models/translation_view_model.rb +19 -0
- metadata +74 -11
- data/Makefile +0 -11
- data/lib/ad_localize/csv_file_manager.rb +0 -64
- data/lib/ad_localize/csv_parser.rb +0 -165
- data/lib/ad_localize/platform/android_formatter.rb +0 -70
- data/lib/ad_localize/platform/ios_formatter.rb +0 -143
- data/lib/ad_localize/platform/json_formatter.rb +0 -17
- data/lib/ad_localize/platform/platform_formatter.rb +0 -109
- data/lib/ad_localize/platform/yml_formatter.rb +0 -19
- data/lib/ad_localize/runner.rb +0 -55
@@ -0,0 +1,14 @@
|
|
1
|
+
module AdLocalize
|
2
|
+
module Mappers
|
3
|
+
class TranslationGroupMapper
|
4
|
+
def initialize(translation_mapper: TranslationMapper.new)
|
5
|
+
@translation_mapper = translation_mapper
|
6
|
+
end
|
7
|
+
|
8
|
+
def map(label:, translations:)
|
9
|
+
translation_view_models = translations.map { |translation| @translation_mapper.map(translation: translation) }
|
10
|
+
ViewModels::TranslationGroupViewModel.new(label: label, translation_view_models: translation_view_models)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module AdLocalize
|
2
|
+
module Mappers
|
3
|
+
class TranslationMapper
|
4
|
+
def map(translation:)
|
5
|
+
ViewModels::TranslationViewModel.new(
|
6
|
+
label: translation.key.label,
|
7
|
+
key: key(translation: translation),
|
8
|
+
value: sanitize_value(value: translation.value),
|
9
|
+
comment: translation.comment
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def sanitize_value(value:)
|
16
|
+
value
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def key(translation:)
|
22
|
+
if translation.key.plural?
|
23
|
+
translation.key.plural_key
|
24
|
+
elsif translation.key.adaptive?
|
25
|
+
translation.key.adaptive_key
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module AdLocalize
|
2
|
+
module Mappers
|
3
|
+
class ValueRangeToWording
|
4
|
+
def map(value_range:)
|
5
|
+
values = value_range.values
|
6
|
+
analyze_header(first_row: values.first)
|
7
|
+
return unless valid_header?
|
8
|
+
|
9
|
+
translations = map_rows(values: values)
|
10
|
+
locale_wordings = translations.group_by(&:locale).map do |locale, group|
|
11
|
+
Entities::LocaleWording.new(locale: locale, translations: group)
|
12
|
+
end
|
13
|
+
Entities::Wording.new(locale_wordings: locale_wordings, default_locale: @locale_mapping.keys.first)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def map_rows(values:)
|
19
|
+
translations = []
|
20
|
+
values[1..-1].each do |row|
|
21
|
+
row_translations = map_row(row: row)
|
22
|
+
next if row_translations.blank?
|
23
|
+
|
24
|
+
existing_keys = translations.map(&:key)
|
25
|
+
new_translations = row_translations.reject do |translation|
|
26
|
+
existing_keys.any? do |key|
|
27
|
+
existing_plural_key = key.label == translation.key.label && key.plural? && translation.key.singular?
|
28
|
+
key.same_as?(key: translation.key) || existing_plural_key
|
29
|
+
end
|
30
|
+
end
|
31
|
+
translations.concat(new_translations)
|
32
|
+
end
|
33
|
+
translations
|
34
|
+
end
|
35
|
+
|
36
|
+
def analyze_header(first_row:)
|
37
|
+
@header = first_row
|
38
|
+
@key_index = first_row.index(Constant::CSV_WORDING_KEYS_COLUMN)
|
39
|
+
@locale_mapping = {}
|
40
|
+
first_row[@key_index.succ..-1].each_index do |relative_index|
|
41
|
+
absolute_index = @key_index.succ + relative_index
|
42
|
+
next if first_row[absolute_index].blank? || first_row[absolute_index].include?(Constant::COMMENT_KEY_COLUMN_IDENTIFIER)
|
43
|
+
@locale_mapping[first_row[absolute_index]] = { key_index: absolute_index }
|
44
|
+
comment_column_name = "#{Constant::COMMENT_KEY_COLUMN_IDENTIFIER} #{first_row[absolute_index]}"
|
45
|
+
@locale_mapping[first_row[absolute_index]][:comment_index] = first_row.index(comment_column_name)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def map_row(row:)
|
50
|
+
csv_wording_key = row[@key_index]
|
51
|
+
return if csv_wording_key.blank?
|
52
|
+
key = Entities::Key.new(label: csv_wording_key)
|
53
|
+
@locale_mapping.map do |locale, index_mapping|
|
54
|
+
comment = index_mapping[:comment_index].nil? ? nil : row[index_mapping[:comment_index]]
|
55
|
+
Entities::Translation.new(
|
56
|
+
locale: locale,
|
57
|
+
key: key,
|
58
|
+
value: row[index_mapping[:key_index]],
|
59
|
+
comment: comment
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def valid_header?
|
65
|
+
@key_index.present? || @locale_mapping.keys.size.positive?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -1,65 +1,38 @@
|
|
1
1
|
module AdLocalize
|
2
2
|
class OptionHandler
|
3
|
-
|
3
|
+
def self.parse!(options)
|
4
|
+
option_parser = OptionParser.new do |parser|
|
5
|
+
parser.banner = "Usage: exe/ad_localize [options] file(s)"
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
opts.on("-d", "--debug", "Run in debug mode") do
|
18
|
-
args[:debug] = true
|
19
|
-
LOGGER.debug!
|
20
|
-
end
|
21
|
-
opts.on("-k", "--drive-key #{GOOGLE_DRIVE_DOCUMENT_ID.dig(:length)}_characters", String, "Use google drive spreadsheets") do |key|
|
22
|
-
is_valid_drive_key = !!(key =~ GOOGLE_DRIVE_DOCUMENT_ID.dig(:regexp)) && (key.size >= GOOGLE_DRIVE_DOCUMENT_ID.dig(:length))
|
23
|
-
raise ArgumentError.new("Invalid google drive spreadsheet key \"#{key}\"") unless is_valid_drive_key
|
24
|
-
args[:drive_key] = key
|
25
|
-
end
|
26
|
-
opts.on("-s", "--drive-sheet SHEET_ID", String, "Use a specific sheet id for Google Drive spreadsheets with several sheets") do |value|
|
27
|
-
args[:sheet_id] = value
|
28
|
-
end
|
29
|
-
opts.on("-a", "--use-service-account", "Use a Google Cloud Service Account to access the file. An GCLOUD_CLIENT_SECRET environment variable containting the client_secret.json content is needed.") do
|
30
|
-
args[:use_service_account] = true
|
31
|
-
end
|
32
|
-
opts.on("-o", "--only platform1,platform2", Array, "Only generate localisation files for the specified platforms. Supported platforms : #{Constant::SUPPORTED_PLATFORMS.join(', ')}") do |platforms|
|
33
|
-
args[:only] = filter_option_args("-o", platforms) { |platform| !!Constant::SUPPORTED_PLATFORMS.index(platform) }
|
34
|
-
end
|
35
|
-
opts.on("-t", "--target-dir PATH", String, "Path to the target directory") do |output_path|
|
36
|
-
pn = Pathname.new(output_path)
|
37
|
-
if pn.directory? and pn.readable? and pn.writable?
|
38
|
-
args[:output_path] = output_path
|
39
|
-
else
|
40
|
-
raise ArgumentError.new("Invalid target directory. Check the permissions")
|
41
|
-
end
|
42
|
-
end
|
7
|
+
parser.on("-d", "--debug", TrueClass, "Run in debug mode")
|
8
|
+
parser.on("-e", "--export-all-sheets", TrueClass,
|
9
|
+
<<~DOC
|
10
|
+
Export all sheets from spreadsheet specified by --drive-key option.
|
11
|
+
\tBy default, generates one export directory per sheet (see -m|--merge-sheets option to merge them).
|
12
|
+
\tAn GCLOUD_CLIENT_SECRET environment variable containing the client_secret.json content is needed.
|
13
|
+
DOC
|
14
|
+
)
|
15
|
+
parser.on("-h", "--help", "Prints help") do
|
16
|
+
puts parser
|
17
|
+
exit
|
43
18
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
19
|
+
parser.on("-k", "--drive-key SPREADSHEET_ID", String, "Use google drive spreadsheets")
|
20
|
+
parser.on("-m", "--merge-policy POLICY", String,
|
21
|
+
<<~DOC
|
22
|
+
Merge specified csv (or sheets from --export-all) instead of exporting each csv.
|
23
|
+
\treplace: if a key is already defined, replace its value.
|
24
|
+
\tkeep: if a key is already defined, keep the previous value.
|
25
|
+
DOC
|
26
|
+
)
|
27
|
+
parser.on("-o", "--only PLATFORMS", Array, "PLATFORMS is a comma separated list. Only generate localisation files for the specified platforms. Supported platforms : #{Requests::ExportRequest::SUPPORTED_PLATFORMS.to_sentence}")
|
28
|
+
parser.on("-s", "--sheets SHEET_IDS", Array, "SHEET_IDS is a comma separated list. Use a specific sheet id for Google Drive spreadsheets with several sheets")
|
29
|
+
parser.on("-t", "--target-dir PATH", String, "Path to the target directory")
|
54
30
|
end
|
55
31
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
LOGGER.log(:debug, :red, "Invalid arg(s) for option #{option}: #{invalid_args.join(', ')}") unless invalid_args.empty?
|
61
|
-
result
|
62
|
-
end
|
32
|
+
args = {}
|
33
|
+
option_parser.parse!(options, into: args)
|
34
|
+
args[:csv_paths] = options
|
35
|
+
return args
|
63
36
|
end
|
64
37
|
end
|
65
|
-
end
|
38
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module AdLocalize
|
2
|
+
module Repositories
|
3
|
+
class GSheetsRepository
|
4
|
+
SCOPES = [Google::Apis::SheetsV4::AUTH_SPREADSHEETS_READONLY]
|
5
|
+
ROWS_MAJOR_DIMENSION = 'ROWS'.freeze
|
6
|
+
SPREADSHEET_APPLICATION_NAME = 'ad_localize'.freeze
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@service = Google::Apis::SheetsV4::SheetsService.new
|
10
|
+
@service.client_options.application_name = SPREADSHEET_APPLICATION_NAME
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_sheets_values(g_spreadsheet_options:)
|
14
|
+
configure(json_configuration: g_spreadsheet_options.service_account_config) if @service.authorization.nil?
|
15
|
+
spreadsheet = @service.get_spreadsheet(g_spreadsheet_options.spreadsheet_id)
|
16
|
+
if g_spreadsheet_options.export_all
|
17
|
+
spreadsheet.sheets.map { |sheet| get_sheet_values(spreadsheet_id: g_spreadsheet_options.spreadsheet_id, sheet: sheet) }
|
18
|
+
elsif g_spreadsheet_options.sheet_ids.nil? || g_spreadsheet_options.sheet_ids.size.zero?
|
19
|
+
spreadsheet.sheets[0..0].map { |sheet| get_sheet_values(spreadsheet_id: g_spreadsheet_options.spreadsheet_id, sheet: sheet) }
|
20
|
+
else
|
21
|
+
spreadsheet.sheets.select do |sheet|
|
22
|
+
g_spreadsheet_options.sheet_ids.include?(sheet.properties.sheet_id)
|
23
|
+
end.map do |sheet|
|
24
|
+
get_sheet_values(spreadsheet_id: g_spreadsheet_options.spreadsheet_id, sheet: sheet)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def configure(json_configuration:)
|
32
|
+
raise ArgumentError.new('No service account configuration') if json_configuration.blank?
|
33
|
+
json_key_io = StringIO.new(json_configuration)
|
34
|
+
authorizer = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: json_key_io, scope: SCOPES)
|
35
|
+
@service.authorization = authorizer
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_sheet_values(spreadsheet_id:, sheet:)
|
39
|
+
range = sheet.properties.title
|
40
|
+
@service.get_spreadsheet_values(spreadsheet_id, range, major_dimension: ROWS_MAJOR_DIMENSION)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module AdLocalize
|
2
|
+
module Requests
|
3
|
+
class ExportRequest
|
4
|
+
SUPPORTED_PLATFORMS = %w(ios android yml json properties).freeze
|
5
|
+
DEFAULT_EXPORT_FOLDER = 'exports'.freeze
|
6
|
+
CSV_CONTENT_TYPES = %w(text/csv text/plain).freeze
|
7
|
+
|
8
|
+
def initialize(**args)
|
9
|
+
@locales = Array(args[:locales].presence)
|
10
|
+
@platforms = args[:platforms].blank? ? SUPPORTED_PLATFORMS : Array(args[:platforms])
|
11
|
+
@csv_paths = Array(args[:csv_paths])
|
12
|
+
@g_spreadsheet_options = args[:g_spreadsheet_options]
|
13
|
+
@verbose = args[:verbose].presence || false
|
14
|
+
@output_path = Pathname.new(args[:output_path].presence || DEFAULT_EXPORT_FOLDER)
|
15
|
+
if @csv_paths.size > 1 || @g_spreadsheet_options&.has_multiple_sheets?
|
16
|
+
@merge_policy = MergePolicy.new(policy: args[:merge_policy].presence || MergePolicy::DEFAULT_POLICY)
|
17
|
+
else
|
18
|
+
@merge_policy = nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader(
|
23
|
+
:locales,
|
24
|
+
:platforms,
|
25
|
+
:g_spreadsheet_options,
|
26
|
+
:output_path,
|
27
|
+
:verbose,
|
28
|
+
:merge_policy
|
29
|
+
)
|
30
|
+
|
31
|
+
attr_accessor(:csv_paths)
|
32
|
+
|
33
|
+
def has_csv_files?
|
34
|
+
!@csv_paths.blank? && @csv_paths.all? { |csv_path| File.exist?(csv_path) && is_csv?(path: csv_path) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def has_g_spreadsheet_options?
|
38
|
+
@g_spreadsheet_options.present?
|
39
|
+
end
|
40
|
+
|
41
|
+
def multiple_platforms?
|
42
|
+
@platforms.size > 1
|
43
|
+
end
|
44
|
+
|
45
|
+
def valid?
|
46
|
+
valid_platforms? && (valid_csv_options? || valid_g_spreadsheet_options?)
|
47
|
+
end
|
48
|
+
|
49
|
+
def verbose?
|
50
|
+
verbose
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def valid_csv_options?
|
56
|
+
has_csv_files? && (@csv_paths.size == 1 || (@csv_paths.size > 1 && @merge_policy&.valid?))
|
57
|
+
end
|
58
|
+
|
59
|
+
def valid_platforms?
|
60
|
+
@platforms.size.positive? && (@platforms & SUPPORTED_PLATFORMS).size == @platforms.size
|
61
|
+
end
|
62
|
+
|
63
|
+
def is_csv?(path:)
|
64
|
+
(MIME::Types.of(path).map(&:content_type) & CSV_CONTENT_TYPES).present?
|
65
|
+
end
|
66
|
+
|
67
|
+
def valid_g_spreadsheet_options?
|
68
|
+
return false if @g_spreadsheet_options.blank?
|
69
|
+
if @g_spreadsheet_options.has_multiple_sheets?
|
70
|
+
@g_spreadsheet_options.valid? && @merge_policy&.valid?
|
71
|
+
else
|
72
|
+
@g_spreadsheet_options.valid?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module AdLocalize
|
2
|
+
module Requests
|
3
|
+
class GSpreadsheetOptions
|
4
|
+
attr_accessor(
|
5
|
+
:spreadsheet_id,
|
6
|
+
:sheet_ids,
|
7
|
+
:export_all,
|
8
|
+
:service_account_config
|
9
|
+
)
|
10
|
+
|
11
|
+
def initialize(**args)
|
12
|
+
@spreadsheet_id = args[:spreadsheet_id]
|
13
|
+
@sheet_ids = Array(args[:sheet_ids])
|
14
|
+
@export_all = args[:export_all] || false
|
15
|
+
@service_account_config = args[:service_account_config].presence
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid?
|
19
|
+
(spreadsheet_id && !export_all) || (spreadsheet_id && service_account_config.present?)
|
20
|
+
end
|
21
|
+
|
22
|
+
def public_download_urls
|
23
|
+
return [] if @service_account_config
|
24
|
+
if @sheet_ids.size.zero?
|
25
|
+
[public_download_url(sheet_id: nil)]
|
26
|
+
else
|
27
|
+
@sheet_ids.map { |sheet_id| public_download_url(sheet_id: sheet_id) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_multiple_sheets?
|
32
|
+
export_all || @sheet_ids.size > 1
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def public_download_url(sheet_id:)
|
38
|
+
query_id = sheet_id.blank? ? "id=#{@spreadsheet_id}" : "gid=#{sheet_id}"
|
39
|
+
"https://docs.google.com/spreadsheets/d/#{@spreadsheet_id}/export?format=csv&#{query_id}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def valid_export_all_config
|
43
|
+
export_all && service_account_config.present?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module AdLocalize
|
2
|
+
module Requests
|
3
|
+
class MergePolicy
|
4
|
+
REPLACE_POLICY = 'replace'.freeze
|
5
|
+
KEEP_POLICY = 'keep'.freeze
|
6
|
+
MERGE_POLICIES = [KEEP_POLICY, REPLACE_POLICY]
|
7
|
+
DEFAULT_POLICY = KEEP_POLICY
|
8
|
+
|
9
|
+
attr_reader(:policy)
|
10
|
+
|
11
|
+
def initialize(policy:)
|
12
|
+
@policy = policy
|
13
|
+
end
|
14
|
+
|
15
|
+
def keep?
|
16
|
+
@policy == KEEP_POLICY
|
17
|
+
end
|
18
|
+
|
19
|
+
def replace?
|
20
|
+
@policy == REPLACE_POLICY
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid?
|
24
|
+
@policy.present? && MERGE_POLICIES.include?(@policy)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module AdLocalize
|
2
|
+
module Serializers
|
3
|
+
class InfoPlistSerializer
|
4
|
+
include WithTemplate
|
5
|
+
|
6
|
+
INFO_PLIST_FILENAME = "InfoPlist.strings".freeze
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@translation_mapper = Mappers::IOSTranslationMapper.new
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def template_path
|
15
|
+
TEMPLATES_DIRECTORY + "/ios/#{INFO_PLIST_FILENAME}.erb"
|
16
|
+
end
|
17
|
+
|
18
|
+
def hash_binding(locale_wording:)
|
19
|
+
{ translations: map_translations(translations: locale_wording.info_plists) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def map_translations(translations:)
|
23
|
+
translations.map { |translation| @translation_mapper.map(translation: translation) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|