cantemo-portal-agent 1.2.4 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de359aa5f03562ec1007a7bdb3a9dc0af6362216
4
- data.tar.gz: 1fb3d59042129c18561dd1504a9ace1a5508a385
3
+ metadata.gz: f0df20d26170e018fbb101b896771dda9a848a8a
4
+ data.tar.gz: 977b72cf9a04ce9c70b31dc03436a57c78a5675a
5
5
  SHA512:
6
- metadata.gz: 4a75c0ac6f20dedffbfb5cd7575828ea43ea29c75b1c4fea6f56c029ac4ef89dcd7d740d2b048bb04f3c455ef3420f4b7c16264ac799d7f0d4b6334dda0f87b2
7
- data.tar.gz: b793017b7a68087dd13d1a278c9f37ca2cbf77bbf4a29455b9dd7f70f97ac137e4c3304698027c8cb37bb988855ff560f46da54782be700ede429b4750ee10a3
6
+ metadata.gz: 5173fe6dbe088d8ab5195c59c3666887d957cd2876e86c65463dd3da4386594973252ddb93fc714ef6831c0685cda06db0cbd8413424e9e46b8c6646b233938f
7
+ data.tar.gz: 4ad8f5e06305f2cd174c3bcb6a86c7959414ba257dcd59580cfd32dd9fe7ef072aedef4033f840e732987237738e8a4616f9b0586b57d8266cdaf7c8c4fffd4a
@@ -35,19 +35,22 @@ def args; @args end
35
35
  op = OptionParser.new
36
36
  op.on('-c', '--config-file-path FILEPATH', 'The path to the configuration file.',
37
37
  "Default Path(s): #{args[:config_file_path]}") { |v| args[:config_file_path] = v }
38
- op.on('-b', '--[no-]background', 'Tells the application to run in the background.') { |v| args[:daemonize] = v }
39
- op.on('-v', '--version', 'Output the version and exit.') { puts "Version #{Cantemo::Portal::Agent::VERSION}"; exit }
40
- op.on('--help', 'Show this message.') { puts op; exit }
38
+ # op.on('-b', '--[no-]background', 'Tells the application to run in the background.') { |v| args[:daemonize] = v }
39
+ op.on_tail('-t', '--log-to FILEPATH', 'Log file to log to') { |log_to| args[:log_to] = log_to }
40
+ op.on_tail('-l', '--log-level LEVEL', ['fatal', 'error', 'warn', 'info', 'debug'], 'Select logging level') do |log_level|
41
+ args[:log_level] = log_level.upcase
42
+ end
43
+ op.on_tail('-v', '--version', 'Output the version and exit.') { puts "Version #{Cantemo::Portal::Agent::VERSION}"; exit }
44
+ op.on_tail('--help', 'Show this message.') { puts op; exit }
41
45
  op.load
42
46
  op.parse!
43
47
 
44
48
  config_file_path = args[:config_file_path]
45
49
  args[:config_file_path].map! { |v| File.expand_path(v) } if config_file_path.is_a?(Array)
46
50
 
47
- command = ARGV.first.dup
48
-
51
+ command = ARGV.first
49
52
  daemon_control_command_present = command && begin
50
- command.downcase!
53
+ command = command.dup.downcase if command
51
54
  %w(start stop restart run zap killall status).include?(command)
52
55
  end
53
56
 
@@ -71,9 +74,11 @@ should_daemonize = (daemon_control_command_present && %w(start restart).include?
71
74
  #
72
75
  #
73
76
 
74
-
75
-
76
77
  class Watcher < Envoi::Mam::Cantemo::Agent::WatchFolderManager; end
77
78
  # daemonize ? Watcher.run_as_daemon(args, { force: true }) : Watcher.run(args)
78
79
  # daemon_control_command_present ? Watcher.run_as_daemon(args) : Watcher.run(args)
79
- Watcher.run_with_process_manager(args)
80
+ begin
81
+ Watcher.run_with_process_manager(args)
82
+ rescue => e
83
+ abort("An error occurred. #{e.message}\n#{e.backtrace}")
84
+ end
@@ -1,7 +1,7 @@
1
1
  module Cantemo
2
2
  module Portal
3
3
  class Agent
4
- VERSION = '1.2.4'.freeze
4
+ VERSION = '1.2.5'.freeze
5
5
  end
6
6
  end
7
7
  end
@@ -1,4 +1,4 @@
1
- if [ 'watchfolder', 'watchfolders'].include?((ARGV.first || '').tr('_-', ''))
1
+ if [ 'watchfolder', 'watchfolders'].include?((ARGV.first || '').tr('_-', '').downcase)
2
2
  require 'cantemo/portal/agent/cli/commands/watch_folders'
3
3
  else
4
4
  require 'envoi/mam/agent/cli/commands/cantemo-agent'
@@ -132,6 +132,15 @@ module Envoi
132
132
  logger.warn { "No Supported TransferClient Configuration#{transfer_type && !transfer_type.empty? ? " for transfer type '#{transfer_type}' " : ''}Found in Storage Configuration." }
133
133
  end
134
134
 
135
+ # @param [Hash] args
136
+ # @option args [String] :file_path
137
+ # @option args [String] :storage_id
138
+ # @option args [String] :transfer_type ('')
139
+ # @option args [Boolean] :import_file (true)
140
+ # @option args [Boolean] :preserve_path (storage_config['preserve_path'] || default_preserve_path)
141
+ # @return [Hash]
142
+ #
143
+ #
135
144
  def upload(args = {})
136
145
  _response = {}
137
146
 
@@ -149,17 +158,18 @@ module Envoi
149
158
 
150
159
  transfer_type = args[:transfer_type] || ''
151
160
  storage_id = args[:storage_id]
152
- vidispine_storage_config = agent_config_storages[storage_id]
161
+ storage_config = agent_config_storages[storage_id]
153
162
 
154
- unless vidispine_storage_config && !vidispine_storage_config.empty?
163
+ unless storage_config && !storage_config.empty?
155
164
  raise "No configuration found for storage '#{storage_id}'"
156
165
  end
157
166
 
158
- should_import_file = args.fetch(:import_file, vidispine_storage_config.fetch('import', true))
167
+ should_import_file = args.fetch(:import_file, storage_config.fetch('import', true))
159
168
 
160
- should_preserve_path = args.fetch(:preserve_path, vidispine_storage_config.fetch('preserve_path', default_preserve_file_path))
169
+ should_preserve_path = args.fetch(:preserve_path,
170
+ storage_config.fetch('preserve_path', default_preserve_file_path))
161
171
 
162
- destination_path = args[:destination_path] || vidispine_storage_config['destination_path'] || '/'
172
+ destination_path = args[:destination_path] || storage_config['destination_path'] || '/'
163
173
  relative_path = should_preserve_path ? File.dirname(file_path) : nil
164
174
  relative_path = File.expand_path(relative_path) if relative_path == '.'
165
175
 
@@ -171,7 +181,7 @@ module Envoi
171
181
 
172
182
  transfer_response = begin
173
183
  response = nil
174
- aspera_config = vidispine_storage_config['aspera']
184
+ aspera_config = storage_config['aspera']
175
185
  begin
176
186
  if (transfer_type.empty? || transfer_type == :aspera) && (aspera_config && !aspera_config.empty?)
177
187
  client = Envoi::Mam::Agent::TransferClient::Aspera.new(agent: self)
@@ -181,7 +191,7 @@ module Envoi
181
191
  logger.error { "Aspera Transfer Failed. '#{e.message}'\n#{e.backtrace.first}" }
182
192
  end
183
193
 
184
- s3_config = vidispine_storage_config['s3']
194
+ s3_config = storage_config['s3']
185
195
  begin
186
196
  if !response && (transfer_type.empty? || transfer_type == :s3) && (s3_config && !s3_config.empty?)
187
197
  _target_path = target_path
@@ -202,7 +212,7 @@ module Envoi
202
212
  _response[:transfer_response] = transfer_response
203
213
 
204
214
  if transfer_response.nil?
205
- logger.warn { "No supported TransferClient configuration#{transfer_type && !transfer_type.empty? ? " for transfer type '#{transfer_type}' " : ''}found in storage configuration." }
215
+ logger.warn { "No supported TransferClient configuration#{transfer_type && !transfer_type.empty? ? " for transfer type '#{transfer_type}'" : ''} found in storage configuration." }
206
216
  _response[:success] = false
207
217
  return _response
208
218
  end
@@ -240,7 +250,7 @@ module Envoi
240
250
  # @option args [Hash] :import_options ({})
241
251
  # @option args [String] :item_id
242
252
  # @option args [Hash] :response_object ({})
243
- # @option args [String] :shape_id (@default_vidispine_shape_tag)
253
+ # @option args [String] :shape_tag (@default_vidispine_shape_tag)
244
254
  # @option args [String] :storage_id
245
255
  # @option args [String] :target_path
246
256
  #
@@ -256,9 +266,8 @@ module Envoi
256
266
  item_id = args[:item_id]
257
267
  shape_tag = args[:shape_tag] || default_vidispine_shape_tag
258
268
 
259
- import_args_in = args[:import_args]
260
- import_options = args[:import_options] || {}
261
-
269
+ item_add_args_in = args[:item_add_args] || { }
270
+ item_add_options_in = args[:item_add_options] || { }
262
271
 
263
272
  # attach file to item as shape
264
273
  path_on_storage = File.join(target_path, File.basename(file_path))
@@ -292,28 +301,26 @@ module Envoi
292
301
 
293
302
  if item_id
294
303
  item_shape_import_response = api_client.item_shape_import(item_id: item_id,
295
- tag: shape_tag, fileId: file_id)
304
+ tag: shape_tag, file_id: file_id)
296
305
  else
