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 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
@@ -0,0 +1,2 @@
1
+ require "sgtn-client/sgtn-client"
2
+
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+
2
+ VERSION_INFO = [0, 1, 7].freeze
3
+ VERSION = VERSION_INFO.map(&:to_s).join('.').freeze
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: []