Skip to content

Instantly share code, notes, and snippets.

@jtsagata
Created January 5, 2010 17:41
Show Gist options
  • Save jtsagata/269547 to your computer and use it in GitHub Desktop.
Save jtsagata/269547 to your computer and use it in GitHub Desktop.
require 'htmlentities'
require 'i18n/backend/active_record'
module I18n
module Backend
require 'i18n/core_ext/object/meta_class'
# Just to enhance the I18n.
module JustALoader
include Metadata
include Cache
include Fallbacks
end
class ActiveRecord
class Translation
before_save :before_save_callback
named_scope :official, :conditions =>{:official => true}
def before_save_callback
I18n.cache_store.delete(I18n.backend.cache_key(self.locale.to_s,self.key.to_s))
end
end
end
class SuperStore < ActiveRecord
attr_accessor :file_store, :decoder
include InterpolationCompiler
include Pluralization
def initialize
super
self.file_store = Simple.new
self.decoder = HTMLEntities.new
end
def lookup(locale, key, scope = [], separator = nil)
return unless key
result= I18n.cache_store.fetch(cache_key(locale.to_s,key.to_s)) do
found_locale = code = engine = nil
I18n.fallbacks[locale].each do |fallback|
found_locale = fallback
engine = :file
code = file_store.send(:lookup,fallback,key)
break if !code.nil?
engine = :db
code = super(fallback,key)
raise(I18n::MissingTranslationData.new(locale, key, options)) if code.class == I18n::MissingTranslationData
break if !code.nil?
end
if engine == :db
end
if !code.nil?
code = code.dup
code.translation_metadata ={:locale => found_locale,:locale_request=> locale,:locale_engine => engine}
end
code
end
result
end
def translate(locale, key, options = {})
scope = options.values_at(:scope)
separator ||= I18n.default_separator
key = (Array(scope) + Array(key)).join(separator)
#TODO: Don't look at cache twice
code = lookup(locale,key,scope)
begin
result = super
rescue
end
if result.nil?
unless ActiveRecord::Translation.locale(locale).lookup(key).exists?
translation = ActiveRecord::Translation.create :locale => locale.to_s, :key => key
end
elsif code.translation_metadata[:locale] != code.translation_metadata[:locale_request]
unless ActiveRecord::Translation.locale(locale).lookup(key).exists?
value = google_translate(result,locale,code.translation_metadata[:locale])
translation = ActiveRecord::Translation.new :locale => locale.to_s, :key => key, :value=>value
interpolations = options.reject { |name, v| Base::RESERVED_KEYS.include?(name) }.keys
translation.interpolations = interpolations
translation.save
end
end
raise I18n::MissingTranslationData.new(locale, key, options) if result.nil?
result = result.dup
result.translation_metadata = code.translation_metadata
result
end
def google_translate( text, to, from='en' )
begin
new_text = text.dup # I hate frozen objects
new_text.gsub!("{{","[[_")
new_text.gsub!("}}","_]]")
base = 'http://ajax.googleapis.com/ajax/services/language/translate'
params = {:langpair => "#{from.to_s}|#{to.to_s}",:q => new_text,:v =>1.0}
query = params.map{ |k,v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&')
response = Net::HTTP.get_response( URI.parse( "#{base}?#{query}" ) )
json = JSON.parse( response.body )
if json['responseStatus'] == 200
result = json['responseData']['translatedText']
result.gsub!("[[_","{{")
result.gsub!("_]]","}}")
return self.decoder.decode(result)
end
rescue
end
nil
end
def cache_key(*args)
hash = RUBY_VERSION >= "1.8.7" ? args.hash : args.inspect
keys = ['i18n', I18n.cache_namespace, hash]
keys.compact.join('-')
end
end
end
end
I18n.load_path += Dir.glob(File.join(Rails.root.join('config', 'locales'),'**','*.{rb,yml}'))
I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
I18n.backend = I18n::Backend::SuperStore.new
I18n.default_locale = :"en"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment