gp-ruby-client 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2caa679ac2292972b32a4e0d44a19f7a7201c0f4
4
+ data.tar.gz: 81bcdb42c564a483ed96e1f89fe7c24d2754e047
5
+ SHA512:
6
+ metadata.gz: 76a1e6551a3651c72412259e6ef1bd8727f92ca33787477b226593b3349c759aed74ef31e6659e27723c5596606657591e4d33b792a0638e6a80541cd3408c51
7
+ data.tar.gz: 253c20540d0916a51f5f20b62905d71a2e9911f1af6d0508ea28bf5ba1a24aa1f6225a05fe9d749caebd112a454a1e07c6f7b25a8512c751a8b6f23bb5ca78d6
@@ -0,0 +1,52 @@
1
+ =begin
2
+ Copyright IBM Corp. 2015
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ class CacheControl
18
+ =begin
19
+ This class is meant to control how often the application updates
20
+
21
+ ttl = how many seconds the application waits before updating
22
+ last_accessed = when you last accessed the application
23
+ =end
24
+ @@cache_ttl = 600
25
+ @@cache_last_accessed = Time.now
26
+
27
+ def get_ttl
28
+ @@cache_ttl
29
+ end
30
+
31
+ def set_ttl(seconds)
32
+ @@cache_ttl = seconds
33
+ end
34
+
35
+ # Sets cache_ttl to a high number so it never (rarely) updates
36
+ def turn_off_cache_update
37
+ @@cache_ttl = 9999999999
38
+ end
39
+
40
+ # Sets cache_ttl to 0 so cache will update every time
41
+ def always_cache_update
42
+ @@cache_ttl = 0
43
+ end
44
+
45
+ def get_last_accessed_time
46
+ @@cache_last_accessed
47
+ end
48
+
49
+ def set_last_accessed_time(time)
50
+ @@cache_last_accessed = time
51
+ end
52
+ end
@@ -0,0 +1,108 @@
1
+ =begin
2
+ Copyright IBM Corp. 2015
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ =begin
18
+ This class is meant to be the main container that holds all the necessary objects
19
+
20
+ It contains a service account object that identifies who you are and a REST client object
21
+ that makes the REST API calls and store the results of those calls. You must provide your bundle identifies
22
+ in order for the application to run effectively. You can choose the default translation language you would like
23
+ by setting the locale
24
+
25
+ cache_control = Cache Control Object - See cache_control.rb
26
+ locale = locale of the translated strings. Default is "" which indicates all locales will be loaded
27
+ use_service = parameter to set if user would like to disable/enable service
28
+ bundle_id = ID of the bundle that contains the translations
29
+ service_account = Service Account Object - See service_account.rb
30
+ rest_client = REST Client object - See rest_client.rb
31
+ =end
32
+
33
+ module GP
34
+ module Ruby
35
+ class Client
36
+ require_relative './service_account.rb'
37
+ require_relative './rest_client.rb'
38
+ require_relative './cache_control.rb'
39
+
40
+ @@cache_control = CacheControl.new
41
+
42
+ @@locale = ""
43
+
44
+ @@just_started = true
45
+ @@use_service = true
46
+
47
+ def initialize(bundle_id)
48
+ @@bundle_id = bundle_id
49
+
50
+ if @@use_service && (Time.now - @@cache_control.get_last_accessed_time >= @@cache_control.get_ttl || @@just_started)
51
+ @@just_started = false
52
+ @@cache_control.set_last_accessed_time(Time.now)
53
+
54
+ backend = {}
55
+ I18n.backend = I18n::Backend::Chain.new(I18n::Backend::KeyValue.new(backend), I18n.backend)
56
+
57
+ @@service_account = ServiceAccount.new
58
+ if @@service_account.nil?
59
+ raise "No valid service account"
60
+ end
61
+
62
+ @@rest_client = RESTClient.new(@@service_account, @@bundle_id, @@locale)
63
+ end
64
+ end
65
+
66
+ def get_bundle_id
67
+ @@bundle_id
68
+ end
69
+
70
+ def set_bundle_id(bundle_id)
71
+ @@bundle_id = bundle_id
72
+ end
73
+
74
+ def get_locale
75
+ @@locale
76
+ end
77
+
78
+ def set_locale(locale)
79
+ @@locale = locale
80
+ end
81
+
82
+ def get_cache_control
83
+ @@cache_control
84
+ end
85
+
86
+ def get_service_account
87
+ @@service_account
88
+ end
89
+
90
+ def get_rest_client
91
+ @@rest_client
92
+ end
93
+
94
+ def disable_service
95
+ @@use_service = false
96
+ end
97
+
98
+ def enable_service
99
+ @@use_service = true
100
+ end
101
+
102
+ def get_default_locale
103
+ request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first
104
+ end
105
+
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,51 @@
1
+ =begin
2
+ Copyright IBM Corp. 2015
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ require 'time'
18
+ require 'openssl'
19
+ require 'base64'
20
+
21
+ class HMAC
22
+ =begin
23
+ This class is meant to provide HMAC authentication when making the REST API calls.
24
+ =end
25
+ GAAS_SCHEME_STRING ||= "GaaS-HMAC"
26
+ SEPARATOR ||= ":"
27
+ ENCODING ||= "ISO-8859-1"
28
+ SHA1_STRING ||= "sha1"
29
+
30
+ def get_auth_credentials(uid, secret, method, url, rfc1123date, body)
31
+ signature = get_signature(secret,method,url,rfc1123date,body)
32
+ if !signature.empty?
33
+ output = "#{GAAS_SCHEME_STRING} #{uid}#{SEPARATOR}#{signature}"
34
+ return output
35
+ end
36
+ end
37
+
38
+ def get_signature(secret,method,url,rfc1123date,body)
39
+ secret.encode(ENCODING)
40
+
41
+ key = "#{method.encode(ENCODING)}\n#{url.encode(ENCODING)}\n#{rfc1123date.encode(ENCODING)}\n#{body.encode(ENCODING)}"
42
+
43
+ digest = OpenSSL::Digest.new(SHA1_STRING)
44
+ hex_string = OpenSSL::HMAC.digest(digest,secret,key)
45
+ return Base64.encode64(hex_string)
46
+ end
47
+
48
+ def get_rfc1123_date
49
+ Time.now.httpdate
50
+ end
51
+ end
@@ -0,0 +1,195 @@
1
+ =begin
2
+ Copyright IBM Corp. 2015
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ require 'net/http'
18
+ require 'json'
19
+ require_relative './hmac.rb'
20
+
21
+ class RESTClient
22
+ =begin
23
+ This object is used to make the REST API calls using credentials found in your service account object
24
+ and store the results of the REST API calls.
25
+
26
+ bundles = list of all the bundles associated to your service instance
27
+ language = a map of the languages of your translated string in the following format: {sourceLanguage : [targetLanguages]}
28
+ resource_data = hash containing your translalated strings in the following format: {locale: {key : translated_value}}
29
+ service_account = ServiceAccount object that contains the credentials necessary to make the REST API calls. See service_account.rb
30
+ bundle_id = ID of the bundle that contains the translated strings
31
+ =end
32
+
33
+ BUNDLE_STRING ||= "bundle"
34
+ SOURCE_LANGUAGE_STRING ||= "sourceLanguage"
35
+ TARGET_LANGUAGES_STRING ||= "targetLanguages"
36
+ RESOURCE_STRINGS ||= "resourceStrings"
37
+ BUNDLE_ID_STRING ||= "bundleIds"
38
+
39
+ URL_PATH ||= "v2/bundles"
40
+
41
+ @supportedLangs = ['en','de','es','fr','it', 'ja','ko', 'pt-BR', 'zh-Hans', 'zh-Hant']
42
+ @expectedMatches = {
43
+ 'en': 'en', 'en_US': 'en', 'en-US': 'en',
44
+ 'de': 'de', 'de_at': 'de', 'de-at': 'de',
45
+ 'es': 'es', 'es_mx': 'es', 'es-mx': 'es',
46
+ 'fr': 'fr', 'fr_FR': 'fr', 'fr-Fr': 'fr', 'fr_CA': 'fr',
47
+ 'it': 'it', 'it_ch': 'it', 'it-ch': 'it', 'it-IT': 'it',
48
+ 'ja': 'ja', 'ja_JA': 'ja', 'ja-JA': 'ja',
49
+ 'ko': 'ko', 'ko_KO': 'ko', 'ko-KO': 'ko',
50
+ 'pt-BR': 'pt-BR', 'pt': nil,
51
+ 'zh': 'zh-Hans', 'zh-tw': 'zh-Hant', 'zh-cn': 'zh-Hans',
52
+ 'zh-hk': 'zh-Hant', 'zh-sg': 'zh-Hans',
53
+ }
54
+
55
+ def initialize(service_account, bundle_id, locale = "")
56
+ @bundles = []
57
+ @languages = {}
58
+ @resource_data = {}
59
+ @service_account = service_account
60
+ @bundle_id = bundle_id
61
+
62
+ get_resource_strings(locale)
63
+ end
64
+
65
+ def get_bundles
66
+ if @bundles.empty?
67
+ url_string = "#{@service_account.get_url_string}/#{@service_account.get_instance_id}/#{URL_PATH}"
68
+ response = make_request(url_string, service_account)
69
+ @bundles = request[BUNDLE_ID_STRING]
70
+ end
71
+ @bundles
72
+ end
73
+
74
+ #bundle info contains the languages - used get_bundle_info to reflect current API
75
+ def get_bundle_info
76
+ if @languages.empty?
77
+ url_string = "#{@service_account.get_url_string}/#{@service_account.get_instance_id}/#{URL_PATH}/#{@bundle_id}"
78
+ puts url_string
79
+ response = make_request(url_string, @service_account)
80
+ source_language = response[BUNDLE_STRING][SOURCE_LANGUAGE_STRING]
81
+ @languages[source_language] = response[BUNDLE_STRING][TARGET_LANGUAGES_STRING]
82
+ end
83
+ @languages
84
+ end
85
+
86
+ def get_resource_strings(locale = "")
87
+ if @resource_data.empty?
88
+ target_languages = []
89
+
90
+ if locale.empty?
91
+ language_dictionary = get_bundle_info
92
+ target_languages = get_target_languages.dup
93
+ target_languages << get_source_language
94
+ else
95
+ if (!@supportedLangs.include? locale)
96
+ if (@expectedMatches.has_key? locale)
97
+ locale = @expectedMatches[locale]
98
+ else
99
+ raise "Unsupported Locale: #{locale}"
100
+ end
101
+ end
102
+ target_languages << locale
103
+ end
104
+
105
+ get_translations(@service_account, target_languages, @bundle_id)
106
+ else
107
+ @resource_data
108
+ end
109
+ end
110
+
111
+ def has_language(language)
112
+ if language.equal? get_source_language
113
+ return true
114
+ end
115
+ get_target_languages.each do |lang|
116
+ if lang.equal? language
117
+ return true
118
+ end
119
+ end
120
+
121
+ return false
122
+ end
123
+
124
+ def get_source_language
125
+ @languages.keys[0]
126
+ end
127
+
128
+ def get_target_languages
129
+ source_language = get_source_language
130
+ @languages[source_language]
131
+ end
132
+
133
+ def get_service_account
134
+ @service_account
135
+ end
136
+
137
+ def get_bundle_id
138
+ @bundle_id
139
+ end
140
+
141
+ def set_resource_strings (map)
142
+ @resource_data = map
143
+ end
144
+
145
+ def set_service_account(sa)
146
+ @service_account = sa
147
+ end
148
+
149
+ def set_bundle_id(name)
150
+ @bundle_id = name
151
+ end
152
+
153
+ private
154
+
155
+ def make_request(url, service_account, basic_auth = false)
156
+ uri = URI.parse(url.to_s)
157
+ request = Net::HTTP::Get.new uri.path
158
+
159
+ if basic_auth
160
+ request.basic_auth(service_account.get_user_id, service_account.get_password)
161
+ else
162
+ hmac = HMAC.new
163
+ d = hmac.get_rfc1123_date
164
+ request["Date"] = d
165
+ request["Authorization"] = hmac.get_auth_credentials(service_account.get_user_id, service_account.get_password, "GET", url,d, "").strip
166
+ end
167
+
168
+ response = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') {|http|
169
+ http.request(request)
170
+ }
171
+ json_response = JSON.parse(response.body)
172
+
173
+ if json_response["status"] != "SUCCESS"
174
+ raise "Invalid HTTP Request #{json_response["message"]}"
175
+ end
176
+
177
+ return json_response
178
+ end
179
+
180
+ def get_translations(service_account, locale_list, project_name)
181
+ url_string = "#{service_account.get_url_string}/#{service_account.get_instance_id}/#{URL_PATH}/#{project_name}"
182
+
183
+ locale_list.each do |language|
184
+ target_lang_url = "#{url_string}/#{language}"
185
+ response = make_request(target_lang_url, service_account)
186
+
187
+ @resource_data[language] = {}
188
+
189
+ response[RESOURCE_STRINGS].each do |key, value|
190
+ I18n.backend.store_translations(language, {key => value}, :escape => false)
191
+ @resource_data[language][key] = value
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,166 @@
1
+ =begin
2
+ Copyright IBM Corp. 2015
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ require 'json'
18
+
19
+ class ServiceAccount
20
+ =begin
21
+ This object is meant to identify the user and contains credentials needed to make the REST API calls
22
+
23
+ This class will either use user-provided variables, environment variables or vcap_services variables in your application
24
+
25
+ url = base url string user must call for REST API
26
+ user_id = ID of user
27
+ password = password of user
28
+ instance_id = ID of your specific service instanceId
29
+ =end
30
+
31
+ GP_URL ||= "GP_URL"
32
+ GP_USER_ID ||= "GP_USER_ID"
33
+ GP_PWD ||= "GP_PASSWORD"
34
+ GP_INSTANCE_ID ||="GP_INSTANCE_ID"
35
+
36
+ APP_NAME ||= "g11n-pipeline"
37
+ APP_NAME_REGEX = /gp-(.*)/
38
+
39
+ VCAP_SERVICES ||= "VCAP_SERVICES"
40
+
41
+ CREDENTIALS ||= "credentials"
42
+ CREDENTIALS_INDEX = 0
43
+
44
+ URL_STRING ||="url"
45
+ USER_ID_STRING ||= "userId"
46
+ PASSWORD_STRING ||= "password"
47
+ INSTANCE_ID_STRING ||= "instanceId"
48
+
49
+ def initialize(url_string = "", user_id = "", pwd = "", instance_id = "")
50
+ if !url_string.empty? && !user_id.empty? && !pwd.empty? && !instance_id.empty?
51
+ @url_string = url_string
52
+ @user_id = user_id
53
+ @pwd = pwd
54
+ @instance_id = instance_id
55
+ else
56
+ account = get_service_account_via_env_var
57
+
58
+ if account.nil?
59
+ account = get_service_account_via_vcap_service
60
+ if account.nil?
61
+ raise "Couldn't create a service account"
62
+ end
63
+ end
64
+
65
+ @url_string = account[0]
66
+ @user_id = account[1]
67
+ @pwd = account[2]
68
+ @instance_id=account[3]
69
+
70
+ end
71
+ end
72
+
73
+ def get_url_string
74
+ @url_string
75
+ end
76
+
77
+ def get_user_id
78
+ @user_id
79
+ end
80
+
81
+ def get_password
82
+ @pwd
83
+ end
84
+
85
+ def get_instance_id
86
+ @instance_id
87
+ end
88
+
89
+ def set_url_string(url)
90
+ @url_string = url
91
+ end
92
+
93
+ def set_user_id(user_id)
94
+ @user_id = user_id
95
+ end
96
+
97
+ def set_password(password)
98
+ @pwd = password
99
+ end
100
+
101
+ def set_instance_id(instance_id)
102
+ @instance_id = instance_id
103
+ end
104
+
105
+ private
106
+
107
+ def get_service_account_via_env_var
108
+
109
+ url_string = ENV[GP_URL]
110
+ if url_string.nil?
111
+ return
112
+ end
113
+
114
+ user_id = ENV[GP_USER_ID]
115
+ if user_id.nil?
116
+ return
117
+ end
118
+
119
+ pwd = ENV[GP_PWD]
120
+ if pwd.nil?
121
+ return
122
+ end
123
+
124
+ instance_id = ENV[GP_INSTANCE_ID]
125
+ if instance_id.nil?
126
+ return
127
+ end
128
+
129
+ return [url_string, user_id, pwd,instance_id]
130
+ end
131
+
132
+ def get_service_account_via_vcap_service
133
+
134
+ vcap_services = ENV[VCAP_SERVICES]
135
+
136
+ if vcap_services.nil?
137
+ return
138
+ end
139
+
140
+ json_vcap_services = JSON.parse(vcap_services)
141
+
142
+ app_name = ""
143
+ json_vcap_services.each do |key, value|
144
+ if (key =~ APP_NAME_REGEX or key.equals? (APP_NAME))
145
+ app_name = key
146
+ break
147
+ end
148
+ end
149
+
150
+ credentials_list = JSON.parse(vcap_services)[app_name][CREDENTIALS_INDEX][CREDENTIALS]
151
+
152
+ if !credentials_list.nil?
153
+ url = credentials_list[URL_STRING]
154
+ user_id = credentials_list[USER_ID_STRING]
155
+ pwd = credentials_list[PASSWORD_STRING]
156
+ instance_id = credentials_list[INSTANCE_ID_STRING]
157
+ if url.nil? || user_id.nil? || pwd.nil? || instance_id.nil?
158
+ return
159
+ end
160
+
161
+ return [url, user_id, pwd, instance_id]
162
+ end
163
+
164
+ return
165
+ end
166
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gp-ruby-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Visaahan Anandarajah
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-27 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby SDK for Globalization Pipeline on IBM Bluemix
14
+ email: visanand@ca.ibm.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/cache_control.rb
20
+ - lib/gp-ruby-client.rb
21
+ - lib/hmac.rb
22
+ - lib/rest_client.rb
23
+ - lib/service_account.rb
24
+ homepage:
25
+ licenses: []
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.4.5.1
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Ruby SDK for Globalization Pipeline
47
+ test_files: []
48
+ has_rdoc: