ad_localize 5.0.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +6 -3
  3. data/.rubocop.yml +5 -0
  4. data/.rubocop_todo.yml +319 -0
  5. data/CHANGELOG.md +24 -0
  6. data/Gemfile +1 -0
  7. data/Gemfile.lock +54 -48
  8. data/README.md +32 -10
  9. data/Rakefile +1 -0
  10. data/ad_localize.gemspec +10 -9
  11. data/bin/console +1 -0
  12. data/exe/ad_localize +2 -1
  13. data/lib/ad_localize/ad_logger.rb +5 -10
  14. data/lib/ad_localize/cli.rb +10 -3
  15. data/lib/ad_localize/entities/key.rb +3 -76
  16. data/lib/ad_localize/entities/locale_wording.rb +32 -52
  17. data/lib/ad_localize/entities/platform.rb +13 -0
  18. data/lib/ad_localize/entities/simple_wording.rb +6 -0
  19. data/lib/ad_localize/entities/wording_type.rb +11 -0
  20. data/lib/ad_localize/interactors/base_generate_files.rb +37 -0
  21. data/lib/ad_localize/interactors/download_spreadsheets.rb +20 -0
  22. data/lib/ad_localize/interactors/export_wording.rb +26 -20
  23. data/lib/ad_localize/interactors/generate_info_plist.rb +24 -0
  24. data/lib/ad_localize/interactors/generate_ios_files.rb +12 -0
  25. data/lib/ad_localize/interactors/generate_json.rb +20 -0
  26. data/lib/ad_localize/interactors/generate_localizable_strings.rb +24 -0
  27. data/lib/ad_localize/interactors/generate_localizable_strings_dict.rb +24 -0
  28. data/lib/ad_localize/interactors/generate_properties.rb +20 -0
  29. data/lib/ad_localize/interactors/generate_strings.rb +25 -0
  30. data/lib/ad_localize/interactors/generate_yaml.rb +20 -0
  31. data/lib/ad_localize/interactors/merge_wordings.rb +49 -18
  32. data/lib/ad_localize/interactors/parse_csv_files.rb +22 -0
  33. data/lib/ad_localize/interactors/process_export_request.rb +21 -0
  34. data/lib/ad_localize/mappers/locale_wording_to_hash.rb +45 -24
  35. data/lib/ad_localize/mappers/options_to_export_request.rb +14 -22
  36. data/lib/ad_localize/option_handler.rb +50 -27
  37. data/lib/ad_localize/parsers/csv_parser.rb +84 -0
  38. data/lib/ad_localize/parsers/key_parser.rb +62 -0
  39. data/lib/ad_localize/repositories/drive_repository.rb +53 -0
  40. data/lib/ad_localize/repositories/file_system_repository.rb +2 -1
  41. data/lib/ad_localize/requests/export_request.rb +95 -57
  42. data/lib/ad_localize/sanitizers/ios_sanitizer.rb +12 -0
  43. data/lib/ad_localize/{mappers/android_translation_mapper.rb → sanitizers/ios_to_android_sanitizer.rb} +8 -8
  44. data/lib/ad_localize/sanitizers/pass_through_sanitizer.rb +10 -0
  45. data/lib/ad_localize/serializers/info_plist_serializer.rb +9 -11
  46. data/lib/ad_localize/serializers/json_serializer.rb +3 -5
  47. data/lib/ad_localize/serializers/localizable_strings_serializer.rb +9 -15
  48. data/lib/ad_localize/serializers/localizable_stringsdict_serializer.rb +12 -25
  49. data/lib/ad_localize/serializers/properties_serializer.rb +9 -11
  50. data/lib/ad_localize/serializers/strings_serializer.rb +12 -21
  51. data/lib/ad_localize/serializers/templated_serializer.rb +51 -0
  52. data/lib/ad_localize/serializers/yaml_serializer.rb +4 -6
  53. data/lib/ad_localize/templates/android/strings.xml.erb +6 -6
  54. data/lib/ad_localize/templates/ios/Localizable.stringsdict.erb +14 -14
  55. data/lib/ad_localize/version.rb +2 -1
  56. data/lib/ad_localize/view_models/compound_wording_view_model.rb +2 -0
  57. data/lib/ad_localize/view_models/simple_wording_view_model.rb +2 -0
  58. data/lib/ad_localize.rb +33 -35
  59. metadata +70 -47
  60. data/lib/ad_localize/constant.rb +0 -6
  61. data/lib/ad_localize/entities/translation.rb +0 -32
  62. data/lib/ad_localize/entities/wording.rb +0 -24
  63. data/lib/ad_localize/interactors/execute_export_request.rb +0 -45
  64. data/lib/ad_localize/interactors/export_csv_files.rb +0 -20
  65. data/lib/ad_localize/interactors/export_g_spreadsheet.rb +0 -64
  66. data/lib/ad_localize/interactors/platforms/export_android_locale_wording.rb +0 -44
  67. data/lib/ad_localize/interactors/platforms/export_csv_locale_wording.rb +0 -22
  68. data/lib/ad_localize/interactors/platforms/export_ios_locale_wording.rb +0 -75
  69. data/lib/ad_localize/interactors/platforms/export_json_locale_wording.rb +0 -27
  70. data/lib/ad_localize/interactors/platforms/export_platform_factory.rb +0 -50
  71. data/lib/ad_localize/interactors/platforms/export_properties_locale_wording.rb +0 -32
  72. data/lib/ad_localize/interactors/platforms/export_yaml_locale_wording.rb +0 -27
  73. data/lib/ad_localize/mappers/csv_path_to_wording.rb +0 -73
  74. data/lib/ad_localize/mappers/ios_translation_mapper.rb +0 -12
  75. data/lib/ad_localize/mappers/translation_group_mapper.rb +0 -14
  76. data/lib/ad_localize/mappers/translation_mapper.rb +0 -30
  77. data/lib/ad_localize/mappers/value_range_to_wording.rb +0 -67
  78. data/lib/ad_localize/repositories/g_sheets_repository.rb +0 -44
  79. data/lib/ad_localize/requests/export_wording_options.rb +0 -24
  80. data/lib/ad_localize/requests/g_spreadsheet_options.rb +0 -47
  81. data/lib/ad_localize/requests/merge_policy.rb +0 -28
  82. data/lib/ad_localize/serializers/with_template.rb +0 -19
  83. data/lib/ad_localize/validators/key_validator.rb +0 -31
  84. data/lib/ad_localize/view_models/translation_group_view_model.rb +0 -19
  85. data/lib/ad_localize/view_models/translation_view_model.rb +0 -23
