singleton-client 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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: []