ubiquity-wiredrive 1.0.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.
@@ -0,0 +1,399 @@
1
+ require 'ubiquity/wiredrive/api/v2/client'
2
+
3
+ class Ubiquity::Wiredrive::API::V2::Utilities < Ubiquity::Wiredrive::API::V2::Client
4
+
5
+ def asset_create_extended(args = { }, options = { })
6
+ _args = args ? args.dup : { }
7
+ project_name = _args.delete(:project_name) { }
8
+ file_path = _args.delete(:file_path) { }
9
+
10
+ if file_path
11
+ file_name = File.basename(file_path)
12
+ _args[:name] ||= file_name
13
+ end
14
+
15
+ if project_name
16
+ _args[:project_id] ||= begin
17
+ project = project_get_by_name(:name => project_name)
18
+ raise ArgumentError, "Project Not Found by Name. '#{project_name}'" unless project
19
+ project['id']
20
+ end
21
+ end
22
+
23
+ asset = asset_create(_args, options)
24
+ return unless asset
25
+
26
+ if file_path
27
+ asset_id = asset['id']
28
+ location = asset_primary_file_init(:asset_id => asset_id)
29
+ return unless location
30
+ file_upload(:file_path => file_path, :destination_uri => location)
31
+ end
32
+
33
+ asset
34
+ end
35
+
36
+ def folder_create(args = { }, options = { })
37
+ args_out = args.merge(:is_folder => true, :workflow => 'project')
38
+ asset_create(args_out, options)
39
+ end
40
+
41
+ def folders_get(args = { }, options = { })
42
+ args_out = args.merge(:is_folder => true)
43
+ assets_get(args_out, options)
44
+ end
45
+
46
+ def project_get_by_name(args = { }, options = { })
47
+ project_name = case args
48
+ when String; args
49
+ when Hash; args[:name]
50
+ end
51
+ projects = projects_get( { :name => project_name }, options)
52
+ projects.first
53
+ end
54
+
55
+ def path_check(path, path_contains_asset = false, options = { })
56
+ return false unless path
57
+
58
+ # Remove any and all instances of '/' from the beginning of the path
59
+ path = path[1..-1] while path.start_with? '/'
60
+
61
+ path_ary = path.split('/')
62
+
63
+ existing_path_result = path_resolve(path, path_contains_asset, options)
64
+ existing_path_ary = existing_path_result[:id_path_ary]
65
+ check_path_length = path_ary.length
66
+
67
+ # Get a count of the number of elements which were found to exist
68
+ existing_path_length = existing_path_ary.length
69
+
70
+ # Drop the first n elements of the array which corresponds to the number of elements found to be existing
71
+ missing_path = path_ary.drop(existing_path_length)
72
+ # In the following logic tree the goal is indicate what was searched for and what was found. If we didn't search
73
+ # for the component (folder/asset) then we don't want to set the missing indicator var
74
+ # (folder_missing/asset_missing) for component as a boolean but instead leave it nil.
75
+ missing_path_length = missing_path.length
76
+ if missing_path_length > 0
77
+ # something is missing
78
+
79
+ if missing_path_length == check_path_length
80
+ # everything is missing in our path
81
+
82
+ project_missing = true
83
+ if path_contains_asset
84
+ # we are missing everything and we were looking for an asset so it must be missing
85
+ asset_missing = true
86
+
87
+ if check_path_length > 2
88
+ #if we were looking for more than two things (project, folder, and asset) and we are missing everything then folders are missing also
89
+ searched_folders = true
90
+ folder_missing = true
91
+ else
92
+
93
+ #if we are only looking for 2 things then that is only project and asset, folders weren't in the path so we aren't missing them
94
+ searched_folders = false
95
+ folder_missing = false
96
+ end
97
+ else
98
+ if check_path_length > 1
99
+ # If we are looking for more than one thing then it was project and folder and both are missing
100
+ searched_folders = true
101
+ folder_missing = true
102
+ else
103
+ searched_folders = false
104
+ folder_missing = false
105
+ end
106
+ end
107
+ else
108
+ #we have found at least one thing and it starts with project
109
+ project_missing = false
110
+ if path_contains_asset
111
+ #missing at least 1 and the asset is at the end so we know it's missing
112
+ asset_missing = true
113
+ if missing_path_length == 1
114
+ #if we are only missing one thing and it's the asset then it's not a folder!
115
+ folder_missing = false
116
+ searched_folders = check_path_length > 2
117
+ else
118
+ # missing_path_length is more than 1
119
+ if check_path_length > 2
120
+ #we are looking for project, folder, and asset and missing at least 3 things so they are all missing
121
+ searched_folders = true
122
+ folder_missing = true
123
+ else
124
+ #we are only looking for project and asset so no folders are missing
125
+ searched_folders = false
126
+ folder_missing = false
127
+ end
128
+ end
129
+ else
130
+ #if we are missing something and the project was found and there was no asset then it must be a folder
131
+ searched_folders = true
132
+ folder_missing = true
133
+ end
134
+ end
135
+ else
136
+ searched_folders = !existing_path_result[:folders].empty?
137
+ project_missing = folder_missing = asset_missing = false
138
+ end
139
+
140
+ {
141
+ :check_path_ary => path_ary,
142
+ :existing => existing_path_result,
143
+ :missing_path => missing_path,
144
+ :searched_folders => searched_folders,
145
+ :project_missing => project_missing,
146
+ :folder_missing => folder_missing,
147
+ :asset_missing => asset_missing,
148
+ }
149
+ end
150
+
151
+ def path_create(args = { }, options = { })
152
+ args = { :path => args } if args.is_a?(String)
153
+ logger.debug { "PATH CREATE: #{args.inspect}" }
154
+
155
+ path = args[:path]
156
+ raise ArgumentError, ':path is a required argument.' unless path
157
+
158
+ contains_asset = args.fetch(:contains_asset, false)
159
+ asset_file_path = args[:asset_file_path]
160
+ overwrite_asset = args.fetch(:overwrite_asset, false)
161
+ additional_asset_create_params = args[:additional_asset_create_params] || { }
162
+
163
+ path_check_result = path_check(path, contains_asset)
164
+ logger.debug { "CHECK PATH RESULT #{path_check_result.inspect}" }
165
+ return false unless path_check_result
166
+
167
+ project_missing = path_check_result[:project_missing]
168
+ folder_missing = path_check_result[:folder_missing]
169
+ asset_missing = path_check_result[:asset_missing]
170
+
171
+ existing = path_check_result[:existing]
172
+
173
+ asset = existing[:asset]
174
+
175
+ searched_folders = path_check_result[:searched_folders]
176
+
177
+ missing_path = path_check_result[:missing_path]
178
+
179
+ project_name = path_check_result[:check_path_ary][0]
180
+
181
+ if project_missing
182
+ logger.debug { "Missing Project - Creating Project '#{project_name}'" }
183
+ project = project_create(:name => project_name)
184
+ raise "Error Creating Project. Response: #{project}" unless project.is_a?(Hash)
185
+
186
+ path_check_result[:project] = project
187
+ project_id = project['id']
188
+ missing_path.shift
189
+ logger.debug { "Created Project '#{project_name}' - #{project_id}" }
190
+ else
191
+ project_id = existing[:id_path_ary].first
192
+ end
193
+
194
+ if searched_folders
195
+ if folder_missing
196
+ # logger.debug "FMP: #{missing_path}"
197
+
198
+ parent_folder_id = (existing[:id_path_ary].length <= 1) ? 0 : existing[:id_path_ary].last
199
+
200
+ asset_name = missing_path.pop if contains_asset
201
+
202
+ previous_missing = project_missing
203
+ missing_path.each do |folder_name|
204
+ # sleep path_creation_delay if path_creation_delay and previous_missing
205
+ begin
206
+ logger.debug { "Creating folder '#{folder_name}' parent id: #{parent_folder_id} project id: #{project_id}" }
207
+ new_folder = folder_create(:name => folder_name, :project_id => project_id, :parent_id => parent_folder_id)
208
+ raise "Error Creating Folder. Response: #{new_folder}" unless new_folder.is_a?(Hash)
209
+
210
+ logger.debug { "New Folder Created: #{new_folder.inspect}" }
211
+ parent_folder_id = new_folder['id']
212
+ rescue => e
213
+ raise "Failed to create folder '#{folder_name}' parent id: '#{parent_folder_id}' project id: '#{project_id}'. Exception: #{e.message}"
214
+ end
215
+ previous_missing = true
216
+ end
217
+
218
+ else
219
+ if contains_asset and not asset_missing
220
+ parent_folder_id = existing[:id_path_ary].fetch(-2)
221
+ else
222
+ parent_folder_id = existing[:id_path_ary].last
223
+ end
224
+ end
225
+ else
226
+ parent_folder_id = nil
227
+ end
228
+
229
+ if contains_asset
230
+
231
+ asset_name ||= File.basename(asset_file_path)
232
+ additional_asset_create_params = { } unless additional_asset_create_params.is_a?(Hash)
233
+ additional_asset_create_params[:parent_id] = parent_folder_id if parent_folder_id
234
+ additional_asset_create_params[:project_id] = project_id
235
+ additional_asset_create_params[:file_path] = asset_file_path
236
+ additional_asset_create_params[:name] = asset_name
237
+ additional_asset_create_params[:workflow] = 'project'
238
+
239
+ logger.debug { "Path Create Asset Handling. Asset Missing: #{asset_missing} Create Args: #{additional_asset_create_params.inspect}" }
240
+
241
+ if overwrite_asset and !asset_missing
242
+ asset_id = existing[:id_path_ary].last
243
+ begin
244
+ raise "Error Message: #{error_message}" unless asset_delete(:id => asset_id)
245
+ rescue => e
246
+ raise e, "Error Deleting Existing Asset. Asset ID: #{asset_id} Exception: #{e.message}"
247
+ end
248
+ asset_missing = true
249
+ end
250
+
251
+ if asset_missing
252
+ asset = asset_create_extended(additional_asset_create_params)
253
+ raise "Error Creating Asset: #{asset.inspect} Args: #{additional_asset_create_params.inspect}" unless success?
254
+ else
255
+ # additional_asset_create_params = additional_asset_create_params.delete_if { |k,v| asset[k] == v }
256
+ # asset_edit_extended(asset['id'], additional_asset_create_params) unless additional_asset_create_params.empty?
257
+ # metadata_create_if_not_exists(asset['id'], metadata) if metadata and !metadata.empty?
258
+ end
259
+
260
+ path_check_result[:asset] = asset
261
+ end
262
+ result = path_check_result.merge({ :project_id => project_id, :parent_folder_id => parent_folder_id })
263
+ logger.debug { "Create Missing Path Result: #{result.inspect}" }
264
+ return result
265
+
266
+ end
267
+
268
+
269
+ def path_resolve(path, path_contains_asset = false, options = { })
270
+
271
+ id_path_ary = [ ]
272
+ name_path_ary = [ ]
273
+
274
+ return_first_matching_asset = options.fetch(:return_first_matching_asset, true)
275
+
276
+ if path.is_a?(String)
277
+ # Remove any leading slashes
278
+ path = path[1..-1] while path.start_with?('/')
279
+
280
+ path_ary = path.split('/')
281
+ elsif path.is_a?(Array)
282
+ path_ary = path.dup
283
+ else
284
+ raise ArgumentError, "path is required to be a String or an Array. Path Class Name: #{path.class.name}"
285
+ end
286
+
287
+ asset_name = path_ary.pop if path_contains_asset
288
+
289
+ # The first element must be the name of the project
290
+ project_name = path_ary.shift
291
+ raise ArgumentError, 'path must contain a project name.' unless project_name
292
+ logger.debug { "Search for Project Name: #{project_name}" }
293
+ projects = projects_get(:name => project_name)
294
+ project = projects.first
295
+ return {
296
+ :name_path => '/',
297
+ :name_path_ary => [ ],
298
+
299
+ :id_path => '/',
300
+ :id_path_ary => [ ],
301
+
302
+ :project => nil,
303
+ :asset => nil,
304
+ :folders => [ ]
305
+ } if !project or project.empty?
306
+
307
+ project_id = project['id']
308
+ id_path_ary << project_id
309
+ name_path_ary << project_name
310
+
311
+ parsed_folders = path_resolve_folder(project_id, path_ary)
312
+
313
+ if parsed_folders.nil?
314
+ asset_folder_id = 0
315
+ folders = []
316
+ else
317
+ id_path_ary.concat(parsed_folders[:id_path_ary])
318
+ name_path_ary.concat(parsed_folders[:name_path_ary])
319
+ asset_folder_id = parsed_folders[:id_path_ary].last if path_contains_asset
320
+ folders = parsed_folders.fetch(:folder_ary, [])
321
+ end
322
+
323
+ # ASSET PROCESSING - BEGIN
324
+ asset = nil
325
+ if path_contains_asset and (asset_folder_id or path_ary.length == 2)
326
+ assets = assets_get(:name => asset_name, :is_folder => false, :project_id => project_id, :parent_id => asset_folder_id)
327
+ if assets and !assets.empty?
328
+ assets = [ assets.first ] if return_first_matching_asset
329
+ # Just add the whole array to the array
330
+ id_path_ary.concat assets.map { |_asset| _asset['id'] }
331
+ name_path_ary.concat assets.map { |_asset| _asset['name'] }
332
+ end
333
+ end
334
+
335
+ # ASSET PROCESSING - END
336
+
337
+ {
338
+ :name_path => "/#{name_path_ary.join('/')}",
339
+ :name_path_ary => name_path_ary,
340
+
341
+ :id_path => "/#{id_path_ary.join('/')}",
342
+ :id_path_ary => id_path_ary,
343
+
344
+ :project => project,
345
+ :asset => asset,
346
+ :folders => folders
347
+ }
348
+ end
349
+
350
+ def path_resolve_folder(project_id, path, parent_id = nil)
351
+ if path.is_a?(Array)
352
+ path_ary = path.dup
353
+ elsif path.is_a? String
354
+ path = path[1..-1] while path.start_with?('/')
355
+ path_ary = path.split('/')
356
+ end
357
+
358
+ return nil if !path_ary or path_ary.empty?
359
+
360
+ id_path_ary = [ ]
361
+ name_path_ary = [ ]
362
+
363
+ folder_name = path_ary.shift
364
+ name_path_ary << folder_name
365
+
366
+ args_out = {
367
+ :project_id => project_id,
368
+ :name => folder_name
369
+ }
370
+ args_out[:parent_id] = parent_id if parent_id
371
+
372
+ folders = folders_get(args_out)
373
+ folder = folders.first
374
+ return nil unless folder
375
+
376
+ folder_ary = [ folder ]
377
+
378
+ folder_id = folder['id']
379
+
380
+ id_path_ary << folder_id.to_s
381
+
382
+ resolved_folder_path = path_resolve_folder(project_id, path_ary, folder_id)
383
+
384
+ unless resolved_folder_path.nil?
385
+ id_path_ary.concat(resolved_folder_path[:id_path_ary] || [ ])
386
+ name_path_ary.concat(resolved_folder_path[:name_path_ary] || [ ])
387
+ folder_ary.concat(resolved_folder_path[:folder_ary] || [ ])
388
+ end
389
+
390
+ {
391
+ :id_path_ary => id_path_ary,
392
+ :name_path_ary => name_path_ary,
393
+ :folder_ary => folder_ary
394
+ }
395
+ end
396
+
397
+
398
+ end
399
+
@@ -0,0 +1,13 @@
1
+ require 'ubiquity/wiredrive/api/v3/client'
2
+ require 'ubiquity/wiredrive/api/v3/utilities'
3
+
4
+ module Ubiquity
5
+ module Wiredrive
6
+ module API
7
+ module V3
8
+
9
+ end
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,231 @@
1
+ require 'yaml'
2
+
3
+ require 'ubiquity/wiredrive/api/v3/http_client'
4
+ require 'ubiquity/wiredrive/api/v3/client/requests'
5
+
6
+ class Ubiquity::Wiredrive::API::V3::Client
7
+
8
+ attr_accessor :logger
9
+
10
+ attr_accessor :http_client, :request, :response, :http_response, :client_code
11
+
12
+ def initialize(args = { })
13
+ _token_cache = args.fetch(:token_cache_allow, false)
14
+
15
+ _token = args[:auth_token] || _token_cache ? token_cache_read(args) : nil
16
+ args[:auth_token] = _token if _token.is_a?(String) # _token.is_a?(String) ? Token.new(_token, self) : _token if _token
17
+
18
+ initialize_logger(args)
19
+ initialize_http_client(args)
20
+
21
+ unless _token
22
+ _do_login = args.fetch(:do_login, true)
23
+ if _do_login
24
+ _token = login_and_set_token(args)
25
+ args[:auth_token] = _token
26
+ token_cache_write(args) if _token_cache && _token
27
+ end
28
+ end
29
+ end
30
+
31
+ def token_cache_read(args)
32
+ _token_path = args[:token_cache_path] || '_token.yaml'
33
+ _token_path = File.expand_path(_token_path)
34
+ _token = File.exists?(_token_path) ? YAML.load_file(_token_path) : nil
35
+ _token
36
+ end
37
+
38
+ def token_cache_write(args)
39
+ _token = args[:auth_token]
40
+ return unless _token
41
+ _token_path = args[:token_cache_path] || '_token.yaml'
42
+ _token_path = File.expand_path(_token_path)
43
+ logger.debug { "Writing Token Cache - '#{_token_path}'" }
44
+ File.open(_token_path, 'w') { |f| f.write(YAML.dump(_token)) }
45
+ end
46
+
47
+ def login_and_set_token(args)
48
+ _credentials = args[:credentials] || args
49
+ _client_code = _credentials[:client_code]
50
+ _username = _credentials[:username]
51
+ _password = _credentials[:password]
52
+ if _client_code && _username && _password
53
+ token_data = auth_token(_credentials)
54
+ self.auth_token = token_data
55
+ end
56
+ token_data
57
+ end
58
+
59
+ def initialize_logger(args = { })
60
+ @logger = args[:logger] ||= Logger.new(args[:log_to] || STDOUT)
61
+ log_level = args[:log_level]
62
+ if log_level
63
+ @logger.level = log_level
64
+ args[:logger] = @logger
65
+ end
66
+ @logger
67
+ end
68
+
69
+ def initialize_http_client(args = { })
70
+ @http_client = Ubiquity::Wiredrive::API::V3::HTTPClient.new(args)
71
+ end
72
+
73
+ # @param [Requests::BaseRequest] request
74
+ # @param [Hash, nil] options
75
+ # @option options [Boolean] :execute_request (true) Will execute the request
76
+ # @option options [Boolean] :return_request (true) Will return the request instance instead of nil. Only applies if
77
+ # execute_request is false.
78
+ def process_request(request, options = nil)
79
+ # @paginator = nil
80
+ @response = nil
81
+ @request = request
82
+ logger.warn { "Request is Missing Required Arguments: #{request.missing_required_arguments.inspect}" } unless request.missing_required_arguments.empty?
83
+
84
+ # if ([:all, 'all'].include?(request.arguments[:_page]))
85
+ # request.arguments[:_page] = 1
86
+ # include_remaining_pages = true
87
+ # else
88
+ # include_remaining_pages = false
89
+ # end
90
+
91
+ request.client = self unless request.client
92
+ options ||= request.options
93
+
94
+ return (options.fetch(:return_request, true) ? request : nil) unless options.fetch(:execute_request, true)
95
+
96
+ #@response = http_client.call_method(request.http_method, { :path => request.path, :query => request.query, :body => request.body }, options)
97
+ @response = request.execute
98
+
99
+ # if include_remaining_pages
100
+ # return paginator.include_remaining_pages
101
+ # end
102
+
103
+ if @response.is_a?(Hash)
104
+ _results = @response['results']
105
+ return _results if _results
106
+ end
107
+
108
+ @response
109
+ end
110
+
111
+ # Exposes HTTP Methods
112
+ # @example http(:get, '/')
113
+ def http(method, *args)
114
+ @request = nil
115
+ @response = http_client.send(method, *args)
116
+ @request = http_client.request
117
+ response
118
+ end
119
+
120
+ # def paginator
121
+ # @paginator ||= Paginator.new(self) if @response
122
+ # end
123
+
124
+ def process_request_using_class(request_class, args = { }, options = { })
125
+ @response = nil
126
+ @request = request_class.new(args, options)
127
+ process_request(request, options)
128
+ end
129
+
130
+ def error
131
+ _error = errors.first
132
+ return _error.inspect if _error.is_a?(Hash)
133
+ _error
134
+ end
135
+
136
+ def error_message
137
+ _error = error
138
+ _error.is_a?(Hash) ? (_error['message'] || _error) : _error
139
+ end
140
+
141
+ def errors
142
+ return (response['errors'] || [ ]) if response.is_a?(Hash)
143
+ [ ]
144
+ end
145
+
146
+ def success?
147
+ return unless request
148
+ return request.success? if request.respond_to?(:success?)
149
+
150
+ _code = http_client.response.code
151
+ _code and _code.start_with?('2')
152
+ end
153
+
154
+ def auth_token=(value)
155
+ http_client.auth_token = value
156
+ end
157
+
158
+ # ################################################################################################################## #
159
+ # @!group API METHODS
160
+
161
+ def auth_token(args = { }, options = { })
162
+ _request = Requests::BaseRequest.new(
163
+ args,
164
+ {
165
+ :http_path => 'auth/api-token-auth',
166
+ :http_method => :post,
167
+ :default_parameter_send_in_value => :body,
168
+ :parameters => [
169
+ { :name => :client_code, :required => true, :default_value => client_code },
170
+ { :name => :username, :required => true },
171
+ { :name => :password, :required => true }
172
+ ]
173
+ }.merge(options)
174
+ )
175
+ _initial_http_host_address = http_client.http_host_address
176
+ client_code = _request.arguments[:client_code]
177
+ _http_host_address = "#{client_code}.wiredrive.com"
178
+
179
+ http_client.http_host_address = _http_host_address
180
+ _response = process_request(_request, options)
181
+ http_client.http_host_address = _initial_http_host_address
182
+ _token = http_client.response['Authorization']
183
+ _token || _response
184
+ end
185
+
186
+ def invitations_get(args = { }, options = { })
187
+
188
+ end
189
+
190
+ def presentation_authorize_get(args = { }, options = { })
191
+ _request = Requests::BaseRequest.new(
192
+ args,
193
+ {
194
+ :http_path => 'presentation-orch-api/api/authorize/#{path_arguments[:invite_token]}',
195
+ :default_parameter_send_in_value => :path,
196
+ :parameters => [
197
+ { :name => :invite_token, :aliases => [ :token ], :required => true },
198
+ { :name => :password, :required => true, :send_in => :query }
199
+ ]
200
+ }.merge(options)
201
+ )
202
+ _response = process_request(_request, options)
203
+ _token = http_client.response['Authorization']
204
+ _token || _response
205
+ end
206
+
207
+ def presentation_get(args = { }, options = { })
208
+ _request = Requests::BaseRequest.new(
209
+ args,
210
+ {
211
+ :http_path => 'presentation-orch-api/api/presentations/#{path_arguments[:presentation_id]}',
212
+ :default_parameter_send_in_value => :path,
213
+ :parameters => [
214
+ { :name => :presentation_id, :aliases => [ :id ], :required => true }
215
+ ]
216
+ }.merge(options)
217
+ )
218
+ process_request(_request, options)
219
+ end
220
+
221
+ def users_get(args = { }, options = { })
222
+ http(:get, 'user-orch-api/api/users')
223
+ end
224
+
225
+ def users_projects_get(args = { }, options = { })
226
+ http(:get, 'user-orch-api/api/users/projects')
227
+ end
228
+
229
+ # @!endgroup API METHODS
230
+
231
+ end