@@ -1,75 +0,0 @@
1
- module AdLocalize
2
- module Interactors
3
- module Platforms
4
- class ExportIOSLocaleWording
5
- INFO_PLIST_FILENAME = "InfoPlist.strings".freeze
6
- LOCALIZABLE_STRINGS_FILENAME = "Localizable.strings".freeze
7
- LOCALIZABLE_STRINGSDICT_FILENAME = "Localizable.stringsdict".freeze
8
- LOCALE_DIRECTORY_CONVENTION = "%{locale}.lproj".freeze
9
-
10
- def initialize
11
- @info_plist_serializer = Serializers::InfoPlistSerializer.new
12
- @strings_serializer = Serializers::LocalizableStringsSerializer.new
13
- @stringsdict_serializer = Serializers::LocalizableStringsdictSerializer.new
14
- @file_system_repository = Repositories::FileSystemRepository.new
15
- end
16
-
17
- def call(export_wording_options:)
18
- bypass_empty_values = export_wording_options.bypass_empty_values
19
-
20
- export_wording_options.locales.each do |locale|
21
- LOGGER.debug("Starting export iOS wording for locale #{locale}")
22
- locale_wording = export_wording_options.wording.translations_for(locale: locale)
23
- next unless has_ios_wording?(locale_wording: locale_wording)
24
-
25
- locale_directory_name = LOCALE_DIRECTORY_CONVENTION % { locale: locale }
26
- output_dir = export_wording_options.platform_output_directory.join(locale_directory_name)
27
- @file_system_repository.create_directory(path: output_dir)
28
- export_files(locale_wording: locale_wording, output_dir: output_dir, bypass_empty_values: bypass_empty_values)
29
- end
30
- end
31
-
32
- private
33
-
34
- def export_files(locale_wording:, output_dir:, bypass_empty_values:)
35
- export_info_plist(locale_wording: locale_wording, output_dir: output_dir)
36
- export_localizable_strings(locale_wording: locale_wording, output_dir: output_dir, bypass_empty_values: bypass_empty_values)
37
- export_localizable_stringsdict(locale_wording: locale_wording, output_dir: output_dir, bypass_empty_values: bypass_empty_values)
38
- end
39
-
40
- def has_ios_wording?(locale_wording:)
41
- locale_wording.has_info_plist_keys? ||
42
- locale_wording.has_singular_keys? ||
43
- locale_wording.has_plural_keys? ||
44
- locale_wording.has_adaptive_keys?
45
- end
46
-
47
- def export_info_plist(locale_wording:, output_dir:)
48
- return unless locale_wording.has_info_plist_keys?
49
-
50
- content = @info_plist_serializer.render(locale_wording: locale_wording)
51
- @file_system_repository.write(content: content, path: output_dir.join(INFO_PLIST_FILENAME))
52
- LOGGER.debug("#{INFO_PLIST_FILENAME} done !")
53
- end
54
-
55
- def export_localizable_strings(locale_wording:, output_dir:, bypass_empty_values:)
56
- return unless locale_wording.has_singular_keys?
57
-
58
- @strings_serializer.bypass_empty_values = bypass_empty_values
59
- content = @strings_serializer.render(locale_wording: locale_wording)
60
- @file_system_repository.write(content: content, path: output_dir.join(LOCALIZABLE_STRINGS_FILENAME))
61
- LOGGER.debug("#{LOCALIZABLE_STRINGS_FILENAME} done !")
62
- end
63
-
64
- def export_localizable_stringsdict(locale_wording:, output_dir:, bypass_empty_values:)
65
- return unless locale_wording.has_plural_keys? || locale_wording.has_adaptive_keys?
66
-
67
- @stringsdict_serializer.bypass_empty_values = bypass_empty_values
68
- content = @stringsdict_serializer.render(locale_wording: locale_wording)
69
- @file_system_repository.write(content: content, path: output_dir.join(LOCALIZABLE_STRINGSDICT_FILENAME))
70
- LOGGER.debug("#{LOCALIZABLE_STRINGSDICT_FILENAME} done !")
71
- end
72
- end
73
- end
74
- end
75
- end
@@ -1,27 +0,0 @@
1
- module AdLocalize
2
- module Interactors
3
- module Platforms
4
- class ExportJSONLocaleWording
5
- def initialize
6
- @json_serializer = Serializers::JSONSerializer.new
7
- @file_system_repository = Repositories::FileSystemRepository.new
8
- end
9
-
10
- def call(export_wording_options:)
11
- output_dir = export_wording_options.platform_output_directory
12
-
13
- export_wording_options.locales.each do |locale|
14
- LOGGER.debug("Starting export JSON wording for locale #{locale}")
15
- locale_wording = export_wording_options.wording.translations_for(locale: locale)
16
- content = @json_serializer.render(locale_wording: locale_wording)
17
- next if content[locale].blank?
18
-
19
- @file_system_repository.create_directory(path: output_dir)
20
- @file_system_repository.write(content: content, path: output_dir.join("#{locale}.json"))
21
- LOGGER.debug("#{locale}.json done !")
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,50 +0,0 @@
1
- module AdLocalize
2
- module Interactors
3
- module Platforms
4
- class ExportPlatformFactory
5
- def build(platform:)
6
- case platform
7
- when 'json'
8
- json_builder
9
- when 'yml'
10
- yaml_builder
11
- when 'android'
12
- android_builder
13
- when 'ios'
14
- ios_builder
15
- when 'properties'
16
- properties_builder
17
- when 'csv'
18
- csv_builder
19
- else
20
- raise ArgumentError.new('Unknown platform for builder factory')
21
- end
22
- end
23
-
24
- def json_builder
25
- @json_builder ||= ExportJSONLocaleWording.new
26
- end
27
-
28
- def yaml_builder
29
- @yaml_builder ||= ExportYAMLLocaleWording.new
30
- end
31
-
32
- def android_builder
33
- @android_builder ||= ExportAndroidLocaleWording.new
34
- end
35
-
36
- def ios_builder
37
- @ios_builder ||= ExportIOSLocaleWording.new
38
- end
39
-
40
- def properties_builder
41
- @properties_builder ||= ExportPropertiesLocaleWording.new
42
- end
43
-
44
- def csv_builder
45
- @csv_builder ||= ExportCSVLocaleWording.new
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,32 +0,0 @@
1
- module AdLocalize
2
- module Interactors
3
- module Platforms
4
- class ExportPropertiesLocaleWording
5
- def initialize
6
- @properties_serializer = Serializers::PropertiesSerializer.new
7
- @file_system_repository = Repositories::FileSystemRepository.new
8
- end
9
-
10
- def call(export_wording_options:)
11
- export_wording_options.locales.each do |locale|
12
- LOGGER.debug("Starting export Properties wording for locale #{locale}")
13
- locale_wording = export_wording_options.wording.translations_for(locale: locale)
14
- return unless has_properties_wording?(locale_wording: locale_wording)
15
-
16
- content = @properties_serializer.render(locale_wording: locale_wording)
17
- @file_system_repository.create_directory(path: export_wording_options.platform_output_directory)
18
- output_path = export_wording_options.platform_output_directory.join("#{locale}.properties")
19
- @file_system_repository.write(content: content, path: output_path)
20
- LOGGER.debug("#{locale}.properties done !")
21
- end
22
- end
23
-
24
- private
25
-
26
- def has_properties_wording?(locale_wording:)
27
- locale_wording.has_singular_keys?
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,27 +0,0 @@
1
- module AdLocalize
2
- module Interactors
3
- module Platforms
4
- class ExportYAMLLocaleWording
5
- def initialize
6
- @yaml_serializer = Serializers::YAMLSerializer.new
7
- @file_system_repository = Repositories::FileSystemRepository.new
8
- end
9
-
10
- def call(export_wording_options:)
11
- output_dir = export_wording_options.platform_output_directory
12
-
13
- export_wording_options.locales.each do |locale|
14
- LOGGER.debug("Starting export YAML wording for locale #{locale}")
15
- locale_wording = export_wording_options.wording.translations_for(locale: locale)
16
- content = @yaml_serializer.render(locale_wording: locale_wording)
17
- next if content[locale].blank?
18
-
19
- @file_system_repository.create_directory(path: output_dir)
20
- @file_system_repository.write(content: content, path: output_dir.join("#{locale}.yml"))
21
- LOGGER.debug("#{locale}.yml done !")
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,73 +0,0 @@
1
- module AdLocalize
2
- module Mappers
3
- class CSVPathToWording
4
- def map(csv_path:)
5
- @headers = CSV.foreach(csv_path).first
6
- return unless valid?(csv_path: csv_path)
7
- translations = []
8
- validator = Validators::KeyValidator.new
9
-
10
- CSV.foreach(csv_path, headers: true, skip_blanks: true) do |row|
11
- row_translations = map_row(row: row, locales: locales)
12
- next if row_translations.blank?
13
-
14
- current_key = row_translations.first.key
15
- next if validator.has_warnings?(current_key)
16
-
17
- translations.concat(row_translations)
18
- end
19
-
20
- locale_wordings = translations.group_by(&:locale).map do |locale, group|
21
- Entities::LocaleWording.new(locale: locale, translations: group)
22
- end
23
- Entities::Wording.new(locale_wordings: locale_wordings, default_locale: locales.first)
24
- end
25
-
26
- private
27
-
28
- def valid?(csv_path:)
29
- File.exist?(csv_path) && has_key_column? && has_locales?
30
- end
31
-
32
- def locales
33
- @locales ||= compute_locales
34
- end
35
-
36
- def compute_locales
37
- return [] unless has_key_column? && key_column_index < @headers.size.pred
38
-
39
- @headers.slice(key_column_index.succ..-1).compact.reject do |header|
40
- header.to_s.include?(Constant::COMMENT_KEY_COLUMN_IDENTIFIER)
41
- end
42
- end
43
-
44
- def has_locales?
45
- locales.present?
46
- end
47
-
48
- def has_key_column?
49
- key_column_index.present?
50
- end
51
-
52
- def key_column_index
53
- @key_column_index ||= @headers.index(Constant::CSV_WORDING_KEYS_COLUMN)
54
- end
55
-
56
- def map_row(row:, locales:)
57
- csv_wording_key = row.field(Constant::CSV_WORDING_KEYS_COLUMN)
58
- return if csv_wording_key.blank?
59
-
60
- key = Entities::Key.new(label: csv_wording_key)
61
- locales.map do |locale|
62
- comment_column_name = "#{Constant::COMMENT_KEY_COLUMN_IDENTIFIER} #{locale}"
63
- Entities::Translation.new(
64
- locale: locale,
65
- key: key,
66
- value: row.field(locale),
67
- comment: row.field(comment_column_name)
68
- )
69
- end
70
- end
71
- end
72
- end
73
- end
@@ -1,12 +0,0 @@
1
- module AdLocalize
2
- module Mappers
3
- class IOSTranslationMapper < TranslationMapper
4
- private
5
-
6
- def sanitize_value(value:)
7
- return if value.blank?
8
- value.gsub(/(?<!\\)\"/, "\\\"")
9
- end
10
- end
11
- end
12
- end
@@ -1,14 +0,0 @@
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
@@ -1,30 +0,0 @@
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
@@ -1,67 +0,0 @@
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
- validator = Validators::KeyValidator.new
21
-
22
- values[1..-1].each do |row|
23
- row_translations = map_row(row: row)
24
- next if row_translations.blank?
25
-
26
- current_key = row_translations.first.key
27
- next if validator.has_warnings?(current_key)
28
-
29
- translations.concat(row_translations)
30
- end
31
- translations
32
- end
33
-
34
- def analyze_header(first_row:)
35
- @header = first_row
36
- @key_index = first_row.index(Constant::CSV_WORDING_KEYS_COLUMN)
37
- @locale_mapping = {}
38
- first_row[@key_index.succ..-1].each_index do |relative_index|
39
- absolute_index = @key_index.succ + relative_index
40
- next if first_row[absolute_index].blank? || first_row[absolute_index].include?(Constant::COMMENT_KEY_COLUMN_IDENTIFIER)
41
- @locale_mapping[first_row[absolute_index]] = { key_index: absolute_index }
42
- comment_column_name = "#{Constant::COMMENT_KEY_COLUMN_IDENTIFIER} #{first_row[absolute_index]}"
43
- @locale_mapping[first_row[absolute_index]][:comment_index] = first_row.index(comment_column_name)
44
- end
45
- end
46
-
47
- def map_row(row:)
48
- csv_wording_key = row[@key_index]
49
- return if csv_wording_key.blank?
50
- key = Entities::Key.new(label: csv_wording_key)
51
- @locale_mapping.map do |locale, index_mapping|
52
- comment = index_mapping[:comment_index].nil? ? nil : row[index_mapping[:comment_index]]
53
- Entities::Translation.new(
54
- locale: locale,
55
- key: key,
56
- value: row[index_mapping[:key_index]],
57
- comment: comment
58
- )
59
- end
60
- end
61
-
62
- def valid_header?
63
- @key_index.present? || @locale_mapping.keys.size.positive?
64
- end
65
- end
66
- end
67
- end
@@ -1,44 +0,0 @@
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.to_s)
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
@@ -1,24 +0,0 @@
1
- module AdLocalize
2
- module Requests
3
- class ExportWordingOptions
4
- def initialize(wording:, platform_output_directory:, locales: [], bypass_empty_values: false, csv_paths: [])
5
- @wording = wording
6
- @locales = locales
7
- @platform_output_directory = platform_output_directory
8
- @bypass_empty_values = bypass_empty_values
9
- @csv_paths = csv_paths
10
- end
11
-
12
- attr_reader(
13
- :wording,
14
- :platform_output_directory,
15
- :bypass_empty_values,
16
- :locales
17
- )
18
-
19
- attr_accessor(
20
- :csv_paths
21
- )
22
- end
23
- end
24
- end
@@ -1,47 +0,0 @@
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
@@ -1,28 +0,0 @@
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
@@ -1,19 +0,0 @@
1
- module AdLocalize
2
- module Serializers
3
- module WithTemplate
4
- TEMPLATES_DIRECTORY = __dir__ + "/../templates"
5
-
6
- def render(locale_wording:)
7
- hash_binding = hash_binding(locale_wording: locale_wording)
8
- return unless hash_binding
9
- render_template(template_path: template_path, hash_binding: hash_binding)
10
- end
11
-
12
- def render_template(template_path:, hash_binding:)
13
- template = File.read(template_path)
14
- renderer = ERB.new(template, trim_mode: '-')
15
- renderer.result_with_hash(hash_binding)
16
- end
17
- end
18
- end
19
- end
@@ -1,31 +0,0 @@
1
- module AdLocalize
2
- module Validators
3
- class KeyValidator
4
-
5
- def initialize
6
- @existing_key_for_label = {}
7
- end
8
-
9
- def has_warnings?(current_key)
10
- current_label = current_key.label
11
- existing_key = @existing_key_for_label[current_label]
12
-
13
- has_warnings = false
14
-
15
- unless existing_key.nil?
16
- existing_plural_key = existing_key.label == current_key.label && existing_key.plural? && current_key.singular?
17
- existing_singular_key = existing_key.label == current_key.label && existing_key.singular? && current_key.plural?
18
- is_same_key = existing_key.same_as?(key: current_key)
19
- LOGGER.warn "A plural value already exist for key '#{current_label}'. Remove duplicates." if existing_plural_key
20
- LOGGER.warn "A singular value already exist for key '#{current_label}'. Remove duplicates." if existing_singular_key
21
- LOGGER.warn "Some values already exist for key '#{current_label}'. Remove duplicates." if is_same_key
22
- has_warnings = is_same_key || existing_plural_key || existing_singular_key
23
- end
24
-
25
- @existing_key_for_label[current_label] = current_key
26
-
27
- has_warnings
28
- end
29
- end
30
- end
31
- end
@@ -1,19 +0,0 @@
1
- module AdLocalize
2
- module ViewModels
3
- class TranslationGroupViewModel
4
- attr_reader(
5
- :label,
6
- :translation_view_models
7
- )
8
-
9
- def initialize(label:, translation_view_models:)
10
- @label = label
11
- @translation_view_models = translation_view_models
12
- end
13
-
14
- def has_translations?
15
- (translation_view_models || []).any?(&:has_value?)
16
- end
17
- end
18
- end
19
- end
@@ -1,23 +0,0 @@
1
- module AdLocalize
2
- module ViewModels
3
- class TranslationViewModel
4
- attr_reader(
5
- :label,
6
- :key,
7
- :value,
8
- :comment
9
- )
10
-
11
- def initialize(label:, key:, value:, comment:)
12
- @label = label
13
- @key = key
14
- @value = value
15
- @comment = comment
16
- end
17
-
18
- def has_value?
19
- value.present?
20
- end
21
- end
22
- end
23
- end