singleton-client 0.7.0
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 +7 -0
- data/README.md +54 -0
- data/lib/sgtn-client/api/source.rb +74 -0
- data/lib/sgtn-client/api/t.rb +22 -0
- data/lib/sgtn-client/api/translation.rb +122 -0
- data/lib/sgtn-client/core/cache.rb +83 -0
- data/lib/sgtn-client/core/config.rb +166 -0
- data/lib/sgtn-client/core/exceptions.rb +112 -0
- data/lib/sgtn-client/core/logging.rb +50 -0
- data/lib/sgtn-client/core/request.rb +17 -0
- data/lib/sgtn-client/sgtn-client.rb +70 -0
- data/lib/sgtn-client/util/cache-util.rb +39 -0
- data/lib/sgtn-client/util/locale-util.rb +31 -0
- data/lib/sgtn-client/util/validate-util.rb +44 -0
- data/lib/singleton-ruby.rb +2 -0
- data/lib/version.rb +3 -0
- metadata +278 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4bff1730aecabe391982a491a349af0a51af8f7c894d79a3704866959460dec5
|
4
|
+
data.tar.gz: ef351201885c96d9ada076af3f780291fc645ac100541bcdb87a7dd2f5bdf9c6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e10e2f79a2654cd0055dbfa555149c536aa2d7557b9ce1af12206abe2106e851cbb9b428e0e8f8fa6a6833a69f5566ec4a80df6d739d1c46d5b750a9e64d9653
|
7
|
+
data.tar.gz: f7cfc58191dae18ae6b1235980d2009e9d308982ac80c977ffd769884817d4b9745cfb5415996681b9085e366abd93c1b44119983663ecbdf2be4a8d59ff5c86
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Singeleton client for Ruby
|
2
|
+
|
3
|
+
## Prerequisites
|
4
|
+
- Ruby version: 3.0.0 or above
|
5
|
+
- Bundler version: 2.2.3 or above
|
6
|
+
|
7
|
+
## Run Unit Test
|
8
|
+
rake spec:unit
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
Basic Usage:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
require 'singleton-ruby'
|
16
|
+
|
17
|
+
include SgtnClient
|
18
|
+
|
19
|
+
SgtnClient.load(file, mode)
|
20
|
+
|
21
|
+
SgtnClient::Source.loadBundles(locale)
|
22
|
+
|
23
|
+
@Result = SgtnClient::Translation.getString(component, key, locale)
|
24
|
+
|
25
|
+
```
|
26
|
+
## API Usage
|
27
|
+
|
28
|
+
### Get a string's translation
|
29
|
+
SgtnClient::Translation.getString(component, key, locale)
|
30
|
+
|
31
|
+
### Get a string's translation and format it with placeholders
|
32
|
+
SgtnClient::Translation.getString_f(component, key, args, locale)
|
33
|
+
|
34
|
+
### Get a component's translations
|
35
|
+
SgtnClient::Translation.getStrings(component, locale)
|
36
|
+
|
37
|
+
|
38
|
+
## API Usage(with request_store)
|
39
|
+
|
40
|
+
Before call below APIs(without locale and component arguments), it requires to set the locale and component in the initial codes.
|
41
|
+
|
42
|
+
### Get a string's translation
|
43
|
+
SgtnClient::T.s(key)
|
44
|
+
|
45
|
+
### Get a string's translation and format it with placeholders
|
46
|
+
SgtnClient::T.s_f(key, args)
|
47
|
+
|
48
|
+
### Get a component's translations
|
49
|
+
SgtnClient::T.c()
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module SgtnClient
|
5
|
+
|
6
|
+
autoload :CacheUtil, "sgtn-client/util/cache-util"
|
7
|
+
|
8
|
+
class Source
|
9
|
+
|
10
|
+
def self.getSource(component, key, locale)
|
11
|
+
cache_key = SgtnClient::CacheUtil.get_cachekey(component, locale)
|
12
|
+
items = SgtnClient::CacheUtil.get_cache(cache_key)
|
13
|
+
if items.nil?
|
14
|
+
items = getBundle(component, locale)
|
15
|
+
SgtnClient.logger.debug "Putting sources items into cache with key: " + cache_key
|
16
|
+
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
17
|
+
else
|
18
|
+
SgtnClient.logger.debug "Getting sources from cache with key: " + cache_key
|
19
|
+
end
|
20
|
+
if items.nil?
|
21
|
+
return key
|
22
|
+
end
|
23
|
+
str = items[locale][key]
|
24
|
+
return str
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.getSources(component, locale)
|
28
|
+
cache_key = SgtnClient::CacheUtil.get_cachekey(component, locale)
|
29
|
+
items = SgtnClient::CacheUtil.get_cache(cache_key)
|
30
|
+
if items.nil?
|
31
|
+
items = getBundle(component, locale)
|
32
|
+
SgtnClient.logger.debug "Putting sources items into cache with key: " + cache_key
|
33
|
+
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
34
|
+
else
|
35
|
+
SgtnClient.logger.debug "Getting sources from cache with key: " + cache_key
|
36
|
+
end
|
37
|
+
return items
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.loadBundles(locale)
|
41
|
+
env = SgtnClient::Config.default_environment
|
42
|
+
SgtnClient::Config.configurations.default = locale
|
43
|
+
source_bundle = SgtnClient::Config.configurations[env]["source_bundle"]
|
44
|
+
SgtnClient.logger.debug "Loading [" + locale + "] source bundles from path: " + source_bundle
|
45
|
+
Dir.children(source_bundle).each do |component|
|
46
|
+
yamlfile = File.join(source_bundle, component + "/" + locale + ".yml")
|
47
|
+
bundle = read_yml(yamlfile)
|
48
|
+
cachekey = SgtnClient::CacheUtil.get_cachekey(component, locale)
|
49
|
+
SgtnClient::CacheUtil.write_cache(cachekey,bundle)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def self.getBundle(component, locale)
|
55
|
+
env = SgtnClient::Config.default_environment
|
56
|
+
source_bundle = SgtnClient::Config.configurations[env]["source_bundle"]
|
57
|
+
bundlepath = source_bundle + "/" + component + "/" + locale + ".yml"
|
58
|
+
SgtnClient.logger.debug "Getting source from bundle: " + bundlepath
|
59
|
+
begin
|
60
|
+
bundle = read_yml(bundlepath)
|
61
|
+
rescue => exception
|
62
|
+
SgtnClient.logger.error exception.message
|
63
|
+
end
|
64
|
+
return bundle
|
65
|
+
end
|
66
|
+
|
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
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SgtnClient
|
2
|
+
class T < Translation
|
3
|
+
|
4
|
+
def self.s(key)
|
5
|
+
locale = RequestStore.store[:locale]
|
6
|
+
component = RequestStore.store[:component]
|
7
|
+
return getString(component, key, locale)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.s_f(key, args)
|
11
|
+
locale = RequestStore.store[:locale]
|
12
|
+
component = RequestStore.store[:component]
|
13
|
+
return getString_f(component, key, args, locale)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.c()
|
17
|
+
locale = RequestStore.store[:locale]
|
18
|
+
component = RequestStore.store[:component]
|
19
|
+
return getStrings(component, locale)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
module SgtnClient
|
4
|
+
|
5
|
+
module Core
|
6
|
+
autoload :Request, "sgtn-client/core/request"
|
7
|
+
autoload :Cache, "sgtn-client/core/cache"
|
8
|
+
autoload :CacheUtil, "sgtn-client/util/cache-util"
|
9
|
+
autoload :LocaleUtil, "sgtn-client/util/locale-util"
|
10
|
+
end
|
11
|
+
|
12
|
+
class Translation
|
13
|
+
|
14
|
+
def self.getString(component, key, locale)
|
15
|
+
flocale = SgtnClient::LocaleUtil.fallback(locale)
|
16
|
+
cache_key = SgtnClient::CacheUtil.get_cachekey(component, flocale)
|
17
|
+
items = SgtnClient::CacheUtil.get_cache(cache_key)
|
18
|
+
if items.nil?
|
19
|
+
items = getTranslations(component, flocale)
|
20
|
+
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
21
|
+
else
|
22
|
+
SgtnClient.logger.debug "Getting translations from cache with key: " + cache_key
|
23
|
+
end
|
24
|
+
|
25
|
+
default = SgtnClient::Config.configurations.default
|
26
|
+
if items.nil? || items["messages"] == nil
|
27
|
+
return SgtnClient::Source.getSource(component, key, default)
|
28
|
+
end
|
29
|
+
str = items["messages"][key]
|
30
|
+
if str.nil?
|
31
|
+
return SgtnClient::Source.getSource(component, key, default)
|
32
|
+
else
|
33
|
+
return str
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.getString_f(component, key, args, locale)
|
38
|
+
s = getString(component, key, locale)
|
39
|
+
if args.is_a?(Hash)
|
40
|
+
args.each do |source, arg|
|
41
|
+
s.gsub! "{#{source}}", arg
|
42
|
+
end
|
43
|
+
elsif args.is_a?(Array)
|
44
|
+
s = sprintf s % args
|
45
|
+
end
|
46
|
+
return s
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.getStrings(component, locale)
|
50
|
+
flocale = SgtnClient::LocaleUtil.fallback(locale)
|
51
|
+
cache_key = SgtnClient::CacheUtil.get_cachekey(component, flocale)
|
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
|
+
|
60
|
+
default = SgtnClient::Config.configurations.default
|
61
|
+
if items.nil? || items["messages"] == nil
|
62
|
+
items = {}
|
63
|
+
s = SgtnClient::Source.getSources(component, default)
|
64
|
+
default_component, value = s.first
|
65
|
+
items["component"] = default_component
|
66
|
+
items["messages"] = value
|
67
|
+
items["locale"] = 'source'
|
68
|
+
end
|
69
|
+
return items
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def self.getTranslations(component, locale)
|
76
|
+
env = SgtnClient::Config.default_environment
|
77
|
+
mode = SgtnClient::Config.configurations[env]["bundle_mode"]
|
78
|
+
if mode == 'offline'
|
79
|
+
return get_offbundle(component, locale)
|
80
|
+
else
|
81
|
+
return get_server(component, locale)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.get_offbundle(component, locale)
|
86
|
+
env = SgtnClient::Config.default_environment
|
87
|
+
product_name = SgtnClient::Config.configurations[env]["product_name"]
|
88
|
+
version = SgtnClient::Config.configurations[env]["version"].to_s
|
89
|
+
translation_bundle = SgtnClient::Config.configurations[env]["translation_bundle"]
|
90
|
+
bundlepath = translation_bundle + "/" + product_name + "/" + version + "/" + component + "/messages_" + locale + ".json"
|
91
|
+
SgtnClient.logger.debug "Getting translations from offline bundle: " + bundlepath
|
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
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.get_server(component, locale)
|
102
|
+
env = SgtnClient::Config.default_environment
|
103
|
+
product_name = SgtnClient::Config.configurations[env]["product_name"]
|
104
|
+
vip_server = SgtnClient::Config.configurations[env]["vip_server"]
|
105
|
+
SgtnClient.logger.debug "Getting translations from server: " + vip_server
|
106
|
+
version = SgtnClient::Config.configurations[env]["version"].to_s
|
107
|
+
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
|
+
begin
|
110
|
+
obj = SgtnClient::Core::Request.get(url)
|
111
|
+
rescue => exception
|
112
|
+
SgtnClient.logger.error exception.message
|
113
|
+
end
|
114
|
+
if obj != nil
|
115
|
+
obj = obj["data"]
|
116
|
+
end
|
117
|
+
return obj
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module SgtnClient::Core
|
4
|
+
class Cache
|
5
|
+
Entry = Struct.new(:expiry, :value)
|
6
|
+
|
7
|
+
def self.initialize(disabled=false, opts={})
|
8
|
+
$opts = opts
|
9
|
+
SgtnClient.logger.debug "Initialize cache......"
|
10
|
+
if disabled == false
|
11
|
+
$data = Hash.new
|
12
|
+
SgtnClient.logger.debug "Cache is enabled!"
|
13
|
+
else
|
14
|
+
SgtnClient.logger.debug "Cache is disabled!"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.keys
|
19
|
+
if $data == nil
|
20
|
+
return nil
|
21
|
+
end
|
22
|
+
SgtnClient.logger.debug "Get cache keys"
|
23
|
+
$data.keys
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.get(key)
|
27
|
+
if $data == nil
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
SgtnClient.logger.debug "Get cache for key: " + key
|
31
|
+
invalidate
|
32
|
+
$data[key][:value] if has(key)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.has(key)
|
36
|
+
if $data == nil
|
37
|
+
return nil
|
38
|
+
end
|
39
|
+
SgtnClient.logger.debug "Has cache for key: " + key
|
40
|
+
$data.has_key? key
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.put(key, value, ttl=nil)
|
44
|
+
if $data == nil
|
45
|
+
return nil
|
46
|
+
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
|
+
end
|
52
|
+
|
53
|
+
def self.delete(key)
|
54
|
+
if $data == nil
|
55
|
+
return nil
|
56
|
+
end
|
57
|
+
SgtnClient.logger.debug "Delete cache for key: " + key
|
58
|
+
$data.delete key
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.clear
|
62
|
+
if $data == nil
|
63
|
+
return nil
|
64
|
+
end
|
65
|
+
SgtnClient.logger.debug "Clear cache!"
|
66
|
+
$data = Hash.new
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.invalidate
|
70
|
+
if $data == nil
|
71
|
+
return nil
|
72
|
+
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
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module SgtnClient
|
5
|
+
#include Exceptions
|
6
|
+
module Configuration
|
7
|
+
|
8
|
+
def config
|
9
|
+
@config ||= Config.config
|
10
|
+
end
|
11
|
+
|
12
|
+
def set_config(env, override_configurations = {})
|
13
|
+
@config =
|
14
|
+
case env
|
15
|
+
when Config
|
16
|
+
env
|
17
|
+
when Hash
|
18
|
+
begin
|
19
|
+
config.dup.merge!(env)
|
20
|
+
rescue Errno::ENOENT => error
|
21
|
+
Config.new(env)
|
22
|
+
end
|
23
|
+
else
|
24
|
+
Config.config(env, override_configurations)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
alias_method :config=, :set_config
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
class Config
|
34
|
+
|
35
|
+
attr_accessor :username, :password, :signature, :app_id, :cert_path,
|
36
|
+
:token, :token_secret, :subject,
|
37
|
+
:http_timeout, :http_proxy,
|
38
|
+
:device_ipaddress, :sandbox_email_address,
|
39
|
+
:mode, :endpoint, :merchant_endpoint, :platform_endpoint, :ipn_endpoint,
|
40
|
+
:rest_endpoint, :rest_token_endpoint, :client_id, :client_secret,
|
41
|
+
:openid_endpoint, :openid_redirect_uri, :openid_client_id, :openid_client_secret,
|
42
|
+
:verbose_logging, :product_name, :version, :vip_server, :bundle_mode,
|
43
|
+
:translation_bundle, :source_bundle, :cache_expiry_period, :disable_cache
|
44
|
+
|
45
|
+
|
46
|
+
# Create Config object
|
47
|
+
# === Options(Hash)
|
48
|
+
# * <tt>username</tt> -- Username
|
49
|
+
# * <tt>password</tt> -- Password
|
50
|
+
# * <tt>signature</tt> (Optional if certificate present) -- Signature
|
51
|
+
# * <tt>app_id</tt> -- Application ID
|
52
|
+
# * <tt>cert_path</tt> (Optional if signature present) -- Certificate file path
|
53
|
+
def initialize(options)
|
54
|
+
merge!(options)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Override configurations
|
58
|
+
def merge!(options)
|
59
|
+
options.each do |key, value|
|
60
|
+
send("#{key}=", value)
|
61
|
+
end
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
class << self
|
66
|
+
|
67
|
+
@@config_cache = {}
|
68
|
+
def load(file_name, default_env = default_environment)
|
69
|
+
@@config_cache = {}
|
70
|
+
@@configurations = read_configurations(file_name)
|
71
|
+
@@default_environment = default_env
|
72
|
+
config
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Get default environment name
|
77
|
+
def default_environment
|
78
|
+
@@default_environment ||= ENV['SGTN_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV'] || "development"
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
# Set default environment
|
83
|
+
def default_environment=(env)
|
84
|
+
@@default_environment = env.to_s
|
85
|
+
end
|
86
|
+
|
87
|
+
def configure(options = {}, &block)
|
88
|
+
begin
|
89
|
+
self.config.merge!(options)
|
90
|
+
rescue Errno::ENOENT
|
91
|
+
self.configurations = { default_environment => options }
|
92
|
+
end
|
93
|
+
block.call(self.config) if block
|
94
|
+
self.config
|
95
|
+
end
|
96
|
+
alias_method :set_config, :configure
|
97
|
+
|
98
|
+
# Create or Load Config object based on given environment and configurations.
|
99
|
+
# === Attributes
|
100
|
+
# * <tt>env</tt> (Optional) -- Environment name
|
101
|
+
# * <tt>override_configuration</tt> (Optional) -- Override the configuration given in file.
|
102
|
+
# === Example
|
103
|
+
# Config.config
|
104
|
+
# Config.config(:development)
|
105
|
+
# Config.config(:development, { :app_id => "XYZ" })
|
106
|
+
def config(env = default_environment, override_configuration = {})
|
107
|
+
if env.is_a? Hash
|
108
|
+
override_configuration = env
|
109
|
+
env = default_environment
|
110
|
+
end
|
111
|
+
if override_configuration.nil? or override_configuration.empty?
|
112
|
+
default_config(env)
|
113
|
+
else
|
114
|
+
default_config(env).dup.merge!(override_configuration)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def default_config(env = nil)
|
119
|
+
env = (env || default_environment).to_s
|
120
|
+
if configurations[env]
|
121
|
+
@@config_cache[env] ||= new(configurations[env])
|
122
|
+
else
|
123
|
+
raise SgtnClient::Exceptions::MissingConfig.new("Configuration[#{env}] NotFound")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Get raw configurations in Hash format.
|
128
|
+
def configurations
|
129
|
+
@@configurations ||= read_configurations
|
130
|
+
end
|
131
|
+
|
132
|
+
# Set configuration
|
133
|
+
def configurations=(configs)
|
134
|
+
@@config_cache = {}
|
135
|
+
@@configurations = configs && Hash[configs.map{|k,v| [k.to_s, v] }]
|
136
|
+
end
|
137
|
+
|
138
|
+
# Set logger
|
139
|
+
def logger=(logger)
|
140
|
+
Logging.logger = logger
|
141
|
+
end
|
142
|
+
|
143
|
+
# Get logger
|
144
|
+
def logger
|
145
|
+
if @@configurations[:mode] == 'live' and Logging.logger.level == Logger::DEBUG
|
146
|
+
Logging.logger.warn "DEBUG log level not allowed in live mode for security of confidential information. Changing log level to INFO..."
|
147
|
+
Logging.logger.level = Logger::INFO
|
148
|
+
end
|
149
|
+
Logging.logger
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
# Read configurations from the given file name
|
154
|
+
# === Arguments
|
155
|
+
# * <tt>file_name</tt> (Optional) -- Configuration file path
|
156
|
+
def read_configurations(file_name = "config/sgtnclient.yml")
|
157
|
+
erb = ERB.new(File.read(file_name))
|
158
|
+
erb.filename = file_name
|
159
|
+
YAML.load(erb.result)
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
module SgtnClient
|
5
|
+
module Exceptions
|
6
|
+
class ConnectionError < StandardError # :nodoc:
|
7
|
+
attr_reader :response
|
8
|
+
|
9
|
+
def initialize(response, message = nil)
|
10
|
+
@response = response
|
11
|
+
@message = message
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
begin
|
16
|
+
response_body = MultiJson.load(response.body)
|
17
|
+
debug_id = response["sgtn-debug-id"]
|
18
|
+
debug_id = response["correlation-id"] if debug_id.to_s == ''
|
19
|
+
debug_id = response_body["debug_id"] if debug_id.to_s == ''
|
20
|
+
rescue
|
21
|
+
end
|
22
|
+
message = "Failed."
|
23
|
+
message << " Response code = #{response.code}." if response.respond_to?(:code)
|
24
|
+
message << " Response message = #{response.message}." if response.respond_to?(:message)
|
25
|
+
message << " Response debug ID = #{debug_id}." if debug_id
|
26
|
+
message
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Raised when a Timeout::Error occurs.
|
31
|
+
class TimeoutError < ConnectionError
|
32
|
+
def initialize(message)
|
33
|
+
@message = message
|
34
|
+
end
|
35
|
+
def to_s; @message ;end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Raised when a OpenSSL::SSL::SSLError occurs.
|
39
|
+
class SSLError < ConnectionError
|
40
|
+
def initialize(message)
|
41
|
+
@message = message
|
42
|
+
end
|
43
|
+
def to_s; @message ;end
|
44
|
+
end
|
45
|
+
|
46
|
+
# 3xx Redirection
|
47
|
+
class Redirection < ConnectionError # :nodoc:
|
48
|
+
def to_s
|
49
|
+
response['Location'] ? "#{super} => #{response['Location']}" : super
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class MissingParam < ArgumentError # :nodoc:
|
54
|
+
end
|
55
|
+
|
56
|
+
class MissingConfig < StandardError # :nodoc:
|
57
|
+
end
|
58
|
+
|
59
|
+
# 4xx Client Error
|
60
|
+
class ClientError < ConnectionError # :nodoc:
|
61
|
+
end
|
62
|
+
|
63
|
+
# 400 Bad Request
|
64
|
+
class BadRequest < ClientError # :nodoc:
|
65
|
+
end
|
66
|
+
|
67
|
+
# 401 Unauthorized
|
68
|
+
class UnauthorizedAccess < ClientError # :nodoc:
|
69
|
+
end
|
70
|
+
|
71
|
+
# 403 Forbidden
|
72
|
+
class ForbiddenAccess < ClientError # :nodoc:
|
73
|
+
end
|
74
|
+
|
75
|
+
# 404 Not Found
|
76
|
+
class ResourceNotFound < ClientError # :nodoc:
|
77
|
+
end
|
78
|
+
|
79
|
+
# 409 Conflict
|
80
|
+
class ResourceConflict < ClientError # :nodoc:
|
81
|
+
end
|
82
|
+
|
83
|
+
# 410 Gone
|
84
|
+
class ResourceGone < ClientError # :nodoc:
|
85
|
+
end
|
86
|
+
|
87
|
+
# 422 Unprocessable Entity
|
88
|
+
class ResourceInvalid < ClientError # :nodoc:
|
89
|
+
end
|
90
|
+
|
91
|
+
# 5xx Server Error
|
92
|
+
class ServerError < ConnectionError # :nodoc:
|
93
|
+
end
|
94
|
+
|
95
|
+
# 405 Method Not Allowed
|
96
|
+
class MethodNotAllowed < ClientError # :nodoc:
|
97
|
+
def allowed_methods
|
98
|
+
@response['Allow'].split(',').map { |verb| verb.strip.downcase.to_sym }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# API error: returned as 200 + "error" key in response.
|
103
|
+
class UnsuccessfulApiCall < RuntimeError
|
104
|
+
attr_reader :api_error
|
105
|
+
|
106
|
+
def initialize(api_error)
|
107
|
+
super(api_error['message'])
|
108
|
+
@api_error = api_error
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module SgtnClient
|
4
|
+
|
5
|
+
# Include Logging module to provide logger functionality.
|
6
|
+
# == Configure logger
|
7
|
+
# Logging.logger = Logger.new(STDERR)
|
8
|
+
#
|
9
|
+
# == Example
|
10
|
+
# include Logger
|
11
|
+
# logger.info "Debug message"
|
12
|
+
module Logging
|
13
|
+
|
14
|
+
# Get logger object
|
15
|
+
def logger
|
16
|
+
@logger ||= Logging.logger
|
17
|
+
end
|
18
|
+
|
19
|
+
def log_event(message, &block)
|
20
|
+
start_time = Time.now
|
21
|
+
block.call
|
22
|
+
ensure
|
23
|
+
logger.info sprintf("[%.3fs] %s", Time.now - start_time, message)
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
|
28
|
+
# Get or Create configured logger based on the default environment configuration
|
29
|
+
def logger
|
30
|
+
@logger ||= Logger.new(STDERR)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Set logger directly and clear the loggers cache.
|
34
|
+
# === Attributes
|
35
|
+
# * <tt>logger</tt> -- Logger object
|
36
|
+
# === Example
|
37
|
+
# Logging.logger = Logger.new(STDERR)
|
38
|
+
def logger=(logger)
|
39
|
+
@logger = logger
|
40
|
+
if Config.config.mode.eql? 'live' and @logger.level == Logger::DEBUG
|
41
|
+
@logger.warn "DEBUG log level not allowed in live mode for security of confidential information. Changing log level to INFO..."
|
42
|
+
@logger.level = Logger::INFO
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module SgtnClient::Core
|
5
|
+
class Request
|
6
|
+
def self.get(url)
|
7
|
+
res = RestClient.get(url)
|
8
|
+
begin
|
9
|
+
obj = MultiJson.load(res)
|
10
|
+
rescue MultiJson::ParseError => exception
|
11
|
+
exception.data
|
12
|
+
exception.cause
|
13
|
+
end
|
14
|
+
return obj
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module SgtnClient
|
2
|
+
module Core
|
3
|
+
autoload :Cache, "sgtn-client/core/cache"
|
4
|
+
end
|
5
|
+
|
6
|
+
autoload :Translation, "sgtn-client/api/translation"
|
7
|
+
autoload :T, "sgtn-client/api/t"
|
8
|
+
autoload :Source, "sgtn-client/api/source"
|
9
|
+
autoload :Config, "sgtn-client/core/config"
|
10
|
+
autoload :Logging, "sgtn-client/core/logging"
|
11
|
+
autoload :Exceptions, "sgtn-client/core/exceptions"
|
12
|
+
autoload :ValidateUtil, "sgtn-client/util/validate-util"
|
13
|
+
autoload :LocaleUtil, "sgtn-client/util/locale-util"
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def configure(options = {}, &block)
|
17
|
+
SgtnClient::Config.configure(options, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
include Logging
|
21
|
+
def load(*args)
|
22
|
+
# load configuration file
|
23
|
+
begin
|
24
|
+
SgtnClient::Config.load(args[0], args[1])
|
25
|
+
SgtnClient::ValidateUtil.validate_config()
|
26
|
+
rescue => exception
|
27
|
+
file = File.open('./error.log', 'a')
|
28
|
+
file.sync = true
|
29
|
+
log = Logger.new(file)
|
30
|
+
log.error exception.message
|
31
|
+
end
|
32
|
+
|
33
|
+
# create log file
|
34
|
+
file = './sgtnclient_d.log'
|
35
|
+
if args[2] != nil
|
36
|
+
file = args[2]
|
37
|
+
end
|
38
|
+
file = File.open(file, 'a')
|
39
|
+
file.sync = true
|
40
|
+
SgtnClient.logger = Logger.new(file)
|
41
|
+
|
42
|
+
# Set log level for sandbox mode
|
43
|
+
env = SgtnClient::Config.default_environment
|
44
|
+
mode = SgtnClient::Config.configurations[env]["mode"]
|
45
|
+
SgtnClient.logger.info "Current mode is: " + mode
|
46
|
+
if mode == 'sandbox'
|
47
|
+
SgtnClient.logger.level = Logger::DEBUG
|
48
|
+
else
|
49
|
+
SgtnClient.logger.level = Logger::INFO
|
50
|
+
end
|
51
|
+
|
52
|
+
# initialize cache
|
53
|
+
disable_cache = SgtnClient::Config.configurations[env]["disable_cache"]
|
54
|
+
if disable_cache != nil
|
55
|
+
SgtnClient::Core::Cache.initialize(disable_cache)
|
56
|
+
else
|
57
|
+
SgtnClient::Core::Cache.initialize()
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def logger
|
62
|
+
SgtnClient::Config.logger
|
63
|
+
end
|
64
|
+
|
65
|
+
def logger=(log)
|
66
|
+
SgtnClient::Config.logger = log
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module SgtnClient
|
5
|
+
|
6
|
+
module Core
|
7
|
+
autoload :Cache, "sgtn-client/core/cache"
|
8
|
+
end
|
9
|
+
|
10
|
+
class CacheUtil
|
11
|
+
|
12
|
+
def self.get_cache(cache_key)
|
13
|
+
items = SgtnClient::Core::Cache.get(cache_key)
|
14
|
+
return items
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.clear_cache()
|
18
|
+
SgtnClient::Core::Cache.clear()
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.write_cache(cache_key, items)
|
22
|
+
env = SgtnClient::Config.default_environment
|
23
|
+
cache_expiry_period = SgtnClient::Config.configurations[env]["cache_expiry_period"]
|
24
|
+
# expired after 24 hours
|
25
|
+
if cache_expiry_period == nil
|
26
|
+
cache_expiry_period = 24*60
|
27
|
+
end
|
28
|
+
SgtnClient::Core::Cache.put(cache_key, items, cache_expiry_period)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.get_cachekey(component, locale)
|
32
|
+
env = SgtnClient::Config.default_environment
|
33
|
+
product_name = SgtnClient::Config.configurations[env]["product_name"]
|
34
|
+
version = SgtnClient::Config.configurations[env]["version"].to_s
|
35
|
+
return product_name + "_" + version + "_" + component + "_" + locale
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SgtnClient
|
2
|
+
|
3
|
+
DEFAULT_LOCALES = ['en', 'de', 'es', 'fr', 'ko', 'ja', 'zh-Hans', 'zh-Hant']
|
4
|
+
|
5
|
+
MAP_LOCALES = {
|
6
|
+
"zh-CN" =>"zh-Hans",
|
7
|
+
"zh-TW" =>"zh-Hant",
|
8
|
+
"zh-Hans-CN" =>"zh-Hans",
|
9
|
+
"zh-Hant-TW" =>"zh-Hant",
|
10
|
+
}
|
11
|
+
|
12
|
+
class LocaleUtil
|
13
|
+
def self.fallback(locale)
|
14
|
+
found = SgtnClient::DEFAULT_LOCALES.select {|e| e == locale}
|
15
|
+
if !found.empty?
|
16
|
+
return found[0]
|
17
|
+
end
|
18
|
+
if SgtnClient::MAP_LOCALES.key?(locale)
|
19
|
+
return SgtnClient::MAP_LOCALES[locale]
|
20
|
+
end
|
21
|
+
parts = locale.split("-")
|
22
|
+
if parts.size > 1
|
23
|
+
f = SgtnClient::DEFAULT_LOCALES.select {|e| e == parts[0]}
|
24
|
+
if !f.empty?
|
25
|
+
return f[0]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
return locale
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
module SgtnClient
|
3
|
+
|
4
|
+
class ValidateUtil
|
5
|
+
|
6
|
+
def self.validate_config()
|
7
|
+
SgtnClient.logger.debug "-----------Start to validate configuration's setting itmes-----------"
|
8
|
+
env = SgtnClient::Config.default_environment
|
9
|
+
messages = "\n"
|
10
|
+
|
11
|
+
mode = SgtnClient::Config.configurations[env]["mode"]
|
12
|
+
if mode != 'sandbox' && mode != 'live'
|
13
|
+
messages = messages + "Configuration[mode] has to be 'sandbox' or 'live'!\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
bundle_mode = SgtnClient::Config.configurations[env]["bundle_mode"]
|
17
|
+
if bundle_mode != 'offline' && bundle_mode != 'online'
|
18
|
+
messages = messages + "Configuration[bundle_mode] has to be 'offline' or 'online'!\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
#version = SgtnClient::Config.configurations[env]["version"]
|
22
|
+
#if version.is_a? Integer
|
23
|
+
#messages = messages + "Configuration[version] has to be standard as '#.#.#, e.g '1.0.0'!\n"
|
24
|
+
#end
|
25
|
+
|
26
|
+
cache_expiry_period = SgtnClient::Config.configurations[env]["cache_expiry_period"]
|
27
|
+
if cache_expiry_period != nil && (cache_expiry_period.is_a? Integer) == false
|
28
|
+
messages = messages + "Configuration[cache_expiry_period] has to be a number!\n"
|
29
|
+
end
|
30
|
+
|
31
|
+
disable_cache = SgtnClient::Config.configurations[env]["disable_cache"]
|
32
|
+
if disable_cache != nil && disable_cache != false && disable_cache != true
|
33
|
+
messages = messages + "Configuration[disable_cache] has to be a 'true' or 'false'!\n"
|
34
|
+
end
|
35
|
+
|
36
|
+
if messages != "\n"
|
37
|
+
raise SgtnClient::Exceptions::MissingConfig.new(messages)
|
38
|
+
end
|
39
|
+
SgtnClient.logger.debug "-----------End to validate configuration's setting itmes-----------"
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,278 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: singleton-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- VMware G11n Team
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-11-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: multi_json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: request_store
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webmock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry-doc
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rdoc
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.4.2
|
118
|
+
- - "<"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '6.0'
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: 2.4.2
|
128
|
+
- - "<"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '6.0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: rubocop
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0.49'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - "~>"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0.49'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: http-accept
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: 1.7.0
|
152
|
+
- - "<"
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '2.0'
|
155
|
+
type: :runtime
|
156
|
+
prerelease: false
|
157
|
+
version_requirements: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 1.7.0
|
162
|
+
- - "<"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '2.0'
|
165
|
+
- !ruby/object:Gem::Dependency
|
166
|
+
name: http-cookie
|
167
|
+
requirement: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: 1.0.2
|
172
|
+
- - "<"
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '2.0'
|
175
|
+
type: :runtime
|
176
|
+
prerelease: false
|
177
|
+
version_requirements: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: 1.0.2
|
182
|
+
- - "<"
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: '2.0'
|
185
|
+
- !ruby/object:Gem::Dependency
|
186
|
+
name: mime-types
|
187
|
+
requirement: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ">="
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: '1.16'
|
192
|
+
- - "<"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '4.0'
|
195
|
+
type: :runtime
|
196
|
+
prerelease: false
|
197
|
+
version_requirements: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '1.16'
|
202
|
+
- - "<"
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
version: '4.0'
|
205
|
+
- !ruby/object:Gem::Dependency
|
206
|
+
name: netrc
|
207
|
+
requirement: !ruby/object:Gem::Requirement
|
208
|
+
requirements:
|
209
|
+
- - "~>"
|
210
|
+
- !ruby/object:Gem::Version
|
211
|
+
version: '0.8'
|
212
|
+
type: :runtime
|
213
|
+
prerelease: false
|
214
|
+
version_requirements: !ruby/object:Gem::Requirement
|
215
|
+
requirements:
|
216
|
+
- - "~>"
|
217
|
+
- !ruby/object:Gem::Version
|
218
|
+
version: '0.8'
|
219
|
+
- !ruby/object:Gem::Dependency
|
220
|
+
name: multi_json
|
221
|
+
requirement: !ruby/object:Gem::Requirement
|
222
|
+
requirements:
|
223
|
+
- - "~>"
|
224
|
+
- !ruby/object:Gem::Version
|
225
|
+
version: '1.0'
|
226
|
+
type: :runtime
|
227
|
+
prerelease: false
|
228
|
+
version_requirements: !ruby/object:Gem::Requirement
|
229
|
+
requirements:
|
230
|
+
- - "~>"
|
231
|
+
- !ruby/object:Gem::Version
|
232
|
+
version: '1.0'
|
233
|
+
description: Singleton Ruby client
|
234
|
+
email: g11n-vip-project@vmware.com
|
235
|
+
executables: []
|
236
|
+
extensions: []
|
237
|
+
extra_rdoc_files:
|
238
|
+
- README.md
|
239
|
+
files:
|
240
|
+
- README.md
|
241
|
+
- lib/sgtn-client/api/source.rb
|
242
|
+
- lib/sgtn-client/api/t.rb
|
243
|
+
- lib/sgtn-client/api/translation.rb
|
244
|
+
- lib/sgtn-client/core/cache.rb
|
245
|
+
- lib/sgtn-client/core/config.rb
|
246
|
+
- lib/sgtn-client/core/exceptions.rb
|
247
|
+
- lib/sgtn-client/core/logging.rb
|
248
|
+
- lib/sgtn-client/core/request.rb
|
249
|
+
- lib/sgtn-client/sgtn-client.rb
|
250
|
+
- lib/sgtn-client/util/cache-util.rb
|
251
|
+
- lib/sgtn-client/util/locale-util.rb
|
252
|
+
- lib/sgtn-client/util/validate-util.rb
|
253
|
+
- lib/singleton-ruby.rb
|
254
|
+
- lib/version.rb
|
255
|
+
homepage: https://github.com/vmware/singleton
|
256
|
+
licenses:
|
257
|
+
- EPL 2.0
|
258
|
+
metadata: {}
|
259
|
+
post_install_message:
|
260
|
+
rdoc_options: []
|
261
|
+
require_paths:
|
262
|
+
- lib
|
263
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
264
|
+
requirements:
|
265
|
+
- - ">="
|
266
|
+
- !ruby/object:Gem::Version
|
267
|
+
version: 2.0.0
|
268
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
269
|
+
requirements:
|
270
|
+
- - ">="
|
271
|
+
- !ruby/object:Gem::Version
|
272
|
+
version: '0'
|
273
|
+
requirements: []
|
274
|
+
rubygems_version: 3.2.22
|
275
|
+
signing_key:
|
276
|
+
specification_version: 4
|
277
|
+
summary: Singleton Ruby client
|
278
|
+
test_files: []
|