singleton-client-test 0.7.7.2 → 0.7.7.5
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/source.rb +0 -3
- data/lib/sgtn-client/api/t.rb +2 -0
- data/lib/sgtn-client/api/translation.rb +42 -30
- data/lib/sgtn-client/common/data.rb +40 -3
- data/lib/sgtn-client/common/single_operation.rb +7 -8
- data/lib/sgtn-client/common.rb +10 -0
- data/lib/sgtn-client/core/config.rb +55 -174
- data/lib/sgtn-client/i18n_backend.rb +48 -0
- data/lib/sgtn-client/loader/cache.rb +30 -46
- data/lib/sgtn-client/loader/chain_loader.rb +3 -1
- data/lib/sgtn-client/loader/loader_factory.rb +6 -13
- data/lib/sgtn-client/loader/local_translation.rb +5 -10
- data/lib/sgtn-client/loader/server.rb +8 -13
- data/lib/sgtn-client/loader/single_loader.rb +22 -24
- data/lib/sgtn-client/loader/source.rb +6 -11
- data/lib/sgtn-client/loader/source_comparer.rb +1 -6
- data/lib/sgtn-client/loader.rb +19 -0
- data/lib/sgtn-client/sgtn-client.rb +38 -84
- data/lib/sgtn-client/util/locale-util.rb +59 -28
- data/lib/sgtn-client/util/string-util.rb +5 -2
- data/lib/sgtn-client/util/validate-util.rb +10 -20
- data/lib/singleton-client.rb +16 -6
- data/lib/singleton-ruby.rb +2 -3
- metadata +23 -43
- data/lib/sgtn-client/core/cache.rb +0 -34
- data/lib/sgtn-client/core/logging.rb +0 -52
- data/lib/sgtn-client/util/cache-util.rb +0 -40
@@ -1,6 +1,8 @@
|
|
1
1
|
# Copyright 2022 VMware, Inc.
|
2
2
|
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
|
+
require 'set'
|
5
|
+
|
4
6
|
module SgtnClient
|
5
7
|
module TranslationLoader
|
6
8
|
class Chain
|
@@ -23,7 +25,7 @@ module SgtnClient
|
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
|
-
raise exception ||
|
28
|
+
raise exception || SingletonError.new("can't load component: #{component}, locale: #{locale}")
|
27
29
|
end
|
28
30
|
|
29
31
|
def available_bundles
|
@@ -3,26 +3,19 @@
|
|
3
3
|
|
4
4
|
module SgtnClient
|
5
5
|
module TranslationLoader
|
6
|
-
autoload :Source, 'sgtn-client/loader/source'
|
7
|
-
autoload :SgtnServer, 'sgtn-client/loader/server'
|
8
|
-
autoload :LocalTranslation, 'sgtn-client/loader/local_translation'
|
9
|
-
autoload :Chain, 'sgtn-client/loader/chain_loader'
|
10
|
-
autoload :SourceComparer, 'sgtn-client/loader/source_comparer'
|
11
|
-
autoload :SingleLoader, 'sgtn-client/loader/single_loader'
|
12
|
-
autoload :Cache, 'sgtn-client/loader/cache'
|
13
|
-
|
14
6
|
module LoaderFactory
|
15
7
|
def self.create(config)
|
16
|
-
SgtnClient.logger.info "[#{method(__callee__).owner}.#{__callee__}] config=#{config}"
|
8
|
+
SgtnClient.logger.info "[#{method(__callee__).owner}.#{__callee__}] config=#{config.inspect}"
|
17
9
|
|
18
10
|
loaders = []
|
19
|
-
loaders << Source.new(config) if config
|
20
|
-
loaders << SgtnServer.new(config) if config
|
21
|
-
loaders << LocalTranslation.new(config) if config
|
22
|
-
raise
|
11
|
+
loaders << Source.new(config) if config.source_bundle
|
12
|
+
loaders << SgtnServer.new(config) if config.vip_server
|
13
|
+
loaders << LocalTranslation.new(config) if config.translation_bundle
|
14
|
+
raise SingletonError, 'no translation is available!' if loaders.empty?
|
23
15
|
|
24
16
|
chain_loader = Class.new(Chain)
|
25
17
|
chain_loader.include SourceComparer
|
18
|
+
chain_loader.include CacheFiller
|
26
19
|
chain_loader.include SingleLoader
|
27
20
|
chain_loader.include Cache
|
28
21
|
|
@@ -3,25 +3,20 @@
|
|
3
3
|
|
4
4
|
require 'json'
|
5
5
|
require 'pathname'
|
6
|
+
require 'set'
|
6
7
|
|
7
8
|
module SgtnClient
|
8
|
-
module Common
|
9
|
-
autoload :BundleID, 'sgtn-client/common/data'
|
10
|
-
end
|
11
|
-
|
12
9
|
module TranslationLoader
|
13
|
-
autoload :CONSTS, 'sgtn-client/loader/consts'
|
14
|
-
|
15
10
|
class LocalTranslation
|
16
11
|
BUNDLE_PREFIX = 'messages_'.freeze
|
17
12
|
BUNDLE_SUFFIX = '.json'.freeze
|
18
13
|
|
19
14
|
def initialize(config)
|
20
|
-
@base_path = Pathname.new(config
|
15
|
+
@base_path = Pathname.new(config.translation_bundle) + config.product_name + config.version.to_s
|
21
16
|
end
|
22
17
|
|
23
18
|
def load_bundle(component, locale)
|
24
|
-
SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}] component=#{component}, locale=#{locale}"
|
19
|
+
SgtnClient.logger.debug { "[#{method(__callee__).owner}.#{__callee__}] component=#{component}, locale=#{locale}" }
|
25
20
|
|
26
21
|
file_name = BUNDLE_PREFIX + locale + BUNDLE_SUFFIX
|
27
22
|
file_path = @base_path + component + file_name
|
@@ -29,13 +24,13 @@ module SgtnClient
|
|
29
24
|
bundle_data = JSON.parse(File.read(file_path))
|
30
25
|
messages = bundle_data['messages']
|
31
26
|
|
32
|
-
raise
|
27
|
+
raise SingletonError, "no messages in local bundle file: #{file_path}." unless messages
|
33
28
|
|
34
29
|
messages
|
35
30
|
end
|
36
31
|
|
37
32
|
def available_bundles
|
38
|
-
SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}]"
|
33
|
+
SgtnClient.logger.debug { "[#{method(__callee__).owner}.#{__callee__}]" }
|
39
34
|
|
40
35
|
@available_bundles ||= begin
|
41
36
|
@base_path.glob('*/*.json').reduce(Set.new) do |bundles, f|
|
@@ -5,15 +5,10 @@
|
|
5
5
|
|
6
6
|
require 'faraday'
|
7
7
|
require 'faraday_middleware'
|
8
|
+
require 'set'
|
8
9
|
|
9
10
|
module SgtnClient
|
10
|
-
module Common
|
11
|
-
autoload :BundleID, 'sgtn-client/common/data'
|
12
|
-
end
|
13
|
-
|
14
11
|
module TranslationLoader
|
15
|
-
autoload :CONSTS, 'sgtn-client/loader/consts'
|
16
|
-
|
17
12
|
class SgtnServer
|
18
13
|
ERROR_ILLEGAL_DATA = 'server returned illegal data.'
|
19
14
|
ERROR_BUSINESS_ERROR = 'server returned business error.'
|
@@ -21,9 +16,9 @@ module SgtnClient
|
|
21
16
|
REQUEST_ARGUMENTS = { timeout: 10 }.freeze
|
22
17
|
|
23
18
|
def initialize(config)
|
24
|
-
@server_url = config
|
19
|
+
@server_url = config.vip_server
|
25
20
|
|
26
|
-
product_root = format('i18n/api/v2/translation/products/%s/versions/%s', config
|
21
|
+
product_root = format('i18n/api/v2/translation/products/%s/versions/%s', config.product_name, config.version)
|
27
22
|
|
28
23
|
@bundle_url = "#{product_root}/locales/%s/components/%s"
|
29
24
|
@locales_url = "#{product_root}/localelist"
|
@@ -31,14 +26,14 @@ module SgtnClient
|
|
31
26
|
end
|
32
27
|
|
33
28
|
def load_bundle(component, locale)
|
34
|
-
SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}] component=#{component}, locale=#{locale}"
|
29
|
+
SgtnClient.logger.debug { "[#{method(__callee__).owner}.#{__callee__}] component=#{component}, locale=#{locale}" }
|
35
30
|
|
36
31
|
messages = query_server(format(@bundle_url, locale, component), ['messages'])
|
37
32
|
messages
|
38
33
|
end
|
39
34
|
|
40
35
|
def available_bundles
|
41
|
-
SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}]"
|
36
|
+
SgtnClient.logger.debug { "[#{method(__callee__).owner}.#{__callee__}]" }
|
42
37
|
|
43
38
|
components_thread = Thread.new { available_components }
|
44
39
|
available_locales.reduce(Set.new) do |bundles, locale|
|
@@ -73,7 +68,7 @@ module SgtnClient
|
|
73
68
|
|
74
69
|
def extract_data(parsedbody, path_to_data)
|
75
70
|
data = parsedbody.dig('data', *path_to_data)
|
76
|
-
raise
|
71
|
+
raise SingletonError, "no expected data in response. Body is: #{parsedbody}" unless data
|
77
72
|
|
78
73
|
data
|
79
74
|
end
|
@@ -81,13 +76,13 @@ module SgtnClient
|
|
81
76
|
def process_business_error(parsedbody)
|
82
77
|
b_code = parsedbody.dig('response', 'code')
|
83
78
|
unless b_code >= 200 && b_code < 300 || b_code >= 600 && b_code < 700
|
84
|
-
raise
|
79
|
+
raise SingletonError, "#{ERROR_BUSINESS_ERROR} #{parsedbody['response']}"
|
85
80
|
end
|
86
81
|
|
87
82
|
# 600 means a successful response, 6xx means partial successful.
|
88
83
|
SgtnClient.logger.warn "#{ERROR_BUSINESS_ERROR} #{parsedbody['response']}" if b_code > 600
|
89
84
|
rescue TypeError, ArgumentError, NoMethodError => e
|
90
|
-
raise
|
85
|
+
raise SingletonError, "#{ERROR_ILLEGAL_DATA} #{e}. Body is: #{parsedbody}"
|
91
86
|
end
|
92
87
|
end
|
93
88
|
end
|
@@ -2,46 +2,44 @@
|
|
2
2
|
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
4
|
module SgtnClient
|
5
|
-
autoload :SingleOperation, 'sgtn-client/common/single_operation'
|
6
|
-
autoload :CacheUtil, 'sgtn-client/util/cache-util'
|
7
|
-
|
8
5
|
module TranslationLoader
|
9
|
-
autoload :CONSTS, 'sgtn-client/loader/consts'
|
10
|
-
|
11
6
|
module SingleLoader
|
12
|
-
def load_bundle(component, locale)
|
13
|
-
SgtnClient.logger.debug "[#{__FILE__}][#{__callee__}] component=#{component}, locale=#{locale}"
|
7
|
+
def load_bundle(component, locale, sync: true)
|
8
|
+
SgtnClient.logger.debug { "[#{__FILE__}][#{__callee__}] component=#{component}, locale=#{locale}" }
|
14
9
|
|
15
|
-
|
16
|
-
id = CacheUtil.get_cachekey(component, locale)
|
17
|
-
@single_bundle_loader.operate(id, component, locale)&.value
|
10
|
+
do_single_load(Common::BundleID.new(component, locale), sync) { super(component, locale) }
|
18
11
|
end
|
19
12
|
|
20
|
-
def available_bundles
|
21
|
-
SgtnClient.logger.debug "[#{__FILE__}][#{__callee__}]"
|
13
|
+
def available_bundles(sync: true)
|
14
|
+
SgtnClient.logger.debug { "[#{__FILE__}][#{__callee__}]" }
|
22
15
|
|
23
|
-
|
24
|
-
@single_available_bundles_loader.operate(CONSTS::AVAILABLE_BUNDLES_KEY)&.value
|
16
|
+
do_single_load(CONSTS::AVAILABLE_BUNDLES_KEY, sync) { super() }
|
25
17
|
end
|
26
18
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
loader = nil
|
31
|
-
none_alive = proc { |_, thread| thread.nil? }
|
32
|
-
creator = proc do |id, _, *args|
|
19
|
+
def initialize(*args)
|
20
|
+
none_alive = proc { |_, thread| thread.nil? || thread.alive? == false }
|
21
|
+
creator = proc do |id, &block|
|
33
22
|
Thread.new do
|
34
|
-
SgtnClient.logger.debug "start single loading #{id}"
|
23
|
+
SgtnClient.logger.debug { "start single loading #{id}" }
|
35
24
|
begin
|
36
|
-
block.call
|
25
|
+
block.call
|
37
26
|
ensure
|
38
27
|
# delete thread from hash after finish
|
39
|
-
|
28
|
+
@single_loader.remove_object(id)
|
40
29
|
end
|
41
30
|
end
|
42
31
|
end
|
43
32
|
|
44
|
-
|
33
|
+
@single_loader = SingleOperation.new(none_alive, &creator)
|
34
|
+
|
35
|
+
super
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def do_single_load(id, sync, &block)
|
41
|
+
thread = @single_loader.operate(id, &block)
|
42
|
+
thread&.value if sync
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
@@ -2,25 +2,20 @@
|
|
2
2
|
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
4
|
require 'pathname'
|
5
|
+
require 'set'
|
5
6
|
require 'yaml'
|
6
7
|
|
7
8
|
module SgtnClient
|
8
|
-
module Common
|
9
|
-
autoload :BundleID, 'sgtn-client/common/data'
|
10
|
-
end
|
11
|
-
|
12
9
|
module TranslationLoader
|
13
|
-
autoload :CONSTS, 'sgtn-client/loader/consts'
|
14
|
-
|
15
10
|
class Source
|
16
11
|
def initialize(config)
|
17
|
-
@source_bundle_path = Pathname.new(config
|
12
|
+
@source_bundle_path = Pathname.new(config.source_bundle)
|
18
13
|
end
|
19
14
|
|
20
15
|
def load_bundle(component, locale = nil)
|
21
16
|
return if locale && locale != CONSTS::REAL_SOURCE_LOCALE # return when NOT querying source
|
22
17
|
|
23
|
-
SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}] component=#{component}"
|
18
|
+
SgtnClient.logger.debug { "[#{method(__callee__).owner}.#{__callee__}] component=#{component}" }
|
24
19
|
|
25
20
|
total_messages = {}
|
26
21
|
|
@@ -34,18 +29,18 @@ module SgtnClient
|
|
34
29
|
end
|
35
30
|
end
|
36
31
|
|
37
|
-
raise
|
32
|
+
raise SingletonError, "no local source messages for component #{component}" if total_messages.empty?
|
38
33
|
|
39
34
|
total_messages
|
40
35
|
end
|
41
36
|
|
42
37
|
def available_bundles
|
43
|
-
SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}]"
|
38
|
+
SgtnClient.logger.debug { "[#{method(__callee__).owner}.#{__callee__}]" }
|
44
39
|
|
45
40
|
@available_bundles ||= begin
|
46
41
|
@source_bundle_path.children.select(&:directory?).reduce(Set.new) do |bundles, component|
|
47
42
|
component.glob('**/*.{yml, yaml}') do |_|
|
48
|
-
bundles << Common::BundleID.new(component.basename.to_s,
|
43
|
+
bundles << Common::BundleID.new(component.basename.to_s, LocaleUtil.get_source_locale)
|
49
44
|
break bundles
|
50
45
|
end || bundles
|
51
46
|
end
|
@@ -2,15 +2,10 @@
|
|
2
2
|
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
4
|
module SgtnClient
|
5
|
-
autoload :StringUtil, 'sgtn-client/util/string-util'
|
6
|
-
autoload :LocaleUtil, 'sgtn-client/util/locale-util'
|
7
|
-
|
8
5
|
module TranslationLoader
|
9
|
-
autoload :CONSTS, 'sgtn-client/loader/consts'
|
10
|
-
|
11
6
|
module SourceComparer
|
12
7
|
def load_bundle(component, locale)
|
13
|
-
SgtnClient.logger.debug "[#{__FILE__}][#{__callee__}] component=#{component}, locale=#{locale}"
|
8
|
+
SgtnClient.logger.debug { "[#{__FILE__}][#{__callee__}] component=#{component}, locale=#{locale}" }
|
14
9
|
|
15
10
|
# source locale and old source locale don't need comparison because they are bases of comparison
|
16
11
|
real_locale = cache_to_real_map[locale]
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2022 VMware, Inc.
|
4
|
+
# SPDX-License-Identifier: EPL-2.0
|
5
|
+
|
6
|
+
module SgtnClient
|
7
|
+
module TranslationLoader # :nodoc:
|
8
|
+
autoload :Cache, 'sgtn-client/loader/cache'
|
9
|
+
autoload :CacheFiller, 'sgtn-client/loader/cache'
|
10
|
+
autoload :Chain, 'sgtn-client/loader/chain_loader'
|
11
|
+
autoload :CONSTS, 'sgtn-client/loader/consts'
|
12
|
+
autoload :LoaderFactory, 'sgtn-client/loader/loader_factory'
|
13
|
+
autoload :LocalTranslation, 'sgtn-client/loader/local_translation'
|
14
|
+
autoload :SgtnServer, 'sgtn-client/loader/server'
|
15
|
+
autoload :SingleLoader, 'sgtn-client/loader/single_loader'
|
16
|
+
autoload :SourceComparer, 'sgtn-client/loader/source_comparer'
|
17
|
+
autoload :Source, 'sgtn-client/loader/source'
|
18
|
+
end
|
19
|
+
end
|
@@ -1,88 +1,42 @@
|
|
1
1
|
# Copyright 2022 VMware, Inc.
|
2
2
|
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
rescue => exception
|
43
|
-
file = File.open('./error.log', 'a')
|
44
|
-
file.sync = true
|
45
|
-
log = Logger.new(file)
|
46
|
-
log.error exception.message
|
47
|
-
end
|
48
|
-
|
49
|
-
# create log file
|
50
|
-
file = './sgtnclient_d.log'
|
51
|
-
SgtnClient.logger.debug "[Client][load]create log file=#{file}"
|
52
|
-
if args[2] != nil
|
53
|
-
file = args[2]
|
54
|
-
end
|
55
|
-
file = File.open(file, 'a')
|
56
|
-
file.sync = true
|
57
|
-
SgtnClient.logger = Logger.new(file, LOGFILE_SHIFT_AGE)
|
58
|
-
|
59
|
-
# Set log level for sandbox mode
|
60
|
-
env = SgtnClient::Config.default_environment
|
61
|
-
mode = SgtnClient::Config.configurations[env]["mode"]
|
62
|
-
SgtnClient.logger.debug "[Client][load]set log level, mode=#{mode}"
|
63
|
-
if mode == 'sandbox'
|
64
|
-
SgtnClient.logger.level = Logger::DEBUG
|
65
|
-
else
|
66
|
-
SgtnClient.logger.level = Logger::INFO
|
67
|
-
end
|
68
|
-
|
69
|
-
# initialize cache
|
70
|
-
disable_cache = SgtnClient::Config.configurations[env]["disable_cache"]
|
71
|
-
SgtnClient.logger.debug "[Client][load]cache initialize, disable_cache=#{disable_cache}"
|
72
|
-
if disable_cache != nil
|
73
|
-
SgtnClient::Core::Cache.initialize(disable_cache)
|
74
|
-
else
|
75
|
-
SgtnClient::Core::Cache.initialize()
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def logger
|
80
|
-
SgtnClient::Config.logger
|
81
|
-
end
|
82
|
-
|
83
|
-
def logger=(log)
|
84
|
-
SgtnClient::Config.logger = log
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
4
|
+
require 'forwardable'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module SgtnClient # :nodoc:
|
8
|
+
autoload :Common, 'sgtn-client/common'
|
9
|
+
autoload :TranslationLoader, 'sgtn-client/loader'
|
10
|
+
autoload :SingleOperation, 'sgtn-client/common/single_operation'
|
11
|
+
autoload :Translation, 'sgtn-client/api/translation'
|
12
|
+
autoload :T, 'sgtn-client/api/t'
|
13
|
+
autoload :Source, 'sgtn-client/api/source'
|
14
|
+
autoload :Config, 'sgtn-client/core/config'
|
15
|
+
autoload :Exceptions, 'sgtn-client/core/exceptions'
|
16
|
+
autoload :ValidateUtil, 'sgtn-client/util/validate-util'
|
17
|
+
autoload :LocaleUtil, 'sgtn-client/util/locale-util'
|
18
|
+
autoload :StringUtil, 'sgtn-client/util/string-util'
|
19
|
+
autoload :SingletonError, 'sgtn-client/exceptions'
|
20
|
+
autoload :I18nBackend, 'sgtn-client/i18n_backend'
|
21
|
+
|
22
|
+
module Formatters # :nodoc:
|
23
|
+
autoload :PluralFormatter, 'sgtn-client/formatters/plurals/plural_formatter'
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
extend Forwardable
|
28
|
+
|
29
|
+
def_delegator Config, :instance, :config
|
30
|
+
def_delegators :config, :logger, :logger=
|
31
|
+
|
32
|
+
def load(config_file, env, log_file = nil)
|
33
|
+
configurations = YAML.load(File.read(config_file))
|
34
|
+
config_hash = configurations[env]
|
35
|
+
raise "Configuration[#{env}] NotFound" unless config_hash
|
36
|
+
|
37
|
+
config_hash['log_file'] = log_file if log_file
|
38
|
+
config.update(config_hash)
|
39
|
+
ValidateUtil.validate_config
|
40
|
+
end
|
41
|
+
end
|
88
42
|
end
|
@@ -3,10 +3,10 @@
|
|
3
3
|
# Copyright 2022 VMware, Inc.
|
4
4
|
# SPDX-License-Identifier: EPL-2.0
|
5
5
|
|
6
|
-
require '
|
6
|
+
require 'concurrent/map'
|
7
7
|
|
8
8
|
module SgtnClient
|
9
|
-
class LocaleUtil
|
9
|
+
class LocaleUtil # :nodoc:
|
10
10
|
MAP_LOCALES = {
|
11
11
|
'zh-cn' => 'zh-hans',
|
12
12
|
'zh-tw' => 'zh-hant',
|
@@ -14,57 +14,88 @@ module SgtnClient
|
|
14
14
|
'zh-hant-tw' => 'zh-hant'
|
15
15
|
}.freeze
|
16
16
|
LOCALE_SEPARATOR = '-'
|
17
|
+
EN_LOCALE = 'en'
|
18
|
+
@locale_match_results = Concurrent::Map.new
|
19
|
+
@lowercase_locales_map = Concurrent::Map.new
|
20
|
+
|
21
|
+
def self.get_best_locale(locale, component)
|
22
|
+
component_result = @locale_match_results[component] ||= begin
|
23
|
+
components = SgtnClient.config.available_components
|
24
|
+
unless components.empty? || components.include?(component)
|
25
|
+
raise SingletonError, "component '#{component}' doesn't exist!"
|
26
|
+
end
|
27
|
+
|
28
|
+
Concurrent::Map.new
|
29
|
+
end
|
17
30
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
component_result[locale] ||= begin
|
32
|
+
# component_result.shift if component_result.size >= 50
|
33
|
+
if SgtnClient.config.available_locales(component).include?(locale)
|
34
|
+
locale
|
35
|
+
elsif locale.nil?
|
36
|
+
get_fallback_locale
|
37
|
+
else
|
38
|
+
locale = locale.to_s
|
39
|
+
if locale.empty?
|
40
|
+
get_fallback_locale
|
41
|
+
else
|
42
|
+
candidates = lowercase_locales_map(component)
|
43
|
+
if candidates.empty?
|
44
|
+
locale
|
45
|
+
else
|
46
|
+
get_best_match(locale.gsub('_', LOCALE_SEPARATOR).downcase, candidates)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
31
51
|
end
|
32
52
|
|
33
|
-
def self.get_best_match(locale)
|
53
|
+
def self.get_best_match(locale, candidates)
|
34
54
|
locale = MAP_LOCALES[locale] || locale
|
35
|
-
|
55
|
+
candidates[locale] or begin
|
36
56
|
index = locale.rindex(LOCALE_SEPARATOR)
|
37
57
|
return get_fallback_locale if index.nil?
|
38
58
|
|
39
|
-
get_best_match(locale[0...index])
|
59
|
+
get_best_match(locale[0...index], candidates)
|
40
60
|
end
|
41
61
|
end
|
42
62
|
|
43
63
|
def self.get_source_locale
|
44
|
-
|
64
|
+
EN_LOCALE
|
45
65
|
end
|
46
66
|
|
47
67
|
def self.get_default_locale
|
48
|
-
|
49
|
-
SgtnClient::Config.configurations[env]['default_language']
|
68
|
+
EN_LOCALE
|
50
69
|
end
|
51
70
|
|
52
71
|
def self.get_fallback_locale
|
53
|
-
|
72
|
+
locale_fallbacks[0]
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.locale_fallbacks
|
76
|
+
@locale_fallbacks ||= [get_default_locale, get_source_locale, EN_LOCALE].uniq(&:to_s) - [nil, '']
|
54
77
|
end
|
55
78
|
|
56
|
-
def self.lowercase_locales_map
|
57
|
-
@lowercase_locales_map ||=
|
79
|
+
def self.lowercase_locales_map(component)
|
80
|
+
@lowercase_locales_map[component] ||= SgtnClient.config.available_locales(component).each_with_object({}) do |locale, memo|
|
58
81
|
memo[locale.to_s.downcase] = locale
|
59
82
|
end
|
60
83
|
end
|
61
84
|
|
62
|
-
def self.
|
63
|
-
|
85
|
+
def self.reset_locale_data(type, component = nil)
|
86
|
+
return unless type == :available_locales
|
87
|
+
|
88
|
+
if component.nil?
|
89
|
+
@locale_match_results.clear
|
90
|
+
@lowercase_locales_map.clear
|
91
|
+
else
|
92
|
+
@locale_match_results.delete(component)
|
93
|
+
@lowercase_locales_map.delete(component)
|
94
|
+
end
|
64
95
|
end
|
65
96
|
|
66
|
-
SgtnClient
|
97
|
+
SgtnClient.config.add_observer(self, :reset_locale_data)
|
67
98
|
|
68
|
-
private_class_method :get_best_match, :lowercase_locales_map, :
|
99
|
+
private_class_method :get_best_match, :lowercase_locales_map, :reset_locale_data
|
69
100
|
end
|
70
101
|
end
|
@@ -6,32 +6,22 @@ module SgtnClient
|
|
6
6
|
class ValidateUtil
|
7
7
|
|
8
8
|
def self.validate_config()
|
9
|
-
|
10
|
-
|
11
|
-
messages = "\n"
|
9
|
+
puts "validating config..."
|
10
|
+
messages = ""
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
version = SgtnClient.config.version
|
13
|
+
SgtnClient.config.version = version.to_s
|
14
|
+
if version.to_s !~ /\A(\d+\.)*\d+\z/
|
15
|
+
messages = messages + "Configuration[version] has to be standard as '#.#.#, e.g '1.0.0'!\n"
|
16
16
|
end
|
17
|
-
|
18
|
-
#version = SgtnClient::Config.configurations[env]["version"]
|
19
|
-
#if version.is_a? Integer
|
20
|
-
#messages = messages + "Configuration[version] has to be standard as '#.#.#, e.g '1.0.0'!\n"
|
21
|
-
#end
|
22
17
|
|
23
|
-
cache_expiry_period = SgtnClient
|
18
|
+
cache_expiry_period = SgtnClient.config.cache_expiry_period
|
24
19
|
if cache_expiry_period != nil && (cache_expiry_period.is_a? Integer) == false
|
25
20
|
messages = messages + "Configuration[cache_expiry_period] has to be a number!\n"
|
26
21
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
messages = messages + "Configuration[disable_cache] has to be a 'true' or 'false'!\n"
|
31
|
-
end
|
32
|
-
|
33
|
-
if messages != "\n"
|
34
|
-
raise SgtnClient::Exceptions::MissingConfig.new(messages)
|
22
|
+
|
23
|
+
if messages != ""
|
24
|
+
raise Exceptions::MissingConfig.new(messages)
|
35
25
|
end
|
36
26
|
end
|
37
27
|
|