crowdin-cli 0.0.9 → 0.0.10
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/README.md +2 -0
- data/bin/crowdin-cli +79 -42
- data/lib/crowdin-cli.rb +1 -0
- data/lib/crowdin-cli/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -4,6 +4,8 @@ A Command-Line Interface to sync files between your computer/server and [Crowdin
|
|
4
4
|
|
5
5
|
It is cross-platform and runs in a terminal (Linux, MacOS X) or in cmd.exe (Windows).
|
6
6
|
|
7
|
+
> **WARNING**: This is a development version: It contains the latest changes, but may also have severe known issues, including crashes and data loss situations. In fact, it may not work at all.
|
8
|
+
|
7
9
|
## Installation
|
8
10
|
|
9
11
|
Add this line to your application's Gemfile:
|
data/bin/crowdin-cli
CHANGED
@@ -3,46 +3,50 @@
|
|
3
3
|
require 'pp'
|
4
4
|
require 'crowdin-cli'
|
5
5
|
|
6
|
-
#
|
7
|
-
# return existing directory structure in Crowdin project
|
6
|
+
# Return +hierarchy+ of directories and files in Crowdin project
|
8
7
|
#
|
9
|
-
|
8
|
+
# +files+ - basically, it's project files details from API method `project_info`
|
9
|
+
#
|
10
|
+
def get_remote_files_hierarchy(files, root = '/', hierarchy = { dirs: [], files: [] })
|
10
11
|
files.each do |node|
|
11
12
|
case node['node_type']
|
12
13
|
when 'directory'
|
13
|
-
|
14
|
-
|
14
|
+
hierarchy[:dirs] << "#{root}#{node['name']}"
|
15
|
+
get_remote_files_hierarchy(node['files'], root + node['name'] + '/', hierarchy)
|
15
16
|
when 'file'
|
16
|
-
|
17
|
+
hierarchy[:files] << "#{root}#{node['name']}"
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
|
-
return
|
21
|
+
return hierarchy
|
21
22
|
end
|
22
23
|
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
24
|
+
# Return +hierarchy+ of local directories and files
|
25
|
+
#
|
26
|
+
# @params [Array] files a list of files in a local directory.
|
26
27
|
#
|
27
|
-
def
|
28
|
-
|
28
|
+
def get_local_files_hierarchy(files, hierarchy = { dirs: [], files: [] })
|
29
|
+
hierarchy[:files] = files
|
29
30
|
|
30
|
-
|
31
|
+
dirs = files.inject([]) do |res, a|
|
31
32
|
res << a.split('/').drop(1).inject([]) do |res, s|
|
32
33
|
res << res.last.to_s + '/' + s
|
33
34
|
end
|
34
35
|
end
|
35
|
-
#
|
36
|
-
|
37
|
-
files.map(&:pop) # delete last element from each array
|
38
|
-
result[:dirs] = files.flatten.uniq
|
36
|
+
dirs.map(&:pop) # delete last element from each array
|
37
|
+
hierarchy[:dirs] = dirs.flatten.uniq
|
39
38
|
|
40
|
-
return
|
39
|
+
return hierarchy
|
41
40
|
end
|
42
41
|
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
42
|
+
# @param [String] path relative path to file in Crowdin project
|
43
|
+
# @param [String] export_pattern basically, is a file['translation'] from crowdin.yaml
|
44
|
+
# @param [Hash] lang language information
|
45
|
+
# @option lang [String] :name
|
46
|
+
# @option lang [String] :crowdin_code
|
47
|
+
# @option lang [String] :iso_639_1
|
48
|
+
# @option lang [String] :iso_639_3
|
49
|
+
# @option lang [String] :locale
|
46
50
|
#
|
47
51
|
def export_pattern_to_path(path, export_pattern, lang)
|
48
52
|
original_path = File.dirname(path)
|
@@ -60,10 +64,34 @@ def export_pattern_to_path(path, export_pattern, lang)
|
|
60
64
|
'%original_file_name%' => original_file_name,
|
61
65
|
'%original_path%' => original_path,
|
62
66
|
'%file_extension%' => file_extension,
|
63
|
-
'%file_name%' =>
|
67
|
+
'%file_name%' => file_name,
|
64
68
|
})
|
65
69
|
end
|
66
70
|
|
71
|
+
def android_locale_code(locale_code)
|
72
|
+
locale_code = case locale_code
|
73
|
+
when 'he-IL' then 'iw-IL'
|
74
|
+
when 'yi-DE' then 'ji-DE'
|
75
|
+
when 'id-ID' then 'in-ID'
|
76
|
+
else locale_code
|
77
|
+
end
|
78
|
+
return locale_code.sub('-', '-r')
|
79
|
+
end
|
80
|
+
|
81
|
+
# Return a string representing that part of the directory tree that is common to all the files
|
82
|
+
#
|
83
|
+
# @params [Array] paths set of strings representing directory paths
|
84
|
+
#
|
85
|
+
def find_common_directory_path(paths)
|
86
|
+
return paths.first if paths.length <= 1
|
87
|
+
arr = paths.sort
|
88
|
+
first = arr.first.split('/')
|
89
|
+
last = arr.last.split('/')
|
90
|
+
i = 0
|
91
|
+
i += 1 while first[i] == last[i] && i <= first.length
|
92
|
+
first.slice(0, i).join('/')
|
93
|
+
end
|
94
|
+
|
67
95
|
def unzip_file(file, dest)
|
68
96
|
# overwrite files if they already exist inside of the extracted path
|
69
97
|
Zip.options[:on_exists_proc] = true
|
@@ -78,15 +106,6 @@ def unzip_file(file, dest)
|
|
78
106
|
end
|
79
107
|
end
|
80
108
|
|
81
|
-
def android_locale_code(locale_code)
|
82
|
-
locale_code = case locale_code
|
83
|
-
when 'he-IL' then 'iw-IL'
|
84
|
-
when 'yi-DE' then 'ji-DE'
|
85
|
-
when 'id-ID' then 'in-ID'
|
86
|
-
else locale_code
|
87
|
-
end
|
88
|
-
return locale_code.sub('-', '-r')
|
89
|
-
end
|
90
109
|
|
91
110
|
###
|
92
111
|
include GLI::App
|
@@ -122,7 +141,6 @@ command :upload do |c|
|
|
122
141
|
# end
|
123
142
|
#end
|
124
143
|
|
125
|
-
# TODO: change variables names!
|
126
144
|
c.desc 'Upload source files'
|
127
145
|
c.command :sources do |c|
|
128
146
|
c.action do |global_options, options, args|
|
@@ -134,15 +152,18 @@ command :upload do |c|
|
|
134
152
|
supported_languages = @crowdin.supported_languages
|
135
153
|
source_language = supported_languages.find{ |lang| lang['crowdin_code'] == source_language }
|
136
154
|
|
137
|
-
remote_project_tree =
|
155
|
+
remote_project_tree = get_remote_files_hierarchy(project_info['files'])
|
138
156
|
|
139
157
|
local_files = []
|
158
|
+
dest_files = []
|
140
159
|
@config['files'].each do |file|
|
141
160
|
if File.exist?("#{@base_path}#{file['source']}")
|
142
161
|
local_files << { dest: file['source'], source: "#{@base_path}#{file['source']}", export_pattern: file['translation'] }
|
143
162
|
else
|
144
163
|
Dir.glob("#{@base_path}#{file['source']}").each do |source|
|
145
164
|
dest = source.sub("#{@base_path}", '') # relative path in Crowdin
|
165
|
+
dest_files << dest
|
166
|
+
|
146
167
|
file_pattern = export_pattern_to_path(dest, file['translation'], source_language)
|
147
168
|
|
148
169
|
diff = (dest.split('/') - file_pattern.split('/')).join('/')
|
@@ -154,7 +175,16 @@ command :upload do |c|
|
|
154
175
|
end
|
155
176
|
end
|
156
177
|
|
157
|
-
local_project_tree =
|
178
|
+
local_project_tree = get_local_files_hierarchy(local_files.collect{ |h| h[:dest] })
|
179
|
+
|
180
|
+
common_dir = find_common_directory_path(dest_files)
|
181
|
+
|
182
|
+
if common_dir
|
183
|
+
local_files.each{ |file| file[:dest].sub!(common_dir, '') }
|
184
|
+
local_project_tree[:dirs].each{ |dir| dir.sub!(common_dir, '')}
|
185
|
+
local_project_tree[:dirs].delete_if{ |dir| dir == ''}
|
186
|
+
local_project_tree[:files].each{ |file| file.sub!(common_dir, '')}
|
187
|
+
end
|
158
188
|
|
159
189
|
# Create directory tree
|
160
190
|
#
|
@@ -209,7 +239,7 @@ command :upload do |c|
|
|
209
239
|
|
210
240
|
project_info = @crowdin.project_info
|
211
241
|
|
212
|
-
remote_project_tree =
|
242
|
+
remote_project_tree = get_remote_files_hierarchy(project_info['files'])
|
213
243
|
|
214
244
|
if language == 'all'
|
215
245
|
project_languages = project_info['languages'].collect{ |h| h['code'] }
|
@@ -224,6 +254,7 @@ command :upload do |c|
|
|
224
254
|
source_language = supported_languages.find{ |lang| lang['crowdin_code'] == source_language }
|
225
255
|
|
226
256
|
translated_files = Hash.new{ |hash, key| hash[key] = Array.new }
|
257
|
+
dest_files = []
|
227
258
|
|
228
259
|
@config['files'].each do |file|
|
229
260
|
if File.exists?("#{@base_path}#{file['source']}")
|
@@ -231,12 +262,12 @@ command :upload do |c|
|
|
231
262
|
|
232
263
|
translation_languages.each do |lang|
|
233
264
|
source = export_pattern_to_path(dest, file['translation'], lang)
|
234
|
-
|
235
265
|
translated_files[lang['crowdin_code']] << { source: "#{@base_path}#{source}", dest: dest }
|
236
266
|
end
|
237
267
|
else
|
238
268
|
Dir.glob("#{@base_path}#{file['source']}").each do |source|
|
239
|
-
dest = source.sub("#{@base_path}", '')
|
269
|
+
dest = source.sub("#{@base_path}", '') # relative path in Crowdin
|
270
|
+
dest_files << dest
|
240
271
|
|
241
272
|
file_pattern = export_pattern_to_path(dest, file['translation'], source_language)
|
242
273
|
|
@@ -245,7 +276,6 @@ command :upload do |c|
|
|
245
276
|
|
246
277
|
translation_languages.each do |lang|
|
247
278
|
source = export_pattern_to_path(dest, export_pattern, lang)
|
248
|
-
|
249
279
|
translated_files[lang['crowdin_code']] << { source: "#{@base_path}#{source}", dest: dest }
|
250
280
|
end
|
251
281
|
|
@@ -258,14 +288,21 @@ command :upload do |c|
|
|
258
288
|
params[:import_eq_suggestions] = options[:import_eq_suggestions] ? 1 : 0
|
259
289
|
params[:auto_approve_imported] = options[:auto_approve_imported] ? 1 : 0
|
260
290
|
|
291
|
+
common_dir = find_common_directory_path(dest_files)
|
261
292
|
|
262
293
|
translated_files.each do |language, files|
|
263
294
|
files.each do |file|
|
264
|
-
|
265
|
-
|
266
|
-
|
295
|
+
file[:dest].sub!(common_dir, '')
|
296
|
+
if remote_project_tree[:files].include?(file[:dest])
|
297
|
+
if File.exist?(file[:source])
|
298
|
+
puts "Uploading #{file[:source].sub(@base_path, '')}"
|
299
|
+
@crowdin.upload_translation([] << file, language, params)
|
300
|
+
else
|
301
|
+
puts "Local file #{file[:source]} not exists"
|
302
|
+
end
|
267
303
|
else
|
268
|
-
|
304
|
+
# if source file not exist, don't upload translation
|
305
|
+
puts "Skip #{file[:source].sub(@base_path, '')}"
|
269
306
|
end
|
270
307
|
end
|
271
308
|
end
|
data/lib/crowdin-cli.rb
CHANGED
data/lib/crowdin-cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crowdin-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|