bin/crowdin-cli in crowdin-cli-0.0.9 vs bin/crowdin-cli in crowdin-cli-0.0.10

- old
+ new

@@ -1,50 +1,54 @@ #!/usr/bin/env ruby require 'pp' require 'crowdin-cli' -# using for upload source files -# return existing directory structure in Crowdin project +# Return +hierarchy+ of directories and files in Crowdin project # -def walk_remote_tree(files, root = '/', result = { dirs: [], files: [] }) +# +files+ - basically, it's project files details from API method `project_info` +# +def get_remote_files_hierarchy(files, root = '/', hierarchy = { dirs: [], files: [] }) files.each do |node| case node['node_type'] when 'directory' - result[:dirs] << "#{root}#{node['name']}" - walk_remote_tree(node['files'], root + node['name'] + '/', result) + hierarchy[:dirs] << "#{root}#{node['name']}" + get_remote_files_hierarchy(node['files'], root + node['name'] + '/', hierarchy) when 'file' - result[:files] << "#{root}#{node['name']}" + hierarchy[:files] << "#{root}#{node['name']}" end end - return result + return hierarchy end -# using for upload source files -# return local directory structute -# first argument: ['/path/to/admin/en.xml', '/path/to/user/settings/strings.xml'] +# Return +hierarchy+ of local directories and files # -def walk_local_tree(files, result = { dirs: [], files: [] }) - result[:files] = files +# @params [Array] files a list of files in a local directory. +# +def get_local_files_hierarchy(files, hierarchy = { dirs: [], files: [] }) + hierarchy[:files] = files - files = files.inject([]) do |res, a| + dirs = files.inject([]) do |res, a| res << a.split('/').drop(1).inject([]) do |res, s| res << res.last.to_s + '/' + s end end - # Ex: files = [["/path", "/path/to", "/path/to/admin", "/path/to/admin/en.xml"], ... ] + dirs.map(&:pop) # delete last element from each array + hierarchy[:dirs] = dirs.flatten.uniq - files.map(&:pop) # delete last element from each array - result[:dirs] = files.flatten.uniq - - return result + return hierarchy end -# +path_ - relative path to file in Crowdin project -# +export_pattern+ - basically, is a file['translation'] from crowdin.yaml -# +lang+ - Hash containing language information +# @param [String] path relative path to file in Crowdin project +# @param [String] export_pattern basically, is a file['translation'] from crowdin.yaml +# @param [Hash] lang language information +# @option lang [String] :name +# @option lang [String] :crowdin_code +# @option lang [String] :iso_639_1 +# @option lang [String] :iso_639_3 +# @option lang [String] :locale # def export_pattern_to_path(path, export_pattern, lang) original_path = File.dirname(path) original_file_name = File.basename(path) file_extension = File.extname(path)[1..-1] @@ -58,14 +62,38 @@ '%locale_with_underscore%' => lang['locale'].gsub('-', '_'), '%android_code%' => android_locale_code(lang['locale']), '%original_file_name%' => original_file_name, '%original_path%' => original_path, '%file_extension%' => file_extension, - '%file_name%' => file_extension, + '%file_name%' => file_name, }) end +def android_locale_code(locale_code) + locale_code = case locale_code + when 'he-IL' then 'iw-IL' + when 'yi-DE' then 'ji-DE' + when 'id-ID' then 'in-ID' + else locale_code + end + return locale_code.sub('-', '-r') +end + +# Return a string representing that part of the directory tree that is common to all the files +# +# @params [Array] paths set of strings representing directory paths +# +def find_common_directory_path(paths) + return paths.first if paths.length <= 1 + arr = paths.sort + first = arr.first.split('/') + last = arr.last.split('/') + i = 0 + i += 1 while first[i] == last[i] && i <= first.length + first.slice(0, i).join('/') +end + def unzip_file(file, dest) # overwrite files if they already exist inside of the extracted path Zip.options[:on_exists_proc] = true Zip::ZipFile.open(file) do |zip_file| @@ -76,19 +104,10 @@ zip_file.extract(f, f_path) end end end -def android_locale_code(locale_code) - locale_code = case locale_code - when 'he-IL' then 'iw-IL' - when 'yi-DE' then 'ji-DE' - when 'id-ID' then 'in-ID' - else locale_code - end - return locale_code.sub('-', '-r') -end ### include GLI::App program_desc 'A CLI to sync locale files with crowdin.net' @@ -120,11 +139,10 @@ # puts options # puts "`upload all` command ran" # end #end - # TODO: change variables names! c.desc 'Upload source files' c.command :sources do |c| c.action do |global_options, options, args| project_info = @crowdin.project_info @@ -132,19 +150,22 @@ # Crowdin supported languages list supported_languages = @crowdin.supported_languages source_language = supported_languages.find{ |lang| lang['crowdin_code'] == source_language } - remote_project_tree = walk_remote_tree(project_info['files']) + remote_project_tree = get_remote_files_hierarchy(project_info['files']) local_files = [] + dest_files = [] @config['files'].each do |file| if File.exist?("#{@base_path}#{file['source']}") local_files << { dest: file['source'], source: "#{@base_path}#{file['source']}", export_pattern: file['translation'] } else Dir.glob("#{@base_path}#{file['source']}").each do |source| dest = source.sub("#{@base_path}", '') # relative path in Crowdin + dest_files << dest + file_pattern = export_pattern_to_path(dest, file['translation'], source_language) diff = (dest.split('/') - file_pattern.split('/')).join('/') export_pattern = file['translation'].sub('**', diff) @@ -152,12 +173,21 @@ end end end - local_project_tree = walk_local_tree(local_files.collect{ |h| h[:dest] }) + local_project_tree = get_local_files_hierarchy(local_files.collect{ |h| h[:dest] }) + common_dir = find_common_directory_path(dest_files) + + if common_dir + local_files.each{ |file| file[:dest].sub!(common_dir, '') } + local_project_tree[:dirs].each{ |dir| dir.sub!(common_dir, '')} + local_project_tree[:dirs].delete_if{ |dir| dir == ''} + local_project_tree[:files].each{ |file| file.sub!(common_dir, '')} + end + # Create directory tree # create_dirs = local_project_tree[:dirs] - remote_project_tree[:dirs] create_dirs.each do |dir| puts "Create directory `#{dir}`" @@ -207,11 +237,11 @@ c.action do |global_options, options, args| language = options[:language] project_info = @crowdin.project_info - remote_project_tree = walk_remote_tree(project_info['files']) + remote_project_tree = get_remote_files_hierarchy(project_info['files']) if language == 'all' project_languages = project_info['languages'].collect{ |h| h['code'] } else project_languages = [] << language @@ -222,32 +252,32 @@ source_language = project_info['source_language']['code'] source_language = supported_languages.find{ |lang| lang['crowdin_code'] == source_language } translated_files = Hash.new{ |hash, key| hash[key] = Array.new } + dest_files = [] @config['files'].each do |file| if File.exists?("#{@base_path}#{file['source']}") dest = file['source'].sub("#{@base_path}", '') translation_languages.each do |lang| source = export_pattern_to_path(dest, file['translation'], lang) - translated_files[lang['crowdin_code']] << { source: "#{@base_path}#{source}", dest: dest } end else Dir.glob("#{@base_path}#{file['source']}").each do |source| - dest = source.sub("#{@base_path}", '') + dest = source.sub("#{@base_path}", '') # relative path in Crowdin + dest_files << dest file_pattern = export_pattern_to_path(dest, file['translation'], source_language) diff = (dest.split('/') - file_pattern.split('/')).join('/') export_pattern = file['translation'].sub('**', diff) translation_languages.each do |lang| source = export_pattern_to_path(dest, export_pattern, lang) - translated_files[lang['crowdin_code']] << { source: "#{@base_path}#{source}", dest: dest } end end end # if @@ -256,17 +286,24 @@ params = {} params[:import_duplicates] = options[:import_dublicates] ? 1 : 0 params[:import_eq_suggestions] = options[:import_eq_suggestions] ? 1 : 0 params[:auto_approve_imported] = options[:auto_approve_imported] ? 1 : 0 + common_dir = find_common_directory_path(dest_files) translated_files.each do |language, files| files.each do |file| - if File.exist?(file[:source]) - puts "Uploading #{file[:source]}" - @crowdin.upload_translation([] << file, language, params) + file[:dest].sub!(common_dir, '') + if remote_project_tree[:files].include?(file[:dest]) + if File.exist?(file[:source]) + puts "Uploading #{file[:source].sub(@base_path, '')}" + @crowdin.upload_translation([] << file, language, params) + else + puts "Local file #{file[:source]} not exists" + end else - puts "Local file #{file[:source]} not exists" + # if source file not exist, don't upload translation + puts "Skip #{file[:source].sub(@base_path, '')}" end end end end # action