diff --git a/app/services/discourse_translator/amazon.rb b/app/services/discourse_translator/amazon.rb index 3f3f3d95..98252a1a 100644 --- a/app/services/discourse_translator/amazon.rb +++ b/app/services/discourse_translator/amazon.rb @@ -108,40 +108,36 @@ def self.access_token_key end def self.detect!(topic_or_post) - save_detected_locale(topic_or_post) do - begin - client.translate_text( - { - text: truncate(text_for_detection(topic_or_post)), - source_language_code: "auto", - target_language_code: SUPPORTED_LANG_MAPPING[I18n.locale], - }, - )&.source_language_code - rescue Aws::Errors::MissingCredentialsError - raise I18n.t("translator.amazon.invalid_credentials") - end + begin + client.translate_text( + { + text: truncate(text_for_detection(topic_or_post)), + source_language_code: "auto", + target_language_code: SUPPORTED_LANG_MAPPING[I18n.locale], + }, + )&.source_language_code + rescue Aws::Errors::MissingCredentialsError + raise I18n.t("translator.amazon.invalid_credentials") end end def self.translate!(translatable, target_locale_sym = I18n.locale) detected_lang = detect(translatable) - save_translation(translatable, target_locale_sym) do - begin - client.translate_text( - { - text: truncate(text_for_translation(translatable)), - source_language_code: "auto", - target_language_code: SUPPORTED_LANG_MAPPING[target_locale_sym], - }, - ) - rescue Aws::Translate::Errors::UnsupportedLanguagePairException - raise I18n.t( - "translator.failed", - source_locale: detected_lang, - target_locale: target_locale_sym, - ) - end + begin + client.translate_text( + { + text: truncate(text_for_translation(translatable)), + source_language_code: "auto", + target_language_code: SUPPORTED_LANG_MAPPING[target_locale_sym], + }, + ) + rescue Aws::Translate::Errors::UnsupportedLanguagePairException + raise I18n.t( + "translator.failed", + source_locale: detected_lang, + target_locale: target_locale_sym, + ) end end diff --git a/app/services/discourse_translator/base.rb b/app/services/discourse_translator/base.rb index 2d0713c5..eac1d435 100644 --- a/app/services/discourse_translator/base.rb +++ b/app/services/discourse_translator/base.rb @@ -33,7 +33,7 @@ def self.translate(translatable, target_locale_sym = I18n.locale) detected_lang = detect(translatable) if translatable.locale_matches?(target_locale_sym) - return detected_lang, get_text(translatable) + return detected_lang, get_untranslated(translatable) end translation = translatable.translation_for(target_locale_sym) @@ -48,12 +48,18 @@ def self.translate(translatable, target_locale_sym = I18n.locale) ), ) end - [detected_lang, translate!(translatable, target_locale_sym)] + + translated = translate!(translatable, target_locale_sym) + save_translation(translatable, target_locale_sym) { translated } + [detected_lang, translated] end - # Subclasses must implement this method to translate the text of a post or topic - # then use the save_translation method to store the translated text. + # Subclasses must implement this method to translate the text of a + # post or topic and return only the translated text. + # Subclasses should use text_for_translation # @param translatable [Post|Topic] + # @param target_locale_sym [Symbol] + # @return [String] def self.translate!(translatable, target_locale_sym = I18n.locale) raise "Not Implemented" end @@ -63,13 +69,16 @@ def self.translate!(translatable, target_locale_sym = I18n.locale) # @param translatable [Post|Topic] def self.detect(translatable) return if text_for_detection(translatable).blank? - get_detected_locale(translatable) || detect!(translatable) + get_detected_locale(translatable) || + save_detected_locale(translatable) { detect!(translatable) } end # Subclasses must implement this method to detect the text of a post or topic - # then use the save_detected_locale method to store the detected locale. + # and return only the detected locale. + # Subclasses should use text_for_detection # @param translatable [Post|Topic] - def self.detect!(post) + # @return [String] + def self.detect!(translatable) raise "Not Implemented" end @@ -100,15 +109,6 @@ def self.save_detected_locale(translatable) detected_locale end - def self.get_text(translatable) - case translatable.class.name - when "Post" - translatable.cooked - when "Topic" - translatable.title - end - end - def self.language_supported?(detected_lang) raise NotImplementedError unless self.const_defined?(:SUPPORTED_LANG_MAPPING) supported_lang = const_get(:SUPPORTED_LANG_MAPPING) @@ -129,11 +129,24 @@ def self.strip_tags_for_detection(detection_text) end def self.text_for_detection(translatable) - strip_tags_for_detection(get_text(translatable)).truncate(DETECTION_CHAR_LIMIT, omission: nil) + strip_tags_for_detection(get_untranslated(translatable)).truncate( + DETECTION_CHAR_LIMIT, + omission: nil, + ) end def self.text_for_translation(translatable) - get_text(translatable).truncate(SiteSetting.max_characters_per_translation, omission: nil) + max_char = SiteSetting.max_characters_per_translation + get_untranslated(translatable).truncate(max_char, omission: nil) + end + + def self.get_untranslated(translatable) + case translatable.class.name + when "Post" + translatable.cooked + when "Topic" + translatable.title + end end end end diff --git a/app/services/discourse_translator/discourse_ai.rb b/app/services/discourse_translator/discourse_ai.rb index f99015a6..a61741f8 100644 --- a/app/services/discourse_translator/discourse_ai.rb +++ b/app/services/discourse_translator/discourse_ai.rb @@ -12,21 +12,28 @@ def self.language_supported?(detected_lang) end def self.detect!(topic_or_post) - return unless required_settings_enabled - - save_detected_locale(topic_or_post) do - ::DiscourseAi::LanguageDetector.new(text_for_detection(topic_or_post)).detect + unless required_settings_enabled + raise TranslatorError.new( + I18n.t( + "translator.discourse_ai.ai_helper_required", + { base_url: Discourse.base_url }, + ), + ) end + + ::DiscourseAi::LanguageDetector.new(text_for_detection(topic_or_post)).detect end def self.translate!(translatable, target_locale_sym = I18n.locale) - return unless required_settings_enabled - save_translation(translatable, target_locale_sym) do - ::DiscourseAi::Translator.new( - text_for_translation(translatable), - target_locale_sym, - ).translate + unless required_settings_enabled + raise TranslatorError.new( + I18n.t( + "translator.discourse_ai.ai_helper_required", + { base_url: Discourse.base_url }, + ), + ) end + ::DiscourseAi::Translator.new(text_for_translation(translatable), target_locale_sym).translate end private diff --git a/app/services/discourse_translator/google.rb b/app/services/discourse_translator/google.rb index 19f2ad01..e6110abe 100644 --- a/app/services/discourse_translator/google.rb +++ b/app/services/discourse_translator/google.rb @@ -75,13 +75,11 @@ def self.access_token end def self.detect!(topic_or_post) - save_detected_locale(topic_or_post) do - result(DETECT_URI, q: text_for_detection(topic_or_post))["detections"][0].max do |a, b| - a.confidence <=> b.confidence - end[ - "language" - ] - end + result(DETECT_URI, q: text_for_detection(topic_or_post))["detections"][0].max do |a, b| + a.confidence <=> b.confidence + end[ + "language" + ] end def self.translate_supported?(source, target) @@ -91,16 +89,14 @@ def self.translate_supported?(source, target) def self.translate!(translatable, target_locale_sym = I18n.locale) detected_locale = detect(translatable) - save_translation(translatable, target_locale_sym) do - res = - result( - TRANSLATE_URI, - q: text_for_translation(translatable), - source: detected_locale, - target: SUPPORTED_LANG_MAPPING[target_locale_sym], - ) - res["translations"][0]["translatedText"] - end + res = + result( + TRANSLATE_URI, + q: text_for_translation(translatable), + source: detected_locale, + target: SUPPORTED_LANG_MAPPING[target_locale_sym], + ) + res["translations"][0]["translatedText"] end def self.result(url, body) diff --git a/app/services/discourse_translator/libre_translate.rb b/app/services/discourse_translator/libre_translate.rb index 73e53c87..24eda2d4 100644 --- a/app/services/discourse_translator/libre_translate.rb +++ b/app/services/discourse_translator/libre_translate.rb @@ -79,14 +79,12 @@ def self.access_token end def self.detect!(topic_or_post) - save_detected_locale(topic_or_post) do - res = - result( - detect_uri, - q: ActionController::Base.helpers.strip_tags(text_for_detection(topic_or_post)), - ) - !res.empty? ? res[0]["language"] : "en" - end + res = + result( + detect_uri, + q: ActionController::Base.helpers.strip_tags(text_for_detection(topic_or_post)), + ) + !res.empty? ? res[0]["language"] : "en" end def self.translate_supported?(source, target) @@ -98,17 +96,15 @@ def self.translate_supported?(source, target) def self.translate!(translatable, target_locale_sym = I18n.locale) detected_lang = detect(translatable) - save_translation(translatable, target_locale_sym) do - res = - result( - translate_uri, - q: text_for_translation(translatable), - source: detected_lang, - target: SUPPORTED_LANG_MAPPING[target_locale_sym], - format: "html", - ) - res["translatedText"] - end + res = + result( + translate_uri, + q: text_for_translation(translatable), + source: detected_lang, + target: SUPPORTED_LANG_MAPPING[target_locale_sym], + format: "html", + ) + res["translatedText"] end def self.get(url) diff --git a/app/services/discourse_translator/microsoft.rb b/app/services/discourse_translator/microsoft.rb index 2f75f2a9..8148b221 100644 --- a/app/services/discourse_translator/microsoft.rb +++ b/app/services/discourse_translator/microsoft.rb @@ -149,12 +149,10 @@ def self.access_token_key end def self.detect!(topic_or_post) - save_detected_locale(topic_or_post) do - body = [{ "Text" => text_for_detection(topic_or_post) }].to_json - uri = URI(detect_endpoint) - uri.query = URI.encode_www_form(self.default_query) - result(uri.to_s, body, default_headers).first["language"] - end + body = [{ "Text" => text_for_detection(topic_or_post) }].to_json + uri = URI(detect_endpoint) + uri.query = URI.encode_www_form(self.default_query) + result(uri.to_s, body, default_headers).first["language"] end def self.translate!(translatable, target_locale_sym = I18n.locale) @@ -166,17 +164,12 @@ def self.translate!(translatable, target_locale_sym = I18n.locale) locale = SUPPORTED_LANG_MAPPING[target_locale_sym] || (raise I18n.t("translator.not_supported")) - save_translation(translatable, target_locale_sym) do - query = default_query.merge("from" => detected_lang, "to" => locale, "textType" => "html") - - body = [{ "Text" => text_for_translation(translatable) }].to_json - - uri = URI(translate_endpoint) - uri.query = URI.encode_www_form(query) - - response_body = result(uri.to_s, body, default_headers) - response_body.first["translations"].first["text"] - end + query = default_query.merge("from" => detected_lang, "to" => locale, "textType" => "html") + body = [{ "Text" => text_for_translation(translatable) }].to_json + uri = URI(translate_endpoint) + uri.query = URI.encode_www_form(query) + response_body = result(uri.to_s, body, default_headers) + response_body.first["translations"].first["text"] end def self.translate_supported?(detected_lang, target_lang) diff --git a/app/services/discourse_translator/yandex.rb b/app/services/discourse_translator/yandex.rb index 7cf7d650..f12efc0f 100644 --- a/app/services/discourse_translator/yandex.rb +++ b/app/services/discourse_translator/yandex.rb @@ -124,12 +124,10 @@ def self.access_token end def self.detect!(topic_or_post) - save_detected_locale(topic_or_post) do - query = default_query.merge("text" => text_for_detection(topic_or_post)) - uri = URI(DETECT_URI) - uri.query = URI.encode_www_form(query) - result(uri.to_s, "", default_headers)["lang"] - end + query = default_query.merge("text" => text_for_detection(topic_or_post)) + uri = URI(DETECT_URI) + uri.query = URI.encode_www_form(query) + result(uri.to_s, "", default_headers)["lang"] end def self.translate!(translatable, target_locale_sym = I18n.locale) @@ -137,20 +135,18 @@ def self.translate!(translatable, target_locale_sym = I18n.locale) locale = SUPPORTED_LANG_MAPPING[target_locale_sym] || (raise I18n.t("translator.not_supported")) - save_translation(translatable, target_locale_sym) do - query = - default_query.merge( - "lang" => "#{detected_lang}-#{locale}", - "text" => text_for_translation(translatable), - "format" => "html", - ) + query = + default_query.merge( + "lang" => "#{detected_lang}-#{locale}", + "text" => text_for_translation(translatable), + "format" => "html", + ) - uri = URI(TRANSLATE_URI) - uri.query = URI.encode_www_form(query) + uri = URI(TRANSLATE_URI) + uri.query = URI.encode_www_form(query) - response_body = result(uri.to_s, "", default_headers) - response_body["text"][0] - end + response_body = result(uri.to_s, "", default_headers) + response_body["text"][0] end def self.translate_supported?(detected_lang, target_lang) diff --git a/spec/services/discourse_ai_spec.rb b/spec/services/discourse_ai_spec.rb index dbf8d428..ba631ed7 100644 --- a/spec/services/discourse_ai_spec.rb +++ b/spec/services/discourse_ai_spec.rb @@ -27,13 +27,11 @@ end describe ".detect!" do - it "stores the detected language" do + it "returns the detected language" do locale = "de" DiscourseAi::Completions::Llm.with_prepared_responses(["de"]) do - DiscourseTranslator::DiscourseAi.detect!(post) + expect(DiscourseTranslator::DiscourseAi.detect!(post)).to eq locale end - - expect(post.detected_locale).to eq locale end end