ad_localize 5.0.0 → 6.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 (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