cantemo-portal-agent 1.0.9

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,41 @@
1
+ #!/usr/bin/env ruby
2
+ lib_path = __FILE__ == '(irb)' ? File.join(Dir.cwd, 'lib') : File.expand_path('../../../lib', __FILE__)
3
+ $:.unshift(lib_path) unless $:.include?(lib_path) or !File.exists?(lib_path)
4
+ require 'rubygems'
5
+
6
+ require 'envoi/mam/agent/cli'
7
+ require 'envoi/mam/vdms/agent'
8
+
9
+ current_command = ARGV.shift
10
+ ARGV << '--help' if ARGV.empty?
11
+
12
+ args = {
13
+ :config_file_path => default_config_file_paths,
14
+ :dry_run => false,
15
+ :preserve_path => true,
16
+ :destination_path => File.expand_path('.'),
17
+ }
18
+
19
+ args[:config_service_app_id] = ENV['ENVOI_MAM_AGENT_APP_ID']
20
+ args[:config_service_app_token] = ENV['ENVOI_MAM_AGENT_APP_TOKEN']
21
+ args[:config_service_app_url] = ENV['ENVOI_MAM_AGENT_APP_URL']
22
+
23
+ op = OptionParser.new
24
+ op.on('-c', '--config-file-path FILEPATH', 'The path to the configuration file.') { |v| args[:config_file_path] = v }
25
+ op.on('--agent-app-id ID', '') { |v| args[:config_service_app_id] = v }
26
+ op.on('--agent-token TOKEN', '') { |v| args[:config_service_app_token] = v }
27
+ op.on('--agent-service-api URL', '') { |v| args[:config_service_api_url] = v }
28
+
29
+ op.on('-d', '--destination-path DIRPATH', 'The destination path to download or upload to.', "default: '#{args[:destination_path]}'") { |v| args[:destination_path] = v }
30
+ op.on('-p','--[no-]preserve-path', "default: #{args[:preserve_path]}") { |v| args[:preserve_path] = v }
31
+
32
+ # op.on('--dry-run', 'Run without executing the transfer.') { |v| args[:dry_run] = v }
33
+ op.on('--help', 'Show this message.') { puts op; exit }
34
+ op.load
35
+ op.parse!
36
+
37
+ args[:file_path] ||= ARGV.shift
38
+ args[:destination_path] ||= ARGV.shift unless ARGV.empty?
39
+
40
+ agent = Envoi::Mam::Vdms::Agent.load_config_and_init(args)
41
+ agent.run_operation
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+ lib_path = __FILE__ == '(irb)' ? File.join(Dir.cwd, 'lib') : File.expand_path('../../../lib', __FILE__)
3
+ $:.unshift(lib_path) unless $:.include?(lib_path) or !File.exists?(lib_path)
4
+ require 'rubygems'
5
+ require 'optparse'
6
+ require 'open3'
7
+
8
+ require 'envoi/mam/agent/cli'
9
+ require 'envoi/mam/vidispine/agent'
10
+
11
+ default_config_file_paths = Envoi::Mam::Agent::Cli::CONFIG_FILE_PATHS
12
+
13
+ aspera_ascp_paths = Envoi::Mam::Agent::TransferClient::Aspera::ASCP_PATHS
14
+ default_aspera_ascp_path = aspera_ascp_paths.find { |v| File.exist? v } || aspera_ascp_paths.first
15
+
16
+ current_command = ARGV.shift
17
+ ARGV << '--help' if ARGV.empty?
18
+
19
+ args = {
20
+ :config_file_path => default_config_file_paths,
21
+ :default_ascp_path => default_aspera_ascp_path,
22
+ :dry_run => false,
23
+ :operation => :download,
24
+ :preserve_path => true,
25
+ :transfer_type => '',
26
+ }
27
+
28
+ args[:config_service_app_id] = ENV['ENVOI_MAM_AGENT_APP_ID']
29
+ args[:config_service_app_token] = ENV['ENVOI_MAM_AGENT_APP_TOKEN']
30
+ args[:config_service_app_url] = ENV['ENVOI_MAM_AGENT_APP_URL']
31
+
32
+ op = OptionParser.new
33
+ op.on('-c', '--config-file-path FILEPATH', 'The path to the configuration file.', "Default Path(s): #{args[:config_file_path]}") { |v| args[:config_file_path] = v }
34
+ op.on('--agent-app-id ID', '') { |v| args[:config_service_app_id] = v }
35
+ op.on('--agent-token TOKEN', '') { |v| args[:config_service_app_token] = v }
36
+ op.on('--agent-service-api URL', '') { |v| args[:config_service_api_url] = v }
37
+
38
+ op.on('-i', '--item-id ITEMID', 'The Vidispine item id.') { |v| args[:item_id] = v }
39
+ op.on('-s', '--shape-id SHAPEID', 'The Vidispine shape id.') { |v| args[:shape_id] = v }
40
+ op.on('-t', '--shape-tag SHAPETAG', 'The Vidispine shape tag used to find the shape when a shape id is not supplied.') { |v| args[:shape_tag] = v }
41
+ op.on('--storage-id STORAGEID', 'The Vidispine storage id to use for the transfer.') { |v| args[:storage_id] = v}
42
+
43
+ op.on('-d', '--destination-path DIRPATH', 'The destination path to download or upload to.', "default: '.'") { |v| args[:destination_path] = v }
44
+ op.on('-p','--[no-]preserve-path', "default: true") { |v| args[:preserve_path] = v }
45
+ op.on('-p', '--operation OP', [ :download, :upload ], 'Transfer Direction.', "default: #{args[:operation]}" ) { |v| args[:operation] = v }
46
+ op.on('--transfer-type TYPE', [ :aspera, :s3 ],'Force the type of transfer to use. Ex: aspera || s3') { |v| args[:transfer_type] = v }
47
+ op.on('--transfer-token TOKEN', '') { |v| args[:transfer_token] = v }
48
+ op.on('--dry-run', 'Run without executing the transfer.') { |v| args[:dry_run] = v }
49
+ op.on('--help', 'Show this message.') { puts op; exit }
50
+ op.load
51
+ op.parse!
52
+
53
+ args[:file_path] ||= ARGV.shift
54
+ args[:destination_path] ||= ARGV.shift unless ARGV.empty?
55
+
56
+ agent = Envoi::Mam::Vidispine::Agent.load_config_and_init(args)
57
+ agent.run_operation
@@ -0,0 +1,223 @@
1
+ require 'cgi'
2
+ require 'open-uri'
3
+
4
+ require 'ubiquity/wiredrive/presentation_utility'
5
+ require 'ubiquity/envoi/api/utilities'
6
+
7
+ require 'envoi/mam/agent/cli'
8
+ require 'envoi/mam/wiredrive/agent'
9
+ require 'envoi/mam/iconik/agent'
10
+
11
+ current_command = ARGV.shift
12
+ ARGV << '--help' if ARGV.empty?
13
+
14
+ default_config_file_paths = Envoi::Mam::Agent::Cli::CONFIG_FILE_PATHS
15
+ # test_args = %w(--download --send-to-envoi --destination-path /tmp)
16
+ # ARGV.concat test_args
17
+ args = {
18
+ :config_file_path => default_config_file_paths,
19
+ :dry_run => false,
20
+ :preserve_path => true,
21
+ :destination_path => File.expand_path('.'),
22
+ :should_download_presentation => false,
23
+ :should_add_presentation_assets_to_envoi => false
24
+ }
25
+
26
+ args[:config_service_app_id] = ENV['ENVOI_MAM_AGENT_APP_ID']
27
+ args[:config_service_app_token] = ENV['ENVOI_MAM_AGENT_APP_TOKEN']
28
+ args[:config_service_app_url] = ENV['ENVOI_MAM_AGENT_APP_URL']
29
+
30
+ op = OptionParser.new
31
+ op.on('-c', '--config-file-path FILEPATH', 'The path to the configuration file.') { |v| args[:config_file_path] = v }
32
+ op.on('--agent-app-id ID', '') { |v| args[:config_service_app_id] = v }
33
+ op.on('--agent-token TOKEN', '') { |v| args[:config_service_app_token] = v }
34
+ op.on('--agent-service-api URL', '') { |v| args[:config_service_api_url] = v }
35
+
36
+ op.on('--presentation-invitation-token TOKEN', 'Presentation invitation token.') { |v| args[:presentation_invitation_token] = v }
37
+ op.on('--presentation-password PASSWORD', 'Presentation password') { |v| args[:presentation_password] = v }
38
+ op.on('--presentation-url URL', 'A shared presentation URL.') { |v| args[:presentation_url] = v }
39
+ # op.on('--presentation-id ID', '') { |v| args[:presentation_id] = v }
40
+ #
41
+ op.on('--[no-]download-presentation-assets', 'Determines if presentation asset files should be downloaded.') { |v| args[:should_download_presentation] = v }
42
+ op.on('--[no-]add-assets-to-envoi', 'Determines if presentation assets should be added to Envoi.') { |v| args[:should_add_presentation_assets_to_envoi] = v }
43
+ op.on('--[no-]add-assets-to-iconik', '') { |v| args[:should_add_presentation_assets_to_iconik] = v }
44
+ op.on('--iconik-storage-id STORAGEID', '') { |v| args[:iconik_storage_id] = v }
45
+
46
+ op.on('-d', '--destination-path DIRPATH', 'The destination path to download or upload to.', "default: '#{args[:destination_path]}'") { |v| args[:destination_path] = v }
47
+ op.on('-p','--[no-]preserve-path', "default: #{args[:preserve_path]}") { |v| args[:preserve_path] = v }
48
+
49
+ # op.on('--dry-run', 'Run without executing the transfer.') { |v| args[:dry_run] = v }
50
+ op.on('--help', 'Show this message.') { puts op; exit }
51
+ op.load
52
+ op.parse!
53
+
54
+ args[:destination_path] ||= ARGV.shift unless ARGV.empty?
55
+
56
+ presentation_url ||= args[:presentation_url] || ARGV.shift
57
+ if presentation_url
58
+ uri = URI(presentation_url)
59
+ presentation_invitation_token = uri.path
60
+ presentation_url_token = presentation_invitation_token[1..-1] if presentation_invitation_token.start_with?('/')
61
+
62
+ query_data = uri.query ? Hash[uri.query.split('&').map { |v| v.split('=') }] : { }
63
+ query_password = query_data['password']
64
+ presentation_url_password ||= query_password
65
+
66
+ args[:presentation_invitation_token] ||= presentation_url_token
67
+ args[:presentation_password] ||= presentation_url_password
68
+ end
69
+
70
+ class EnvoiImportUtility
71
+
72
+ attr_accessor :initial_args, :api_client
73
+
74
+ def initialize(args = { })
75
+ @initial_args = args
76
+ initialize_api_client(args)
77
+ end
78
+
79
+ def after_initialize
80
+ @default_original_storage_id = args[:default_original_storage_id]
81
+ @default_thumbnail_storage_id = args[:default_thumbnail_storage_id]
82
+ end
83
+
84
+ def initialize_api_client(args = { })
85
+ @api_client = Ubiquity::Envoi::API::Utilities.new(args)
86
+ end
87
+
88
+ def import_wiredrive_presentation_asset(asset, options = { })
89
+ title = asset['title'] || asset['label']
90
+ description = asset['description']
91
+ keywords = asset['keywords']
92
+
93
+ media_elements = asset['media']
94
+
95
+ media = media_elements.find { |me| me['type'] == 'original' }
96
+ raise 'No original media found.' unless media
97
+ url = media['url']
98
+ uri = URI(url)
99
+ mime_type = media['mimeType']
100
+ size = media['fileSize']
101
+
102
+
103
+ url_path = uri.path.split('?').first
104
+ filename = File.basename(url_path)
105
+
106
+ original_storage_id = options[:original_storage_id] || options[:storage_id] || @default_original_storage_id
107
+ create_args = {
108
+ :name => title,
109
+ :description => description,
110
+ :file => {
111
+ :mime => 'video/mp4', # mime_type,
112
+ :path => url,
113
+ :name => filename,
114
+ :storage_key => url_path,
115
+ :setting_id => original_storage_id,
116
+ 'size' => size || 0
117
+ }
118
+ }
119
+ r = api_client.media_file_create(create_args)
120
+
121
+ media_file_id = r['id']
122
+ raise 'No id found in response' unless media_file_id
123
+
124
+ video_thumb = asset['thumbnails'].find { |e| e['category'] == 'max' }
125
+ if video_thumb
126
+ thumbnail_storage_id = options[:thumbnail_storage_id] || options[:storage_id] || @default_thumbnail_storage_id
127
+ video_thumb_url = video_thumb['url']
128
+ video_thumb_uri = URI(video_thumb_url)
129
+ video_thumb_path = video_thumb_uri.path.split('?').first
130
+ media_file_file_add_args = {
131
+ 'media_file_id' => media_file_id,
132
+ 'shape_type' => 'thumb',
133
+ 'shape_label' => 'Thumbnail',
134
+ 'name' => File.basename(video_thumb_path),
135
+ 'mime' => 'image/jpeg',
136
+ 'path' => video_thumb_url,
137
+ 'size' => 0,
138
+ 'setting_id' => thumbnail_storage_id,
139
+ 'storage_key' => video_thumb_path
140
+ }
141
+ r = api_client.media_file_file_add(media_file_file_add_args)
142
+
143
+ end
144
+ end
145
+
146
+ end
147
+
148
+ @args = args
149
+ def wdpu(args = @args); @wdpu ||= Ubiquity::Wiredrive::PresentationUtility.new(args) end
150
+
151
+ def presentation_assets_get(args = @args)
152
+ presentation_invitation_token = args[:presentation_invitation_token]
153
+ presentation_password = args[:presentation_password]
154
+ wdpu.presentation_assets_get_using_token(presentation_invitation_token, presentation_password)
155
+ end
156
+ def presentation_assets; @presentation_assets ||= presentation_assets_get end
157
+
158
+ if args[:should_download_presentation]
159
+ presentation_assets_download_results = wdpu.presentation_assets_download(assets: presentation_assets, destination_path: args[:destination_path], overwrite: args[:overwrite_on_download])
160
+ end
161
+
162
+ if args[:should_add_presentation_assets_to_envoi]
163
+
164
+ wda = Envoi::Mam::Wiredrive::Agent.load_config_and_init(args)
165
+ envoi_config = wda.config['envoi']
166
+ envoi_http_host_address = envoi_config['http_host_address']
167
+ envoi_username = envoi_config['username']
168
+ envoi_password = envoi_config['password']
169
+ envoi_original_storage_id = envoi_config['original_storage_id'] || envoi_config['default_storage_id']
170
+ envoi_thumbnail_storage_id = envoi_config['thumbnail_storage_id'] || envoi_config['default_storage_id']
171
+ envoi_args = { http_host_address: envoi_http_host_address, username: envoi_username, password: envoi_password }
172
+ envoi = EnvoiImportUtility.new(envoi_args)
173
+ presentation_assets.each do |a|
174
+ begin
175
+ envoi.import_wiredrive_presentation_asset(a, { original_storage_id: envoi_original_storage_id, thumbnail_storage_id: envoi_thumbnail_storage_id })
176
+ rescue => e
177
+ warn "#{e.message} #{$@.first}"
178
+ end
179
+
180
+ end
181
+ end
182
+
183
+ if args[:should_add_presentation_assets_to_iconik]
184
+ presentation_assets_download_results ||= wdpu.presentation_assets_download(assets: presentation_assets, destination_path: '/tmp')
185
+
186
+ # wda = Envoi::Mam::Wiredrive::Agent.load_config_and_init(args)
187
+ # iconik_config = wda.config['iconik']
188
+
189
+ iconik = Envoi::Mam::Iconik::Agent.load_config_and_init(args)
190
+ iconik_storage_id = args[:iconik_storage_id]
191
+ presentation_assets_download_results.each do |r|
192
+ # asset = r[:asset]
193
+ media_elements_downloaded = r[:media_element_download_responses]
194
+ media_element_downloaded = media_elements_downloaded.first
195
+ file_path = media_element_downloaded[:destination_file_path]
196
+ begin
197
+ # puts "WD FP: #{media_element_downloaded}"
198
+ iconik.upload(file_path: file_path, storage_id: iconik_storage_id, destination_path: '/', preserve_path: false)
199
+ rescue => e
200
+ warn "#{e.message} #{$@.first}"
201
+ end
202
+ end
203
+
204
+ end
205
+
206
+ if args[:should_add_presentation_assets_to_vidispine]
207
+ presentation_assets_download_results ||= wdpu.presentation_assets_download(assets: presentation_assets, destination_path: '/tmp')
208
+
209
+ vidispine = Envoi::Mam::Vidispine::Agent.load_config_and_init(args)
210
+ vidispine_storage_id = args[:vidispine_storage_id]
211
+ presentation_assets_download_results.each do |r|
212
+ # asset = r[:asset]
213
+ media_elements_downloaded = r[:media_element_download_responses]
214
+ media_element_downloaded = media_elements_downloaded.first
215
+ file_path = media_element_downloaded[:destination_file_path]
216
+ begin
217
+ vidispine.upload(file_path: file_path, storage_id: vidispine_storage_id, destination_path: '/', preserve_path: false)
218
+ rescue => e
219
+ warn "#{e.message} #{$@.first}"
220
+ end
221
+ end
222
+
223
+ end
File without changes
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ module Envoi
6
+ module Mam
7
+ class Agent
8
+ class ConfigServiceClient
9
+
10
+ DEFAULT_API_URL = 'https://9nyhwwwjw7.execute-api.us-east-1.amazonaws.com/latest/'
11
+
12
+
13
+ def self.config_get(args = { })
14
+ app_id = args[:app_id]
15
+ token = args[:token]
16
+ api_url = args[:api_url] || DEFAULT_API_URL
17
+ request_url = "#{api_url}getuserrecord?token=#{token}&application_id=#{app_id}"
18
+ uri = URI(request_url)
19
+ http = Net::HTTP.new(uri.host, uri.port)
20
+ http.use_ssl = true
21
+ req = Net::HTTP::Get.new(uri.request_uri)
22
+ response = http.request(req)
23
+
24
+ code = response.code
25
+ body_raw = response.body
26
+
27
+ unless code == '200'
28
+ puts uri.to_s
29
+ puts uri.request_uri
30
+ puts code
31
+ puts body_raw
32
+ return false
33
+ end
34
+
35
+ body_parsed = JSON.parse(body_raw)
36
+ result = body_parsed['result']
37
+ raise "Invalid response from configuration service. No result found. '#{body_raw}'" unless result
38
+
39
+ app_data = result.first
40
+ raise "Invalid response from configuration service. No app data found. '#{body_raw}'" unless app_data
41
+
42
+ agent_data_raw = app_data['agentdata']
43
+ raise "Invalid response from configuration service. No agentdata found. '#{body_raw}'" unless agent_data_raw
44
+
45
+ begin
46
+ agent_data = JSON.parse(agent_data_raw)
47
+ rescue => e
48
+ raise "Error parsing agentdata. #{e.message} '#{body_raw}'"
49
+ end
50
+
51
+ agent_data
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
60
+ end
File without changes
File without changes
File without changes
@@ -0,0 +1,37 @@
1
+
2
+ require 'envoi/mam/agent'
3
+
4
+ module Envoi
5
+ module Mam
6
+ class Agent
7
+ class TransferClient
8
+
9
+ attr_accessor :agent, :logger, :initial_args
10
+
11
+ def initialize(args = { })
12
+ @initial_args = args
13
+ @agent = args[:agent]
14
+ initialize_logger(args)
15
+
16
+ after_initialize
17
+ end
18
+
19
+ def after_initialize
20
+ # To be overridden by child class
21
+ end
22
+
23
+ def initialize_logger(args = { })
24
+ @logger = agent.logger if agent && agent.respond_to?(:logger) && agent.logger
25
+ end
26
+
27
+ # TransferClient
28
+ end
29
+
30
+ # Agent
31
+ end
32
+
33
+ # Mam
34
+ end
35
+
36
+ # Envoi
37
+ end
@@ -0,0 +1,91 @@
1
+ require 'envoi/mam/agent/transfer_client'
2
+
3
+ module Envoi
4
+ module Mam
5
+ class Agent
6
+ class TransferClient
7
+
8
+ class Aspera < TransferClient
9
+
10
+ DEFAULT_DESTINATION_PATH = '.'
11
+ DEFAULT_ASCP_ARGS = '-v -k3 --overwrite=diff -P 33001'
12
+
13
+ ASCP_PATHS = [
14
+ '/usr/local/bin/ascp',
15
+ '/usr/bin/ascp',
16
+ '/Library/Aspera/bin/ascp',
17
+ '~/Applications/Aspera CLI/bin/ascp',
18
+ '~/Applications/Aspera Connect.app/Contents/Resources/ascp',
19
+ '/Applications/Aspera Connect.app/Contents/Resources/ascp'
20
+ ]
21
+ ASCP_PATHS.map { |v| File.expand_path(v) }
22
+
23
+ attr_accessor :default_ascp_path, :ascp_path, :default_ascp_args
24
+
25
+ def after_initialize(args = initial_args)
26
+ @default_ascp_path = args[:default_aspera_ascp_path]
27
+ @default_ascp_path ||= ASCP_PATHS.find { |v| File.exists? v } || ASCP_PATHS.first
28
+ @default_ascp_args = args[:default_ascp_args] || args[:default_aspera_ascp_args] || DEFAULT_ASCP_ARGS
29
+ end
30
+
31
+ def ascp_path_exists?
32
+ File.executable?(@ascp_path)
33
+ end
34
+
35
+ def build_ascp_command(config, mode, source_path, target_path)
36
+ aspera_host_address = config['host_address'] || config['host']
37
+ aspera_username = config['username']
38
+ aspera_password = config['password']
39
+ aspera_token = config['aspera_transfer_token'] || config['aspera_token'] || config['token'] || config['transfer_token']
40
+
41
+ @ascp_path = config['ascp_path'] || default_ascp_path
42
+ @ascp_path = File.expand_path(@ascp_path)
43
+
44
+ aspera_ascp_path = @ascp_path
45
+
46
+ ascp_args = config['ascp_args'] || default_ascp_args || agent.default_ascp_args
47
+ # command = %(export ASPERA_SCP_PASS="#{aspera_password}"; "#{aspera_ascp_path}" #{ascp_args} --host="#{aspera_host_address}" --user=#{aspera_username} --mode=#{mode} "#{source_path}" "#{target_path}" )
48
+ command = ''
49
+ command << %(export ASPERA_SCP_PASS="#{aspera_password}"; ) if aspera_password
50
+ command << %("#{aspera_ascp_path}" --mode=#{mode} --host="#{aspera_host_address}" --user="#{aspera_username}")
51
+ command << %( #{ascp_args}) if ascp_args && !ascp_args.empty?
52
+ command << %( -W "#{aspera_token}") if aspera_token && !aspera_token.empty?
53
+ command << %( "#{source_path.gsub('"', '\"')}" "#{target_path.gsub('"', '\"')}")
54
+ end
55
+
56
+ def download(config, path, destination_path = DEFAULT_DESTINATION_PATH)
57
+ aspera_base_path = config['base_path'] || ''
58
+ source_path = File.join(aspera_base_path, path)
59
+ command = build_ascp_command(config, 'recv', source_path, destination_path)
60
+
61
+ unless ascp_path_exists?
62
+ warn "ASCP not found. '#{ascp_path}'"
63
+ return false
64
+ end
65
+ agent.shell_execute(command)
66
+ end
67
+
68
+ def upload(config, path, destination_path = DEFAULT_DESTINATION_PATH)
69
+ aspera_base_path = config['base_path'] || ''
70
+ source_path = path
71
+ destination_path = aspera_base_path.empty? ? destination_path : File.join(aspera_base_path, destination_path)
72
+ command = build_ascp_command(config, 'send', source_path, destination_path)
73
+
74
+ unless ascp_path_exists?
75
+ warn "ASCP not found. '#{ascp_path}'"
76
+ return false
77
+ end
78
+ agent.shell_execute(command)
79
+ end
80
+
81
+ # AsperaTransferClient
82
+ end
83
+
84
+ # TransferClient
85
+ end
86
+ # Agent
87
+ end
88
+ # Mam
89
+ end
90
+ # Envoi
91
+ end