phrase 0.2.2 → 0.2.3
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.
- data/.gitignore +1 -0
- data/lib/phrase/api/client.rb +3 -2
- data/lib/phrase/tool.rb +75 -50
- data/lib/phrase/tool/options.rb +13 -1
- data/lib/phrase/version.rb +1 -1
- metadata +16 -16
data/.gitignore
CHANGED
data/lib/phrase/api/client.rb
CHANGED
@@ -75,11 +75,12 @@ class Phrase::Api::Client
|
|
75
75
|
true
|
76
76
|
end
|
77
77
|
|
78
|
-
def download_translations_for_locale(name)
|
78
|
+
def download_translations_for_locale(name, format=Phrase::Tool::DEFAULT_DOWNLOAD_FORMAT)
|
79
79
|
raise "You must specify a name" if name.nil? or name.blank?
|
80
|
+
raise "You must specify a format" if format.nil? or format.blank?
|
80
81
|
|
81
82
|
begin
|
82
|
-
content = perform_api_request("/translations/download", :get, {'locale' => name})
|
83
|
+
content = perform_api_request("/translations/download.#{format}", :get, {'locale' => name})
|
83
84
|
return content
|
84
85
|
rescue Phrase::Api::Exceptions::ServerError => e
|
85
86
|
raise "Translations #{name} could not be downloaded"
|
data/lib/phrase/tool.rb
CHANGED
@@ -9,6 +9,10 @@ class Phrase::Tool
|
|
9
9
|
autoload :Options, 'phrase/tool/options'
|
10
10
|
autoload :TagValidator, 'phrase/tool/tag_validator'
|
11
11
|
|
12
|
+
ALLOWED_FILE_TYPES = %w(yml pot po)
|
13
|
+
ALLOWED_DOWNLOAD_FORMATS = %w(yml po)
|
14
|
+
DEFAULT_DOWNLOAD_FORMAT = "yml"
|
15
|
+
|
12
16
|
attr_accessor :config, :options
|
13
17
|
|
14
18
|
def initialize(argv)
|
@@ -42,13 +46,13 @@ protected
|
|
42
46
|
def init
|
43
47
|
secret = @options.get(:secret)
|
44
48
|
unless secret.present?
|
45
|
-
|
46
|
-
|
49
|
+
print_error "Need a secret to init, but found none."
|
50
|
+
print_error "Please provide the --secret=YOUR_SECRET parameter."
|
47
51
|
exit(41)
|
48
52
|
end
|
49
53
|
|
50
54
|
@config.secret = secret
|
51
|
-
|
55
|
+
print_message "Wrote secret to config file .phrase"
|
52
56
|
|
53
57
|
default_locale_name = @options.get(:default_locale)
|
54
58
|
create_locale(default_locale_name)
|
@@ -59,13 +63,13 @@ protected
|
|
59
63
|
check_config_available
|
60
64
|
tags = @options.get(:tags)
|
61
65
|
unless tags.empty? or valid_tags_are_given?(tags)
|
62
|
-
|
66
|
+
print_error "Invalid tags: Only letters, numbers, underscores and dashes are allowed"
|
63
67
|
exit(43)
|
64
68
|
end
|
65
69
|
|
66
70
|
files = choose_files_to_upload
|
67
71
|
if files.empty?
|
68
|
-
|
72
|
+
print_message "Could not find any files to upload :("
|
69
73
|
exit(43)
|
70
74
|
end
|
71
75
|
|
@@ -85,9 +89,15 @@ protected
|
|
85
89
|
locales = fetch_locales
|
86
90
|
end
|
87
91
|
|
92
|
+
format = @options.get(:format) || DEFAULT_DOWNLOAD_FORMAT
|
93
|
+
unless ALLOWED_DOWNLOAD_FORMATS.include?(format)
|
94
|
+
print_error "Invalid format: #{format}"
|
95
|
+
exit(43)
|
96
|
+
end
|
97
|
+
|
88
98
|
locales.each do |locale_name|
|
89
|
-
print "Downloading phrase.#{locale_name}
|
90
|
-
fetch_translations_for_locale(locale_name)
|
99
|
+
print "Downloading phrase.#{locale_name}.#{format}..."
|
100
|
+
fetch_translations_for_locale(locale_name, format)
|
91
101
|
end
|
92
102
|
end
|
93
103
|
|
@@ -107,32 +117,34 @@ USAGE
|
|
107
117
|
end
|
108
118
|
|
109
119
|
def print_version
|
110
|
-
|
120
|
+
print_message "phrase version #{Phrase::VERSION}"
|
111
121
|
end
|
112
122
|
|
113
123
|
private
|
114
124
|
def choose_files_to_upload
|
115
125
|
file_name = args[1]
|
116
|
-
|
126
|
+
recursive = @options.get(:recursive)
|
127
|
+
|
117
128
|
unless file_name
|
118
129
|
if self.class.rails_default_locale_folder_is_available
|
119
130
|
file_name = self.class.rails_default_locale_folder
|
120
|
-
|
131
|
+
print_message "No file or directory specified, using #{self.class.rails_default_locale_folder}"
|
121
132
|
else
|
122
|
-
|
123
|
-
|
124
|
-
|
133
|
+
print_error "Need either a file or directory:"
|
134
|
+
print_error "phrase push FILE"
|
135
|
+
print_error "phrase push DIRECTORY"
|
125
136
|
exit(46)
|
126
137
|
end
|
127
138
|
end
|
128
139
|
|
129
140
|
unless File.exist?(file_name)
|
130
|
-
|
141
|
+
print_error "The file #{file_name} could not be found."
|
131
142
|
exit(42)
|
132
143
|
end
|
133
144
|
|
134
145
|
if File.directory?(file_name)
|
135
|
-
|
146
|
+
pattern = recursive ? "#{File.expand_path(file_name)}/**/*" : "#{File.expand_path(file_name)}/**"
|
147
|
+
files = Dir.glob(pattern)
|
136
148
|
else
|
137
149
|
files = [file_name]
|
138
150
|
end
|
@@ -140,44 +152,48 @@ private
|
|
140
152
|
|
141
153
|
def upload_files(files, tags=[])
|
142
154
|
files.each do |file|
|
143
|
-
|
155
|
+
upload_file(file, tags)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def upload_file(file, tags=[])
|
160
|
+
valid = true
|
144
161
|
|
145
|
-
|
146
|
-
|
147
|
-
|
162
|
+
if File.directory?(file)
|
163
|
+
valid = false
|
164
|
+
end
|
148
165
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
166
|
+
unless file_valid?(file)
|
167
|
+
valid = false
|
168
|
+
print_error "Notice: Could not upload #{file} (type not supported)"
|
169
|
+
end
|
153
170
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
end
|
171
|
+
if valid
|
172
|
+
begin
|
173
|
+
tagged = " (tagged: #{tags.join(", ")})" if tags.size > 0
|
174
|
+
print_message "Uploading #{file}#{tagged}..."
|
175
|
+
api_client.upload(file, File.read(file), tags)
|
176
|
+
print_message "OK"
|
177
|
+
rescue Exception => e
|
178
|
+
print_message "Failed"
|
179
|
+
print_server_error(e.message, file)
|
164
180
|
end
|
165
181
|
end
|
166
182
|
end
|
167
183
|
|
168
|
-
def fetch_translations_for_locale(name)
|
184
|
+
def fetch_translations_for_locale(name, format=DEFAULT_DOWNLOAD_FORMAT)
|
169
185
|
begin
|
170
|
-
content = api_client.download_translations_for_locale(name)
|
171
|
-
|
172
|
-
store_translations_file(name, content)
|
186
|
+
content = api_client.download_translations_for_locale(name, format)
|
187
|
+
print_message "OK"
|
188
|
+
store_translations_file(name, content, format)
|
173
189
|
rescue Exception => e
|
174
|
-
|
190
|
+
print_error "Failed"
|
175
191
|
print_server_error(e.message)
|
176
192
|
end
|
177
193
|
end
|
178
194
|
|
179
|
-
def store_translations_file(name, content)
|
180
|
-
File.open("phrase/locales/phrase.#{name}
|
195
|
+
def store_translations_file(name, content, format=DEFAULT_DOWNLOAD_FORMAT)
|
196
|
+
File.open("phrase/locales/phrase.#{name}.#{format}", "w") do |file|
|
181
197
|
file.write(content)
|
182
198
|
end
|
183
199
|
end
|
@@ -185,10 +201,10 @@ private
|
|
185
201
|
def fetch_locales
|
186
202
|
begin
|
187
203
|
locales = api_client.fetch_locales
|
188
|
-
|
204
|
+
print_message "Fetched all locales"
|
189
205
|
return locales
|
190
206
|
rescue Exception => e
|
191
|
-
|
207
|
+
print_message "Failed"
|
192
208
|
print_server_error(e.message)
|
193
209
|
exit(47)
|
194
210
|
end
|
@@ -197,18 +213,18 @@ private
|
|
197
213
|
def create_locale(name)
|
198
214
|
begin
|
199
215
|
api_client.create_locale(name)
|
200
|
-
|
216
|
+
print_message "Created locale \"#{name}\""
|
201
217
|
rescue Exception => e
|
202
|
-
|
218
|
+
print_message "Notice: Locale \"#{name}\" could not be created (maybe it already exists)"
|
203
219
|
end
|
204
220
|
end
|
205
221
|
|
206
222
|
def make_locale_default(name)
|
207
223
|
begin
|
208
224
|
api_client.make_locale_default(name)
|
209
|
-
|
225
|
+
print_message "Locale \"#{name}\" is now the default locale"
|
210
226
|
rescue Exception => e
|
211
|
-
|
227
|
+
print_message "Notice: Locale \"#{name}\" could not be made the default locale"
|
212
228
|
print_server_error(e.message)
|
213
229
|
end
|
214
230
|
end
|
@@ -218,15 +234,24 @@ private
|
|
218
234
|
end
|
219
235
|
|
220
236
|
def print_server_error(message, filename=nil)
|
221
|
-
|
237
|
+
print_error "#{message} (#{filename})"
|
238
|
+
end
|
239
|
+
|
240
|
+
def print_message(message)
|
241
|
+
puts message
|
242
|
+
end
|
243
|
+
|
244
|
+
def print_error(message)
|
245
|
+
$stderr.puts message
|
222
246
|
end
|
223
247
|
|
224
248
|
def args
|
225
249
|
@args
|
226
250
|
end
|
227
251
|
|
228
|
-
def
|
229
|
-
|
252
|
+
def file_valid?(filepath)
|
253
|
+
extension = filepath.split('.').last
|
254
|
+
ALLOWED_FILE_TYPES.include?(extension)
|
230
255
|
end
|
231
256
|
|
232
257
|
def create_locales_folder!
|
@@ -235,7 +260,7 @@ private
|
|
235
260
|
|
236
261
|
def check_config_available
|
237
262
|
if !@config.secret || @config.secret.empty?
|
238
|
-
|
263
|
+
print_error "No config present. You need to initialize phrase first."
|
239
264
|
exit(43)
|
240
265
|
end
|
241
266
|
end
|
data/lib/phrase/tool/options.rb
CHANGED
@@ -16,9 +16,11 @@ class Phrase::Tool::Options
|
|
16
16
|
default_locale: "en"
|
17
17
|
},
|
18
18
|
push: {
|
19
|
-
tags: []
|
19
|
+
tags: [],
|
20
|
+
recursive: false
|
20
21
|
},
|
21
22
|
pull: {
|
23
|
+
format: "yml"
|
22
24
|
}
|
23
25
|
}
|
24
26
|
options.parse!(args)
|
@@ -49,6 +51,16 @@ private
|
|
49
51
|
opts.on("--tags=foo,bar", Array, "List of tags for phrase push (separated by comma)") do |tags|
|
50
52
|
@data[command_name][:tags] = tags
|
51
53
|
end
|
54
|
+
|
55
|
+
opts.on("-R", "--recursive", "Push files in subfolders as well (recursively)") do |recursive|
|
56
|
+
@data[command_name][:recursive] = true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
when :pull
|
60
|
+
OptionParser.new do |opts|
|
61
|
+
opts.on("--format=yml", String, "Allowed formats: #{Phrase::Tool::ALLOWED_DOWNLOAD_FORMATS.join(", ")}") do |format|
|
62
|
+
@data[command_name][:format] = format
|
63
|
+
end
|
52
64
|
end
|
53
65
|
else
|
54
66
|
OptionParser.new do |opts|
|
data/lib/phrase/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phrase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
|
-
requirement: &
|
16
|
+
requirement: &70265216292960 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '3.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70265216292960
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: addressable
|
27
|
-
requirement: &
|
27
|
+
requirement: &70265216292500 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 2.2.8
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70265216292500
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: json
|
38
|
-
requirement: &
|
38
|
+
requirement: &70265216292120 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70265216292120
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
|
-
requirement: &
|
49
|
+
requirement: &70265216291660 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70265216291660
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: i18n
|
60
|
-
requirement: &
|
60
|
+
requirement: &70265216291240 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70265216291240
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: webmock
|
71
|
-
requirement: &
|
71
|
+
requirement: &70265216290820 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70265216290820
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: vcr
|
82
|
-
requirement: &
|
82
|
+
requirement: &70265216290400 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70265216290400
|
91
91
|
description: phrase allows you to edit translations in-place on the page itself. More
|
92
92
|
information at phraseapp.com
|
93
93
|
email:
|