pijaz-sdk 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: c25982be3bc718b3b003f145ae097c354e9c4024
4
+ data.tar.gz: 0d1956ea89c9669ead1064c69dc7b5b6de4f8513
5
+ SHA512:
6
+ metadata.gz: d2d6fe8bc50ef1a7480733148a44942e8ab4030d34333991b4744fe70486a4a6d061a3301556bce54aff0326a48ef021e2b62623e85bed809de47128b30bb850
7
+ data.tar.gz: a1ab7e222d82870d2dc782985cae78cb24f8c9cd172f81761c1938ce6087f88631c8dfa29c1c1ab988bc8eb5d82bd25386c7c59a7348961cf8497da6fdbbcf66
@@ -0,0 +1,11 @@
1
+ =begin
2
+
3
+ Class Pijaz.
4
+
5
+ Bootstrap class for all API classes, puts them under one table instance.
6
+
7
+ =end
8
+
9
+ require_relative "pijaz/server_manager"
10
+ require_relative "pijaz/product"
11
+
@@ -0,0 +1,203 @@
1
+ =begin
2
+
3
+ Class: Product
4
+
5
+ Manages a renderable product.
6
+
7
+ PUBLIC METHODS:
8
+
9
+ clearRenderParameters()
10
+ generateUrl(additionalParams)
11
+ getAccessInfo()
12
+ getRenderParameter(key)
13
+ getWorkflowId()
14
+ saveToFile(filepath,additionalParams)
15
+ setAccessInfo(accessInfo)
16
+ setRenderParameter(key,newValue)
17
+ setWorkflowId(newWorkflowId)
18
+
19
+ PRIVATE METHODS:
20
+
21
+ _setFinalParams(additionalParams)
22
+
23
+ =end
24
+
25
+ require 'open-uri'
26
+
27
+ module Pijaz
28
+ module SDK
29
+ class Product
30
+
31
+ # PUBLIC METHODS
32
+
33
+ # Clear out all current render parameters.
34
+ #
35
+ # Any parameters currently stored with the product, including those passed
36
+ # when the product was instantiated, are cleared.
37
+ def clearRenderParameters()
38
+ @renderParameters = {}
39
+ end
40
+
41
+ # Build a fully formed URL which can be used to make a request for the
42
+ # product from a rendering server.
43
+ #
44
+ # @param additionalParams
45
+ # Optional. A hash of additional render parameters to be used for this
46
+ # request only.
47
+ # @return
48
+ # A fully formed URL that can be used in a render server HTTP request.
49
+ def generateUrl(additionalParams={})
50
+ finalParams = self._setFinalParams(additionalParams)
51
+ options = {}
52
+ options['product'] = self
53
+ options['renderParameters'] = finalParams
54
+ params = @serverManager.buildRenderCommand(options)
55
+ if params then
56
+ url = @serverManager.buildRenderServerUrlRequest(params)
57
+ url
58
+ end
59
+ end
60
+
61
+ # Return the access info for the product.
62
+ #
63
+ # Required method for products passed to the ServerManager object.
64
+ # @return
65
+ # The access info.
66
+ def getAccessInfo()
67
+ @accessInfo
68
+ end
69
+
70
+ # Retrieve a render parameter.
71
+ #
72
+ # @param key: The parameter name.
73
+ # @return:
74
+ # The render parameter, or the default render parameter if not set.
75
+ def getRenderParameter(key)
76
+ value = (@renderParameters[key] or @productPropertyDefaults[key])
77
+ value
78
+ end
79
+
80
+ # Return the workflow ID.
81
+ #
82
+ # @return:
83
+ # The workflow ID.
84
+ def getWorkflowId()
85
+ @workflowId
86
+ end
87
+
88
+ # Create a new product instance.
89
+ #
90
+ # @param inParameters
91
+ # A hash with the following key/value pairs.
92
+ #
93
+ # serverManager: Required. An instance of the ServerManager class.
94
+ # workflowId: Required. The workflow ID for the product.
95
+ # renderParameters: Optional. A hash of render parameters to be included
96
+ # with every render request. They depend on the product, but these are
97
+ # typically supported params:
98
+ # message: Primary message to display.
99
+ # font: Font to use.
100
+ # halign: Horizontal justification (left, center, right, full).
101
+ # valign: Vertical justification (top, middle, bottom, full, even).
102
+ # quality: Image quality to produce (0-100).
103
+ def initialize(inParameters)
104
+ params = inParameters
105
+ @serverManager = params['serverManager']
106
+ @workflowId = params['workflowId']
107
+ @renderParameters = (params['renderParameters'] or {})
108
+ @accessInfo = nil
109
+ @productPropertyDefaults = {}
110
+ end
111
+
112
+ # Convenience method for saving a product directly to a file.
113
+ #
114
+ # This takes care of generating the render URL, making the request to the
115
+ # render server for the product, and saving to a file.
116
+ #
117
+ # @param filepath
118
+ # Required. The full file path.
119
+ # @param additionalParams
120
+ # Optional. A hash of additional render parameters to be used for this
121
+ # request only.
122
+ # @return
123
+ # True on successful save of the file, false otherwise.
124
+ def saveToFile(filepath, additionalParams)
125
+ url = self.generateUrl(additionalParams)
126
+ if url
127
+ response = open(url).read
128
+ if response
129
+ File.open(filepath, 'wb') do |fo|
130
+ fo.write response
131
+ return true
132
+ end
133
+ end
134
+ end
135
+ false
136
+ end
137
+
138
+ # Set the access info for the product.
139
+ #
140
+ # Required method for products passed to the ServerManager object.
141
+ def setAccessInfo(accessInfo)
142
+ if accessInfo
143
+ @accessInfo = accessInfo
144
+ else
145
+ @accessInfo = nil
146
+ end
147
+ end
148
+
149
+ # Set a render parameter on the product.
150
+ #
151
+ # @param key
152
+ # The parameter name. Optionally a hash of parameter key/value pairs can
153
+ # be passed as the first argument, and each pair will be added.
154
+ # @param newValue
155
+ # The parameter value.
156
+ def setRenderParameter(key, newValue=nil)
157
+ if key.is_a?(Hash)
158
+ key.each do |k, v|
159
+ self.setRenderParameter(k, v)
160
+ end
161
+ else
162
+ param = @renderParameters[key]
163
+ default = @productPropertyDefaults[key]
164
+ if param != newValue
165
+ if newValue == nil or newValue == default
166
+ @renderParameters[key] = nil
167
+ else
168
+ @renderParameters[key] = newValue
169
+ end
170
+ end
171
+ end
172
+ end
173
+
174
+ # Set the workflow ID.
175
+ def setWorkflowId(newWorkflowId)
176
+ if @workflowId != newWorkflowId
177
+ @accessInfo = nil
178
+ @workflowId = newWorkflowId
179
+ end
180
+ end
181
+
182
+ # PRIVATE METHODS
183
+
184
+ # Set the final render parameters for the product.
185
+ #
186
+ # @param additionalParams
187
+ # A hash of additional render parameters.
188
+ def _setFinalParams(additionalParams)
189
+ finalParams = Marshal.load(Marshal.dump(@renderParameters))
190
+ if additionalParams.is_a?(Hash)
191
+ additionalParams.each do |k, v|
192
+ if v
193
+ finalParams[k] = v
194
+ end
195
+ end
196
+ end
197
+ finalParams['workflow'] = @workflowId
198
+ finalParams
199
+ end
200
+
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,334 @@
1
+ =begin
2
+
3
+ Class: ServerManager
4
+
5
+ Server manager class, used for making calls to a Pijaz API service and/or
6
+ rendering service.
7
+
8
+ PUBLIC METHODS:
9
+
10
+ buildRenderCommand(inParameters)
11
+ buildRenderServerUrlRequest(inParameters)
12
+ getApiKey()
13
+ getApiServerUrl()
14
+ getApiVersion()
15
+ getAppId()
16
+ getRenderServerUrl()
17
+ sendApiCommand(inParameters)
18
+
19
+ PRIVATE METHODS:
20
+
21
+ _buildRenderServerQueryParams(params)
22
+ _extractInfo(data)
23
+ _extractResult(data)
24
+ _httpRequest(url, method,
25
+ _isRenderRequestAllowed(product)
26
+ _parseJson(jsonString)
27
+ _processAccessToken(params, data)
28
+ _sendApiCommand(inParameters, retries)
29
+ _stringifyParameters(params, separator)
30
+
31
+ =end
32
+
33
+ PIJAZ_API_VERSION = 1
34
+ PIJAZ_API_SERVER = 'http://api.pijaz.com/'
35
+ PIJAZ_RENDER_SERVER = 'http://render.pijaz.com/'
36
+ SERVER_REQUEST_ATTEMPTS = 2
37
+
38
+ require "rubygems"
39
+ require "json"
40
+ require 'net/http'
41
+ require 'uri'
42
+
43
+ module Pijaz
44
+ module SDK
45
+ class ServerManager
46
+
47
+ # PUBLIC METHODS
48
+
49
+ # Build the set of query parameters for a render request.
50
+ #
51
+ # @param inParameters
52
+ # A hash with the following key/value pairs.
53
+ #
54
+ # product: An instance of the Product class
55
+ # renderParameters: A hash of all params sent to the render request.
56
+ #
57
+ # @return
58
+ # If successful, a hash of query parameters to pass to the rendering
59
+ # server. These can be converted into a full URL by calling
60
+ # buildRenderServerUrlRequest(params).
61
+ def buildRenderCommand(inParameters)
62
+ params = inParameters
63
+ if self._isRenderRequestAllowed(params['product'])
64
+ self._buildRenderServerQueryParams(params)
65
+ else
66
+ commandParameters = {}
67
+ commandParameters['workflow'] = params['renderParameters']['workflow']
68
+ if params['renderParameters']['xml']
69
+ commandParameters['xml'] = params['renderParameters']['xml']
70
+ end
71
+ options = {}
72
+ options['command'] = 'get-token'
73
+ options['commandParameters'] = commandParameters
74
+ response = self.sendApiCommand(options)
75
+ if response
76
+ self._processAccessToken(params, response)
77
+ end
78
+ end
79
+ end
80
+
81
+ # Builds a fully qualified render request URL.
82
+ #
83
+ # @param inParameters
84
+ # A hash of query parameters for the render request.
85
+ # @return:
86
+ # The constructed URL.
87
+ def buildRenderServerUrlRequest(inParameters)
88
+ url = self.getRenderServerUrl() + "render-image?" + self._stringifyParameters(inParameters)
89
+ url
90
+ end
91
+
92
+ # Get the API key of the client application.
93
+ #
94
+ # @return:
95
+ # The API key.
96
+ def getApiKey()
97
+ @apiKey
98
+ end
99
+
100
+ # Get current API server URL.
101
+ #
102
+ # @return:
103
+ # The API server URL.
104
+ def getApiServerUrl()
105
+ @apiServer
106
+ end
107
+
108
+ # Get the API version the server manager is using.
109
+ #
110
+ # @return:
111
+ # The API version.
112
+ def getApiVersion()
113
+ @apiVersion
114
+ end
115
+
116
+ # Get the client application ID.
117
+ #
118
+ # @return:
119
+ # The application ID.
120
+ def getAppId()
121
+ @appId
122
+ end
123
+
124
+ # Get current render server URL.
125
+ #
126
+ # @return:
127
+ # The render server URL.
128
+ def getRenderServerUrl()
129
+ @renderServer
130
+ end
131
+
132
+ # Create a new instance of the server manager class.
133
+ #
134
+ # @param inParameters
135
+ # A hash with the following key/value pairs.
136
+ # appId: Required. The ID of the client application.
137
+ # apiKey: Required. The API key associated with the client. This key should
138
+ # be kept confidential, and is used to allow the associated client to
139
+ # access the API server.
140
+ # renderServer: Optional. The base URL of the rendering service. Include
141
+ # the trailing slash. Default: http://render.pijaz.com/
142
+ # apiServer: Optional. The base URL of the API service. Include
143
+ # the trailing slash. Default: http://api.pijaz.com/
144
+ # refreshFuzzSeconds: Optional. Number of seconds to shave off the lifetime
145
+ # of a rendering access token, this allows a smooth re-request for a new
146
+ # set of access params. Default: 10
147
+ # apiVersion: Optional. The API version to use. Currently, only version 1
148
+ # is supported. Default: 1
149
+ def initialize(inParameters)
150
+ params = inParameters
151
+ @appId = params['appId']
152
+ @apiKey = params['apiKey']
153
+ @apiServer = (params['apiServer'] or PIJAZ_API_SERVER)
154
+ @renderServer = (params['renderServer'] or PIJAZ_RENDER_SERVER)
155
+ @refreshFuzzSeconds = (params['refreshFuzzSeconds'] or 10)
156
+ @apiVersion = (params['apiVersion'] or PIJAZ_API_VERSION)
157
+ end
158
+
159
+ # Send a command to the API server.
160
+ #
161
+ # @param inParameters
162
+ # A hash with the following key/value pairs:
163
+ # command: Required. The command to send to the API server. One of the
164
+ # following:
165
+ # get-token: Retrieve a rendering access token for a workflow.
166
+ # commandParameters:
167
+ # workflow: The workflow ID.
168
+ # commandParameters: Optional. A hash of parameters. See individual
169
+ # command for more information
170
+ # method: Optional. The HTTP request type. GET or POST. Default: GET.
171
+ # @return:
172
+ # If the request succeed, then a hash of the response data, otherwise two
173
+ # values: nil, and an error message.
174
+ def sendApiCommand(inParameters)
175
+ _sendApiCommand(inParameters, SERVER_REQUEST_ATTEMPTS - 1)
176
+ end
177
+
178
+ # PRIVATE METHODS
179
+
180
+ # Construct a URL with all user supplied and constructed parameters
181
+ def _buildRenderServerQueryParams(params)
182
+ accessInfo = params['product'].getAccessInfo()
183
+ queryParams = Marshal.load(Marshal.dump(accessInfo['renderAccessParameters']))
184
+ if params['renderParameters'].is_a?(Hash)
185
+ params['renderParameters'].each do |k, v|
186
+ if v
187
+ queryParams[k] = v
188
+ end
189
+ end
190
+ end
191
+ queryParams
192
+ end
193
+
194
+ # Extract the information from a server JSON response.
195
+ def _extractInfo(data)
196
+ json = JSON.parse(data)
197
+ if json['result'] and json['result']['result_num'] and json['result']['result_num'] == 0
198
+ return json['info']
199
+ end
200
+ false
201
+ end
202
+
203
+ # Extract the result from a server JSON response.
204
+ def _extractResult(data)
205
+ json = JSON.parse(data)
206
+ if json['result'] and json['result']['result_num'] and json['result']['result_text']
207
+ return json['result']
208
+ end
209
+ false
210
+ end
211
+
212
+ # Perform an HTTP request.
213
+ #
214
+ # @param endpoint
215
+ # A URI endpoint.
216
+ # @param path
217
+ # A string containing the endpoint path.
218
+ # @param method
219
+ # Optional. A string defining the HTTP request method to use. Only GET
220
+ # and POST are supported.
221
+ # @param data
222
+ # A hash containing data to include in the request.
223
+ # @return
224
+ # A response object.
225
+ def _httpRequest(endpoint, path, method, data)
226
+ method = (method and method.upcase or 'GET')
227
+
228
+ endpoint = endpoint.sub(/(\/)+$/, '')
229
+ uri = URI.parse(endpoint)
230
+ http = Net::HTTP.new(uri.host, uri.port)
231
+ if endpoint.start_with?('https://')
232
+ http.use_ssl = true
233
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
234
+ end
235
+
236
+ request = nil
237
+ if method == 'GET'
238
+ if data.is_a?(Hash)
239
+ path = path + '?' + self._stringifyParameters(data)
240
+ end
241
+ request = Net::HTTP::Get.new(path)
242
+ elsif method == 'POST'
243
+ request = Net::HTTP::Post.new(path)
244
+ request.set_form_data = data
245
+ end
246
+
247
+ response = http.request(request)
248
+ response
249
+ end
250
+
251
+ # Verifies that valid access parameters are attached to the product.
252
+ def _isRenderRequestAllowed(product)
253
+ accessInfo = product.getAccessInfo()
254
+ if accessInfo
255
+ expireTimestamp = accessInfo['timestamp'] + accessInfo['lifetime'] - @refreshFuzzSeconds
256
+ if Time.now.to_i <= expireTimestamp
257
+ return true
258
+ end
259
+ end
260
+ false
261
+ end
262
+
263
+ # Handles setting up product access info and building render params.
264
+ def _processAccessToken(params, data)
265
+ accessInfo = {}
266
+
267
+ # Store the time the access params were obtained -- used to count
268
+ # against the lifetime param to expire the info.
269
+ accessInfo['timestamp'] = Time.now.to_i
270
+ # Extract the lifetime param, no need to pass this along to the
271
+ # rendering server.
272
+ accessInfo['lifetime'] = data['lifetime'].to_i
273
+ data.delete('lifetime')
274
+
275
+ accessInfo['renderAccessParameters'] = data
276
+
277
+ params['product'].setAccessInfo(accessInfo)
278
+
279
+ self._buildRenderServerQueryParams(params)
280
+ end
281
+
282
+ # Sends a command to the API server.
283
+ def _sendApiCommand(inParameters, retries)
284
+ params = inParameters
285
+
286
+ path = '/' + params['command']
287
+ method = (params['method'] or 'GET')
288
+
289
+ params['commandParamaters'] = (params['commandParameters'] or {})
290
+ params['commandParameters']['app_id'] = self.getAppId()
291
+ params['commandParameters']['api_key'] = self.getApiKey()
292
+ params['commandParameters']['api_version'] = self.getApiVersion()
293
+
294
+ # DEBUG.
295
+ #print("uuid: " + params['commandParameters']['request_id'] + ", command: " + params['command'])
296
+
297
+ # TODO: fix return value
298
+ response = self._httpRequest(@apiServer, path, method, params['commandParameters'])
299
+
300
+ if response.code == '200' then
301
+ jsonResult = self._extractResult(response.body)
302
+ if jsonResult['result_num'] == 0
303
+ return self._extractInfo(response.body)
304
+ else
305
+ return nil, jsonResult['result_text']
306
+ end
307
+ else
308
+ if retries > 0
309
+ retries = retries - 1
310
+ return self._sendApiCommand(inParameters, retries)
311
+ else
312
+ return nil, response.code
313
+ end
314
+ end
315
+ end
316
+
317
+ # Builds a parameter string from a hash.
318
+ # @param params
319
+ # Optional. A hash of query parameters, key is parameter name, value is
320
+ # parameter value.
321
+ # @param separator
322
+ # Optional. The separator to use in the constructed string. Default '&'.
323
+ # @return
324
+ # The query string.
325
+ def _stringifyParameters(params, separator='&')
326
+ params.keys.inject('') do |query_string, key|
327
+ query_string << separator unless key == params.keys.first
328
+ query_string << "#{URI.encode(key.to_s)}=#{URI.encode(params[key].to_s)}"
329
+ end
330
+ end
331
+
332
+ end
333
+ end
334
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pijaz-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Chad Phillips
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-27 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This SDK contains the basic libraries to interact with the Pijaz synthesizer
14
+ platform. See http://developer.pijaz.com for more information.
15
+ email: chad@pijaz.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/pijaz-sdk.rb
21
+ - lib/pijaz/product.rb
22
+ - lib/pijaz/server_manager.rb
23
+ homepage: https://github.com/pijaz/pijaz-sdk
24
+ licenses:
25
+ - MIT
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.2.1
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Pijaz Software Development Kit
47
+ test_files: []