Class: TranslationDiff::Provider

Inherits:
Object
  • Object
show all
Defined in:
lib/translation_diff/provider.rb

Overview

Connects this library to one translation service; knows nothing about HTTP itself -- that's HTTPProvider.

Constant Summary collapse

DEFAULT_CAPABILITIES =

A subclass that forgets to declare capabilities under-promises, not over-promises: smaller batches, not silent risk.

TranslationDiff::Capabilities.new(
  max_request_size: 1_000, max_batch_size: 1, max_text_size: nil,
  html: :none, notranslate: false, detects_language: false, reports_billing: false
).freeze
BARE_LANGUAGE_CODE =

A bare alphabetic code is cased the way the vendor documents; anything with a subtag is left alone.

/\A[A-Za-z]{2,3}\z/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Provider

Returns a new instance of Provider.



17
18
19
20
# File 'lib/translation_diff/provider.rb', line 17

def initialize(config)
  @config = config
  ensure_configured!
end

Instance Attribute Details

#config ⇒ Object (readonly)

Returns the value of attribute config.



15
16
17
# File 'lib/translation_diff/provider.rb', line 15

def config
  @config
end

#name ⇒ Object

Stamped by the registry at build time. See #cache_key.



13
14
15
# File 'lib/translation_diff/provider.rb', line 13

def name
  @name
end

Class Method Details

.build(config) ⇒ Object



78
# File 'lib/translation_diff/provider.rb', line 78

def build(config) = new(config)

.capabilities ⇒ Object



76
# File 'lib/translation_diff/provider.rb', line 76

def capabilities = DEFAULT_CAPABILITIES

.configuration_options ⇒ Object



65
# File 'lib/translation_diff/provider.rb', line 65

def configuration_options = []

.configuration_requirements ⇒ Object

Checked once, at build time, so a caller learns what to set before a vendor's own exception does.



74
# File 'lib/translation_diff/provider.rb', line 74

def configuration_requirements = []

.language_case ⇒ Object

The casing this vendor documents for a bare code. DeepL upcases; everyone else takes lower case.



63
# File 'lib/translation_diff/provider.rb', line 63

def language_case = :downcase

.sensitive_options ⇒ Object

Overridable: a provider whose credential is named unusually says so rather than leaking it.



68
69
70
71
# File 'lib/translation_diff/provider.rb', line 68

def sensitive_options
  configuration_options.flat_map { |o| o.is_a?(Hash) ? o.keys : [o] }
                       .select { |key| TranslationDiff::Redaction.sensitive?(key) }
end

Instance Method Details

#billed_characters(reported) ⇒ Object

nil means the provider reported no billing at all; 0 means it reported zero. Both are claims.



32
33
34
35
# File 'lib/translation_diff/provider.rb', line 32

def billed_characters(reported)
  values = reported.compact
  values.empty? ? nil : values.sum
end

#cache_key ⇒ Object

Raising when never stamped, rather than falling back to "", is deliberate: "" would merge namespaces silently.



52
53
54
55
56
57
58
59
# File 'lib/translation_diff/provider.rb', line 52

def cache_key
  return name.to_s unless name.nil?

  raise TranslationDiff::Error,
        "#{self.class} has no cache key: it was instantiated directly instead of being " \
        "built through the registry. Build it through TranslationDiff::Providers.build, " \
        "or give #{self.class} its own #cache_key."
end

#detect(_text) ⇒ Object

Only called when capabilities.detects_language?.

Raises:

  • (NotImplementedError)


43
# File 'lib/translation_diff/provider.rb', line 43

def detect(_text) = raise NotImplementedError, "#{self.class} must implement #detect"

#inspect ⇒ Object

Never the default: a provider holds the configuration, so the default renders every key it holds.



38
# File 'lib/translation_diff/provider.rb', line 38

def inspect = "#<#{self.class.name} name=#{name.inspect} config=#{config.inspect}>"

#language(value) ⇒ Object

Callers write whichever casing their old configuration used; the vendor gets the one it documents.



23
24
25
26
27
28
29
# File 'lib/translation_diff/provider.rb', line 23

def language(value)
  code = value.to_s
  return nil if code.empty?
  return code unless code.match?(BARE_LANGUAGE_CODE)

  self.class.language_case == :upcase ? code.upcase : code.downcase
end

#languages ⇒ Object

Only rake languages:refresh calls this; a provider that cannot answer is skipped, not failed.

Raises:

  • (NotImplementedError)


46
# File 'lib/translation_diff/provider.rb', line 46

def languages = raise NotImplementedError, "#{self.class} cannot fetch its languages"

#languages_endpoint ⇒ Object

The full URL #languages fetches; a provider whose fetch has more than one shape narrows this further.



49
# File 'lib/translation_diff/provider.rb', line 49

def languages_endpoint = respond_to?(:api_base) ? api_base.to_s : ""

#translate(_request) ⇒ Object

Raises:

  • (NotImplementedError)


40
# File 'lib/translation_diff/provider.rb', line 40

def translate(_request) = raise NotImplementedError, "#{self.class} must implement #translate"