bin/crowdin-cli in crowdin-cli-0.2.0 vs bin/crowdin-cli in crowdin-cli-0.2.1

- old
+ new

@@ -55,26 +55,26 @@ # @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, languages_mapping = nil) - original_path = File.dirname(path) + original_path = File.dirname(path)[1..-1] original_file_name = File.basename(path) file_extension = File.extname(path)[1..-1] file_name = File.basename(path, File.extname(path)) pattern = { + '%original_file_name%' => original_file_name, + '%original_path%' => original_path, + '%file_extension%' => file_extension, + '%file_name%' => file_name, '%language%' => lang['name'], '%two_letters_code%' => lang['iso_639_1'], '%three_letters_code%' => lang['iso_639_3'], '%locale%' => lang['locale'], '%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_name, } placeholders = pattern.inject([]){ |memo, h| memo << h.first[/%(.*)%/, 1] } unless languages_mapping.nil? @@ -96,11 +96,12 @@ if pattern_regexp.names.include?('double_asterisk') and path.match(pattern_regexp) double_asterisk = path.match(pattern_regexp)['double_asterisk'] translation = translation.sub('**', double_asterisk) end - export_pattern = translation.split('/').reject(&:empty?).join('/').insert(0, '/') + export_pattern = translation.split('/').reject(&:empty?).join('/') + export_pattern.insert(0, '/') if translation.start_with?('/') return export_pattern end # Provides a partial implementation of translate a glob +pattern+ to a regular expression @@ -180,18 +181,20 @@ # +files_list+ is a Hash of key-value pairs. Where key is a posible archive filename based on current project configuration # and value is the expanded filename # def unzip_file_with_translations(zipfile_name, dest_path, files_list) # overwrite files if they already exist inside of the extracted path - Zip.options[:on_exists_proc] = true + Zip.on_exists_proc = true # files that exists in archive and doesn't match current project configuration unmatched_files = [] - Zip::ZipFile.open(zipfile_name) do |zipfile| + Zip::File.open(zipfile_name) do |zipfile| zipfile.select{ |zip_entry| zip_entry.file? }.each do |f| - file = files_list['/' + f.name] + # XXX + # `f' - relative path in archive + file = files_list[f.name] if file fpath = File.join(dest_path, file) FileUtils.mkdir_p(File.dirname(fpath)) puts "Download: `#{file}'" zipfile.extract(f, fpath) @@ -219,26 +222,27 @@ program_long_desc I18n.t('app.long_desc') sort_help :manually # help commands are ordered in the order declared wrap_help_text :to_terminal desc I18n.t('app.switches.verbose.desc') -switch [:verbose, :v], :negatable => false +switch [:v, :verbose], :negatable => false desc I18n.t('app.flags.config.desc') default_value File.join(Dir.pwd, 'crowdin.yaml') arg_name '<s>' -flag [:config,:c] +flag [:c, :config] desc I18n.t('app.commands.upload.desc') long_desc I18n.t('app.commands.upload.long_desc') command :upload do |c| c.desc I18n.t('app.commands.upload.commands.sources.desc') c.long_desc I18n.t('app.commands.upload.commands.sources.long_desc') c.command :sources do |c| c.desc I18n.t('app.commands.upload.commands.sources.switches.auto_update.desc') + c.default_value true c.switch ['auto-update'] c.action do |global_options, options, args| project_info = @crowdin.project_info @@ -256,16 +260,16 @@ @config['files'].each do |file| get_invalid_placeholders(file['translation']).each do |placeholder| puts "Warning: #{placeholder} is not valid variable supported by Crowdin. See http://crowdin.net/page/cli-tool#configuration-file for more details." end - if File.exist?("#{@base_path}#{file['source']}") + if File.exist?(File.join(@base_path, file['source'])) dest = file['source'] dest_files << dest - local_file = { dest: dest, source: "#{@base_path}#{file['source']}", export_pattern: file['translation'] } - # Used only when uploading CSV file to define data columns mapping. + local_file = { dest: dest, source: File.join(@base_path, file['source']), export_pattern: file['translation'] } + # Used only when uploading CSV file to define data columns mapping local_file.merge!({ sheme: file['scheme'] }) if file.has_key?('scheme') local_file.merge!({ first_line_contains_header: file['first_line_contains_header'] }) if file.has_key?('first_line_contains_header') local_files << local_file else @@ -277,11 +281,11 @@ if ignores.include?(dest) Find.prune # Don't look any further into this directory else next end - elsif File.fnmatch?(file['source'], dest) + elsif File.fnmatch?(file['source'], dest, File::FNM_PATHNAME) dest_files << dest export_pattern = construct_export_pattern(dest, file['source'], file['translation']) local_file = { dest: dest, source: source_path, export_pattern: export_pattern } @@ -315,11 +319,11 @@ create_dirs.each do |dir| puts "Create directory `#{dir}`" @crowdin.add_directory(dir) end - if options['auto-update'].nil? or options['auto-update'] + if options['auto-update'] # Update existing files in Crowdin project # # array containing elements common to the two arrays update_files = local_project_tree[:files] & remote_project_tree[:files] files_for_upload = local_files.select{ |file| update_files.include?(file[:dest]) } @@ -363,11 +367,11 @@ c.command :translations do |c| c.desc I18n.t('app.commands.upload.commands.translations.flags.language.desc') c.default_value 'all' c.arg_name 'crowdin_language_code' - c.flag [:language, :l] + c.flag [:l, :language] c.desc I18n.t('app.commands.upload.commands.translations.switches.import_duplicates.desc') c.switch ['import-duplicates'] c.desc I18n.t('app.commands.upload.commands.translations.switches.import_eq_suggestions.desc') @@ -396,32 +400,42 @@ exit_now!("language '#{language}' doesn't exist in a project") end end supported_languages = @crowdin.supported_languages - translation_languages = supported_languages.select{ |lang| project_languages.include?(lang['crowdin_code']) } source_language = project_info['details']['source_language']['code'] source_language = supported_languages.find{ |lang| lang['crowdin_code'] == source_language } + translation_languages = supported_languages.select{ |lang| project_languages.include?(lang['crowdin_code']) } + translated_files = Hash.new{ |hash, key| hash[key] = Array.new } dest_files = [] @config['files'].each do |file| get_invalid_placeholders(file['translation']).each do |placeholder| puts "Warning: #{placeholder} is not valid variable supported by Crowdin. See http://crowdin.net/page/cli-tool#configuration-file for more details." end languages_mapping = file['languages_mapping'] - if File.exists?("#{@base_path}#{file['source']}") + # CSV files only (default: false) + multilingual_spreadsheet = file['multilingual_spreadsheet'] || false + + if multilingual_spreadsheet + file_translation_languages = [] << source_language + else + file_translation_languages = translation_languages + end + + if File.exists?(File.join(@base_path, file['source'])) dest = file['source'].sub("#{@base_path}", '') dest_files << dest - translation_languages.each do |lang| + file_translation_languages.each do |lang| source = export_pattern_to_path(dest, file['translation'], lang, languages_mapping) - translated_files[lang['crowdin_code']] << { source: "#{@base_path}#{source}", dest: dest } + translated_files[lang['crowdin_code']] << { source: File.join(@base_path, source), dest: dest } end else Find.find(@base_path) do |source_path| dest = source_path.sub(@base_path, '') # relative path in Crowdin @@ -430,21 +444,21 @@ if ignores.include?(dest) Find.prune # Don't look any further into this directory else next end - elsif File.fnmatch?(file['source'], dest) + elsif File.fnmatch?(file['source'], dest, File::FNM_PATHNAME) dest_files << dest export_pattern = construct_export_pattern(dest, file['source'], file['translation']) - translation_languages.each do |lang| + file_translation_languages.each do |lang| source = export_pattern_to_path(dest, export_pattern, lang, languages_mapping) - translated_files[lang['crowdin_code']] << { source: "#{@base_path}#{source}", dest: dest } + translated_files[lang['crowdin_code']] << { source: File.join(@base_path, source), dest: dest } end - end + end end # Find end # if end # @config['files'] @@ -492,11 +506,11 @@ #arg_name 'Describe arguments to download here' command :download do |c| c.desc I18n.t('app.commands.download.flags.language.desc') c.arg_name 'language_code' - c.flag [:language, :l], :default_value => 'all' + c.flag [:l, :language], :default_value => 'all' c.action do |global_options ,options, args| language = options[:language] project_info = @crowdin.project_info @@ -514,31 +528,42 @@ # use export API method before to download the most recent translations @crowdin.export_translations supported_languages = @crowdin.supported_languages - translation_languages = supported_languages.select{ |lang| project_languages.include?(lang['crowdin_code']) } source_language = project_info['details']['source_language']['code'] source_language = supported_languages.find{ |lang| lang['crowdin_code'] == source_language } + translation_languages = supported_languages.select{ |lang| project_languages.include?(lang['crowdin_code']) } + # keys is all possible files in .ZIP archive # values is resulted local files downloadable_files_hash = {} @config['files'].each do |file| languages_mapping = file['languages_mapping'] # Hash or NilClass - if File.exists?("#{@base_path}#{file['source']}") + # CSV files only (default: false) + multilingual_spreadsheet = file['multilingual_spreadsheet'] || false + + if multilingual_spreadsheet + file_translation_languages = [] << source_language + else + file_translation_languages = translation_languages + end + + if File.exists?(File.join(@base_path, file['source'])) dest = file['source'].sub("#{@base_path}", '') - translation_languages.each do |lang| + file_translation_languages.each do |lang| zipped_file = export_pattern_to_path(dest, file['translation'], lang) + zipped_file.sub!(/^\//, '') local_file = export_pattern_to_path(dest, file['translation'], lang, languages_mapping) - downloadable_files_hash[zipped_file] = local_file end + else Find.find(@base_path) do |source_path| dest = source_path.sub(@base_path, '') # relative path in Crowdin if File.directory?(source_path) @@ -546,23 +571,22 @@ if ignores.include?(dest) Find.prune # Don't look any further into this directory else next end - elsif File.fnmatch?(file['source'], dest) + elsif File.fnmatch?(file['source'], dest, File::FNM_PATHNAME) export_pattern = construct_export_pattern(dest, file['source'], file['translation']) - translation_languages.each do |lang| + file_translation_languages.each do |lang| zipped_file = export_pattern_to_path(dest, export_pattern, lang) + zipped_file.sub!(/^\//, '') local_file = export_pattern_to_path(dest, export_pattern, lang, languages_mapping) - downloadable_files_hash[zipped_file] = local_file end - end + end end # Find - end # if end # @config['files'] ## tempfile = Tempfile.new(language) @@ -616,11 +640,11 @@ EOS end @config['files'].each do |file| file['source'] = '/' + file['source'] unless file['source'].start_with?('/') - file['translation'] = '/' + file['translation'] unless file['translation'].start_with?('/') + #file['translation'] = '/' + file['translation'] unless file['translation'].start_with?('/') if file['source'].include?('**') if file['source'].scan('**').size > 1 exit_now! <<EOS Source pattern `#{file['source']}` is not valid. The mask `**` can be used only once in the source pattern. @@ -648,17 +672,10 @@ puts <<EOS Warning: Configuration file misses parameter `base_path` that defines your project root directory. Using `#{@base_path}` as a root directory. EOS end - if @config['remote_path'] - @remote_path = @config['remote_path'] - @remote_path = '/' + @remote_path unless @remote_path.start_with?('/') - else - @remote_path = '' - end - @preserve_hierarchy = false if @config['preserve_hierarchy'] @preserve_hierarchy = case @config['preserve_hierarchy'] when true true @@ -670,10 +687,13 @@ EOS end end Crowdin::API.log = Logger.new($stderr) if globals[:verbose] - @crowdin = Crowdin::API.new(api_key: @config['api_key'], project_id: @config['project_identifier'], base_url: @config['base_url'] || 'http://api.crowdin.net') + + base_url = @config['base_url'] || 'http://api.crowdin.net' + @crowdin = Crowdin::API.new(api_key: @config['api_key'], project_id: @config['project_identifier'], base_url: base_url) + begin @crowdin.project_info rescue Crowdin::API::Errors::Error => err raise err rescue