Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions app/jobs/regular/detect_translatable_language.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module ::Jobs
class DetectTranslatableLanguage < ::Jobs::Base
def execute(args)
return unless SiteSetting.translator_enabled

translatable = args[:type].constantize.find_by(id: args[:translatable_id])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we validate that args[:type] returns a string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair!

return if translatable.blank?
begin
translator = "DiscourseTranslator::#{SiteSetting.translator}".constantize
translator.detect(translatable)
rescue ::DiscourseTranslator::ProblemCheckedTranslationError
# problem-checked translation errors gracefully
end
end
end
end
36 changes: 0 additions & 36 deletions app/jobs/scheduled/detect_posts_language.rb

This file was deleted.

25 changes: 25 additions & 0 deletions lib/discourse_translator/automatic_translations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module DiscourseTranslator
class AutomaticTranslations
def inject(plugin)
plugin.on(:post_process_cooked) do |_, post|
if SiteSetting.automatic_translation_target_languages.present? && post.user_id > 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm missing some context on how auto-translation should work for system-type users like system (typically with negative user IDs), I'm assuming from these that they are deliberately exempt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for now, bot posts should not be translated. (so stuff like discobot PMs or AI bot responses should generally be avoided)

Jobs.enqueue(:translate_translatable, type: "Post", translatable_id: post.id)
end
end

plugin.on(:topic_created) do |topic|
if SiteSetting.automatic_translation_target_languages.present? && topic.user_id > 0
Jobs.enqueue(:translate_translatable, type: "Topic", translatable_id: topic.id)
end
end

plugin.on(:topic_edited) do |topic|
if SiteSetting.automatic_translation_target_languages.present? && topic.user_id > 0
Jobs.enqueue(:translate_translatable, type: "Topic", translatable_id: topic.id)
end
end
end
end
end
24 changes: 24 additions & 0 deletions lib/discourse_translator/dual_text_translation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

module DiscourseTranslator
class DualTextTranslation
def inject(plugin)
# in dual-text translations,
# we don't want to send the post for detection if automatic translation already happens,
# as automatic translations send content for language detection as a side effect of translating

plugin.on(:post_process_cooked) do |_, post|
if SiteSetting.automatic_translation_target_languages.nil? &&
Guardian.new.can_detect_language?(post) && post.user_id > 0
Jobs.enqueue(:detect_translatable_language, type: "Post", translatable_id: post.id)
end
end

plugin.on(:topic_created) do |topic|
if SiteSetting.automatic_translation_target_languages.nil? && topic.user_id > 0
Jobs.enqueue(:detect_translatable_language, type: "Topic", translatable_id: post.id)
end
end
end
end
end
42 changes: 42 additions & 0 deletions lib/discourse_translator/inline_translation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

module DiscourseTranslator
class InlineTranslation
def inject(plugin)
plugin.register_modifier(:basic_post_serializer_cooked) do |cooked, serializer|
if !SiteSetting.experimental_topic_translation ||
serializer.scope&.request&.params&.[]("show") == "original" ||
serializer.object.detected_locale == I18n.locale.to_s.gsub("_", "-")
cooked
else
serializer.object.translation_for(I18n.locale).presence
end
end

plugin.register_modifier(:topic_serializer_fancy_title) do |fancy_title, serializer|
if !SiteSetting.experimental_topic_translation ||
serializer.scope&.request&.params&.[]("show") == "original" ||
serializer.object.locale_matches?(I18n.locale)
fancy_title
else
serializer.object.translation_for(I18n.locale).presence&.then { |t| Topic.fancy_title(t) }
end
end

plugin.register_modifier(:topic_view_serializer_fancy_title) do |fancy_title, serializer|
if !SiteSetting.experimental_topic_translation ||
serializer.scope&.request&.params&.[]("show") == "original" ||
serializer.object.topic.locale_matches?(I18n.locale)
fancy_title
else
serializer
.object
.topic
.translation_for(I18n.locale)
.presence
&.then { |t| Topic.fancy_title(t) }
end
end
end
end
end
60 changes: 3 additions & 57 deletions plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,66 +32,12 @@ module ::DiscourseTranslator
TopicViewSerializer.prepend(DiscourseTranslator::TopicViewSerializerExtension)
end

