class Translatomatic::Provider::Microsoft

Interface to the Microsoft translation API @see www.microsoft.com/en-us/translator/translatorapi.aspx @see docs.microsofttranslator.com/text-translate.html

Constants

ARRAYS_NS
BASE_URL
LANGUAGES_URL
LIMITS_URL1
LIMITS_URL2
MAX_TRANSLATIONS
TRANSLATE_URL1

this endpoint returns one translation per source text

TRANSLATE_URL2
WEB_SERVICE_NS

Public Class Methods

new(options = {}) click to toggle source

Create a new Microsoft provider instance

Calls superclass method Translatomatic::Provider::Base::new
# File lib/translatomatic/provider/microsoft.rb, line 23
def initialize(options = {})
  super(options)
  @key = options[:microsoft_api_key] || ENV['MICROSOFT_API_KEY']
  raise t('provider.microsoft.key_required') if @key.nil?
end
supports_alternative_translations?() click to toggle source

(see Base.supports_alternative_translations?)

# File lib/translatomatic/provider/microsoft.rb, line 13
def self.supports_alternative_translations?
  true
end
supports_no_translate_html?() click to toggle source

(see Base.supports_no_translate_html?)

# File lib/translatomatic/provider/microsoft.rb, line 18
def self.supports_no_translate_html?
  true
end

Public Instance Methods

languages() click to toggle source

(see Base#languages)

# File lib/translatomatic/provider/microsoft.rb, line 30
def languages
  @languages ||= fetch_languages
end

Private Instance Methods

add_translations_from_response(response, texts, multiple) click to toggle source
# File lib/translatomatic/provider/microsoft.rb, line 77
def add_translations_from_response(response, texts, multiple)
  doc = Nokogiri::XML(response.body)
  if multiple
    add_translations_from_response_multiple(doc, texts)
  else
    results = doc.search('//xmlns:TranslatedText').collect(&:content)
    texts.zip(results).each do |original, tr|
      add_translations(original, tr)
    end
  end
end
add_translations_from_response_multiple(doc, texts) click to toggle source
# File lib/translatomatic/provider/microsoft.rb, line 89
def add_translations_from_response_multiple(doc, texts)
  # there should be one GetTranslationsResponse for each string
  responses = doc.search('//xmlns:GetTranslationsResponse')
  texts.zip(responses).each do |original, tr|
    results = tr.search('TranslatedText').collect(&:content)
    add_translations(original, results)
  end
end
build_body_xml(strings, from, to, multiple) click to toggle source
# File lib/translatomatic/provider/microsoft.rb, line 112
def build_body_xml(strings, from, to, multiple)
  root = xml_root(multiple) + 'Request'
  xml = Builder::XmlMarkup.new
  xml.tag!(root, 'xmlns:a' => ARRAYS_NS) do
    xml.AppId
    xml.From(from)
    build_options_xml(xml) if multiple
    build_texts_xml(xml, strings)
    xml.To(to)
    xml.MaxTranslations MAX_TRANSLATIONS if multiple
  end
end
build_options_xml(xml) click to toggle source
# File lib/translatomatic/provider/microsoft.rb, line 133
def build_options_xml(xml)
  xml.tag!('Options', 'xmlns:o' => WEB_SERVICE_NS) do
    xml.tag!('o:IncludeMultipleMTAlternatives', 'true')
  end
end
build_texts_xml(xml, strings) click to toggle source
# File lib/translatomatic/provider/microsoft.rb, line 125
def build_texts_xml(xml, strings)
  xml.Texts do
    strings.each do |string|
      xml.tag!('a:string', string)
    end
  end
end
context?(text) click to toggle source
# File lib/translatomatic/provider/microsoft.rb, line 139
def context?(text)
  text.is_a?(Translatomatic::Text) && text.context.present?
end
fetch_languages() click to toggle source
# File lib/translatomatic/provider/microsoft.rb, line 98
def fetch_languages
  # this request redirects to a html page
  headers = { 'Ocp-Apim-Subscription-Key' => @key }
  query = { 'appid' => '' }
  response = http_client.get(LANGUAGES_URL, query, headers: headers)
  log.debug("#{name} response: #{response.body}")
  doc = Nokogiri::XML(response.body)
  doc.search('//xmlns:string').collect(&:content)
end
fetch_translation_array(strings, from, to, multiple) click to toggle source

fetch translations for given strings

# File lib/translatomatic/provider/microsoft.rb, line 59
def fetch_translation_array(strings, from, to, multiple)
  limit = multiple ? LIMITS_URL2 : LIMITS_URL1
  batcher(strings, max_count: limit[0], max_length: limit[1])
    .each_batch do |texts|
    translate_texts(texts, from, to, multiple)
  end
end
perform_translate(strings, from, to) click to toggle source
# File lib/translatomatic/provider/microsoft.rb, line 48
def perform_translate(strings, from, to)
  # get multiple translations for strings with context, so we
  # can choose the best translation.
  strings_with_context = strings.select { |i| context?(i) }
  strings_without_context = strings.reject { |i| context?(i) }

  fetch_translation_array(strings_with_context, from, to, true)
  fetch_translation_array(strings_without_context, from, to, false)
end
translate_texts(texts, from, to, multiple) click to toggle source
# File lib/translatomatic/provider/microsoft.rb, line 67
def translate_texts(texts, from, to, multiple)
  url = multiple ? TRANSLATE_URL2 : TRANSLATE_URL1
  headers = { 'Ocp-Apim-Subscription-Key' => @key }
  body = build_body_xml(texts, from, to, multiple)
  response = http_client.post(url, body,
                              headers: headers,
                              content_type: 'application/xml')
  add_translations_from_response(response, texts, multiple)
end
xml_root(multiple) click to toggle source
# File lib/translatomatic/provider/microsoft.rb, line 108
def xml_root(multiple)
  multiple ? 'GetTranslationsArray' : 'TranslateArray'
end