Skip to content

Instantly share code, notes, and snippets.

@thermistor
Forked from ruuts/translator.rake
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thermistor/b9da7f419cf9b14dcb40 to your computer and use it in GitHub Desktop.
Save thermistor/b9da7f419cf9b14dcb40 to your computer and use it in GitHub Desktop.
namespace :translator do
desc "Export missing translations for a specific locale"
task :export_keys => :environment do
from = ENV['FROM']
to = ENV['TO']
if from.present? and to.present?
translator = Translator.new(
from: from.to_sym,
to: to.to_sym
)
missing = translator.export_keys
if missing.length > 0
filename = "translate_#{from}_to_#{to}.txt"
File.open(filename, 'w') do |file|
file.write missing
end
puts "Created export file: #{filename}"
else
puts "There are no missing translations from #{from} to #{to}"
end
else
puts "Please provide locale to translate for example:"
puts "rake translator:export_keys FROM=en TO=fr"
end
end
desc "Import missing translations for a specific locale"
task :import_keys => :environment do
if ENV['FROM'].present? and ENV['TO'].present? and ENV['FILE'].present?
translator = Translator.new(
from: ENV['FROM'].to_sym,
to: ENV['TO'].to_sym
)
file = File.open(ENV['FILE'])
translator.import_keys(file.read)
translator.write_locale_file
else
puts "Please provide the following arguments:"
puts "rake translator:import_keys FROM=en TO=fr FILE=en_to_fr.translate"
end
end
end
require 'yaml'
class Translator
def initialize(options = {})
@from = options[:from]
@to = options[:to]
@dir = options[:dir] || "config/locales"
end
def prepare_translations_for_missing_keys
I18n.with_locale(@from) do
result = {}
re = Regexp.new("^#{@to}\.")
find_missing_keys.each do |key|
result[key] = I18n.t(key.gsub(re, '')).to_s
end
result
end
end
def export_keys
prepare_translations_for_missing_keys.map do |key, value|
"[[[#{key}]]] #{value}"
end.join("\n")
end
def import_keys(import)
matches = import.scan %r{
\[\[\[ # key start brackets
([^\]]+) # key
\]\]\] # key end brackets
((.(?!\[\[\[))*) # value until brackets
}xm
@import = {}
matches.each do |match|
@import[match[0]] = match[1].to_s.lstrip
end
@import
end
def write_locale_file
new_translations = deflatten_keys(@import)
File.open(path(@to), 'w') do |file|
file.write new_translations.to_yaml
end
end
def find_missing_keys
translations_1 = translations(@from)
translations_2 = translations(@to)
keys_1 = translations_1.present? ? flatten_keys(translations_1) : []
keys_2 = translations_2.present? ? flatten_keys(translations_2) : []
(keys_1 - keys_2).map {|k| "#{@to}.#{k}" }
end
private
def translations(locale)
# I18n.backend.reload! if I18n.backend.initialized?
# I18n.backend.instance_variable_set(:@initialized, true)
# I18n.backend.load_translations(Dir[Rails.root.join('config', 'locales', '**', "*.{rb,yml}")])
I18n.backend.send(:init_translations)
all_translations = I18n.backend.send(:translations)
all_translations.fetch(locale.to_sym, {})
end
def path(locale)
File.expand_path("#{@dir}/#{locale}.yml")
end
def deflatten_keys(hash)
new_hash = {}
hash.each do |k,v|
new_hash.deep_merge!(
k.split('.').reverse.inject(v) {|a,n| { n => a } }
)
end
new_hash
end
def flatten_keys(hash, prefix="")
keys = []
hash.keys.each do |key|
if hash[key].is_a? Hash
current_prefix = prefix + "#{key}."
keys << flatten_keys(hash[key], current_prefix)
else
keys << "#{prefix}#{key}"
end
end
prefix == "" ? keys.flatten : keys
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment