- Conect to remote translation service and translate array of strings - Create SentencesParser module with texts management methods: - Detect split position method: When the text requested to translate is too large, we need split it in smaller parts for we can translate. This method search first valid point (dot or whitespace) for split this text so then we can get an response without dividing the word in half.
82 lines
2.0 KiB
Ruby
82 lines
2.0 KiB
Ruby
require "translator-text"
|
|
include SentencesParser
|
|
|
|
class MicrosoftTranslateClient
|
|
CHARACTERS_LIMIT_PER_REQUEST = 5000
|
|
PREVENTING_TRANSLATION_KEY = "notranslate"
|
|
|
|
def initialize
|
|
api_key = Rails.application.secrets.microsoft_api_key
|
|
@client = TranslatorText::Client.new(api_key)
|
|
end
|
|
|
|
def call(fields_values, locale)
|
|
texts = prepare_texts(fields_values)
|
|
valid_locale = parse_locale(locale)
|
|
request_translation(texts, valid_locale)
|
|
end
|
|
|
|
def fragments_for(text)
|
|
return [text] if text.size <= CHARACTERS_LIMIT_PER_REQUEST
|
|
|
|
split_position = detect_split_position(text)
|
|
start_text = text[0..split_position]
|
|
end_text = text[split_position + 1 .. text.size]
|
|
|
|
fragments_for(start_text) + [end_text]
|
|
end
|
|
|
|
private
|
|
|
|
def request_translation(texts, locale)
|
|
response = []
|
|
split_response = false
|
|
|
|
if characters_count(texts) <= CHARACTERS_LIMIT_PER_REQUEST
|
|
response = @client.translate(texts, to: locale)
|
|
else
|
|
texts.each do |text|
|
|
response << translate_text(text, locale)
|
|
end
|
|
split_response = true
|
|
end
|
|
|
|
parse_response(response, split_response)
|
|
end
|
|
|
|
def translate_text(text, locale)
|
|
fragments_for(text).map do |fragment|
|
|
@client.translate([fragment], to: locale)
|
|
end.flatten
|
|
end
|
|
|
|
def parse_response(response, split_response)
|
|
response.map do |object|
|
|
if split_response
|
|
build_translation(object)
|
|
else
|
|
get_field_value(object)
|
|
end
|
|
end
|
|
end
|
|
|
|
def build_translation(objects)
|
|
objects.map { |object| get_field_value(object) }.join
|
|
end
|
|
|
|
def get_field_value(object)
|
|
text = object.translations[0].text
|
|
notranslate?(text) ? nil : text
|
|
end
|
|
|
|
def prepare_texts(texts)
|
|
texts.map { |text| text || PREVENTING_TRANSLATION_KEY }
|
|
#https://docs.microsoft.com/es-es/azure/cognitive-services/translator/prevent-translation
|
|
end
|
|
|
|
def notranslate?(text)
|
|
text.downcase == PREVENTING_TRANSLATION_KEY
|
|
end
|
|
|
|
end
|