Class: TranslationDiff::Providers::LibreTranslate
- Inherits:
-
HTTPProvider
- Object
- TranslationDiff::Provider
- HTTPProvider
- TranslationDiff::Providers::LibreTranslate
show all
- Defined in:
- lib/translation_diff/providers/libretranslate.rb
Overview
The only free, self-hosted provider here; base URL is required (everyone runs their own), API key is optional.
Constant Summary
collapse
- DEFAULT_FORMAT =
"html".freeze
- AUTO =
The API's own way of asking for detection: source is required, and "auto" means "work it out".
"auto".freeze
- LIBRETRANSLATE_HONOURS_NOTRANSLATE =
Observed 2026-09-09 via Docker: LibreTranslate's HTML format preserves markup but translates content anyway.
false
Constants inherited
from HTTPProvider
HTTPProvider::RETRY_STATUSES, HTTPProvider::TRANSPORT_FAILURES
Class Method Summary
collapse
Instance Method Summary
collapse
#connection, #headers, #translate
Class Method Details
.capabilities ⇒ Object
LibreTranslate publishes no per-request limits; these are this library's own conservative numbers.
12
13
14
15
16
17
18
|
# File 'lib/translation_diff/providers/libretranslate.rb', line 12
def self.capabilities
TranslationDiff::Capabilities.new(
max_request_size: 5_000, max_batch_size: 50, max_text_size: nil,
html: :format, notranslate: LIBRETRANSLATE_HONOURS_NOTRANSLATE,
detects_language: true, reports_billing: false
)
end
|
.configuration_options ⇒ Object
20
|
# File 'lib/translation_diff/providers/libretranslate.rb', line 20
def self.configuration_options = %i[libretranslate_api_key libretranslate_api_base]
|
.configuration_requirements ⇒ Object
21
|
# File 'lib/translation_diff/providers/libretranslate.rb', line 21
def self.configuration_requirements = %i[libretranslate_api_base]
|
Instance Method Details
#api_base ⇒ Object
23
|
# File 'lib/translation_diff/providers/libretranslate.rb', line 23
def api_base = config.libretranslate_api_base
|
#detect(text) ⇒ Object
47
48
49
50
51
52
|
# File 'lib/translation_diff/providers/libretranslate.rb', line 47
def detect(text)
payload = { q: text }
payload[:api_key] = config.libretranslate_api_key if config.libretranslate_api_key
post("detect", payload).body.dig(0, "language")&.downcase
end
|
#languages ⇒ Object
Each entry lists its own targets; a self-hosted instance answers for itself, which is the point.
55
56
57
58
59
60
|
# File 'lib/translation_diff/providers/libretranslate.rb', line 55
def languages
entries = Array(get("languages").body)
{ source: entries.map { |entry| entry["code"] },
target: entries.flat_map { |entry| Array(entry["targets"]) }.uniq }
end
|
#languages_endpoint ⇒ Object
62
|
# File 'lib/translation_diff/providers/libretranslate.rb', line 62
def languages_endpoint = "#{api_base}/languages"
|
#parse_translate_response(body, _headers, request) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
|
# File 'lib/translation_diff/providers/libretranslate.rb', line 34
def parse_translate_response(body, , request)
translated = body["translatedText"]
detected = body["detectedLanguage"]
detected = detected.first if detected.is_a?(Array)
TranslationDiff::Translation::Response.build(
request: request,
texts: translated.is_a?(Array) ? translated : [translated].compact,
detected_source: detected.is_a?(Hash) ? detected["language"]&.downcase : nil,
usage: TranslationDiff::Translation::Usage.new(characters: request.texts.sum(&:size))
)
end
|
#render_translate_payload(request) ⇒ Object
26
27
28
29
30
31
32
|
# File 'lib/translation_diff/providers/libretranslate.rb', line 26
def render_translate_payload(request)
{ format: DEFAULT_FORMAT }
.merge(request.options)
.merge(q: request.texts, target: language(request.to),
source: request.from.nil? ? AUTO : language(request.from))
.tap { |payload| payload[:api_key] = config.libretranslate_api_key if config.libretranslate_api_key }
end
|
#translate_url ⇒ Object
24
|
# File 'lib/translation_diff/providers/libretranslate.rb', line 24
def translate_url = "translate"
|