on(:post_process_cooked) do |_, post|
if Guardian.new.can_detect_language?(post) && post.user_id > 0
Discourse.redis.sadd?(DiscourseTranslator::LANG_DETECT_NEEDED, post.id)
end
end

on(:post_process_cooked) do |_, post|
if SiteSetting.automatic_translation_target_languages.present? && post.user_id > 0
Jobs.enqueue(:translate_translatable, type: "Post", translatable_id: post.id)
end
end

on(:topic_created) do |topic|
if SiteSetting.automatic_translation_target_languages.present? && topic.user_id > 0
Jobs.enqueue(:translate_translatable, type: "Topic", translatable_id: topic.id)
end
end

on(:topic_edited) do |topic|
if SiteSetting.automatic_translation_target_languages.present? && topic.user_id > 0
Jobs.enqueue(:translate_translatable, type: "Topic", translatable_id: topic.id)
end
end

add_to_serializer :post, :can_translate do
scope.can_translate?(object)
end

register_modifier(:basic_post_serializer_cooked) do |cooked, serializer|
if !SiteSetting.experimental_topic_translation ||
serializer.scope&.request&.params&.[]("show") == "original" ||
serializer.object.detected_locale == I18n.locale.to_s.gsub("_", "-")
cooked
else
serializer.object.translation_for(I18n.locale).presence
end
end

register_modifier(:topic_serializer_fancy_title) do |fancy_title, serializer|
if !SiteSetting.experimental_topic_translation ||
serializer.scope&.request&.params&.[]("show") == "original" ||
serializer.object.locale_matches?(I18n.locale)
fancy_title
else
serializer.object.translation_for(I18n.locale).presence&.then { |t| Topic.fancy_title(t) }
end
end
DiscourseTranslator::DualTextTranslation.new.inject(self)
DiscourseTranslator::InlineTranslation.new.inject(self)

register_modifier(:topic_view_serializer_fancy_title) do |fancy_title, serializer|
if !SiteSetting.experimental_topic_translation ||
serializer.scope&.request&.params&.[]("show") == "original" ||
serializer.object.topic.locale_matches?(I18n.locale)
fancy_title
else
serializer
.object
.topic
.translation_for(I18n.locale)
.presence
&.then { |t| Topic.fancy_title(t) }
end
end
DiscourseTranslator::AutomaticTranslations.new.inject(self)
end
84 changes: 0 additions & 84 deletions spec/jobs/detect_posts_language_spec.rb

This file was deleted.

45 changes: 45 additions & 0 deletions spec/jobs/detect_translatable_language_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

require "aws-sdk-translate"

describe Jobs::DetectTranslatableLanguage do
fab!(:post)
fab!(:topic)
let!(:job) { Jobs::DetectTranslatableLanguage.new }

before do
SiteSetting.translator_enabled = true
SiteSetting.translator = "Amazon"
client = Aws::Translate::Client.new(stub_responses: true)
client.stub_responses(
:translate_text,
{ translated_text: "大丈夫", source_language_code: "en", target_language_code: "jp" },
)
Aws::Translate::Client.stubs(:new).returns(client)
end

it "updates detected locale" do
job.execute(type: "Post", translatable_id: post.id)
job.execute(type: "Topic", translatable_id: topic.id)

expect(post.detected_locale).not_to be_nil
expect(topic.detected_locale).not_to be_nil
end

it "does not update detected locale the translator is disabled" do
SiteSetting.translator_enabled = false

job.execute(type: "Post", translatable_id: post.id)
job.execute(type: "Topic", translatable_id: topic.id)

expect(post.detected_locale).to be_nil
expect(topic.detected_locale).to be_nil
end

it "skips content that no longer exist" do
non_existent_id = -1

expect { job.execute(type: "Post", translatable_id: non_existent_id) }.not_to raise_error
expect { job.execute(type: "Topic", translatable_id: non_existent_id) }.not_to raise_error
end
end
Loading