From 8b6a3127a10aa49767608c1134352eb853aa35c5 Mon Sep 17 00:00:00 2001 From: Lee DeBoom Date: Tue, 10 Mar 2020 00:34:28 -0500 Subject: [PATCH] Add Yandex translator backend (#343) --- README.md | 22 +++++++ config/locales/en.yml | 7 +++ config/locales/ru.yml | 7 +++ i18n-tasks.gemspec | 1 + lib/i18n/tasks/configuration.rb | 1 + lib/i18n/tasks/translation.rb | 5 +- .../tasks/translators/yandex_translator.rb | 61 +++++++++++++++++++ 7 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 lib/i18n/tasks/translators/yandex_translator.rb diff --git a/README.md b/README.md index edd5037e..c83a7021 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,17 @@ $ i18n-tasks translate-missing --backend=deepl $ i18n-tasks translate-missing --backend=deepl --from=en fr nl ``` +### Yandex Translate missing keys + +Translate missing values with Yandex Translate ([more below on the API key](#yandex-translation-config)). + +```console +$ i18n-tasks translate-missing --backend=yandex + +# accepts from and locales options: +$ i18n-tasks translate-missing --from=en es fr +``` + ### Find usages See where the keys are used with `i18n-tasks find`: @@ -397,6 +408,17 @@ translation: deepl_api_key: ``` + +### Yandex Translate + +`i18n-tasks translate-missing` requires a Yandex API key, get it at [Yandex](https://tech.yandex.com/translate). + +```yaml +# config/i18n-tasks.yml +translation: + yandex_api_key: +``` + ## Interactive console `i18n-tasks irb` starts an IRB session in i18n-tasks context. Type `guide` for more information. diff --git a/config/locales/en.yml b/config/locales/en.yml index b5eb4c4a..5306c399 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -101,6 +101,13 @@ en: in config/i18n-tasks.yml. Get the key at https://code.google.com/apis/console. no_results: >- Google Translate returned no results. Make sure billing information is set at https://code.google.com/apis/console. + yandex_translate: + errors: + no_api_key: >- + Set Yandex API key via YANDEX_API_KEY environment variable or translation.yandex_api_key + in config/i18n-tasks.yml. Get the key at https://tech.yandex.com/translate. + no_results: >- + Yandex returned no results. health: no_keys_detected: No keys detected. Check data.read in config/i18n-tasks.yml. inconsistent_interpolations: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index b3d2f3d7..a2a52da8 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -101,6 +101,13 @@ ru: no_results: >- Google Translate не дал результатов. Убедитесь в том, что платежная информация добавлена в https://code.google.com/apis/console. + yandex_translate: + errors: + no_api_key: >- + Установить ключ API Яндекса с помощью переменной среды YANDEX_API_KEY или translation.yandex_api_key + в config / i18n-tasks.yml. Получите ключ по адресу https://tech.yandex.com/translate/. + no_results: >- + Яндекс не дал результатов. health: no_keys_detected: Ключи не обнаружены. Проверьте data.read в config/i18n-tasks.yml. inconsistent_interpolations: diff --git a/i18n-tasks.gemspec b/i18n-tasks.gemspec index 3b8c092d..c51adcd9 100644 --- a/i18n-tasks.gemspec +++ b/i18n-tasks.gemspec @@ -50,5 +50,6 @@ TEXT s.add_development_dependency 'rspec', '~> 3.3' s.add_development_dependency 'rubocop', '~> 0.53.0' s.add_development_dependency 'simplecov' + s.add_development_dependency 'yandex-translator' s.add_development_dependency 'yard' end diff --git a/lib/i18n/tasks/configuration.rb b/lib/i18n/tasks/configuration.rb index 590eeeb5..e3a11445 100644 --- a/lib/i18n/tasks/configuration.rb +++ b/lib/i18n/tasks/configuration.rb @@ -59,6 +59,7 @@ def translation_config conf = (config[:translation] || {}).with_indifferent_access conf[:google_translate_api_key] = ENV['GOOGLE_TRANSLATE_API_KEY'] if ENV.key?('GOOGLE_TRANSLATE_API_KEY') conf[:deepl_api_key] = ENV['DEEPL_AUTH_KEY'] if ENV.key?('DEEPL_AUTH_KEY') + conf[:yandex_api_key] = ENV['YANDEX_API_KEY'] if ENV.key?('YANDEX_API_KEY') conf end end diff --git a/lib/i18n/tasks/translation.rb b/lib/i18n/tasks/translation.rb index 0681d531..f0ffbf8c 100644 --- a/lib/i18n/tasks/translation.rb +++ b/lib/i18n/tasks/translation.rb @@ -2,12 +2,13 @@ require 'i18n/tasks/translators/deepl_translator.rb' require 'i18n/tasks/translators/google_translator.rb' +require 'i18n/tasks/translators/yandex_translator.rb' module I18n::Tasks module Translation # @param [I18n::Tasks::Tree::Siblings] forest to translate to the locales of its root nodes # @param [String] from locale - # @param [:deepl, :google] backend + # @param [:deepl, :google, :yandex] backend # @return [I18n::Tasks::Tree::Siblings] translated forest def translate_forest(forest, from:, backend: :google) case backend @@ -15,6 +16,8 @@ def translate_forest(forest, from:, backend: :google) Translators::DeeplTranslator.new(self).translate_forest(forest, from) when :google Translators::GoogleTranslator.new(self).translate_forest(forest, from) + when :yandex + Translators::YandexTranslator.new(self).translate_forest(forest, from) else fail CommandError, "invalid backend: #{backend}" end diff --git a/lib/i18n/tasks/translators/yandex_translator.rb b/lib/i18n/tasks/translators/yandex_translator.rb new file mode 100644 index 00000000..d4069324 --- /dev/null +++ b/lib/i18n/tasks/translators/yandex_translator.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'i18n/tasks/translators/base_translator' + +module I18n::Tasks::Translators + class YandexTranslator < BaseTranslator + def initialize(*) + begin + require 'yandex-translator' + rescue LoadError + raise ::I18n::Tasks::CommandError, "Add gem 'yandex-translator' to your Gemfile to use this command" + end + super + end + + protected + + def translate_values(list, **options) + list.map { |item| translator.translate(item, options) } + end + + def options_for_translate_values(from:, to:, **options) + options.merge( + from: to_yandex_compatible_locale(from), + to: to_yandex_compatible_locale(to) + ) + end + + def options_for_html + { format: 'html' } + end + + def options_for_plain + { format: 'plain' } + end + + def no_results_error_message + I18n.t('i18n_tasks.yandex_translate.errors.no_results') + end + + private + + # Convert 'es-ES' to 'es' + def to_yandex_compatible_locale(locale) + return locale unless locale.include?('-') + locale.split('-', 2).first + end + + def translator + @translator ||= Yandex::Translator.new(api_key) + end + + def api_key + @api_key ||= begin + key = @i18n_tasks.translation_config[:yandex_api_key] + fail ::I18n::Tasks::CommandError, I18n.t('i18n_tasks.yandex_translate.errors.no_api_key') if key.blank? + key + end + end + end +end