ad_localize 3.4.0 → 3.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4a46683de0e489838b53aae0ddd3a4e7e52a0089013fac5b49a07a558bfd322
4
- data.tar.gz: 11523ebff556f015ae9e0a7ec76bf50f75d9317b9fd272e2f0b28e84ae0a070d
3
+ metadata.gz: e814ce7a840c1c9da11fc1f34574929e7ad4805f410319b3c6f79e8f8027024e
4
+ data.tar.gz: 65864cb313e53121a7d9fc06028f944853f3842ee3eb060b7ccdff099b3477a2
5
5
  SHA512:
6
- metadata.gz: 7432f6a5dd72d4635b3c07215ffb2d7afe357a5f93aca0d04635c20c15494571d580af9572ce38b0805afb1762d714dc73ef71ae8f5bd855ebfdfb8dbe9eef0d
7
- data.tar.gz: 5e726801cb6f26bf2c58787297a1e0639cd403f7d9d22c3a8ce82d04fb65a8e3d8cd3b6a94cf1057f9d0b32ebcab9d79ba00867f50d3add3815cd450b945b097
6
+ metadata.gz: f84b9f8ef16b073e98c4e41a87575e35c5881586e1bebe44c226005bbdcf3b9704bc6b869ae4cb6fb4162866560a2e6c69e154b505b058f6923d852093ba1624
7
+ data.tar.gz: 02fe755026fad1ef4bca910a6457ef7d2806b40077fe3acbfc4d7b469372b7382bb7c98098c3220d6fc977cef40255e2c3cf85cc8f927cc1b3f78d9bf7ff31b7
@@ -1,6 +1,6 @@
1
1
  name: Ruby
2
2
 
3
- on: [push]
3
+ on: [push, pull_request]
4
4
 
5
5
  jobs:
6
6
  build:
data/.gitignore CHANGED
@@ -9,4 +9,5 @@ ad_localize/tmp/
9
9
  .idea
10
10
  .byebug_history
11
11
  .ruby-version
