singleton-client 0.7.0 → 0.7.4
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 +21 -24
- data/lib/sgtn-client/api/translation.rb +72 -47
- data/lib/sgtn-client/cldr/core_ext.rb +4 -0
- data/lib/sgtn-client/cldr/localized_date.rb +27 -0
- data/lib/sgtn-client/cldr/localized_datetime.rb +63 -0
- data/lib/sgtn-client/cldr/localized_str.rb +11 -0
- data/lib/sgtn-client/cldr/localized_time.rb +27 -0
- data/lib/sgtn-client/core/cache.rb +57 -40
- data/lib/sgtn-client/core/config.rb +1 -1
- data/lib/sgtn-client/core/request.rb +5 -1
- data/lib/sgtn-client/formatters/plurals/plural_formatter.rb +38 -0
- data/lib/sgtn-client/sgtn-client.rb +9 -1
- data/lib/sgtn-client/util/cache-util.rb +15 -3
- data/lib/sgtn-client/util/file-util.rb +34 -0
- data/lib/sgtn-client/util/validate-util.rb +1 -2
- data/lib/singleton-ruby.rb +2 -1
- data/lib/version.rb +1 -1
- metadata +37 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43d840f37ce5f60b23e16623db0b4393f014eaeaafa0ddf91520225a93bd9c57
|
4
|
+
data.tar.gz: d3c1e045e6c75f7e09cd2790de733a217516afede51dbfede1224cbabcbd3b53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56593be0f8686d669216a849592b9100bb47f52087bf10938d1fae79fb123b9b4ee68baa10e8e627c2ef263e79f2f056aac777e2e5ebc3d8d7f5fbd15b758ce5
|
7
|
+
data.tar.gz: 5eca696945202e002be5c489ee37153d63c6498e4cc8639f5ea3ad11666ac63e4fffee59572e29fbeb0ff4c7489ff29b06a77cb57e2f9f077cde0663ca5e115b
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'erb'
|
2
|
-
require 'yaml'
|
3
1
|
|
4
2
|
module SgtnClient
|
5
3
|
|
@@ -8,43 +6,47 @@ module SgtnClient
|
|
8
6
|
class Source
|
9
7
|
|
10
8
|
def self.getSource(component, key, locale)
|
9
|
+
SgtnClient.logger.debug "[Source][getSource]component=#{component}, key=#{key}, locale=#{locale}"
|
11
10
|
cache_key = SgtnClient::CacheUtil.get_cachekey(component, locale)
|
12
|
-
items = SgtnClient::CacheUtil.get_cache(cache_key)
|
11
|
+
expired, items = SgtnClient::CacheUtil.get_cache(cache_key)
|
13
12
|
if items.nil?
|
14
|
-
items = getBundle(component, locale)
|
15
|
-
SgtnClient.logger.debug "Putting sources items into cache with key: " + cache_key
|
13
|
+
items = getBundle(component, locale)
|
16
14
|
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
17
15
|
else
|
18
|
-
SgtnClient.logger.debug "
|
16
|
+
SgtnClient.logger.debug "[Source][getSource]getting sources from cache with key: " + cache_key
|
19
17
|
end
|
20
|
-
|
21
|
-
|
18
|
+
s = items.nil?? nil : items[locale][key]
|
19
|
+
if items.nil? || s.nil?
|
20
|
+
SgtnClient.logger.debug "[Source][getSource]source not found, return key: " + key
|
21
|
+
#return key
|
22
|
+
return nil
|
23
|
+
else
|
24
|
+
return s
|
22
25
|
end
|
23
|
-
str = items[locale][key]
|
24
|
-
return str
|
25
26
|
end
|
26
27
|
|
27
28
|
def self.getSources(component, locale)
|
29
|
+
SgtnClient.logger.debug "[Source][getSources]component=#{component}, locale=#{locale}"
|
28
30
|
cache_key = SgtnClient::CacheUtil.get_cachekey(component, locale)
|
29
|
-
items = SgtnClient::CacheUtil.get_cache(cache_key)
|
30
|
-
if items.nil?
|
31
|
+
expired, items = SgtnClient::CacheUtil.get_cache(cache_key)
|
32
|
+
if items.nil? || expired
|
31
33
|
items = getBundle(component, locale)
|
32
|
-
SgtnClient.logger.debug "Putting sources items into cache with key: " + cache_key
|
33
34
|
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
34
35
|
else
|
35
|
-
SgtnClient.logger.debug "
|
36
|
+
SgtnClient.logger.debug "[Source][getSources]getting sources from cache with key: " + cache_key
|
36
37
|
end
|
37
38
|
return items
|
38
39
|
end
|
39
40
|
|
40
41
|
def self.loadBundles(locale)
|
42
|
+
SgtnClient.logger.debug "[Source][loadBundles]locale=#{locale}"
|
41
43
|
env = SgtnClient::Config.default_environment
|
42
44
|
SgtnClient::Config.configurations.default = locale
|
43
45
|
source_bundle = SgtnClient::Config.configurations[env]["source_bundle"]
|
44
|
-
|
45
|
-
|
46
|
+
Dir.foreach(source_bundle) do |component|
|
47
|
+
next if component == '.' || component == '..'
|
46
48
|
yamlfile = File.join(source_bundle, component + "/" + locale + ".yml")
|
47
|
-
bundle = read_yml(yamlfile)
|
49
|
+
bundle = SgtnClient::FileUtil.read_yml(yamlfile)
|
48
50
|
cachekey = SgtnClient::CacheUtil.get_cachekey(component, locale)
|
49
51
|
SgtnClient::CacheUtil.write_cache(cachekey,bundle)
|
50
52
|
end
|
@@ -52,23 +54,18 @@ module SgtnClient
|
|
52
54
|
|
53
55
|
private
|
54
56
|
def self.getBundle(component, locale)
|
57
|
+
SgtnClient.logger.debug "[Source][getBundle]component=#{component}, locale=#{locale}"
|
55
58
|
env = SgtnClient::Config.default_environment
|
56
59
|
source_bundle = SgtnClient::Config.configurations[env]["source_bundle"]
|
57
60
|
bundlepath = source_bundle + "/" + component + "/" + locale + ".yml"
|
58
|
-
SgtnClient.logger.debug "Getting source from bundle: " + bundlepath
|
59
61
|
begin
|
60
|
-
bundle = read_yml(bundlepath)
|
62
|
+
bundle = SgtnClient::FileUtil.read_yml(bundlepath)
|
61
63
|
rescue => exception
|
62
64
|
SgtnClient.logger.error exception.message
|
63
65
|
end
|
64
66
|
return bundle
|
65
67
|
end
|
66
68
|
|
67
|
-
def self.read_yml(file_name)
|
68
|
-
erb = ERB.new(File.read(file_name))
|
69
|
-
erb.filename = file_name
|
70
|
-
YAML.load(erb.result)
|
71
|
-
end
|
72
69
|
end
|
73
70
|
|
74
71
|
end
|
@@ -12,30 +12,38 @@ module SgtnClient
|
|
12
12
|
class Translation
|
13
13
|
|
14
14
|
def self.getString(component, key, locale)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
SgtnClient.logger.debug "Getting translations from cache with key: " + cache_key
|
15
|
+
SgtnClient.logger.debug "[Translation.getString]component: #{component}, key: #{key}, locale: #{locale}"
|
16
|
+
str = getTranslation(component, key, locale)
|
17
|
+
if str.nil?
|
18
|
+
str = SgtnClient::Source.getSource(component, key, SgtnClient::Config.configurations.default)
|
19
|
+
if str.nil?
|
20
|
+
SgtnClient.logger.debug "[Translation][getString] Missing source string with key: #{key}, component: #{component}, locale: #{locale}"
|
21
|
+
end
|
23
22
|
end
|
23
|
+
str
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
str = items["messages"][key]
|
26
|
+
def self.getString_p(component, key, plural_args, locale)
|
27
|
+
SgtnClient.logger.debug "[Translation][getString_p]component=#{component}, key=#{key}, locale=#{locale}"
|
28
|
+
str = getTranslation(component, key, locale)
|
30
29
|
if str.nil?
|
31
|
-
|
30
|
+
str = SgtnClient::Source.getSource(component, key, SgtnClient::Config.configurations.default)
|
31
|
+
if str.nil?
|
32
|
+
SgtnClient.logger.debug "[Translation][getString_p] Missing source string with key: #{key}, component: #{component}, locale: #{locale}"
|
33
|
+
return nil
|
34
|
+
end
|
35
|
+
str.to_plural_s(:en, plural_args)
|
32
36
|
else
|
33
|
-
|
37
|
+
str.to_plural_s(locale, plural_args)
|
34
38
|
end
|
35
|
-
|
39
|
+
end
|
36
40
|
|
37
|
-
def self.getString_f(component, key, args, locale)
|
38
|
-
|
41
|
+
def self.getString_f(component, key, args, locale, *optionals)
|
42
|
+
SgtnClient.logger.debug "[Translation][getString_f]component=#{component}, key=#{key}, locale=#{locale}"
|
43
|
+
s = getString(component, key, locale, *optionals)
|
44
|
+
if s.nil?
|
45
|
+
return nil
|
46
|
+
end
|
39
47
|
if args.is_a?(Hash)
|
40
48
|
args.each do |source, arg|
|
41
49
|
s.gsub! "{#{source}}", arg
|
@@ -47,24 +55,20 @@ module SgtnClient
|
|
47
55
|
end
|
48
56
|
|
49
57
|
def self.getStrings(component, locale)
|
50
|
-
|
51
|
-
|
52
|
-
items = SgtnClient::CacheUtil.get_cache(cache_key)
|
53
|
-
if items.nil?
|
54
|
-
items = getTranslations(component, flocale)
|
55
|
-
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
56
|
-
else
|
57
|
-
SgtnClient.logger.debug "Getting translations from cache with key: " + cache_key
|
58
|
-
end
|
59
|
-
|
58
|
+
SgtnClient.logger.debug "[Translation][getStrings]component=#{component}, locale=#{locale}"
|
59
|
+
items = get_cs(component, locale)
|
60
60
|
default = SgtnClient::Config.configurations.default
|
61
61
|
if items.nil? || items["messages"] == nil
|
62
62
|
items = {}
|
63
63
|
s = SgtnClient::Source.getSources(component, default)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
if s.nil?
|
65
|
+
SgtnClient.logger.error "[Translation][getStrings] Missing component: #{component}, locale: #{locale}"
|
66
|
+
else
|
67
|
+
default_component, value = s.first
|
68
|
+
items["component"] = component
|
69
|
+
items["messages"] = value
|
70
|
+
items["locale"] = 'source'
|
71
|
+
end
|
68
72
|
end
|
69
73
|
return items
|
70
74
|
end
|
@@ -72,40 +76,61 @@ module SgtnClient
|
|
72
76
|
|
73
77
|
private
|
74
78
|
|
75
|
-
def self.
|
79
|
+
def self.getTranslation(component, key, locale)
|
80
|
+
items = get_cs(component, locale)
|
81
|
+
if items.nil? || items["messages"] == nil
|
82
|
+
nil
|
83
|
+
else
|
84
|
+
items["messages"][key]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.get_cs(component, locale)
|
89
|
+
flocale = SgtnClient::LocaleUtil.fallback(locale)
|
90
|
+
cache_key = SgtnClient::CacheUtil.get_cachekey(component, flocale)
|
91
|
+
SgtnClient.logger.debug "[Translation][get_cs]cache_key=#{cache_key}"
|
92
|
+
expired, items = SgtnClient::CacheUtil.get_cache(cache_key)
|
93
|
+
if items.nil? || expired
|
94
|
+
items = load(component, flocale)
|
95
|
+
if items.nil?
|
96
|
+
items = SgtnClient::Source.getSources(component, SgtnClient::Config.configurations.default)
|
97
|
+
SgtnClient::Core::Cache.put(cache_key, items, 60)
|
98
|
+
else
|
99
|
+
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
100
|
+
end
|
101
|
+
else
|
102
|
+
SgtnClient.logger.debug "[Translation]get translations from cache with key: " + cache_key
|
103
|
+
end
|
104
|
+
|
105
|
+
return items
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.load(component, locale)
|
76
109
|
env = SgtnClient::Config.default_environment
|
77
110
|
mode = SgtnClient::Config.configurations[env]["bundle_mode"]
|
111
|
+
SgtnClient.logger.debug "[Translation][load]mode=#{mode}"
|
78
112
|
if mode == 'offline'
|
79
|
-
return
|
113
|
+
return load_o(component, locale)
|
80
114
|
else
|
81
|
-
return
|
115
|
+
return load_s(component, locale)
|
82
116
|
end
|
83
117
|
end
|
84
118
|
|
85
|
-
def self.
|
119
|
+
def self.load_o(component, locale)
|
86
120
|
env = SgtnClient::Config.default_environment
|
87
121
|
product_name = SgtnClient::Config.configurations[env]["product_name"]
|
88
122
|
version = SgtnClient::Config.configurations[env]["version"].to_s
|
89
123
|
translation_bundle = SgtnClient::Config.configurations[env]["translation_bundle"]
|
90
124
|
bundlepath = translation_bundle + "/" + product_name + "/" + version + "/" + component + "/messages_" + locale + ".json"
|
91
|
-
SgtnClient.
|
92
|
-
begin
|
93
|
-
file = File.read(bundlepath)
|
94
|
-
data_hash = MultiJson.load(file)
|
95
|
-
rescue => exception
|
96
|
-
SgtnClient.logger.error exception.message
|
97
|
-
end
|
98
|
-
return data_hash
|
125
|
+
SgtnClient::FileUtil.read_json(bundlepath)
|
99
126
|
end
|
100
127
|
|
101
|
-
def self.
|
128
|
+
def self.load_s(component, locale)
|
102
129
|
env = SgtnClient::Config.default_environment
|
103
130
|
product_name = SgtnClient::Config.configurations[env]["product_name"]
|
104
131
|
vip_server = SgtnClient::Config.configurations[env]["vip_server"]
|
105
|
-
SgtnClient.logger.debug "Getting translations from server: " + vip_server
|
106
132
|
version = SgtnClient::Config.configurations[env]["version"].to_s
|
107
133
|
url = vip_server + "/i18n/api/v2/translation/products/" + product_name + "/versions/" + version + "/locales/" + locale + "/components/" + component+ "?checkTranslationStatus=false&machineTranslation=false&pseudo=false"
|
108
|
-
SgtnClient.logger.debug url
|
109
134
|
begin
|
110
135
|
obj = SgtnClient::Core::Request.get(url)
|
111
136
|
rescue => exception
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
Date.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
5
|
+
def l_full_s(locale = TwitterCldr.locale)
|
6
|
+
self.to_datetime().localize(locale).to_date().to_full_s
|
7
|
+
end
|
8
|
+
LOCALIZE
|
9
|
+
|
10
|
+
Date.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
11
|
+
def l_long_s(locale = TwitterCldr.locale)
|
12
|
+
self.to_datetime().localize(locale).to_date().to_long_s
|
13
|
+
end
|
14
|
+
LOCALIZE
|
15
|
+
|
16
|
+
Date.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
17
|
+
def l_medium_s(locale = TwitterCldr.locale)
|
18
|
+
self.to_datetime().localize(locale).to_date().to_medium_s
|
19
|
+
end
|
20
|
+
LOCALIZE
|
21
|
+
|
22
|
+
|
23
|
+
Date.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
24
|
+
def l_short_s(locale = TwitterCldr.locale)
|
25
|
+
self.to_datetime().localize(locale).to_date().to_short_s
|
26
|
+
end
|
27
|
+
LOCALIZE
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
DateTime.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 2
|
5
|
+
def l_full_s(locale = TwitterCldr.locale, *args)
|
6
|
+
timezone = args[0]
|
7
|
+
display_name = args[1]
|
8
|
+
if timezone.nil?
|
9
|
+
self.localize(locale).to_full_s
|
10
|
+
elsif display_name.nil?
|
11
|
+
self.localize(locale).with_timezone(timezone).to_full_s
|
12
|
+
else
|
13
|
+
tz = TwitterCldr::Timezones::Timezone.instance(timezone, locale)
|
14
|
+
tz.display_name_for(self, display_name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
LOCALIZE
|
18
|
+
|
19
|
+
DateTime.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
20
|
+
def l_long_s(locale = TwitterCldr.locale, *args)
|
21
|
+
timezone = args[0]
|
22
|
+
display_name = args[1]
|
23
|
+
if timezone.nil?
|
24
|
+
self.localize(locale).to_long_s
|
25
|
+
elsif display_name.nil?
|
26
|
+
self.localize(locale).with_timezone(timezone).to_long_s
|
27
|
+
else
|
28
|
+
tz = TwitterCldr::Timezones::Timezone.instance(timezone, locale)
|
29
|
+
tz.display_name_for(self, display_name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
LOCALIZE
|
33
|
+
|
34
|
+
DateTime.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
35
|
+
def l_medium_s(locale = TwitterCldr.locale, *args)
|
36
|
+
timezone = args[0]
|
37
|
+
display_name = args[1]
|
38
|
+
if timezone.nil?
|
39
|
+
self.localize(locale).to_medium_s
|
40
|
+
elsif display_name.nil?
|
41
|
+
self.localize(locale).with_timezone(timezone).to_medium_s
|
42
|
+
else
|
43
|
+
tz = TwitterCldr::Timezones::Timezone.instance(timezone, locale)
|
44
|
+
tz.display_name_for(self, display_name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
LOCALIZE
|
48
|
+
|
49
|
+
|
50
|
+
DateTime.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
51
|
+
def l_short_s(locale = TwitterCldr.locale, *args)
|
52
|
+
timezone = args[0]
|
53
|
+
display_name = args[1]
|
54
|
+
if timezone.nil?
|
55
|
+
self.localize(locale).to_short_s
|
56
|
+
elsif display_name.nil?
|
57
|
+
self.localize(locale).with_timezone(timezone).to_short_s
|
58
|
+
else
|
59
|
+
tz = TwitterCldr::Timezones::Timezone.instance(timezone, locale)
|
60
|
+
tz.display_name_for(self, display_name)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
LOCALIZE
|
@@ -0,0 +1,11 @@
|
|
1
|
+
|
2
|
+
String.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
3
|
+
def to_plural_s(locale, arg)
|
4
|
+
num_str = SgtnClient::Formatters::PluralFormatter.new(locale).num_s(self, arg)
|
5
|
+
if num_str.nil? || num_str.empty?
|
6
|
+
self.localize(locale) % arg
|
7
|
+
else
|
8
|
+
num_str
|
9
|
+
end
|
10
|
+
end
|
11
|
+
LOCALIZE
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
Time.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
5
|
+
def l_full_s(locale = TwitterCldr.locale)
|
6
|
+
self.localize(locale).to_full_s
|
7
|
+
end
|
8
|
+
LOCALIZE
|
9
|
+
|
10
|
+
Time.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
11
|
+
def l_long_s(locale = TwitterCldr.locale)
|
12
|
+
self.localize(locale).to_long_s
|
13
|
+
end
|
14
|
+
LOCALIZE
|
15
|
+
|
16
|
+
Time.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
17
|
+
def l_medium_s(locale = TwitterCldr.locale)
|
18
|
+
self.localize(locale).to_medium_s
|
19
|
+
end
|
20
|
+
LOCALIZE
|
21
|
+
|
22
|
+
|
23
|
+
Time.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
24
|
+
def l_short_s(locale = TwitterCldr.locale)
|
25
|
+
self.localize(locale).to_short_s
|
26
|
+
end
|
27
|
+
LOCALIZE
|
@@ -5,78 +5,95 @@ module SgtnClient::Core
|
|
5
5
|
Entry = Struct.new(:expiry, :value)
|
6
6
|
|
7
7
|
def self.initialize(disabled=false, opts={})
|
8
|
-
|
9
|
-
|
8
|
+
@@opts = opts
|
9
|
+
@mutex = Mutex.new
|
10
10
|
if disabled == false
|
11
|
-
|
12
|
-
SgtnClient.logger.debug "Cache is enabled!"
|
11
|
+
@@data = Hash.new
|
12
|
+
SgtnClient.logger.debug "[Cache][initialize]cache is enabled!"
|
13
13
|
else
|
14
|
-
|
14
|
+
@@data = nil
|
15
|
+
SgtnClient.logger.debug "[Cache][initialize]cache is disabled!"
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
19
|
def self.keys
|
19
|
-
if
|
20
|
+
if @@data == nil
|
20
21
|
return nil
|
21
22
|
end
|
22
|
-
SgtnClient.logger.debug "
|
23
|
-
|
23
|
+
SgtnClient.logger.debug "[Cache][keys]get cache keys"
|
24
|
+
@@data.keys
|
24
25
|
end
|
25
26
|
|
26
27
|
def self.get(key)
|
27
|
-
if
|
28
|
-
return nil
|
28
|
+
if @@data == nil
|
29
|
+
return nil, nil
|
29
30
|
end
|
30
|
-
SgtnClient.logger.debug "
|
31
|
-
invalidate
|
32
|
-
$data[key][:value] if has(key)
|
31
|
+
SgtnClient.logger.debug "[Cache][get]get cache for key: " + key
|
32
|
+
invalidate(key)
|
33
33
|
end
|
34
34
|
|
35
35
|
def self.has(key)
|
36
|
-
if
|
36
|
+
if @@data == nil
|
37
37
|
return nil
|
38
38
|
end
|
39
|
-
SgtnClient.logger.debug "
|
40
|
-
|
39
|
+
SgtnClient.logger.debug "[Cache][has]check if the cache has key: #{(@@data.has_key? key)}"
|
40
|
+
@@data.has_key? key
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.put(key, value, ttl=nil)
|
44
|
-
|
45
|
-
|
44
|
+
@mutex.synchronize do
|
45
|
+
if @@data == nil || value == nil
|
46
|
+
return nil
|
47
|
+
end
|
48
|
+
ttl ||= @@opts[:ttl]
|
49
|
+
# hours from new
|
50
|
+
SgtnClient.logger.debug "[Cache][put]put cache for key '" + key + "' with expired time at'" + (Time.now + ttl*60).to_s
|
51
|
+
@@data[key] = Entry.new(Time.now + ttl*60, value)
|
46
52
|
end
|
47
|
-
ttl ||= @opts[:ttl]
|
48
|
-
# hours from new
|
49
|
-
SgtnClient.logger.debug "Put cache for key '" + key + "' with expired time at'" + (Time.now + ttl*60).to_s
|
50
|
-
$data[key] = Entry.new(Time.now + ttl*60, value)
|
51
53
|
end
|
52
54
|
|
53
55
|
def self.delete(key)
|
54
|
-
|
55
|
-
|
56
|
+
@mutex.synchronize do
|
57
|
+
if @@data == nil
|
58
|
+
return nil
|
59
|
+
end
|
60
|
+
SgtnClient.logger.debug "[Cache][delete]delete cache for key: " + key
|
61
|
+
@@data.delete key
|
56
62
|
end
|
57
|
-
SgtnClient.logger.debug "Delete cache for key: " + key
|
58
|
-
$data.delete key
|
59
63
|
end
|
60
64
|
|
61
65
|
def self.clear
|
62
|
-
|
63
|
-
|
66
|
+
@mutex.synchronize do
|
67
|
+
if @@data == nil
|
68
|
+
return nil
|
69
|
+
end
|
70
|
+
SgtnClient.logger.debug "[Cache][clear]clear cache!"
|
71
|
+
@@data = Hash.new
|
64
72
|
end
|
65
|
-
SgtnClient.logger.debug "Clear cache!"
|
66
|
-
$data = Hash.new
|
67
73
|
end
|
68
74
|
|
69
|
-
def self.invalidate
|
70
|
-
|
71
|
-
|
75
|
+
def self.invalidate(key)
|
76
|
+
@mutex.synchronize do
|
77
|
+
if @@data == nil
|
78
|
+
return nil, nil
|
79
|
+
end
|
80
|
+
SgtnClient.logger.debug "[Cache][invalidate]invalidate expired cache......"
|
81
|
+
now = Time.now
|
82
|
+
if has(key)
|
83
|
+
v = @@data[key]
|
84
|
+
expired = false
|
85
|
+
SgtnClient.logger.debug "[Cache][invalidate]check cache: key=#{key}, expiredtime=#{v[:expiry]}, now=#{now}, expired=#{(v[:expiry] < now)}"
|
86
|
+
if v[:expiry] < now
|
87
|
+
SgtnClient.logger.debug "[Cache][invalidate]before deleting the cache: data=#{@@data}"
|
88
|
+
@@data.delete(key)
|
89
|
+
SgtnClient.logger.debug "[Cache][invalidate]after deleting the cache: data=#{@@data}"
|
90
|
+
expired = true
|
91
|
+
end
|
92
|
+
return expired, v[:value]
|
93
|
+
else
|
94
|
+
return nil, nil
|
95
|
+
end
|
72
96
|
end
|
73
|
-
SgtnClient.logger.debug "Invalidating expired cache......"
|
74
|
-
now = Time.now
|
75
|
-
$data.each {
|
76
|
-
|k, v|
|
77
|
-
SgtnClient.logger.debug "Checking cache: key=#{k}, expiredtime=#{v[:expiry]}, now=#{now}, expired=#{(v[:expiry] < now)}"
|
78
|
-
}
|
79
|
-
$data.delete_if {|k, v| v[:expiry] < now}
|
80
97
|
end
|
81
98
|
end
|
82
99
|
|
@@ -40,7 +40,7 @@ module SgtnClient
|
|
40
40
|
:rest_endpoint, :rest_token_endpoint, :client_id, :client_secret,
|
41
41
|
:openid_endpoint, :openid_redirect_uri, :openid_client_id, :openid_client_secret,
|
42
42
|
:verbose_logging, :product_name, :version, :vip_server, :bundle_mode,
|
43
|
-
:translation_bundle, :source_bundle, :cache_expiry_period, :disable_cache
|
43
|
+
:translation_bundle, :source_bundle, :cache_expiry_period, :disable_cache, :default_language
|
44
44
|
|
45
45
|
|
46
46
|
# Create Config object
|
@@ -4,7 +4,11 @@ require 'multi_json'
|
|
4
4
|
module SgtnClient::Core
|
5
5
|
class Request
|
6
6
|
def self.get(url)
|
7
|
-
|
7
|
+
SgtnClient.logger.debug "[Request][get]url=#{url}"
|
8
|
+
res = RestClient::Resource.new(
|
9
|
+
url,
|
10
|
+
:verify_ssl => false
|
11
|
+
).get
|
8
12
|
begin
|
9
13
|
obj = MultiJson.load(res)
|
10
14
|
rescue MultiJson::ParseError => exception
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module SgtnClient
|
4
|
+
module Formatters
|
5
|
+
class PluralFormatter
|
6
|
+
|
7
|
+
attr_reader :locale
|
8
|
+
|
9
|
+
def initialize(locale = TwitterCldr.locale)
|
10
|
+
@locale = TwitterCldr.convert_locale(locale)
|
11
|
+
end
|
12
|
+
|
13
|
+
def num_s(string, replacements)
|
14
|
+
reg = Regexp.union(
|
15
|
+
/%<(\{.*?\})>/
|
16
|
+
)
|
17
|
+
string.gsub(reg) do
|
18
|
+
count_placeholder, patterns = if $1
|
19
|
+
pluralization_hash = JSON.parse($1)
|
20
|
+
if pluralization_hash.is_a?(Hash) && pluralization_hash.size == 1
|
21
|
+
pluralization_hash.first
|
22
|
+
else
|
23
|
+
raise ArgumentError.new('expected a Hash with a single key')
|
24
|
+
end
|
25
|
+
else
|
26
|
+
raise ArgumentError.new('invalide format')
|
27
|
+
end
|
28
|
+
count = replacements[count_placeholder.to_sym].to_s
|
29
|
+
if patterns.is_a?(Hash)
|
30
|
+
return TwitterCldr::Utils.deep_symbolize_keys(patterns)[count.to_sym]
|
31
|
+
else
|
32
|
+
raise ArgumentError.new('expected patterns to be a Hash')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -11,6 +11,12 @@ module SgtnClient
|
|
11
11
|
autoload :Exceptions, "sgtn-client/core/exceptions"
|
12
12
|
autoload :ValidateUtil, "sgtn-client/util/validate-util"
|
13
13
|
autoload :LocaleUtil, "sgtn-client/util/locale-util"
|
14
|
+
autoload :FileUtil, "sgtn-client/util/file-util"
|
15
|
+
|
16
|
+
module Formatters
|
17
|
+
autoload :PluralFormatter, "sgtn-client/formatters/plurals/plural_formatter"
|
18
|
+
end
|
19
|
+
|
14
20
|
|
15
21
|
class << self
|
16
22
|
def configure(options = {}, &block)
|
@@ -32,6 +38,7 @@ module SgtnClient
|
|
32
38
|
|
33
39
|
# create log file
|
34
40
|
file = './sgtnclient_d.log'
|
41
|
+
SgtnClient.logger.debug "[Client][load]create log file=#{file}"
|
35
42
|
if args[2] != nil
|
36
43
|
file = args[2]
|
37
44
|
end
|
@@ -42,7 +49,7 @@ module SgtnClient
|
|
42
49
|
# Set log level for sandbox mode
|
43
50
|
env = SgtnClient::Config.default_environment
|
44
51
|
mode = SgtnClient::Config.configurations[env]["mode"]
|
45
|
-
SgtnClient.logger.
|
52
|
+
SgtnClient.logger.debug "[Client][load]set log level, mode=#{mode}"
|
46
53
|
if mode == 'sandbox'
|
47
54
|
SgtnClient.logger.level = Logger::DEBUG
|
48
55
|
else
|
@@ -51,6 +58,7 @@ module SgtnClient
|
|
51
58
|
|
52
59
|
# initialize cache
|
53
60
|
disable_cache = SgtnClient::Config.configurations[env]["disable_cache"]
|
61
|
+
SgtnClient.logger.debug "[Client][load]cache initialize, disable_cache=#{disable_cache}"
|
54
62
|
if disable_cache != nil
|
55
63
|
SgtnClient::Core::Cache.initialize(disable_cache)
|
56
64
|
else
|
@@ -10,21 +10,27 @@ module SgtnClient
|
|
10
10
|
class CacheUtil
|
11
11
|
|
12
12
|
def self.get_cache(cache_key)
|
13
|
-
items = SgtnClient::Core::Cache.get(cache_key)
|
14
|
-
|
13
|
+
expired, items = SgtnClient::Core::Cache.get(cache_key)
|
14
|
+
SgtnClient.logger.debug "[CacheUtil]get cache with key #{cache_key}, expired #{expired}"
|
15
|
+
return expired, items
|
15
16
|
end
|
16
17
|
|
17
18
|
def self.clear_cache()
|
18
19
|
SgtnClient::Core::Cache.clear()
|
20
|
+
SgtnClient.logger.debug "[CacheUtil]clear cache"
|
19
21
|
end
|
20
22
|
|
21
23
|
def self.write_cache(cache_key, items)
|
24
|
+
if items.nil?
|
25
|
+
return nil
|
26
|
+
end
|
22
27
|
env = SgtnClient::Config.default_environment
|
23
28
|
cache_expiry_period = SgtnClient::Config.configurations[env]["cache_expiry_period"]
|
24
29
|
# expired after 24 hours
|
25
30
|
if cache_expiry_period == nil
|
26
31
|
cache_expiry_period = 24*60
|
27
32
|
end
|
33
|
+
SgtnClient.logger.debug "[CacheUtil]write cache with key #{cache_key}, cache_expiry_period #{cache_expiry_period}, itmes #{items}"
|
28
34
|
SgtnClient::Core::Cache.put(cache_key, items, cache_expiry_period)
|
29
35
|
end
|
30
36
|
|
@@ -32,7 +38,13 @@ module SgtnClient
|
|
32
38
|
env = SgtnClient::Config.default_environment
|
33
39
|
product_name = SgtnClient::Config.configurations[env]["product_name"]
|
34
40
|
version = SgtnClient::Config.configurations[env]["version"].to_s
|
35
|
-
|
41
|
+
default_l = SgtnClient::Config.configurations[env]["default_language"]
|
42
|
+
if default_l == nil
|
43
|
+
default_l = 'en'
|
44
|
+
end
|
45
|
+
lc = locale == default_l ? SgtnClient::Config.configurations.default: locale
|
46
|
+
SgtnClient.logger.debug "[CacheUtil]get cache key: #{lc}"
|
47
|
+
return product_name + "_" + version + "_" + component + "_" + lc
|
36
48
|
end
|
37
49
|
end
|
38
50
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module SgtnClient
|
5
|
+
|
6
|
+
class FileUtil
|
7
|
+
|
8
|
+
@mutex = Mutex.new
|
9
|
+
|
10
|
+
def self.read_json(bundlepath)
|
11
|
+
SgtnClient.logger.debug "[FileUtil]read json file from: " + bundlepath
|
12
|
+
@mutex.synchronize do
|
13
|
+
data_hash = nil
|
14
|
+
begin
|
15
|
+
file = File.read(bundlepath)
|
16
|
+
data_hash = MultiJson.load(file)
|
17
|
+
rescue => exception
|
18
|
+
SgtnClient.logger.error exception.message
|
19
|
+
end
|
20
|
+
return data_hash
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.read_yml(file_name)
|
25
|
+
SgtnClient.logger.debug "[FileUtil]read yml file from: " + file_name
|
26
|
+
@mutex.synchronize do
|
27
|
+
erb = ERB.new(File.read(file_name))
|
28
|
+
erb.filename = file_name
|
29
|
+
YAML.load(erb.result)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -4,8 +4,8 @@ module SgtnClient
|
|
4
4
|
class ValidateUtil
|
5
5
|
|
6
6
|
def self.validate_config()
|
7
|
-
SgtnClient.logger.debug "-----------Start to validate configuration's setting itmes-----------"
|
8
7
|
env = SgtnClient::Config.default_environment
|
8
|
+
SgtnClient.logger.debug "[ValidateUtil][validate_config] env = #{env}"
|
9
9
|
messages = "\n"
|
10
10
|
|
11
11
|
mode = SgtnClient::Config.configurations[env]["mode"]
|
@@ -36,7 +36,6 @@ module SgtnClient
|
|
36
36
|
if messages != "\n"
|
37
37
|
raise SgtnClient::Exceptions::MissingConfig.new(messages)
|
38
38
|
end
|
39
|
-
SgtnClient.logger.debug "-----------End to validate configuration's setting itmes-----------"
|
40
39
|
end
|
41
40
|
|
42
41
|
end
|
data/lib/singleton-ruby.rb
CHANGED
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: singleton-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.4
|
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:
|
11
|
+
date: 2022-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: twitter_cldr
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '6.6'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '6.6'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: webmock
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -230,6 +244,20 @@ dependencies:
|
|
230
244
|
- - "~>"
|
231
245
|
- !ruby/object:Gem::Version
|
232
246
|
version: '1.0'
|
247
|
+
- !ruby/object:Gem::Dependency
|
248
|
+
name: twitter_cldr
|
249
|
+
requirement: !ruby/object:Gem::Requirement
|
250
|
+
requirements:
|
251
|
+
- - "~>"
|
252
|
+
- !ruby/object:Gem::Version
|
253
|
+
version: '6.6'
|
254
|
+
type: :runtime
|
255
|
+
prerelease: false
|
256
|
+
version_requirements: !ruby/object:Gem::Requirement
|
257
|
+
requirements:
|
258
|
+
- - "~>"
|
259
|
+
- !ruby/object:Gem::Version
|
260
|
+
version: '6.6'
|
233
261
|
description: Singleton Ruby client
|
234
262
|
email: g11n-vip-project@vmware.com
|
235
263
|
executables: []
|
@@ -241,13 +269,20 @@ files:
|
|
241
269
|
- lib/sgtn-client/api/source.rb
|
242
270
|
- lib/sgtn-client/api/t.rb
|
243
271
|
- lib/sgtn-client/api/translation.rb
|
272
|
+
- lib/sgtn-client/cldr/core_ext.rb
|
273
|
+
- lib/sgtn-client/cldr/localized_date.rb
|
274
|
+
- lib/sgtn-client/cldr/localized_datetime.rb
|
275
|
+
- lib/sgtn-client/cldr/localized_str.rb
|
276
|
+
- lib/sgtn-client/cldr/localized_time.rb
|
244
277
|
- lib/sgtn-client/core/cache.rb
|
245
278
|
- lib/sgtn-client/core/config.rb
|
246
279
|
- lib/sgtn-client/core/exceptions.rb
|
247
280
|
- lib/sgtn-client/core/logging.rb
|
248
281
|
- lib/sgtn-client/core/request.rb
|
282
|
+
- lib/sgtn-client/formatters/plurals/plural_formatter.rb
|
249
283
|
- lib/sgtn-client/sgtn-client.rb
|
250
284
|
- lib/sgtn-client/util/cache-util.rb
|
285
|
+
- lib/sgtn-client/util/file-util.rb
|
251
286
|
- lib/sgtn-client/util/locale-util.rb
|
252
287
|
- lib/sgtn-client/util/validate-util.rb
|
253
288
|
- lib/singleton-ruby.rb
|