Class: Publication::MetadataTranslator
- Inherits:
-
Object
- Object
- Publication::MetadataTranslator
- Defined in:
- app/services/publication/metadata_translator.rb
Overview
Translates a publication's METADATA (the base name — the slug and display
name derive from it) into the target language, so a French variant is filed
under a French name instead of the English name with a locale suffix.
DeepL translates the PDF body; this covers what its document endpoint never
sees — the catalog record itself. A publication-specific glossary keeps brand
terms and product vocabulary stable ("towel warmer" → "chauffe-serviettes",
brand names untouched).
Non-fatal by design: any LLM failure returns nil (callers fall back to the
source-language name), so a metadata hiccup never sinks an otherwise good
document translation.
Constant Summary collapse
- GLOSSARY_DIR =
Rails.root.join('config/publication_translation').freeze
Class Method Summary collapse
-
.call(text, lang_out:, lang_in: 'en') ⇒ String?
The translated text, or nil when there is nothing to translate or the translation failed.
Class Method Details
.call(text, lang_out:, lang_in: 'en') ⇒ String?
Returns the translated text, or nil when there is nothing
to translate or the translation failed.
30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'app/services/publication/metadata_translator.rb', line 30 def call(text, lang_out:, lang_in: 'en') text = text.to_s.strip return nil if text.blank? || lang_out.to_s.blank? || lang_in.to_s == lang_out.to_s response = AiModelConstants.with_fallback(:translation) do |model_id| RubyLLM.chat(model: model_id).ask(prompt(text, lang_in:, lang_out:)) end response.content.to_s.strip.gsub(/\A["']+|["']+\z/, '').presence rescue StandardError => e Rails.logger.warn "[Publication::MetadataTranslator] #{lang_out} translation failed: #{e.}" nil end |