class AnnoTranslate::TranslationsImporter

Public Class Methods

import(file_prefix, import_from=nil) click to toggle source
# File lib/import_export.rb, line 138
def self.import(file_prefix, import_from=nil)
  importer = self.new(file_prefix, import_from)
  importer.import_translations
end
new(file_prefix, import_from=nil) click to toggle source
# File lib/import_export.rb, line 143
def initialize(file_prefix, import_from=nil)
  # Format pertinent paths for files
  here = File.expand_path(File.dirname(__FILE__))
  config = File.expand_path(File.join(here, "../../config"))
  @translations_support = File.join(config, "translations")
  @import_folder = import_from ? import_from : File.join(@translations_support, "import")
  @locales_folder = File.join(config, "locales")
  @base_yml_file = File.join(@locales_folder, "en.yml")
  @prefix = file_prefix
  @duplicates_file = File.join(@translations_support, "#{@prefix}_shared_strings.yml")

  @base_locale = YAML.load_file(@base_yml_file)
  load_base_ids
  @cache = YAML.load_file(@duplicates_file)

  @foreign_languages = Dir[File.join(@import_folder, "*#{@prefix}*.csv")].map do |csv|
    m = csv.match(/\.([a-z]{2,2}-?[A-Z]{0,2})\.csv$/)
    raise "Failed parsing language code from #{csv}" if m.nil?
    lang_code = m[1]
    raise "Parsed language code '#{lang_code}' is not supported" if !FOREIGN_LOCALES[lang_code]
    dest_yml = File.join(@locales_folder, "#{lang_code}.yml")
    source_csv = File.join(@import_folder, "#{@prefix}.#{lang_code}.csv")
    untranslated_strings_report = File.join(@import_folder, "#{@prefix}.missing.#{lang_code}.txt")
    {
      code: lang_code,
      name: FOREIGN_LOCALES[lang_code],
      yml: dest_yml,
      csv: source_csv,
      missing_translations: [],
      untranslated_report: untranslated_strings_report,
    }
  end
end

Public Instance Methods

import_translations() click to toggle source
# File lib/import_export.rb, line 177
def import_translations
  raise "No CSV files to import\nimport folder: #{@import_folder}\n\n" if @foreign_languages.empty?
  missing_translations = 0
  @foreign_languages.each do |lang|
    puts "Importing #{lang[:name]} (#{lang[:code]}) translations"
    puts "  from: #{lang[:csv]}"
    puts "  to:   #{lang[:yml]}"
    csv_to_yml(lang)
    not_translated = lang[:missing_translations].count
    puts "  WARNING: #{not_translated} untranslated strings found!" if not_translated > 0
    missing_translations += not_translated
  end
  puts "\n#{missing_translations} untranslated strings\nImport complete"
end

Private Instance Methods

csv_to_yml(config) click to toggle source
# File lib/import_export.rb, line 217
def csv_to_yml(config)
  load_translations(config).tap do |translations|
    result = translate_it(config, @base_locale.dup, translations, '')
    File.open(config[:yml], "wb") do |cf|
      cf.print YAML.dump(result)
    end

    # Report untranslated strings
    FileUtils.rm_f config[:untranslated_report]
    if !config[:missing_translations].empty?
      File.open(config[:untranslated_report], "wb", encoding: 'UTF-8') do |report|
        report.puts "Untranslated String ID"
        report.puts "======================"
        config[:missing_translations].each{|id| report.puts id}
      end
      puts "  Missing translations report: #{config[:untranslated_report]}"
    end
  end
end
hash_to_ids(h, prefix=nil) click to toggle source
# File lib/import_export.rb, line 199
def hash_to_ids(h, prefix=nil)
  h.each do |k,v|
    k = "#{prefix}.#{k}" if prefix
    case v
    when Hash
      hash_to_ids v, k
    else
      common_key = replace_id_locale(k)
      @valid_ids[common_key] = v
    end
  end
end
load_base_ids() click to toggle source
# File lib/import_export.rb, line 194
def load_base_ids
  @valid_ids = {}
  hash_to_ids(@base_locale.dup)
end
load_translations(config) click to toggle source
# File lib/import_export.rb, line 237
def load_translations(config)
  {}.tap do |translations|
    CSV.foreach(config[:csv], headers: true, encoding: 'UTF-8') do |row|
      id = row[0] # id = row["Key"]
      translation = row[3] # translation = row["Translated Version"]
      raise "Invalid translation ID found: #{id} - #{translation}" if @valid_ids[replace_id_locale(id)].nil?
      translations[id] = translation
    end

    # Populate keys for duplicated strings with common translation
    @cache.each do |keys|
      primary_key = keys.first
      foreign_key = replace_id_locale(primary_key, config[:code])
      raise "Whoa! No value for #{primary_key}" unless translations.has_key?(foreign_key)
      keys.select{|k| k != primary_key}.each do |dup_key|
        dup_key = replace_id_locale(dup_key, config[:code])
        translations[dup_key] = translations[foreign_key]
      end
    end
  end
end
replace_id_locale(id, replacement='') click to toggle source
# File lib/import_export.rb, line 212
def replace_id_locale(id, replacement='')
  replacement += '.' if !replacement.empty? && !replacement !~ /\.$/
  id.dup.sub(/^[a-zA-Z_-]+\./, replacement)
end
translate_it(config, input, translations, base_key) click to toggle source
# File lib/import_export.rb, line 259
def translate_it(config, input, translations, base_key)
  input.keys.each do |key|

    value = input[key]
    if base_key && !base_key.empty?
      full_key = "#{base_key}.#{key}"
    else
      full_key = key
    end

    case value
    when Hash
      translate_it(config, value, translations, full_key)
    else
      foreign_key = replace_id_locale(full_key, config[:code])
      translation = translations[foreign_key]
      if !translation || translation.empty?
        config[:missing_translations] << foreign_key
      end
      input[key] = translation
    end

  end

  input
end