Prototype translations for Gibberish with Google Language Tools, a mouse click, and 13 lines of code

Posted by face on January 23, 2008

translated pages with google

I wanted to prototype my Gibberish translations before we have an actual translator. I grabbed gibberish_translate and started copying and pasting from Google Language Tools.

After five minutes of this, I thought there has got to be a better way. I googled for an API to the Google tools, and though I found none, I did find a scraping Ruby API called rtranslate. So…

gem install googletranslate
Then I hacked the index method of translations_controller.rb from gibberish_translate. I added the following lines of code

  require 'rtranslate'
  def index
     # ...Mark's entire index method goes here unchanged
    if params[:filter] == "untranslated"
      count=0
      @paginated_keys.each do |key|  
        if ! @translated_messages[key]
          @translated_messages[key] = { 
          :to => Translate.t(@en_messages[key], Language::ENGLISH, session[:translation_locale] ),
          :from => @en_messages[key]
          }
        end
        break if (count += 1) == per_page
        sleep 1 # Let's be nice to google
      end
    end
  end
 # end of index from gibberish_translate's translations_controller.rb

And now Google does the work for me with the click of a mouse!

Note I did make some other changes to Mark’s code. There was a bug in translations_controller.rb in that it lost your current local when saving changes. To fix this I changed the set_translation_locale to use the session of there is no paramater:


  def set_translation_locale
    session[:translation_locale] = params[:translation_locale] if params[:translation_locale]
    session[:translation_locale] = Gibberish.languages.first if Gibberish.languages if ! session[:translation_locale]
  end

I also made some changes to gibberish_translate’s extractor.rb to handle Gibberish strings with default keys ("foo"[] is a valid Gibberish way of saying "foo"[:foo]):


    def message_pattern(start_token, end_token)
      /#{start_token}((?:[^#{end_token}](?:\\#{end_token})?)+)#{end_token}\[:*([a-z_]*)[,\]]/m
    end

    def add_messages(contents, start_token, end_token)
      contents.scan(message_pattern(start_token, end_token)).each do |text, key|
        key = text.tr('[  ]', '_').downcase if ( key == '' )
        add_message(key, remove_quotes(text, end_token))
      end
    end

The final tweaks I made was to make the find system call more portable (no -regex on OpenBSD) and also have it search for strings in my gibberish_rails plugin:


    def files_with_messages
      `find #{dirs_to_search.join(" ")} -type f '(' -name '*rb' -or -name '*.ml' ')'`.split.map(&:chomp)
    end

    def dirs_to_search
      %w(app config lib vendor/plugins/gibberish_rails).map { |dir| "#{RAILS_ROOT}/#{dir}" }
    end

Peace!

Portions of the above code Copyright© 2007 Peter Marklund


Digg! Delicious! Technorati Blinklist Furl Reddit
Comments

Leave a response

Comment

Hint: Comments now accept textile.