297
- import_args = {
298
- storage_id: storage_id,
299
- file_path: path_on_storage,
300
- fileId: file_id,
301
- storage_path_map: { '/' => storage_id }
306
+ item_add_args = {
307
+ storage_id: storage_id,
308
+ file_path: path_on_storage,
309
+ file_id: file_id,
310
+ storage_path_map: { '/' => storage_id }
302
311
  }
303
- import_args.merge!(import_args_in) if import_args_in
312
+ item_add_args.merge(item_add_args_in) if item_add_args_in.is_a?(Hash)
304
313
 
305
- item_shape_import_response = api_client.item_add_using_file_path(import_args, import_options)
314
+ item_add_options = { }
315
+ item_add_options.merge!(item_add_options_in) if item_add_options_in.is_a?(Hash)
316
+
317
+ item_shape_import_response = api_client.item_add_using_file_path(item_add_args, item_add_options)
306
318
  end
307
319
  _response[:import_response] = item_shape_import_response
308
320
 
309
321
  _response
310
322
  end
311
323
 
312
- def upload_transfer_spec_get(file_paths)
313
-
314
- end
315
-
316
-
317
324
  def ingest_file
318
325
  # 1) export ASPERA_SCP_TOKEN="ATB3_AEA9dUI5dd2u1k8XBMVD0qInR-Lyylkz8AylTXLVt5_SMVGR8SO7Sdc0lj6RkoHK_DvAAEWac8bllF_Yan1NbbDTyPj_3BTA"
319
326
  # 2) ascp -i asperaweb_id_dsa.openssh -P 33001 -l 20m /Users/nicholasstokes/Desktop/CantemoAgent.mov xfer@ats-aws-us-west-2.aspera.io:
@@ -42,6 +42,8 @@ module Envoi::Mam::Cantemo
42
42
  args[:default_preserve_file_path] = args.fetch(:default_preserve_file_path, false)
43
43
 
44
44
  @config = Envoi::Mam::Cantemo::Agent.load_config_from_file(args)
45
+ initialize_logger_from_config
46
+
45
47
  cantemo_config = config[:cantemo] || config['cantemo']
46
48
 
47
49
  @default_agent_class = Envoi::Mam::Cantemo::Agent
@@ -63,7 +65,7 @@ module Envoi::Mam::Cantemo
63
65
  @ignored_file_paths_by_watch_folder = Hash.new { |h, k| h[k] = [] }
64
66
  @ignored_file_paths_lock = Mutex.new
65
67
 
66
- @threaded = args.fetch(:threaded, true)
68
+ @threaded = args.fetch(:threaded, config.fetch(:threaded, config.fetch('threaded', true)))
67
69
 
68
70
  @default_maximum_active_processors = DEFAULT_WATCH_FOLDER_PROCESSOR_LIMIT
69
71
  @processors_by_watch_folder = Hash.new { |h, k| h[k] = {} }
@@ -73,7 +75,7 @@ module Envoi::Mam::Cantemo
73
75
 
74
76
  def initialize_logger(args = {})
75
77
  @logger = args[:logger] ||= Logger.new(args[:log_to] || STDOUT)
76
- log_level = args[:log_level] = Logger::DEBUG
78
+ log_level = args[:log_level] = Logger::INFO
77
79
  if log_level
78
80
  @logger.level = log_level
79
81
  args[:logger] = @logger
@@ -81,6 +83,18 @@ module Envoi::Mam::Cantemo
81
83
  @logger
82
84
  end
83
85
 
86
+ def initialize_logger_from_config(_config = @config)
87
+ logger_args = { }
88
+ log_to = _config['log_to']
89
+ logger_args[:log_to] = log_to if log_to
90
+ log_level = _config['log_level']
91
+ if log_level
92
+ _log_level = ['fatal', 'error', 'warn', 'info', 'debug'].find(log_level.downcase)
93
+ logger_args[:log_level] = _log_level.upcase if _log_level
94
+ end
95
+ initialize_logger(logger_args) unless logger_args.empty?
96
+ end
97
+
84
98
  # @param [Hash] watch_folder_def
85
99
  # @option watch_folder_def [String] path
86
100
  # @option watch_folder_def [String] upload_to_storage_id
@@ -140,7 +154,7 @@ module Envoi::Mam::Cantemo
140
154
  end
141
155
 
142
156
  # @param [Object] file
143
- # @return [FalseClass]
157
+ # @return [Hash]
144
158
  def process_file(file)
145
159
  file.processing = true
146
160
  file_name = file.name || file.path
@@ -150,20 +164,26 @@ module Envoi::Mam::Cantemo
150
164
  agent ||= default_agent
151
165
 
152
166
  storage_id = watch_folder.definition['upload_to_storage_id']
153
- quarantine_directory_path = watch_folder.definition['quarantine_directory_path']
154
- completed_directory_path = watch_folder.definition['completed_directory_path']
155
- import_args = watch_folder.definition['import_args']
156
- import_options = watch_folder.definition['import_options']
157
167
 
158
- # full_file_path = File.join(watch_folder.path, file.path)
159
- full_file_path = file.path
160
168
  unless storage_id
161
169
  logger.warn { "Skipping processing of file because of missing storage ID." }
162
170
  return { success: false, message: 'Missing storage ID.' }
163
171
  end
164
172
 
165
- _response = agent.upload(file_path: full_file_path,
166
- storage_id: storage_id, import_args: import_args, import_options: import_options)
173
+ quarantine_directory_path = watch_folder.definition['quarantine_directory_path']
174
+ completed_directory_path = watch_folder.definition['completed_directory_path']
175
+ watch_folder_upload_args = watch_folder.definition['upload_args']
176
+
177
+ # full_file_path = File.join(watch_folder.path, file.path)
178
+ full_file_path = file.path
179
+
180
+ upload_args = {
181
+ file_path: full_file_path,
182
+ storage_id: storage_id
183
+ }
184
+ upload_args.merge!(watch_folder_upload_args) if watch_folder_upload_args.is_a?(Hash)
185
+
186
+ _response = agent.upload(upload_args)
167
187
  _response = { success: _response } if _response == true || _response == false
168
188
 
169
189
  if _response[:success]
@@ -219,7 +239,6 @@ module Envoi::Mam::Cantemo
219
239
  ignored_file_paths = @ignored_file_paths_by_watch_folder[wf]
220
240
  end
221
241
 
222
-
223
242
  stable_files.each do |file|
224
243
  next if file.respond_to?(:ignore?) ? file.ignore? : ignored_file_paths.include?(file.path)
225
244
  next if file.processing || file.processed
@@ -240,9 +259,9 @@ module Envoi::Mam::Cantemo
240
259
 
241
260
  if @threaded
242
261
  active_processors.keep_if { |k, v| k.processing }
243
- if active_processors.length > maximum_active_processors
262
+ if active_processors.length >= maximum_active_processors
244
263
  logger.debug { "Maximum number of active processors reached for watch folder. #{wf.name || wf.paths}" }
245
- next
264
+ break
246
265
  end
247
266
  t = Thread.new(file) do |file|
248
267
  wf = file.watch_folder
@@ -302,7 +321,8 @@ module Envoi::Mam::Cantemo
302
321
  end
303
322
  logger.info { 'Exiting...' }
304
323
  rescue => e
305
- logger.error { "An error occurred.\n#{e.message}\n#{e.backtrace.join("\n")}\n#{e.message}" }
324
+ logger.debug { "EXCEPTION #{e.message} \n#{e.backtrace.join("\n")}\n" }
325
+ logger.error { "An error occurred. #{e.message}" }
306
326
  raise e
307
327
  ensure
308
328
  watch_folders.each { |wf| wf.stop if wf.respond_to?(:stop) }
@@ -331,8 +351,6 @@ module Envoi::Mam::Cantemo
331
351
  def self.run(args)
332
352
  w = self.new(args)
333
353
  w.run
334
- rescue => e
335
- abort("An error occurred. #{e.message}\n#{e.backtrace.join("\n")}")
336
354
  end
337
355
 
338
356
  def self.daemons_run_proc_with_cleanup(options, &block)
@@ -49,7 +49,7 @@ module Envoi
49
49
 
50
50
  def initialize_logger(args = {})
51
51
  @logger = args[:logger] ||= Logger.new(args[:log_to] || STDOUT)
52
- log_level = args[:log_level] = Logger::DEBUG
52
+ log_level = args[:log_level] = Logger::INFO
53
53
  if log_level
54
54
  @logger.level = log_level
55
55
  args[:logger] = @logger
@@ -220,13 +220,20 @@ module Envoi
220
220
  end
221
221
  logger.debug { "Parameter 'upload to storage id' initialized." }
222
222
 
223
- logger.debug { "Initializing parameter 'import args'." }
224
- import_args = watch_folder_def['import_args'] || { }
225
- import_options = watch_folder_def['import_options'] || { }
223
+ logger.debug { "Initializing parameter 'upload/import arguments'." }
224
+ upload_args = watch_folder_def['upload_args']
225
+ item_add_args = watch_folder_def['item_add_args']
226
+ item_add_options = watch_folder_def['item_add_options']
227
+ import_args = watch_folder_def['import_args'] || { }
228
+ import_options = watch_folder_def['import_options'] || { }
229
+
226
230
  import_args = Hash[import_args.map { |k,v| [ k.respond_to?(:to_sym) ? k.to_sym.downcase : k, v ] }]
227
231
  import_options = Hash[import_options.map { |k,v| [ k.respond_to?(:to_sym) ? k.to_sym.downcase : k, v ] }]
228
232
 
229
- add_item_to_collection = import_options.fetch(:add_item_to_collection, import_args[:add_item_to_collection])
233
+ # Allow adding to collection to be overridden
234
+ add_item_to_collection = import_options.fetch(:add_item_to_collection,
235
+ import_args.fetch(:add_item_to_collection,
236
+ watch_folder_def['add_item_to_collection']))
230
237
  if add_item_to_collection.nil? || add_item_to_collection
231
238
  _add_item_to_collection = false
232
239
  collection_id = watch_folder_def['collection_id']
@@ -256,10 +263,36 @@ module Envoi
256
263
  if metadata
257
264
  import_args[:metadata] = metadata
258
265
  watch_folder_def.delete('metadata')
259
- metadata_map = watch_folder_def['metadata_map']
266
+ end
267
+
268
+ metadata_map = watch_folder_def['metadata_map']
269
+ metadata_group = watch_folder_def['metadata_group']
270
+ if metadata_map || metadata_group
271
+ ((metadata_map ||= { })[:__build_metadata_document_options] ||= {})[:parent_group_name] = metadata_group if metadata_group
260
272
  import_options[:metadata_map] ||= metadata_map if metadata_map
261
273
  end
262
- logger.debug { "Parameter 'import args' initialized." }
274
+
275
+ ingest_group = watch_folder_def['ingest_group']
276
+ if ingest_group
277
+ job_metadata = (import_args[:jobmetadata] ||= '')
278
+ job_metadata += ',' unless job_metadata.empty?
279
+ job_metadata += "portal_groups:StringArray=#{ingest_group}"
280
+ import_args[:jobmetadata] = job_metadata
281
+ end
282
+
283
+ item_add_args = symbolize_keys(item_add_args)
284
+ ((item_add_args ||= {})[:import_args] ||= {}).merge! import_args if import_args.is_a?(Hash)
285
+ ((item_add_args ||= {})[:import_options] ||= {}).merge! import_options if import_options.is_a?(Hash)
286
+
287
+ upload_args = symbolize_keys(upload_args)
288
+ ((upload_args ||= {})[:item_add_args] ||= {}).merge! item_add_args if item_add_args.is_a?(Hash)
289
+ ((upload_args ||= {})[:item_add_options] ||= {}).merge! symbolize_keys(item_add_options) if item_add_options.is_a?(Hash)
290
+
291
+ watch_folder_def.delete('import_args')
292
+ watch_folder_def.delete('import_options')
293
+
294
+ watch_folder_def['upload_args'] = upload_args
295
+ logger.debug { "Parameter 'upload/import arguments' initialized." }
263
296
 
264
297
 
265
298
  maximum_active_processors = watch_folder_def['maximum_active_processors']
@@ -305,6 +338,21 @@ module Envoi
305
338
  handler.stable_files
306
339
  end
307
340
 
341
+ # Converts hash keys to symbols
342
+ #
343
+ # @param [Hash] value hash
344
+ # @param [Boolean] recursive Will recurse into any values that are hashes or arrays
345
+ def symbolize_keys (value, recursive = true)
346
+ case value
347
+ when Hash
348
+ Hash[value.map { |k,v| [ k.respond_to?(:to_sym) ? k.to_sym : k, recursive ? symbolize_keys(v, true) : v ] }]
349
+ when Array
350
+ value.map { |v| symbolize_keys(v, recursive) }
351
+ else
352
+ value
353
+ end
354
+ end
355
+
308
356
  end
309
357
 
310
358
  end
@@ -121,7 +121,7 @@ module Envoi
121
121
  end
122
122
 
123
123
  def process_deleted_path(path)
124
- return path.each { |path| process_deleted_path(path, event_type) } if path.is_a?(Array)
124
+ return path.each { |path| process_deleted_path(path) } if path.is_a?(Array)
125
125
  logger.debug { "PATH #{:deleted} '#{path}'" }
126
126
  file = known_path_map[path]
127
127
  known_path_map.delete(path)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cantemo-portal-agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Whitson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-02 00:00:00.000000000 Z
11
+ date: 2019-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asperalm