12
-
12
+ pkg/
13
+ exports/
@@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [3.5.0] - 2020-05-12
8
+ ### Added
9
+ - add support for private spreadsheet using google service acccount by [@sjcqs](https://github.com/sjcqs). Fixes [#31](https://github.com/applidium/ad_localize/issues/31)
10
+ - add makefile for easier testing by [@felginep](https://github.com/felginep)
11
+
12
+ ### Changed
13
+ - improve error message to have useful information in case of google spreadsheet use by [@felginep](https://github.com/felginep). Fixes [#27](https://github.com/applidium/ad_localize/issues/27)
14
+ - platform folder is no longer generated when there is only one platform selected. The files are directly generated in the output path. By [@felginep](https://github.com/felginep). Fixes [#29](https://github.com/applidium/ad_localize/issues/29)
15
+ - raise error when google spreadsheet key is invalid by [@felginep](https://github.com/felginep)
16
+
17
+ ### Fixed
18
+ - auto escape strings in Localizable.strings by [@felginep](https://github.com/felginep). Fixes [#26](https://github.com/applidium/ad_localize/issues/26)
19
+ - trim keys to prevent user error by [@felginep](https://github.com/felginep). Fixes [#16](https://github.com/applidium/ad_localize/issues/16)
20
+
7
21
  ## [3.4.0] - 2019-02-10
8
22
  ### Added
9
23
  - Rails folks, [@epaillous](https://github.com/epaillous) has improved the YAML support. You can now have multi-level wording.
@@ -0,0 +1,78 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ad_localize (3.4.0)
5
+ activesupport (>= 4.2.10)
6
+ colorize (~> 0.8)
7
+ googleauth (~> 0.12.0)
8
+ nokogiri (~> 1.8, >= 1.8.2)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ activesupport (6.0.2.2)
14
+ concurrent-ruby (~> 1.0, >= 1.0.2)
15
+ i18n (>= 0.7, < 2)
16
+ minitest (~> 5.1)
17
+ tzinfo (~> 1.1)
18
+ zeitwerk (~> 2.2)
19
+ addressable (2.7.0)
20
+ public_suffix (>= 2.0.2, < 5.0)
21
+ ansi (1.5.0)
22
+ builder (3.2.4)
23
+ byebug (11.1.3)
24
+ colorize (0.8.1)
25
+ concurrent-ruby (1.1.6)
26
+ diffy (3.3.0)
27
+ faraday (0.17.3)
28
+ multipart-post (>= 1.2, < 3)
29
+ googleauth (0.12.0)
30
+ faraday (>= 0.17.3, < 2.0)
31
+ jwt (>= 1.4, < 3.0)
32
+ memoist (~> 0.16)
33
+ multi_json (~> 1.11)
34
+ os (>= 0.9, < 2.0)
35
+ signet (~> 0.14)
36
+ i18n (1.8.2)
37
+ concurrent-ruby (~> 1.0)
38
+ jwt (2.1.0)
39
+ memoist (0.16.2)
40
+ mini_portile2 (2.4.0)
41
+ minitest (5.14.0)
42
+ minitest-reporters (1.4.2)
43
+ ansi
44
+ builder
45
+ minitest (>= 5.0)
46
+ ruby-progressbar
47
+ multi_json (1.14.1)
48
+ multipart-post (2.0.0)
49
+ nokogiri (1.10.9)
50
+ mini_portile2 (~> 2.4.0)
51
+ os (1.1.0)
52
+ public_suffix (2.0.5)
53
+ rake (12.3.3)
54
+ ruby-progressbar (1.10.1)
55
+ signet (0.14.0)
56
+ addressable (~> 2.3)
57
+ faraday (>= 0.17.3, < 2.0)
58
+ jwt (>= 1.5, < 3.0)
59
+ multi_json (~> 1.10)
60
+ thread_safe (0.3.6)
61
+ tzinfo (1.2.7)
62
+ thread_safe (~> 0.1)
63
+ zeitwerk (2.3.0)
64
+
65
+ PLATFORMS
66
+ ruby
67
+
68
+ DEPENDENCIES
69
+ ad_localize!
70
+ bundler (>= 1.12.0, < 3.0.0)
71
+ byebug (~> 11.0)
72
+ diffy (~> 3.3)
73
+ minitest (~> 5.11)
74
+ minitest-reporters (~> 1.3)
75
+ rake (~> 12.3)
76
+
77
+ BUNDLED WITH
78
+ 2.1.4
@@ -0,0 +1,11 @@
1
+ build:
2
+ gem build ad_localize.gemspec
3
+
4
+ install: clean build
5
+ gem install ad_localize-*.gem
6
+
7
+ clean:
8
+ rm -f ad_localize-*.gem
9
+
10
+ tests:
11
+ bundle exec rake test
data/README.md CHANGED
@@ -29,15 +29,22 @@ $ gem install ad_localize
29
29
  $ bundle exec ad_localize -h
30
30
  ```
31
31
 
32
- * Export wording from a google drive spreadsheet, using the file key
32
+ * Export wording from a google spreadsheet, using the file key. Make sure to enable _Allow external access_ in sharing options.
33
33
  ```
34
34
  $ bundle exec ad_localize -k <your-spreadsheet-drive-key>
35
35
  ```
36
- * Export wording from a google drive spreadsheet, using the file key and specifying a sheet (useful when your file has multiple sheets)
36
+
37
+ * Export wording from a google spreadsheet, using the file key and specifying a sheet (useful when your file has multiple sheets)
37
38
  ```
38
39
  $ bundle exec ad_localize -k <your-spreadsheet-drive-key> -s <your-specific-sheet-id>
39
40
  ```
40
41
 
42
+ * Export wording from a private google spreadsheet using an authorized google account
43
+ ```
44
+ $ export GCLOUD_CLIENT_SECRET=$(cat <client-secret.json>)
45
+ $ bundle exec ad_localize -k <your-spreadsheet-drive-key> -a
46
+ ```
47
+
41
48
  * Only generate wording files for the specified platforms
42
49
  ```
43
50
  $ bundle exec ad_localize -o ios
@@ -62,10 +69,11 @@ $ bundle exec ad_localize -d
62
69
  | favorites | Mes favoris | My favorites |
63
70
  | from_to | du %1$@ au %2$@ | from %1$@ to %2$@ |
64
71
 
65
- - Any column after the `key` column will be considered as a locale column (except from the optional `comment columns)
72
+ - Any column after the `key` column will be considered as a locale column (except from the optional `comment columns)
66
73
  - Keys should be written in Android format : [a-z0-9_]+
67
74
  - Format specifiers must be numeroted if there are more than one in a translation string (eg: "%1$@ %2$@'s report").
68
75
 
76
+
69
77
  #### Comment columns
70
78
 
71
79
  In iOS (and only iOS) you can add a comment to a missing translation.
@@ -111,6 +119,8 @@ exports/
111
119
  └── fr.yml
112
120
  ```
113
121
 
122
+ NB: If you select only one platform, the wording files will directly be generated in the output path. The output path is the `exports` folder in the current directory by default and you can change it using the option `-o`.
123
+
114
124
  ## Plurals
115
125
 
116
126
  Plurals are supported for iOS and Android.
@@ -19,14 +19,16 @@ Gem::Specification.new do |spec|
19
19
  'Nicolas Braun',
20
20
  'Corentin Huard',
21
21
  'Claire Peyron',
22
- 'Claire Dufetrelle'
22
+ 'Claire Dufetrelle',
23
+ 'Pierre Felgines',
24
+ 'Satyan Jacquens'
23
25
  ]
24
26
  spec.email = %w(joanna.vigne@fabernovel.com hugo.hache@fabernovel.com edouard.siegel@fabernovel.com)
25
27
 
26
28
  spec.summary = %q{AdLocalize helps with mobile and web applications wording}
27
29
  spec.description = %q{AdLocalize produces localization files from platform agnostic wording.
28
30
  Supported wording format : CSV. Supported export format: iOS, Android, JSON and YAML}
29
- spec.homepage = 'https://technologies.fabernovel.com'
31
+ spec.homepage = 'https://github.com/applidium/ad_localize'
30
32
 
31
33
  # Specify which files should be added to the gem when it is released.
32
34
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -44,9 +46,10 @@ Gem::Specification.new do |spec|
44
46
  spec.add_development_dependency 'minitest-reporters', '~> 1.3'
45
47
  spec.add_development_dependency 'diffy', '~> 3.3'
46
48
 
47
- spec.add_dependency 'activesupport', '>= 4.2.10'
48
- spec.add_dependency 'nokogiri', '~> 1.8', '>= 1.8.2'
49
+ spec.add_dependency 'activesupport', '~> 5.2'
50
+ spec.add_dependency 'nokogiri', '~> 1.10'
49
51
  spec.add_dependency 'colorize', '~> 0.8'
52
+ spec.add_dependency 'googleauth', '~> 0.12'
50
53
 
51
54
  spec.required_ruby_version = '~> 2.3'
52
55
  end
@@ -8,6 +8,8 @@ require 'csv'
8
8
  require 'logger'
9
9
  require 'colorize'
10
10
  require 'open-uri'
11
+ require 'stringio'
12
+ require 'googleauth'
11
13
  require 'optparse'
12
14
  require 'nokogiri'
13
15
 
@@ -8,13 +8,20 @@ module AdLocalize
8
8
  end
9
9
 
10
10
  # Returns the downloaded file name (it is located in the current directory)
11
- def download_from_drive(key, sheet)
11
+ def download_from_drive(key, sheet, use_service_account=false)
12
12
  LOGGER.log(:info, :green, "Downloading file from google drive...")
13
13
  download_string_path = "./#{key}.csv"
14
14
  begin
15
15
  File.open(download_string_path, "wb") do |saved_file|
16
+ download_url = drive_download_url(key, sheet)
17
+ headers = {}
18
+ if use_service_account
19
+ LOGGER.log(:debug, :green, "Using a service account...")
20
+ token = service_account_access_token()
21
+ headers["Authorization"] = "#{token["token_type"]} #{token["access_token"]}"
22
+ end
16
23
  # the following "open" is provided by open-uri
17
- open(drive_download_url(key, sheet), "rb") do |read_file|
24
+ open(download_url, "rb", headers) do |read_file|
18
25
  saved_file.write(read_file.read)
19
26
  end
20
27
  File.basename saved_file
@@ -42,6 +49,16 @@ module AdLocalize
42
49
  query_id = sheet ? "gid=#{sheet}" : "id=#{key}"
43
50
  "https://docs.google.com/spreadsheets/d/#{key}/export?format=csv&#{query_id}"
44
51
  end
52
+ private
53
+ def service_account_access_token()
54
+ scope = "https://www.googleapis.com/auth/drive.readonly"
55
+ json_key_io = StringIO.new ENV["GCLOUD_CLIENT_SECRET"]
56
+ authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
57
+ json_key_io: json_key_io,
58
+ scope: scope
59
+ )
60
+ authorizer.fetch_access_token!
61
+ end
45
62
  end
46
63
  end
47
64
  end
@@ -99,7 +99,7 @@ module AdLocalize
99
99
  end
100
100
 
101
101
  def parse_key(row)
102
- key = row.field(CSV_WORDING_KEYS_COLUMN)
102
+ key = row.field(CSV_WORDING_KEYS_COLUMN).strip
103
103
  plural_prefix = key.match(PLURAL_KEY_REGEXP)
104
104
  plural_identifier = nil
105
105
  invalid_plural = false
@@ -20,11 +20,15 @@ module AdLocalize
20
20
  end
21
21
  opts.on("-k", "--drive-key #{GOOGLE_DRIVE_DOCUMENT_ID.dig(:length)}_characters", String, "Use google drive spreadsheets") do |key|
22
22
  is_valid_drive_key = !!(key =~ GOOGLE_DRIVE_DOCUMENT_ID.dig(:regexp)) && (key.size >= GOOGLE_DRIVE_DOCUMENT_ID.dig(:length))
23
- args[:drive_key] = is_valid_drive_key ? key : nil
23
+ raise ArgumentError.new("Invalid google drive spreadsheet key \"#{key}\"") unless is_valid_drive_key
24
+ args[:drive_key] = key
24
25
  end
25
26
  opts.on("-s", "--drive-sheet SHEET_ID", String, "Use a specific sheet id for Google Drive spreadsheets with several sheets") do |value|
26
27
  args[:sheet_id] = value
27
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
28
32
  opts.on("-o", "--only platform1,platform2", Array, "Only generate localisation files for the specified platforms. Supported platforms : #{Constant::SUPPORTED_PLATFORMS.join(', ')}") do |platforms|
29
33
  args[:only] = filter_option_args("-o", platforms) { |platform| !!Constant::SUPPORTED_PLATFORMS.index(platform) }
30
34
  end
@@ -44,6 +48,7 @@ module AdLocalize
44
48
  LOGGER.log(:error, :red, "Missing argument for option #{e.args.join(',')}")
45
49
  rescue ArgumentError => e
46
50
  LOGGER.log(:error, :red, e.message)
51
+ raise e
47
52
  end
48
53
  args
49
54
  end
@@ -90,11 +90,16 @@ module AdLocalize::Platform
90
90
 
91
91
  private
92
92
 
93
+ def escape_quotes_if_needed(value)
94
+ value.gsub(/(?<!\\)\"/, "\\\"") # match " unless there is a \ before
95
+ end
96
+
93
97
  def write_localizable(locale:, singulars:, wording_type:, filename:)
94
98
  locale = locale.to_sym
95
99
 
96
100
  singulars.each do |key, locales_wording|
97
101
  value = locales_wording.dig(locale, wording_type)
102
+ value = escape_quotes_if_needed(value)
98
103
  comment = locales_wording.dig(locale, AdLocalize::Constant::COMMENT_KEY_SYMBOL)
99
104
  export_dir(locale).join(filename).open("a") do |file|
100
105
  line = ""
@@ -5,12 +5,13 @@ module AdLocalize::Platform
5
5
  OPTIONS = {output_path: ".."}
6
6
 
7
7
  attr_accessor :platform_dir
8
- attr_reader :default_locale, :output_path
8
+ attr_reader :default_locale, :output_path, :add_intermediate_platform_dir
9
9
 
10
- def initialize(default_locale, output_path)
10
+ def initialize(default_locale, output_path, add_intermediate_platform_dir)
11
11
  @default_locale = default_locale.to_sym
12
12
  @output_path = output_path # Must be set before platform_dir
13
- @platform_dir = export_base_directory.join(platform.to_s)
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
14
15
  create_platform_dir
15
16
  end
16
17
 
@@ -52,7 +53,7 @@ module AdLocalize::Platform
52
53
  end
53
54
 
54
55
  def create_platform_dir
55
- if platform_dir.directory?
56
+ if platform_dir.directory? && add_intermediate_platform_dir
56
57
  FileUtils.rm_rf("#{platform_dir}/.", secure: true)
57
58
  else
58
59
  platform_dir.mkpath
@@ -15,10 +15,14 @@ module AdLocalize
15
15
  file_to_parse = args.first
16
16
  LOGGER.log(:warn, :yellow, "Only one CSV can be treated - the priority goes to #{file_to_parse}") if input_files.length > 1
17
17
  if args.empty?
18
- options[:drive_file] = CsvFileManager.download_from_drive(options.dig(:drive_key), options.dig(:sheet_id))
18
+ options[:drive_file] = CsvFileManager.download_from_drive(options.dig(:drive_key), options.dig(:sheet_id), options.dig(:use_service_account))
19
19
  file_to_parse = options.dig(:drive_file)
20
20
  end
21
- CsvFileManager.csv?(file_to_parse) ? export(file_to_parse) : LOGGER.log(:error, :red, "#{file_to_parse} is not a csv")
21
+ if CsvFileManager.csv?(file_to_parse)
22
+ export(file_to_parse)
23
+ else
24
+ LOGGER.log(:error, :red, "#{file_to_parse} is not a csv. Make sure to enable \"Allow external access\" in sharing options.")
25
+ end
22
26
  CsvFileManager.delete_drive_file(options[:drive_file]) if options[:drive_file]
23
27
  end
24
28
  end
@@ -34,8 +38,13 @@ module AdLocalize
34
38
  LOGGER.log(:error, :red, "No data were found in the file - check if there is a key column in the file")
35
39
  else
36
40
  export_platforms = options.dig(:only) || Constant::SUPPORTED_PLATFORMS
41
+ add_intermediate_platform_dir = export_platforms.length > 1
37
42
  export_platforms.each do |platform|
38
- platform_formatter = "AdLocalize::Platform::#{platform.to_s.camelize}Formatter".constantize.new(parser.locales.first, options.dig(:output_path))
43
+ platform_formatter = "AdLocalize::Platform::#{platform.to_s.camelize}Formatter".constantize.new(
44
+ parser.locales.first,
45
+ options.dig(:output_path),
46
+ add_intermediate_platform_dir
47
+ )
39
48
  parser.locales.each do |locale|
40
49
  platform_formatter.export(locale, data)
41
50
  end
@@ -1,3 +1,3 @@
1
1
  module AdLocalize
2
- VERSION = "3.4.0"
2
+ VERSION = "3.5.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ad_localize
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edouard Siegel
@@ -15,6 +15,8 @@ authors:
15
15
  - Corentin Huard
16
16
  - Claire Peyron
17
17
  - Claire Dufetrelle
18
+ - Pierre Felgines
19
+ - Satyan Jacquens
18
20
  autorequire:
19
21
  bindir: exe
20
22
  cert_chain: []
@@ -114,36 +116,30 @@ dependencies:
114
116
  name: activesupport
115
117
  requirement: !ruby/object:Gem::Requirement
116
118
  requirements:
117
- - - ">="
119
+ - - "~>"
118
120
  - !ruby/object:Gem::Version
119
- version: 4.2.10
121
+ version: '5.2'
120
122
  type: :runtime
121
123
  prerelease: false
122
124
  version_requirements: !ruby/object:Gem::Requirement
123
125
  requirements:
124
- - - ">="
126
+ - - "~>"
125
127
  - !ruby/object:Gem::Version
126
- version: 4.2.10
128
+ version: '5.2'
127
129
  - !ruby/object:Gem::Dependency
128
130
  name: nokogiri
129
131
  requirement: !ruby/object:Gem::Requirement
130
132
  requirements:
131
133
  - - "~>"
132
134
  - !ruby/object:Gem::Version
133
- version: '1.8'
134
- - - ">="
135
- - !ruby/object:Gem::Version
136
- version: 1.8.2
135
+ version: '1.10'
137
136
  type: :runtime
138
137
  prerelease: false
139
138
  version_requirements: !ruby/object:Gem::Requirement
140
139
  requirements:
141
140
  - - "~>"
142
141
  - !ruby/object:Gem::Version
143
- version: '1.8'
144
- - - ">="
145
- - !ruby/object:Gem::Version
146
- version: 1.8.2
142
+ version: '1.10'
147
143
  - !ruby/object:Gem::Dependency
148
144
  name: colorize
149
145
  requirement: !ruby/object:Gem::Requirement
@@ -158,6 +154,20 @@ dependencies:
158
154
  - - "~>"
159
155
  - !ruby/object:Gem::Version
160
156
  version: '0.8'
157
+ - !ruby/object:Gem::Dependency
158
+ name: googleauth
159
+ requirement: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - "~>"
162
+ - !ruby/object:Gem::Version
163
+ version: '0.12'
164
+ type: :runtime
165
+ prerelease: false
166
+ version_requirements: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - "~>"
169
+ - !ruby/object:Gem::Version
170
+ version: '0.12'
161
171
  description: |-
162
172
  AdLocalize produces localization files from platform agnostic wording.
163
173
  Supported wording format : CSV. Supported export format: iOS, Android, JSON and YAML
@@ -176,7 +186,9 @@ files:
176
186
  - CHANGELOG.md
177
187
  - CODE_OF_CONDUCT.md
178
188
  - Gemfile
189
+ - Gemfile.lock
179
190
  - LICENSE.txt
191
+ - Makefile
180
192
  - README.md
181
193
  - Rakefile
182
194
  - ad_localize.gemspec
@@ -197,7 +209,7 @@ files:
197
209
  - lib/ad_localize/platform/yml_formatter.rb
198
210
  - lib/ad_localize/runner.rb
199
211
  - lib/ad_localize/version.rb
200
- homepage: https://technologies.fabernovel.com
212
+ homepage: https://github.com/applidium/ad_localize
201
213
  licenses:
202
214
  - MIT
203
215
  metadata: {}