phrase 0.4.26 → 0.4.27
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +244 -33
- data/lib/phrase/api/client.rb +27 -14
- data/lib/phrase/delegate.rb +5 -0
- data/lib/phrase/formats.rb +15 -1
- data/lib/phrase/formats/play_properties.rb +15 -0
- data/lib/phrase/formats/strings.rb +7 -1
- data/lib/phrase/tool/commands/push.rb +4 -4
- data/lib/phrase/tool/options_factory.rb +4 -0
- data/lib/phrase/version.rb +1 -1
- metadata +27 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 408d79ee86432e8210bcd9fea21891c7821a83d4
|
4
|
+
data.tar.gz: 17071c67ceecb2a81e4e461ef8426422ce440d85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4d92d0ea124d3d0533688b126eb87c412f32ebbcad39e669fb128c6c2eefff0afab7b21fde5827514ccd01ba114d98fadbbe13c70fd4e1a8849cbed75af9f55
|
7
|
+
data.tar.gz: 673beddfc7c78a58c11d36b305c301723bc33e6b475b74e73ef875e60147d1c307d68d75b2441fcdbcfeba9b8b40f3ebd7c5268bc869983a87b6565920e4790f
|
data/README.md
CHANGED
@@ -2,70 +2,281 @@
|
|
2
2
|
[![Code Climate](https://codeclimate.com/github/phrase/phrase.png)](https://codeclimate.com/github/phrase/phrase)
|
3
3
|
[![Build Status](https://secure.travis-ci.org/phrase/phrase.png)](http://travis-ci.org/phrase/phrase)
|
4
4
|
|
5
|
-
|
5
|
+
PhraseApp lets you set up a professional translation process to boost the quality of your translations with the powerful In-Context Editor.
|
6
6
|
|
7
|
-
|
7
|
+
You can order professional translations from within PhraseApp, or just work with your own team. Our platform support various programming languages and frameworks. Such as [Ruby on Rails, Symfony, Zend Framework, iOS, Android and many more](https://phraseapp.com/docs/general/supported-platforms).
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
This client let's you setup PhraseApp with your codebase and enables you to access your locale files through the PhraseApp [API](https://phraseapp.com/docs/api/overview).
|
9
|
+
This client lets you integrate PhraseApp into your project and access your locale files through the PhraseApp [API](https://phraseapp.com/docs/api/overview).
|
12
10
|
|
13
11
|
[Get your free PhraseApp trial](https://phraseapp.com/signup) and start right away.
|
14
12
|
|
15
|
-
|
16
|
-
### References ###
|
17
|
-
* [PhraseApp In-Context Editor](http://demo.phraseapp.com)
|
18
|
-
* [PhraseApp API](https://phraseapp.com/docs/api/overview)
|
19
|
-
|
20
|
-
### Partner-Integrations ###
|
21
|
-
* [PhraseApp and Ruby Motion](https://github.com/phrase/motion-phrase)
|
22
|
-
* [Heroku Add-on](https://addons.heroku.com/phrase)
|
23
|
-
* [Cloudcontrol Add-on](https://phraseapp.com/docs/cloudcontrol/introduction)
|
24
|
-
|
25
|
-
### Testimonials ###
|
26
|
-
PhraseApp helps a lot of software companies. See what [our customers](http://phraseapp.com/testimonials) say.
|
27
|
-
|
28
13
|
### Supported Formats ###
|
29
|
-
You can manage your locale files with PhraseApp if
|
14
|
+
You can manage your locale files with PhraseApp if you use one of the following formats:
|
30
15
|
|
31
16
|
* Ruby/Rails YAML
|
32
17
|
* Gettext
|
18
|
+
* Gettext Template
|
33
19
|
* Android Strings
|
34
20
|
* iOS Localizable Strings
|
35
21
|
* XLIFF
|
36
22
|
* Qt Phrase Book
|
37
23
|
* Qt Translation Source
|
38
|
-
*
|
24
|
+
* Chrome JSON i18n
|
39
25
|
* Simple JSON
|
40
26
|
* Nested JSON
|
27
|
+
* i18n-node-2 JSON
|
41
28
|
* .NET ResX
|
42
29
|
* Windows Phone ResX
|
30
|
+
* Windows 8 Resource
|
43
31
|
* INI
|
44
32
|
* Java Properties .properties
|
45
33
|
* Java Properties XML
|
46
34
|
* Objective-C/Cocoa Property List
|
47
35
|
* Symfony YAML
|
36
|
+
* Symfony2 YAML (Beta)
|
48
37
|
* TMX Translation Memory eXchange
|
38
|
+
* Excel XLSX (Beta)
|
49
39
|
* CSV
|
50
40
|
* PHP Array
|
51
|
-
*
|
41
|
+
* Zendesk CSV
|
42
|
+
* Laravel PHP
|
43
|
+
* Angular Translate
|
52
44
|
* Mozilla Properties
|
45
|
+
* Play Properties
|
46
|
+
|
47
|
+
## Usage
|
48
|
+
|
49
|
+
This command line client is a Ruby gem. If you haven't installed Ruby on your system yet, we have put together a [handy tutorial](https://phraseapp.com/docs/installation/ruby-installation) for you.
|
50
|
+
|
51
|
+
You don't have to use this client but can also use the [API directly](https://phraseapp.com/docs/api/overview).
|
52
|
+
|
53
|
+
### Installation
|
54
|
+
|
55
|
+
Install the gem via `gem install`
|
56
|
+
|
57
|
+
gem install phrase
|
58
|
+
|
59
|
+
or add it to your `Gemfile` when using bundler:
|
60
|
+
|
61
|
+
gem 'phrase'
|
62
|
+
|
63
|
+
and install it
|
64
|
+
|
65
|
+
$ bundle install
|
66
|
+
|
67
|
+
That's it!
|
68
|
+
|
69
|
+
### Initialization
|
70
|
+
|
71
|
+
Before you can use the phrase command line client you have to set up some configuration data. When using Rails we recommend using the Rails generator we provide. For all other environments you can use a simple command to initialize the setup.
|
72
|
+
|
73
|
+
To initialize phrase, your project auth token (secret) is required. You can find the auth token next to the project on [your project overview](https://phraseapp.com/projects).
|
74
|
+
|
75
|
+
#### When using Rails
|
76
|
+
|
77
|
+
Install phrase by executing the Rails generator:
|
78
|
+
|
79
|
+
bundle exec rails generate phrase:install --auth-token=<YOUR_TOKEN>
|
80
|
+
|
81
|
+
This will:
|
82
|
+
|
83
|
+
* create a `phrase.rb` initializer file in `./config/initializers/`
|
84
|
+
* initialize your phrase project by creating a default locale in PhraseApp
|
85
|
+
* create a `.phrase` configuration file containing the secret
|
86
|
+
|
87
|
+
*Using the generator will automatically prepare your Rails application for use with the [In-Context-Editor](https://phraseapp.com/features).*
|
88
|
+
|
89
|
+
#### Without Rails
|
90
|
+
|
91
|
+
You can use the `phrase init` command to initialize your project:
|
92
|
+
|
93
|
+
phrase init --secret=<YOUR_TOKEN>
|
94
|
+
|
95
|
+
This will:
|
96
|
+
|
97
|
+
* initialize your phrase project by creating a default locale in PhraseApp
|
98
|
+
* create a `.phrase` configuration file containing the secret
|
99
|
+
|
100
|
+
### Pushing Locale Files
|
101
|
+
|
102
|
+
Push your localization files to PhraseApp by using the push command:
|
103
|
+
|
104
|
+
phrase push FILE|DIRECTORY
|
105
|
+
|
106
|
+
This will push all files found in the given directory or push only the file if the given path points to a file. The path falls back to `./config/locales`, the default localization file path in Ruby on Rails applications.
|
107
|
+
|
108
|
+
* `--recursive, -R`
|
109
|
+
|
110
|
+
To push all files in a given directory recursively you can use the `--recursive` parameter:
|
111
|
+
|
112
|
+
phrase push </path/to/file.extension> --recursive
|
113
|
+
|
114
|
+
* `--tags`
|
115
|
+
|
116
|
+
Attach one or multiple tags with your file upload. All keys added by the push will be tagged with the specified tags:
|
117
|
+
|
118
|
+
phrase push --tags=foo,bar
|
119
|
+
|
120
|
+
* `--locale`
|
121
|
+
|
122
|
+
Some formats do not contain information about their content's locale. These formats (e.g. Java Properties) require you to specify the locale (name) with the push command:
|
123
|
+
|
124
|
+
phrase push messages.properties --locale=en
|
53
125
|
|
54
|
-
|
126
|
+
* `--format`
|
55
127
|
|
56
|
-
|
128
|
+
Specify the format of the files you want to push. We usually try to guess it by evaluating the file name but sometimes you need to tell us more:
|
129
|
+
|
130
|
+
phrase push messages.json --format=simple_json
|
131
|
+
|
132
|
+
For a full list of all supported formats check our [format guide](https://phraseapp.com/docs/format-guide/overview).
|
133
|
+
|
134
|
+
* `--force-update-translations`
|
57
135
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
* Zend Framework
|
64
|
-
* If your application has translations managed via key-value data in YAML .yml- or .properties-files,
|
65
|
-
uses the i18n#t method or equivalent, has a development or staging system on which translations can be edited
|
66
|
-
We will show you how to build a custom client for our API to push and pull translations from our webservice. Even if you are using a different format for the locale files, e.g. property files, your system can probably be managed with phrase.
|
136
|
+
When pushing files to PhraseApp, we only add new resources (keys and translations) by default. Use this flag if you want to override existing translations as well.
|
137
|
+
|
138
|
+
phrase push most-recent.yml --force-update-translations
|
139
|
+
|
140
|
+
Please note that we do not delete resources from your project even when using this option. Still you have to make sure that your file contains the most recent translations since all translations in your project will be updated with the file content!
|
67
141
|
|
68
|
-
|
142
|
+
* `--skip-unverification`
|
143
|
+
|
144
|
+
When using the `--force-update-translations` flag (see above) we will automatically unverify updated translations if configured in your workflow. Use this flag to prevent all translations being unverified. This option is great if you have copy&replaced strings in your file and just want to update all translations:
|
145
|
+
|
146
|
+
phrase push most-recent.yml --force-update-translations --skip-unverification
|
147
|
+
|
148
|
+
* `--skip-upload-tags`
|
149
|
+
|
150
|
+
When you push translations we will automatically attach new keys to an upload tag. To prevent this from happening, you can use this option:
|
151
|
+
|
152
|
+
phrase push my-file.yml --skip-upload-tags
|
153
|
+
|
154
|
+
This can be very useful if you replace your content very often and do not want to create hundreds of upload-tags.
|
155
|
+
|
156
|
+
* `--convert-emoji`
|
157
|
+
|
158
|
+
When you use Emoji symbols in your locale files (i.e. in iOS Localizable strings files) you can tell us to convert them to more readable symbols:
|
159
|
+
|
160
|
+
phrase push Localizable.strings --convert-emoji
|
161
|
+
|
162
|
+
Please note that you should only use this option if your file definitely contains Emoji symbols since it slows down the upload time quite a bit.
|
163
|
+
|
164
|
+
* `--secret`
|
165
|
+
|
166
|
+
Your project auth token. You can find the auth token in your project overview or project settings form. This will fall back to the token stored in your `.phrase` config file.
|
167
|
+
|
168
|
+
### Pulling Locale files
|
169
|
+
|
170
|
+
Pull your most recent locale files by using the `pull` command:
|
171
|
+
|
172
|
+
phrase pull
|
173
|
+
|
174
|
+
This will pull localization files for all of your locales available in the current project. Files are by default stored at `./phrase/locales` in YAML format.
|
175
|
+
|
176
|
+
* `--format`
|
177
|
+
|
178
|
+
Specify the format you want to download your files in:
|
179
|
+
|
180
|
+
phrase pull en --format=simple_json
|
181
|
+
|
182
|
+
For a full list of all supported formats check our [format guide](https://phraseapp.com/docs/format-guide/overview).
|
183
|
+
|
184
|
+
* `--target`
|
185
|
+
|
186
|
+
Specify where you want to download the files to:
|
187
|
+
|
188
|
+
phrase pull fr --target="./config/locales"
|
189
|
+
|
190
|
+
By default, files will be downloaded to `./phrase/locales`.
|
191
|
+
|
192
|
+
* `--tag`
|
193
|
+
|
194
|
+
Limit results to a given tag instead of downloading all translations:
|
195
|
+
|
196
|
+
phrase pull de --tag=feature-messenger-v2
|
197
|
+
|
198
|
+
* `--updated-since`
|
199
|
+
|
200
|
+
Limit results to translations being updated after the given date and time (UTC) in the format `YYYYMMDDHHMMSS`:
|
201
|
+
|
202
|
+
phrase pull en --updated-since=20140601123000
|
203
|
+
|
204
|
+
* `--include-empty-translations`
|
205
|
+
|
206
|
+
By default we will only return translated keys in the file. Use this flag to include empty translations as well:
|
207
|
+
|
208
|
+
phrase pull en --include-empty-translations
|
209
|
+
|
210
|
+
* `--convert-emoji`
|
211
|
+
|
212
|
+
When you use Emoji symbols in your translations you can tell us to convert them back to correctly encoded symbols:
|
213
|
+
|
214
|
+
phrase pull --convert-emoji
|
215
|
+
|
216
|
+
Please note that you should only use this option if your translations definitely contains Emojis since it slows down the download time a bit.
|
217
|
+
|
218
|
+
* `--secret`
|
219
|
+
|
220
|
+
Your project auth token. You can find the auth token in your project overview or project settings form. This will fall back to the token stored in your `.phrase` config file.
|
221
|
+
|
222
|
+
### Advanced configuration
|
223
|
+
|
224
|
+
The `phrase init` command allows several advanced configuration options to further customize the setup:
|
225
|
+
|
226
|
+
* `--default-locale`
|
227
|
+
|
228
|
+
You can specify a locale that should be used as the default locale when setting up your PhraseApp project (default is `en`).
|
229
|
+
|
230
|
+
phrase init --secret=<YOUR_TOKEN> --default-locale=fr
|
231
|
+
|
232
|
+
* `--default-format`
|
233
|
+
|
234
|
+
Specify a format that should be used as the default format when downloading files (default is `yml`). For a full list of all supported formats check our [format guide](https://phraseapp.com/docs/format-guide/overview).
|
235
|
+
|
236
|
+
* `--domain`
|
237
|
+
|
238
|
+
Set a domain for use with Gettext translation files (default is `phrase`).
|
239
|
+
|
240
|
+
* `--locale-directory`
|
241
|
+
|
242
|
+
Set the directory that contains your source locales (used by the `phrase push` command). Allows [placeholders](#allowed-placeholders-for-advanced-configuration).
|
243
|
+
|
244
|
+
* `--locale-filename`
|
245
|
+
|
246
|
+
Set the filename for files you download from PhraseApp via `phrase pull`. Allows [placeholders](#allowed-placeholders-for-advanced-configuration).
|
247
|
+
|
248
|
+
* `--default-target`
|
249
|
+
|
250
|
+
Set the target directly to store your localization files retrieved by `phrase pull`. Allows [placeholders](#allowed-placeholders-for-advanced-configuration).
|
251
|
+
|
252
|
+
These options will be stored in your `.phrase` config file where you can edit them later on as well.
|
253
|
+
|
254
|
+
### Allowed placeholders for advanced configuration
|
255
|
+
|
256
|
+
Some advanced configuration options support placeholders. These will be replaced with the actual content. This allows you to create more flexible path and filename settings.
|
257
|
+
|
258
|
+
| Placeholder | Description | Default |
|
259
|
+
| --------------- | ---------------------- | ------- |
|
260
|
+
| \<domain\> | Name of the domain | phrase |
|
261
|
+
| \<format\> | Format name/identifier | yml |
|
262
|
+
| \<locale\> | Locale name | en |
|
263
|
+
| \<locale.name\> | Locale name | en |
|
264
|
+
| \<locale.code\> | Locale code | - |
|
265
|
+
|
266
|
+
For example you can specify a different file name for files you retrieve via the `phrase pull` command:
|
267
|
+
|
268
|
+
phrase init --secret=<YOUR_TOKEN> --locale-filename="<locale.name>.yml"
|
269
|
+
|
270
|
+
## Further Information
|
69
271
|
* [Read the PhraseApp documentation](https://phraseapp.com/docs)
|
70
272
|
* [Get your free PhraseApp trial](https://phraseapp.com/signup)
|
71
273
|
* [Get in touch with the engineers](https://phraseapp.com/contact)
|
274
|
+
|
275
|
+
## References
|
276
|
+
* [PhraseApp In-Context Editor](http://demo.phraseapp.com)
|
277
|
+
* [PhraseApp API](https://phraseapp.com/docs/api/overview)
|
278
|
+
|
279
|
+
## Partner-Integrations
|
280
|
+
* [PhraseApp and Ruby Motion](https://github.com/phrase/motion-phrase)
|
281
|
+
* [Heroku Add-on](https://addons.heroku.com/phrase)
|
282
|
+
* [Cloudcontrol Add-on](https://phraseapp.com/docs/cloudcontrol/introduction)
|
data/lib/phrase/api/client.rb
CHANGED
@@ -18,11 +18,12 @@ class Phrase::Api::Client
|
|
18
18
|
METHOD_PUT = :put
|
19
19
|
METHOD_DELETE = :delete
|
20
20
|
|
21
|
-
attr_reader :auth_token
|
21
|
+
attr_reader :auth_token, :project_auth_token
|
22
22
|
|
23
|
-
def initialize(auth_token)
|
23
|
+
def initialize(auth_token, project_auth_token=nil)
|
24
24
|
raise "No auth token specified!" if (auth_token.nil? or auth_token.blank?)
|
25
25
|
@auth_token = auth_token
|
26
|
+
@project_auth_token = project_auth_token
|
26
27
|
end
|
27
28
|
|
28
29
|
def fetch_locales
|
@@ -132,16 +133,30 @@ class Phrase::Api::Client
|
|
132
133
|
parsed(result)
|
133
134
|
end
|
134
135
|
|
135
|
-
def delete_translation_key(id)
|
136
|
+
def delete_translation_key(id, params={})
|
136
137
|
result = perform_api_request("/translation_keys/#{id}", :delete)
|
137
138
|
parsed(result)['success'] == true
|
138
139
|
end
|
139
140
|
|
140
|
-
def delete_multiple_translation_keys(ids)
|
141
|
+
def delete_multiple_translation_keys(ids, params={})
|
141
142
|
result = perform_api_request("/translation_keys/destroy_multiple", :delete, :'ids[]' => ids)
|
142
143
|
parsed(result)['success'] == true
|
143
144
|
end
|
144
145
|
|
146
|
+
def create_session(email, password)
|
147
|
+
params = {
|
148
|
+
email: email,
|
149
|
+
password: password
|
150
|
+
}
|
151
|
+
result = perform_api_request("/sessions", :post, params)
|
152
|
+
parsed(result)["auth_token"]
|
153
|
+
end
|
154
|
+
|
155
|
+
def destroy_session
|
156
|
+
result = perform_api_request("/sessions", :delete)
|
157
|
+
parsed(result)["success"]
|
158
|
+
end
|
159
|
+
|
145
160
|
private
|
146
161
|
def extract_structured_object(translation)
|
147
162
|
if translation.is_a?(Hash)
|
@@ -230,34 +245,32 @@ private
|
|
230
245
|
end
|
231
246
|
|
232
247
|
def get_request(endpoint, params={})
|
233
|
-
params.merge
|
248
|
+
params = params.merge(auth_token: @auth_token)
|
249
|
+
params = params.merge(project_auth_token: @project_auth_token) if @project_auth_token.present?
|
234
250
|
request = Net::HTTP::Get.new("#{api_path_for(endpoint)}?#{query_for_params(params)}")
|
235
251
|
request
|
236
252
|
end
|
237
253
|
|
238
254
|
def post_request(endpoint, params={})
|
239
255
|
request = Net::HTTP::Post.new("#{api_path_for(endpoint)}")
|
240
|
-
params.merge
|
241
|
-
|
242
|
-
})
|
256
|
+
params = params.merge(auth_token: @auth_token)
|
257
|
+
params = params.merge(project_auth_token: @project_auth_token) if @project_auth_token.present?
|
243
258
|
set_form_data(request, params)
|
244
259
|
request
|
245
260
|
end
|
246
261
|
|
247
262
|
def put_request(endpoint, params={})
|
248
263
|
request = Net::HTTP::Put.new("#{api_path_for(endpoint)}")
|
249
|
-
params.merge
|
250
|
-
|
251
|
-
})
|
264
|
+
params = params.merge(auth_token: @auth_token)
|
265
|
+
params = params.merge(project_auth_token: @project_auth_token) if @project_auth_token.present?
|
252
266
|
set_form_data(request, params)
|
253
267
|
request
|
254
268
|
end
|
255
269
|
|
256
270
|
def delete_request(endpoint, params={})
|
257
271
|
request = Net::HTTP::Delete.new("#{api_path_for(endpoint)}")
|
258
|
-
params.merge
|
259
|
-
|
260
|
-
})
|
272
|
+
params = params.merge(auth_token: @auth_token)
|
273
|
+
params = params.merge(project_auth_token: @project_auth_token) if @project_auth_token.present?
|
261
274
|
set_form_data(request, params)
|
262
275
|
request
|
263
276
|
end
|
data/lib/phrase/delegate.rb
CHANGED
data/lib/phrase/formats.rb
CHANGED
@@ -30,10 +30,15 @@ module Phrase
|
|
30
30
|
autoload :Laravel, 'phrase/formats/laravel'
|
31
31
|
autoload :AngularTranslate, 'phrase/formats/angular_translate'
|
32
32
|
autoload :MozillaProperties, 'phrase/formats/mozilla_properties'
|
33
|
+
autoload :PlayProperties, 'phrase/formats/play_properties'
|
33
34
|
|
34
35
|
class Base
|
35
36
|
def self.supports_extension?(extension)
|
36
|
-
self.extensions.map(&:to_s).include?(extension.to_s)
|
37
|
+
self.extensions.map(&:to_s).include?(extension.to_s) or self.renders_locale_as_extension?
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.renders_locale_as_extension?
|
41
|
+
false
|
37
42
|
end
|
38
43
|
|
39
44
|
def self.extensions
|
@@ -99,6 +104,7 @@ module Phrase
|
|
99
104
|
laravel: Phrase::Formats::Laravel,
|
100
105
|
angular_translate: Phrase::Formats::AngularTranslate,
|
101
106
|
mozilla_properties: Phrase::Formats::MozillaProperties,
|
107
|
+
play_properties: Phrase::Formats::PlayProperties,
|
102
108
|
}
|
103
109
|
|
104
110
|
def self.config
|
@@ -136,6 +142,14 @@ module Phrase
|
|
136
142
|
format.nil? ? nil : handler_class_for_format(format).extract_locale_name_from_file_path(file_path)
|
137
143
|
end
|
138
144
|
|
145
|
+
def self.format_valid?(format)
|
146
|
+
if format.present? then
|
147
|
+
format_handler = handler_class_for_format(format)
|
148
|
+
return format_handler.renders_locale_as_extension? if format_handler.present?
|
149
|
+
end
|
150
|
+
false
|
151
|
+
end
|
152
|
+
|
139
153
|
def self.handler_class_for_format(format_name)
|
140
154
|
SUPPORTED_FORMATS.fetch(format_name.to_sym)
|
141
155
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
module Phrase
|
4
|
+
module Formats
|
5
|
+
class PlayProperties < Phrase::Formats::Base
|
6
|
+
def self.filename_for_locale(locale)
|
7
|
+
"messages.#{locale.code}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.renders_locale_as_extension?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -24,10 +24,16 @@ module Phrase
|
|
24
24
|
true
|
25
25
|
end
|
26
26
|
|
27
|
+
# These strings should conform to the same lproj filenames as XCode autogenerates
|
28
|
+
# See complete list here http://www.ibabbleon.com/iOS-Language-Codes-ISO-639.html
|
27
29
|
def self.formatted(name)
|
28
30
|
return name unless name.include?("-")
|
29
31
|
parts = name.split("-")
|
30
|
-
|
32
|
+
if parts.first.downcase.include?("zh")
|
33
|
+
"#{parts.first.downcase}-#{parts.last.capitalize}"
|
34
|
+
else
|
35
|
+
"#{parts.first}-#{parts.last.upcase}"
|
36
|
+
end
|
31
37
|
end
|
32
38
|
private_class_method :formatted
|
33
39
|
|
@@ -39,8 +39,8 @@ private
|
|
39
39
|
def interruptable_upload_files(files)
|
40
40
|
begin
|
41
41
|
Thread.new(files){ upload_files(files) }.join
|
42
|
-
rescue SystemExit, Interrupt, Exception
|
43
|
-
print_error "Failed"
|
42
|
+
rescue SystemExit, Interrupt, Exception => e
|
43
|
+
print_error "Failed! #{e.to_s}"
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -82,7 +82,7 @@ private
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def upload_file(file)
|
85
|
-
if file_valid?(file)
|
85
|
+
if file_valid?(file) or Phrase::Formats.format_valid?(@format) then
|
86
86
|
begin
|
87
87
|
tagged = " (tagged: #{@tags.join(", ")})" if @tags.size > 0
|
88
88
|
print_message "Uploading #{file}#{tagged}..."
|
@@ -120,7 +120,7 @@ private
|
|
120
120
|
def file_seems_to_be_utf16?(file)
|
121
121
|
Phrase::Tool::EncodingDetector.file_seems_to_be_utf16?(file)
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
def file_valid?(filepath)
|
125
125
|
extension = filepath.split('.').last
|
126
126
|
allowed_file_extensions.include?(extension)
|
@@ -120,6 +120,10 @@ class OptionsFactory
|
|
120
120
|
opts.on("-l", "--list", "List all tags") do |list|
|
121
121
|
set[:list] = list
|
122
122
|
end
|
123
|
+
|
124
|
+
opts.on("--secret=YOUR_AUTH_TOKEN", String, "The Auth Token to use for this operation instead of the saved one (optional)") do |secret|
|
125
|
+
set[:secret] = secret
|
126
|
+
end
|
123
127
|
end
|
124
128
|
private_class_method :tags
|
125
129
|
|
data/lib/phrase/version.rb
CHANGED
metadata
CHANGED
@@ -1,153 +1,153 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phrase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dynport GmbH
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: json
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: i18n
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: webmock
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: vcr
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: timecop
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: genspec
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: rails
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
description: phrase allows you to edit translations in-place on the page itself. More
|
@@ -159,8 +159,8 @@ executables:
|
|
159
159
|
extensions: []
|
160
160
|
extra_rdoc_files: []
|
161
161
|
files:
|
162
|
-
- .gitignore
|
163
|
-
- .travis.yml
|
162
|
+
- ".gitignore"
|
163
|
+
- ".travis.yml"
|
164
164
|
- Gemfile
|
165
165
|
- Gemfile.lock
|
166
166
|
- Guardfile
|
@@ -207,6 +207,7 @@ files:
|
|
207
207
|
- lib/phrase/formats/nested_json.rb
|
208
208
|
- lib/phrase/formats/node_json.rb
|
209
209
|
- lib/phrase/formats/php_array.rb
|
210
|
+
- lib/phrase/formats/play_properties.rb
|
210
211
|
- lib/phrase/formats/plist.rb
|
211
212
|
- lib/phrase/formats/properties.rb
|
212
213
|
- lib/phrase/formats/properties_xml.rb
|
@@ -251,12 +252,12 @@ require_paths:
|
|
251
252
|
- lib
|
252
253
|
required_ruby_version: !ruby/object:Gem::Requirement
|
253
254
|
requirements:
|
254
|
-
- -
|
255
|
+
- - ">="
|
255
256
|
- !ruby/object:Gem::Version
|
256
257
|
version: '0'
|
257
258
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
258
259
|
requirements:
|
259
|
-
- -
|
260
|
+
- - ">="
|
260
261
|
- !ruby/object:Gem::Version
|
261
262
|
version: 1.3.6
|
262
263
|
requirements: []
|