singleton-client-test 0.7.7.5 → 0.7.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/sgtn-client/api/translation.rb +30 -47
- data/lib/sgtn-client/common/data.rb +1 -1
- data/lib/sgtn-client/core/config.rb +4 -2
- data/lib/sgtn-client/fallbacks.rb +38 -0
- data/lib/sgtn-client/loader/cache.rb +4 -4
- data/lib/sgtn-client/loader/server.rb +18 -22
- data/lib/sgtn-client/sgtn-client.rb +9 -0
- data/lib/sgtn-client/util/locale-util.rb +3 -2
- data/lib/singleton-client.rb +16 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71f20276ef709f5a183ab1e6572f171bfe9e5cdb0d0f09decea0fdb2e3aa2e88
|
4
|
+
data.tar.gz: 1eeebcc0cc3a964c90a00523fdda8aae09d3dc69ddc51af658c6218eb8e97c05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd7cd9a1b977ddfd9110758b997c26bda3d8f2507f95036c87db24e130b7249f9c57871ce7f46c45827c810f0c7dd991b36dde656d3ce8a809e9ef4792554a65
|
7
|
+
data.tar.gz: 1d8c12a9f7dc6c65ebddcdf1eef50907cd8838a38a0c1a4c98c7001b4b9c77c55c5486d109fc7d9aca01c2c85c99e658ab381e8f2994e7818c73eb3d2a220295
|
@@ -39,63 +39,57 @@ module SgtnClient
|
|
39
39
|
get_translations(component, locale)
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
42
|
+
def get_translation!(key, component, locale)
|
43
|
+
[get_bundle!(component, locale)[key], locale]
|
44
|
+
end
|
45
|
+
|
46
|
+
def translate(key, component, locale = nil, **kwargs, &block)
|
47
|
+
translate!(key, component, locale, **kwargs, &block)
|
48
|
+
rescue StandardError => e
|
49
|
+
SgtnClient.logger.debug { "[#{method(__callee__).owner}.#{__callee__}] {#{key}, #{component}, #{locale}}. #{e}" }
|
50
|
+
key
|
51
|
+
end
|
52
|
+
alias t translate
|
53
|
+
|
54
|
+
# raise error when translation is not found
|
55
|
+
def translate!(key, component, locale = nil, **kwargs, &block)
|
43
56
|
SgtnClient.logger.debug { "[#{method(__callee__).owner}.#{__callee__}] key: #{key}, component: #{component}, locale: #{locale}, args: #{kwargs}" }
|
44
57
|
|
45
58
|
begin
|
46
|
-
best_match_locale = LocaleUtil.get_best_locale(locale ||
|
47
|
-
|
48
|
-
result = messages&.fetch(key, nil)
|
59
|
+
best_match_locale = LocaleUtil.get_best_locale(locale || SgtnClient.locale, component)
|
60
|
+
result, actual_locale = get_translation!(key, component, best_match_locale)
|
49
61
|
rescue StandardError => e
|
50
|
-
|
51
|
-
result = nil
|
62
|
+
raise e if block.nil?
|
52
63
|
end
|
53
|
-
|
54
64
|
if result.nil?
|
55
|
-
|
65
|
+
raise SingletonError, 'translation is missing.' if block.nil?
|
56
66
|
|
57
|
-
result =
|
67
|
+
result = block.call
|
58
68
|
return if result.nil?
|
59
69
|
end
|
60
70
|
|
61
|
-
|
62
|
-
result
|
63
|
-
else
|
64
|
-
result.localize(actual_locale) % kwargs
|
65
|
-
end
|
71
|
+
kwargs.empty? ? result : result.localize(actual_locale) % kwargs
|
66
72
|
end
|
67
|
-
alias t translate
|
73
|
+
alias t! translate!
|
68
74
|
|
69
75
|
def get_translations(component, locale = nil)
|
70
|
-
|
71
|
-
|
72
|
-
best_match_locale = LocaleUtil.get_best_locale(locale || self.locale, component)
|
73
|
-
messages, actual_locale = get_bundle_with_fallback(component, best_match_locale)
|
74
|
-
|
75
|
-
{ 'component' => component, 'locale' => actual_locale, 'messages' => messages } if messages
|
76
|
+
get_translations!(component, locale)
|
76
77
|
rescue StandardError => e
|
77
|
-
SgtnClient.logger.error "[#{method(__callee__).owner}.#{__callee__}]
|
78
|
+
SgtnClient.logger.error "[#{method(__callee__).owner}.#{__callee__}] {#{component}, #{locale}}. #{e}"
|
78
79
|
nil
|
79
80
|
end
|
80
81
|
|
81
|
-
def locale
|
82
|
-
|
83
|
-
|
82
|
+
def get_translations!(component, locale = nil)
|
83
|
+
SgtnClient.logger.debug { "[#{method(__callee__).owner}.#{__callee__}] component: #{component}, locale: #{locale}" }
|
84
|
+
|
85
|
+
best_match_locale = LocaleUtil.get_best_locale(locale || SgtnClient.locale, component)
|
86
|
+
messages = get_bundle!(component, best_match_locale)
|
84
87
|
|
85
|
-
|
86
|
-
RequestStore.store[:locale] = value
|
88
|
+
{ 'component' => component, 'locale' => best_match_locale, 'messages' => messages } if messages
|
87
89
|
end
|
88
90
|
|
89
91
|
private
|
90
92
|
|
91
|
-
def get_bundle(component, locale)
|
92
|
-
get_bundle!(component, locale)
|
93
|
-
rescue StandardError => e
|
94
|
-
SgtnClient.logger.error "[#{method(__callee__).owner}.#{__callee__}] failed to get a bundle. component: #{component}, locale: #{locale}"
|
95
|
-
SgtnClient.logger.error e
|
96
|
-
nil
|
97
|
-
end
|
98
|
-
|
99
93
|
def get_bundle!(component, locale)
|
100
94
|
SgtnClient.config.loader.get_bundle(component, locale)
|
101
95
|
rescue StandardError
|
@@ -106,20 +100,9 @@ module SgtnClient
|
|
106
100
|
SgtnClient.config.notify_observers(:available_locales, component)
|
107
101
|
raise
|
108
102
|
end
|
109
|
-
|
110
|
-
def get_bundle_with_fallback(component, locale)
|
111
|
-
messages = get_bundle(component, locale)
|
112
|
-
return messages, locale if messages
|
113
|
-
|
114
|
-
LocaleUtil.locale_fallbacks.each do |l|
|
115
|
-
next if l == locale
|
116
|
-
|
117
|
-
messages = get_bundle(component, l)
|
118
|
-
return messages, l if messages
|
119
|
-
end
|
120
|
-
end
|
121
103
|
end
|
122
104
|
|
123
105
|
extend Implementation
|
106
|
+
extend Fallbacks
|
124
107
|
end
|
125
108
|
end
|
@@ -18,8 +18,10 @@ module SgtnClient
|
|
18
18
|
def logger
|
19
19
|
@logger ||= if log_file
|
20
20
|
puts "create log file: '#{log_file}', level: #{log_level}"
|
21
|
-
require '
|
22
|
-
|
21
|
+
require 'logging'
|
22
|
+
logger = Logging.logger(log_file, 4, 1_048_576)
|
23
|
+
logger.level = log_level
|
24
|
+
logger
|
23
25
|
else
|
24
26
|
require 'logger'
|
25
27
|
Logger.new(STDOUT, level: log_level || Logger::INFO)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
|
+
|
4
|
+
module SgtnClient
|
5
|
+
module Fallbacks # :nodoc:
|
6
|
+
def get_translation!(key, component, locale)
|
7
|
+
error = nil
|
8
|
+
localechain(locale) do |l|
|
9
|
+
return super(key, component, l)
|
10
|
+
rescue StandardError => e
|
11
|
+
error = e
|
12
|
+
end
|
13
|
+
raise error if error
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_translations!(component, locale = nil)
|
17
|
+
error = nil
|
18
|
+
localechain(locale) do |l|
|
19
|
+
result = super(component, l)
|
20
|
+
return result if result
|
21
|
+
rescue StandardError => e
|
22
|
+
error = e
|
23
|
+
end
|
24
|
+
raise error if error
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def localechain(locale)
|
30
|
+
yield locale
|
31
|
+
LocaleUtil.locale_fallbacks.each do |l|
|
32
|
+
next if l == locale
|
33
|
+
|
34
|
+
yield l
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -15,7 +15,7 @@ module SgtnClient
|
|
15
15
|
|
16
16
|
# get from cache, return expired data immediately
|
17
17
|
def get_bundle(component, locale)
|
18
|
-
SgtnClient.logger.debug { "[#{
|
18
|
+
SgtnClient.logger.debug { "[#{__FILE__}][#{__callee__}] component=#{component}, locale=#{locale}" }
|
19
19
|
|
20
20
|
result = @cache_hash[Common::BundleID.new(component, locale)] || load_bundle(component, locale)
|
21
21
|
ensure
|
@@ -23,7 +23,7 @@ module SgtnClient
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def available_bundles
|
26
|
-
SgtnClient.logger.debug { "[#{
|
26
|
+
SgtnClient.logger.debug { "[#{__FILE__}][#{__callee__}]" }
|
27
27
|
|
28
28
|
result = @cache_hash[CONSTS::AVAILABLE_BUNDLES_KEY] || super
|
29
29
|
ensure
|
@@ -33,13 +33,13 @@ module SgtnClient
|
|
33
33
|
|
34
34
|
module CacheFiller # :nodoc:
|
35
35
|
def load_bundle(component, locale)
|
36
|
-
SgtnClient.logger.debug { "[#{
|
36
|
+
SgtnClient.logger.debug { "[#{__FILE__}][#{__callee__}] CacheFiller, component=#{component}, locale=#{locale}" }
|
37
37
|
|
38
38
|
@cache_hash[Common::BundleID.new(component, locale)] = Common::BundleData.new(super)
|
39
39
|
end
|
40
40
|
|
41
41
|
def available_bundles
|
42
|
-
SgtnClient.logger.debug { "[#{
|
42
|
+
SgtnClient.logger.debug { "[#{__FILE__}][#{__callee__}] CacheFiller" }
|
43
43
|
|
44
44
|
item = super
|
45
45
|
old_item = @cache_hash[CONSTS::AVAILABLE_BUNDLES_KEY]
|
@@ -9,27 +9,34 @@ require 'set'
|
|
9
9
|
|
10
10
|
module SgtnClient
|
11
11
|
module TranslationLoader
|
12
|
-
class SgtnServer
|
12
|
+
class SgtnServer # :nodoc:
|
13
13
|
ERROR_ILLEGAL_DATA = 'server returned illegal data.'
|
14
14
|
ERROR_BUSINESS_ERROR = 'server returned business error.'
|
15
|
+
ERROR_PARTIAL_SUCCESS = 'the request to server was partially successful.'
|
16
|
+
ERROR_NO_DATA = 'no expected data in response from server. path: %s. Body is: %s'
|
15
17
|
|
16
18
|
REQUEST_ARGUMENTS = { timeout: 10 }.freeze
|
17
19
|
|
18
20
|
def initialize(config)
|
19
|
-
|
20
|
-
|
21
|
-
product_root = format('i18n/api/v2/translation/products/%s/versions/%s', config.product_name, config.version)
|
21
|
+
product_root = format('i18n/api/v2/translation/products/%<name>s/versions/%<version>s',
|
22
|
+
name: config.product_name, version: config.version)
|
22
23
|
|
23
24
|
@bundle_url = "#{product_root}/locales/%s/components/%s"
|
24
25
|
@locales_url = "#{product_root}/localelist"
|
25
26
|
@components_url = "#{product_root}/componentlist"
|
27
|
+
|
28
|
+
@conn = Faraday.new(config.vip_server, request: REQUEST_ARGUMENTS) do |f|
|
29
|
+
f.response :json # decode response bodies as JSON
|
30
|
+
f.use :gzip
|
31
|
+
f.response :raise_error
|
32
|
+
f.response :logger, config.logger, { log_level: :debug, headers: false, bodies: true }
|
33
|
+
end
|
26
34
|
end
|
27
35
|
|
28
36
|
def load_bundle(component, locale)
|
29
37
|
SgtnClient.logger.debug { "[#{method(__callee__).owner}.#{__callee__}] component=#{component}, locale=#{locale}" }
|
30
38
|
|
31
|
-
|
32
|
-
messages
|
39
|
+
query_server(format(@bundle_url, locale, component), ['messages'])
|
33
40
|
end
|
34
41
|
|
35
42
|
def available_bundles
|
@@ -54,23 +61,12 @@ module SgtnClient
|
|
54
61
|
end
|
55
62
|
|
56
63
|
def query_server(url, path_to_data = [], queries = nil, headers = nil)
|
57
|
-
|
58
|
-
f.response :json # decode response bodies as JSON
|
59
|
-
f.use :gzip
|
60
|
-
f.response :raise_error
|
61
|
-
f.response :logger, SgtnClient.logger, { log_level: :debug }
|
62
|
-
end
|
63
|
-
resp = conn.get(url, queries, headers)
|
64
|
+
resp = @conn.get(url, queries, headers)
|
64
65
|
|
65
66
|
process_business_error(resp.body)
|
66
|
-
extract_data(resp.body, path_to_data)
|
67
|
-
end
|
68
|
-
|
69
|
-
def extract_data(parsedbody, path_to_data)
|
70
|
-
data = parsedbody.dig('data', *path_to_data)
|
71
|
-
raise SingletonError, "no expected data in response. Body is: #{parsedbody}" unless data
|
72
67
|
|
73
|
-
data
|
68
|
+
resp.body&.dig('data', *path_to_data) ||
|
69
|
+
(raise SingletonError, format(ERROR_NO_DATA, path_to_data, resp.body))
|
74
70
|
end
|
75
71
|
|
76
72
|
def process_business_error(parsedbody)
|
@@ -79,8 +75,8 @@ module SgtnClient
|
|
79
75
|
raise SingletonError, "#{ERROR_BUSINESS_ERROR} #{parsedbody['response']}"
|
80
76
|
end
|
81
77
|
|
82
|
-
# 600 means a successful response, 6xx means partial successful.
|
83
|
-
SgtnClient.logger.warn "#{
|
78
|
+
# 600/200 means a successful response, 6xx/2xx means partial successful.
|
79
|
+
SgtnClient.logger.warn "#{ERROR_PARTIAL_SUCCESS} #{parsedbody['response']}" if b_code != 600 && b_code != 200
|
84
80
|
rescue TypeError, ArgumentError, NoMethodError => e
|
85
81
|
raise SingletonError, "#{ERROR_ILLEGAL_DATA} #{e}. Body is: #{parsedbody}"
|
86
82
|
end
|
@@ -9,6 +9,7 @@ module SgtnClient # :nodoc:
|
|
9
9
|
autoload :TranslationLoader, 'sgtn-client/loader'
|
10
10
|
autoload :SingleOperation, 'sgtn-client/common/single_operation'
|
11
11
|
autoload :Translation, 'sgtn-client/api/translation'
|
12
|
+
autoload :Fallbacks, 'sgtn-client/fallbacks'
|
12
13
|
autoload :T, 'sgtn-client/api/t'
|
13
14
|
autoload :Source, 'sgtn-client/api/source'
|
14
15
|
autoload :Config, 'sgtn-client/core/config'
|
@@ -38,5 +39,13 @@ module SgtnClient # :nodoc:
|
|
38
39
|
config.update(config_hash)
|
39
40
|
ValidateUtil.validate_config
|
40
41
|
end
|
42
|
+
|
43
|
+
def locale
|
44
|
+
RequestStore.store[:locale] ||= LocaleUtil.get_fallback_locale
|
45
|
+
end
|
46
|
+
|
47
|
+
def locale=(value)
|
48
|
+
RequestStore.store[:locale] = value
|
49
|
+
end
|
41
50
|
end
|
42
51
|
end
|
@@ -29,7 +29,8 @@ module SgtnClient
|
|
29
29
|
end
|
30
30
|
|
31
31
|
component_result[locale] ||= begin
|
32
|
-
|
32
|
+
component_result.delete(component_result.keys[Random.rand(component_result.size)]) if component_result.size >= 50
|
33
|
+
|
33
34
|
if SgtnClient.config.available_locales(component).include?(locale)
|
34
35
|
locale
|
35
36
|
elsif locale.nil?
|
@@ -73,7 +74,7 @@ module SgtnClient
|
|
73
74
|
end
|
74
75
|
|
75
76
|
def self.locale_fallbacks
|
76
|
-
@locale_fallbacks ||= [get_default_locale, get_source_locale, EN_LOCALE].uniq(&:to_s) - [nil, '']
|
77
|
+
@locale_fallbacks ||= ([get_default_locale, get_source_locale, EN_LOCALE].uniq(&:to_s) - [nil, '']).freeze
|
77
78
|
end
|
78
79
|
|
79
80
|
def self.lowercase_locales_map(component)
|
data/lib/singleton-client.rb
CHANGED
@@ -14,11 +14,26 @@ module Sgtn # :nodoc:
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def_delegator SgtnClient::Config, :instance, :config
|
17
|
-
delegate %i[translate t get_translations
|
17
|
+
delegate %i[translate! t! translate t get_translations! get_translations] => SgtnClient::Translation,
|
18
|
+
%i[locale locale=] => SgtnClient,
|
18
19
|
%i[logger product_name version vip_server translation_bundle
|
19
20
|
source_bundle cache_expiry_period log_file log_level].flat_map { |m|
|
20
21
|
[m, "#{m}=".to_sym]
|
21
22
|
} => :config
|
23
|
+
|
24
|
+
def with_locale(tmp_locale = nil)
|
25
|
+
if tmp_locale.nil?
|
26
|
+
yield
|
27
|
+
else
|
28
|
+
current_locale = locale
|
29
|
+
self.locale = tmp_locale
|
30
|
+
begin
|
31
|
+
yield
|
32
|
+
ensure
|
33
|
+
self.locale = current_locale
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
22
37
|
end
|
23
38
|
|
24
39
|
I18nBackend = SgtnClient::I18nBackend
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: singleton-client-test
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.7.
|
4
|
+
version: 0.7.7.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- VMware G11n Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: logging
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -144,6 +144,7 @@ files:
|
|
144
144
|
- lib/sgtn-client/core/config.rb
|
145
145
|
- lib/sgtn-client/core/exceptions.rb
|
146
146
|
- lib/sgtn-client/exceptions.rb
|
147
|
+
- lib/sgtn-client/fallbacks.rb
|
147
148
|
- lib/sgtn-client/formatters/plurals/plural_formatter.rb
|
148
149
|
- lib/sgtn-client/i18n_backend.rb
|
149
150
|
- lib/sgtn-client/loader.rb
|