aspera-cli 4.22.0 → 4.24.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +405 -364
- data/CONTRIBUTING.md +86 -29
- data/README.md +1856 -961
- data/bin/ascli +2 -1
- data/bin/asession +4 -4
- data/lib/aspera/agent/base.rb +4 -0
- data/lib/aspera/agent/connect.rb +20 -18
- data/lib/aspera/agent/desktop.rb +14 -11
- data/lib/aspera/agent/direct.rb +39 -31
- data/lib/aspera/agent/httpgw.rb +2 -2
- data/lib/aspera/agent/node.rb +9 -11
- data/lib/aspera/agent/transferd.rb +18 -11
- data/lib/aspera/api/aoc.rb +53 -43
- data/lib/aspera/api/cos_node.rb +7 -5
- data/lib/aspera/api/httpgw.rb +23 -22
- data/lib/aspera/api/node.rb +104 -22
- data/lib/aspera/ascmd.rb +35 -21
- data/lib/aspera/ascp/installation.rb +43 -43
- data/lib/aspera/ascp/management.rb +5 -4
- data/lib/aspera/assert.rb +55 -24
- data/lib/aspera/cli/basic_auth_plugin.rb +8 -7
- data/lib/aspera/cli/error.rb +1 -1
- data/lib/aspera/cli/extended_value.rb +28 -29
- data/lib/aspera/cli/formatter.rb +191 -168
- data/lib/aspera/cli/hints.rb +38 -4
- data/lib/aspera/cli/main.rb +139 -108
- data/lib/aspera/cli/manager.rb +51 -31
- data/lib/aspera/cli/plugin.rb +149 -78
- data/lib/aspera/cli/plugin_factory.rb +2 -2
- data/lib/aspera/cli/plugins/aoc.rb +217 -88
- data/lib/aspera/cli/plugins/ats.rb +15 -13
- data/lib/aspera/cli/plugins/config.rb +105 -227
- data/lib/aspera/cli/plugins/console.rb +49 -18
- data/lib/aspera/cli/plugins/cos.rb +4 -4
- data/lib/aspera/cli/plugins/faspex.rb +45 -51
- data/lib/aspera/cli/plugins/faspex5.rb +162 -163
- data/lib/aspera/cli/plugins/faspio.rb +6 -5
- data/lib/aspera/cli/plugins/httpgw.rb +2 -2
- data/lib/aspera/cli/plugins/node.rb +233 -247
- data/lib/aspera/cli/plugins/orchestrator.rb +10 -14
- data/lib/aspera/cli/plugins/preview.rb +26 -29
- data/lib/aspera/cli/plugins/server.rb +29 -28
- data/lib/aspera/cli/plugins/shares.rb +40 -28
- data/lib/aspera/cli/sync_actions.rb +101 -80
- data/lib/aspera/cli/transfer_agent.rb +55 -58
- data/lib/aspera/cli/transfer_progress.rb +29 -20
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/cli/wizard.rb +160 -0
- data/lib/aspera/colors.rb +13 -8
- data/lib/aspera/command_line_builder.rb +28 -22
- data/lib/aspera/command_line_converter.rb +31 -0
- data/lib/aspera/data_repository.rb +1 -0
- data/lib/aspera/environment.rb +144 -100
- data/lib/aspera/faspex_gw.rb +1 -1
- data/lib/aspera/faspex_postproc.rb +3 -2
- data/lib/aspera/hash_ext.rb +1 -1
- data/lib/aspera/id_generator.rb +10 -10
- data/lib/aspera/keychain/base.rb +18 -0
- data/lib/aspera/keychain/encrypted_hash.rb +6 -12
- data/lib/aspera/keychain/factory.rb +9 -3
- data/lib/aspera/keychain/hashicorp_vault.rb +9 -6
- data/lib/aspera/keychain/macos_security.rb +13 -13
- data/lib/aspera/log.rb +70 -20
- data/lib/aspera/nagios.rb +5 -6
- data/lib/aspera/node_simulator.rb +12 -7
- data/lib/aspera/oauth/base.rb +6 -2
- data/lib/aspera/oauth/factory.rb +25 -18
- data/lib/aspera/oauth/jwt.rb +13 -1
- data/lib/aspera/oauth/url_json.rb +3 -3
- data/lib/aspera/oauth/web.rb +5 -3
- data/lib/aspera/persistency_folder.rb +2 -2
- data/lib/aspera/preview/file_types.rb +43 -35
- data/lib/aspera/preview/generator.rb +26 -13
- data/lib/aspera/preview/terminal.rb +10 -7
- data/lib/aspera/preview/utils.rb +11 -9
- data/lib/aspera/products/connect.rb +2 -1
- data/lib/aspera/products/desktop.rb +1 -1
- data/lib/aspera/products/other.rb +2 -2
- data/lib/aspera/products/transferd.rb +8 -6
- data/lib/aspera/proxy_auto_config.rb +1 -1
- data/lib/aspera/rest.rb +46 -28
- data/lib/aspera/rest_call_error.rb +1 -1
- data/lib/aspera/rest_error_analyzer.rb +1 -0
- data/lib/aspera/resumer.rb +1 -1
- data/lib/aspera/secret_hider.rb +46 -40
- data/lib/aspera/ssh.rb +14 -4
- data/lib/aspera/sync/args.schema.yaml +102 -0
- data/lib/aspera/sync/conf.schema.yaml +701 -0
- data/lib/aspera/sync/database.rb +83 -0
- data/lib/aspera/{transfer/sync.rb → sync/operations.rb} +145 -68
- data/lib/aspera/temp_file_manager.rb +4 -2
- data/lib/aspera/timer_limiter.rb +7 -5
- data/lib/aspera/transfer/error.rb +1 -1
- data/lib/aspera/transfer/error_info.rb +1 -2
- data/lib/aspera/transfer/faux_file.rb +11 -10
- data/lib/aspera/transfer/parameters.rb +6 -5
- data/lib/aspera/transfer/spec.rb +15 -1
- data/lib/aspera/transfer/spec.schema.yaml +316 -293
- data/lib/aspera/transfer/spec_doc.rb +34 -16
- data/lib/aspera/transfer/uri.rb +5 -5
- data/lib/aspera/uri_reader.rb +14 -10
- data/lib/aspera/web_auth.rb +2 -2
- data/lib/aspera/web_server_simple.rb +2 -2
- data.tar.gz.sig +0 -0
- metadata +15 -15
- metadata.gz.sig +0 -0
- data/examples/dascli +0 -30
- data/examples/get_proto_file.rb +0 -8
- data/examples/proxy.pac +0 -60
- data/lib/aspera/transfer/convert.rb +0 -29
- data/lib/aspera/transfer/sync_instance.schema.yaml +0 -13
- data/lib/aspera/transfer/sync_session.schema.yaml +0 -79
data/lib/aspera/oauth/web.rb
CHANGED
@@ -31,8 +31,9 @@ module Aspera
|
|
31
31
|
# generate secure state to check later
|
32
32
|
random_state = SecureRandom.uuid
|
33
33
|
login_page_url = Rest.build_uri(
|
34
|
-
"#{
|
35
|
-
optional_scope_client_id.merge(response_type: 'code', redirect_uri: @redirect_uri, state: random_state)
|
34
|
+
"#{api.base_url}/#{@path_authorize}",
|
35
|
+
optional_scope_client_id.merge(response_type: 'code', redirect_uri: @redirect_uri, state: random_state)
|
36
|
+
)
|
36
37
|
# here, we need a human to authorize on a web page
|
37
38
|
Log.log.info{"login_page_url=#{login_page_url}".bg_red.gray}
|
38
39
|
# start a web server to receive request code
|
@@ -46,7 +47,8 @@ module Aspera
|
|
46
47
|
return create_token_call(optional_scope_client_id(add_secret: true).merge(
|
47
48
|
grant_type: 'authorization_code',
|
48
49
|
code: received_params['code'],
|
49
|
-
redirect_uri: @redirect_uri
|
50
|
+
redirect_uri: @redirect_uri
|
51
|
+
))
|
50
52
|
end
|
51
53
|
end
|
52
54
|
Factory.instance.register_token_creator(Web)
|
@@ -60,7 +60,7 @@ module Aspera
|
|
60
60
|
end
|
61
61
|
|
62
62
|
# Delete persisted items
|
63
|
-
def garbage_collect(persist_category, max_age_seconds=nil)
|
63
|
+
def garbage_collect(persist_category, max_age_seconds = nil)
|
64
64
|
garbage_files = current_files(persist_category)
|
65
65
|
if !max_age_seconds.nil?
|
66
66
|
current_time = Time.now
|
@@ -75,7 +75,7 @@ module Aspera
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def current_files(persist_category)
|
78
|
-
Dir[File.join(@folder, persist_category
|
78
|
+
Dir[File.join(@folder, "#{persist_category}*#{FILE_SUFFIX}")]
|
79
79
|
end
|
80
80
|
|
81
81
|
def current_items(persist_category)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'aspera/log'
|
4
|
+
require 'aspera/assert'
|
4
5
|
require 'singleton'
|
5
6
|
require 'mime/types'
|
6
7
|
|
@@ -9,6 +10,7 @@ module Aspera
|
|
9
10
|
# function conversion_type returns one of the types: CONVERSION_TYPES
|
10
11
|
class FileTypes
|
11
12
|
include Singleton
|
13
|
+
|
12
14
|
# values for conversion_type : input format
|
13
15
|
CONVERSION_TYPES = %i[image office pdf plaintext video].freeze
|
14
16
|
|
@@ -22,6 +24,8 @@ module Aspera
|
|
22
24
|
'application/mxf' => :video,
|
23
25
|
'application/mac-binhex40' => :office,
|
24
26
|
'application/msword' => :office,
|
27
|
+
'application/vnd.ms-excel' => :office,
|
28
|
+
'application/vnd.ms-powerpoint' => :office,
|
25
29
|
'application/rtf' => :office,
|
26
30
|
'application/x-abiword' => :office,
|
27
31
|
'application/x-mspublisher' => :office,
|
@@ -44,7 +48,8 @@ module Aspera
|
|
44
48
|
'application/x-xfig' => :image,
|
45
49
|
'font/ttf' => :image,
|
46
50
|
'text/troff' => :image,
|
47
|
-
'video/x-mng' => :image
|
51
|
+
'video/x-mng' => :image
|
52
|
+
}.freeze
|
48
53
|
|
49
54
|
private_constant :SUPPORTED_MIME_TYPES
|
50
55
|
|
@@ -56,17 +61,43 @@ module Aspera
|
|
56
61
|
end
|
57
62
|
|
58
63
|
# @param mimetype [String] mime type
|
59
|
-
# @return file type, one of enum CONVERSION_TYPES
|
64
|
+
# @return file type, one of enum CONVERSION_TYPES, or nil if not found
|
60
65
|
def mime_to_type(mimetype)
|
66
|
+
Aspera.assert_type(mimetype, String)
|
61
67
|
return SUPPORTED_MIME_TYPES[mimetype] if SUPPORTED_MIME_TYPES.key?(mimetype)
|
62
|
-
return :office if mimetype.start_with?('application/vnd.')
|
68
|
+
return :office if mimetype.start_with?('application/vnd.ms-')
|
69
|
+
return :office if mimetype.start_with?('application/vnd.openxmlformats-officedocument')
|
63
70
|
return :video if mimetype.start_with?('video/')
|
64
71
|
return :image if mimetype.start_with?('image/')
|
65
|
-
return
|
72
|
+
return
|
73
|
+
end
|
74
|
+
|
75
|
+
# @param filepath [String] full path to file
|
76
|
+
# @param mimetype [String] provided by node API
|
77
|
+
# @return file type, one of enum CONVERSION_TYPES
|
78
|
+
# @raise [RuntimeError] if no conversion type found
|
79
|
+
def conversion_type(filepath, mimetype)
|
80
|
+
Log.log.debug{"conversion_type(#{filepath},mime=#{mimetype},magic=#{@use_mimemagic})"}
|
81
|
+
mimetype = nil if mimetype.is_a?(String) && (mimetype == 'application/octet-stream' || mimetype.empty?)
|
82
|
+
# Use mimemagic if available
|
83
|
+
mimetype ||= mime_using_mimemagic(filepath)
|
84
|
+
mimetype ||= mime_using_file(filepath)
|
85
|
+
# from extensions, using local mapping
|
86
|
+
mimetype ||= MIME::Types.of(File.basename(filepath)).first
|
87
|
+
raise "no MIME type found for #{File.basename(filepath)}" if mimetype.nil?
|
88
|
+
conversion_type = mime_to_type(mimetype)
|
89
|
+
raise "no conversion type found for #{File.basename(filepath)}" if conversion_type.nil?
|
90
|
+
Log.log.trace1{"conversion_type(#{File.basename(filepath)}): #{conversion_type.class.name} [#{conversion_type}]"}
|
91
|
+
return conversion_type
|
66
92
|
end
|
67
93
|
|
68
|
-
|
69
|
-
|
94
|
+
private
|
95
|
+
|
96
|
+
# Use mime magic to find mime type based on file content (magic numbers)
|
97
|
+
# @param filepath [String] full path to file
|
98
|
+
# @return [String] mime type, or nil if not found
|
99
|
+
def mime_using_mimemagic(filepath)
|
100
|
+
return unless @use_mimemagic
|
70
101
|
# moved here, as `mimemagic` can cause installation issues
|
71
102
|
require 'mimemagic'
|
72
103
|
require 'mimemagic/version'
|
@@ -83,35 +114,12 @@ module Aspera
|
|
83
114
|
return detected_mime
|
84
115
|
end
|
85
116
|
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
# 1- get type from provided mime type, using local mapping
|
93
|
-
conversion_type = mime_to_type(mimetype) if !mimetype.nil?
|
94
|
-
# 2- else, from computed mime type (if available)
|
95
|
-
if conversion_type.nil? && @use_mimemagic
|
96
|
-
detected_mime = file_to_mime(filepath)
|
97
|
-
if !detected_mime.nil?
|
98
|
-
conversion_type = mime_to_type(detected_mime)
|
99
|
-
if !mimetype.nil?
|
100
|
-
if mimetype.eql?(detected_mime)
|
101
|
-
Log.log.debug('matching mime type per magic number')
|
102
|
-
else
|
103
|
-
# NOTE: detected can be nil
|
104
|
-
Log.log.debug{"non matching mime types: node=[#{mimetype}], magic=[#{detected_mime}]"}
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
# 3- else, from extensions, using local mapping
|
110
|
-
mime_by_ext = MIME::Types.of(File.basename(filepath)).first
|
111
|
-
conversion_type = mime_to_type(mime_by_ext.to_s) if conversion_type.nil? && !mime_by_ext.nil?
|
112
|
-
raise "no conversion type found for #{File.basename(filepath)}" if conversion_type.nil?
|
113
|
-
Log.log.trace1{"conversion_type(#{File.basename(filepath)}): #{conversion_type.class.name} [#{conversion_type}]"}
|
114
|
-
return conversion_type
|
117
|
+
# Use 'file' command to find mime type based on file content (Unix)
|
118
|
+
def mime_using_file(filepath)
|
119
|
+
return Environment.secure_capture(exec: 'file', args: ['--mime-type', '--brief', filepath]).strip
|
120
|
+
rescue => e
|
121
|
+
Log.log.error{"error using 'file' command: #{e.message}"}
|
122
|
+
return
|
115
123
|
end
|
116
124
|
end
|
117
125
|
end
|
@@ -116,7 +116,9 @@ module Aspera
|
|
116
116
|
'-filter:v', "scale='trunc(iw/2)*2:trunc(ih/2)*2'",
|
117
117
|
'-codec:v', 'libx264',
|
118
118
|
'-r', 30,
|
119
|
-
'-pix_fmt', 'yuv420p'
|
119
|
+
'-pix_fmt', 'yuv420p'
|
120
|
+
]
|
121
|
+
)
|
120
122
|
end
|
121
123
|
|
122
124
|
# generate n clips starting at offset
|
@@ -135,7 +137,9 @@ module Aspera
|
|
135
137
|
'-ss', offset_seconds * 0.1,
|
136
138
|
'-t', @options.clips_length,
|
137
139
|
'-filter:v', "scale=#{@options.video_scale}",
|
138
|
-
'-codec:a', 'libmp3lame'
|
140
|
+
'-codec:a', 'libmp3lame'
|
141
|
+
]
|
142
|
+
)
|
139
143
|
f.puts("file '#{tmp_file_name}'")
|
140
144
|
end
|
141
145
|
end
|
@@ -144,7 +148,8 @@ module Aspera
|
|
144
148
|
in_f: file_list_file,
|
145
149
|
in_p: ['-f', 'concat'],
|
146
150
|
out_f: @destination_file_path,
|
147
|
-
out_p: ['-codec', 'copy']
|
151
|
+
out_p: ['-codec', 'copy']
|
152
|
+
)
|
148
153
|
File.delete(file_list_file)
|
149
154
|
end
|
150
155
|
|
@@ -174,7 +179,9 @@ module Aspera
|
|
174
179
|
'-codec:a', 'libmp3lame',
|
175
180
|
'-ac', '2',
|
176
181
|
'-b:a', '128k',
|
177
|
-
'-movflags', 'faststart'
|
182
|
+
'-movflags', 'faststart'
|
183
|
+
]
|
184
|
+
)
|
178
185
|
end
|
179
186
|
|
180
187
|
def convert_video_to_png_using_fixed
|
@@ -182,7 +189,8 @@ module Aspera
|
|
182
189
|
@source_file_path,
|
183
190
|
Utils.video_get_duration(@source_file_path) * @options.thumb_vid_fraction,
|
184
191
|
@options.thumb_vid_scale,
|
185
|
-
@destination_file_path
|
192
|
+
@destination_file_path
|
193
|
+
)
|
186
194
|
end
|
187
195
|
|
188
196
|
# https://trac.ffmpeg.org/wiki/SponsoringPrograms/GSoC/2015#AnimatedPortableNetworkGraphicsAPNG
|
@@ -201,19 +209,21 @@ module Aspera
|
|
201
209
|
'-vf', 'fps=5,scale=120:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse',
|
202
210
|
'-loop', 0,
|
203
211
|
'-f', 'gif'
|
204
|
-
]
|
212
|
+
]
|
213
|
+
)
|
205
214
|
end
|
206
215
|
|
207
216
|
def convert_office_to_png
|
208
|
-
tmp_pdf_file = File.join(this_tmpdir, File.basename(@source_file_path, File.extname(@source_file_path))
|
217
|
+
tmp_pdf_file = File.join(this_tmpdir, "#{File.basename(@source_file_path, File.extname(@source_file_path))}.pdf")
|
209
218
|
Utils.external_command(:unoconv, [
|
210
219
|
'-f', 'pdf',
|
211
220
|
'-o', tmp_pdf_file,
|
212
|
-
@source_file_path
|
221
|
+
@source_file_path
|
222
|
+
])
|
213
223
|
convert_pdf_to_png(tmp_pdf_file)
|
214
224
|
end
|
215
225
|
|
216
|
-
def convert_pdf_to_png(source_file_path=nil)
|
226
|
+
def convert_pdf_to_png(source_file_path = nil)
|
217
227
|
source_file_path ||= @source_file_path
|
218
228
|
Utils.external_command(:magick, [
|
219
229
|
'convert',
|
@@ -221,7 +231,8 @@ module Aspera
|
|
221
231
|
'-background', 'white',
|
222
232
|
'-flatten',
|
223
233
|
"#{source_file_path}[0]",
|
224
|
-
@destination_file_path
|
234
|
+
@destination_file_path
|
235
|
+
])
|
225
236
|
end
|
226
237
|
|
227
238
|
def convert_image_to_png
|
@@ -233,14 +244,15 @@ module Aspera
|
|
233
244
|
'+dither',
|
234
245
|
'-posterize', 40,
|
235
246
|
"#{@source_file_path}[0]",
|
236
|
-
@destination_file_path
|
247
|
+
@destination_file_path
|
248
|
+
])
|
237
249
|
Utils.external_command(:optipng, [@destination_file_path])
|
238
250
|
end
|
239
251
|
|
240
252
|
# text to png
|
241
253
|
def convert_plaintext_to_png
|
242
254
|
# get 100 first lines of text file
|
243
|
-
first_lines = File.
|
255
|
+
first_lines = File.foreach(@source_file_path).first(100).join
|
244
256
|
Utils.external_command(:magick, [
|
245
257
|
'convert',
|
246
258
|
'-size', "#{@options.thumb_img_size}x#{@options.thumb_img_size}",
|
@@ -253,7 +265,8 @@ module Aspera
|
|
253
265
|
'-bordercolor', 'white',
|
254
266
|
'-border', 8,
|
255
267
|
'+repage',
|
256
|
-
@destination_file_path
|
268
|
+
@destination_file_path
|
269
|
+
])
|
257
270
|
end
|
258
271
|
end
|
259
272
|
end
|
@@ -5,9 +5,11 @@
|
|
5
5
|
require 'rainbow'
|
6
6
|
require 'io/console'
|
7
7
|
require 'aspera/log'
|
8
|
+
require 'aspera/environment'
|
8
9
|
module Aspera
|
9
10
|
module Preview
|
10
|
-
# Display a picture in the terminal
|
11
|
+
# Display a picture in the terminal.
|
12
|
+
# Either use coloured characters or iTerm2 protocol.
|
11
13
|
class Terminal
|
12
14
|
# Rainbow only supports 8-bit colors
|
13
15
|
# env vars to detect terminal type
|
@@ -19,13 +21,14 @@ module Aspera
|
|
19
21
|
DEFAULT_FONT_RATIO = 32.0 / 14.0
|
20
22
|
private_constant :TERM_ENV_VARS, :ITERM_NAMES, :DEFAULT_FONT_RATIO
|
21
23
|
class << self
|
22
|
-
# @
|
23
|
-
# @param
|
24
|
-
# @param
|
25
|
-
# @param
|
26
|
-
# @param
|
27
|
-
# @
|
24
|
+
# @param blob [String] The image as a binary string
|
25
|
+
# @param reserve [Integer] Number of lines to reserve for other text than the image
|
26
|
+
# @param text [Boolean] `true` to display the image as text, `false` to use iTerm2 if supported
|
27
|
+
# @param double [Boolean] `true` to use colors on half lines, `false` to use colors on full lines
|
28
|
+
# @param font_ratio [Float] ratio = font height / font width
|
29
|
+
# @return [String] The image as text, or the iTerm2 escape sequence
|
28
30
|
def build(blob, reserve: 3, text: false, double: true, font_ratio: DEFAULT_FONT_RATIO)
|
31
|
+
return '[Image display requires a terminal]' unless Environment.terminal?
|
29
32
|
return iterm_display_image(blob) if iterm_supported? && !text
|
30
33
|
begin
|
31
34
|
# do not require statically, as the package is optional
|
data/lib/aspera/preview/utils.rb
CHANGED
@@ -31,7 +31,7 @@ module Aspera
|
|
31
31
|
end
|
32
32
|
|
33
33
|
# check that external tools can be executed
|
34
|
-
def check_tools(skip_types=[])
|
34
|
+
def check_tools(skip_types = [])
|
35
35
|
tools_to_check = EXTERNAL_TOOLS.dup
|
36
36
|
tools_to_check.delete(:unoconv) if skip_types.include?(:office)
|
37
37
|
# Check for binaries
|
@@ -70,7 +70,8 @@ module Aspera
|
|
70
70
|
'-loglevel', 'error',
|
71
71
|
'-show_entries', 'format=duration',
|
72
72
|
'-print_format', 'default=noprint_wrappers=1:nokey=1', # cspell:disable-line
|
73
|
-
input_file
|
73
|
+
input_file
|
74
|
+
]).to_f
|
74
75
|
end
|
75
76
|
|
76
77
|
def ffmpeg_fmt(temp_folder)
|
@@ -88,24 +89,25 @@ module Aspera
|
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
91
|
-
def video_blend_frames(temp_folder,
|
92
|
-
img1 = get_tmp_num_filepath(temp_folder,
|
93
|
-
img2 = get_tmp_num_filepath(temp_folder,
|
94
|
-
count =
|
92
|
+
def video_blend_frames(temp_folder, index_begin, index_end)
|
93
|
+
img1 = get_tmp_num_filepath(temp_folder, index_begin)
|
94
|
+
img2 = get_tmp_num_filepath(temp_folder, index_end)
|
95
|
+
count = index_end - index_begin - 1
|
95
96
|
1.upto(count) do |i|
|
96
97
|
percent = i * 100 / (count + 1)
|
97
|
-
filename = get_tmp_num_filepath(temp_folder,
|
98
|
+
filename = get_tmp_num_filepath(temp_folder, index_begin + i)
|
98
99
|
external_command(:magick, ['composite', '-blend', percent, img2, img1, filename])
|
99
100
|
end
|
100
101
|
end
|
101
102
|
|
102
|
-
def video_dump_frame(input_file, offset_seconds, scale, output_file, index=nil)
|
103
|
+
def video_dump_frame(input_file, offset_seconds, scale, output_file, index = nil)
|
103
104
|
output_file = get_tmp_num_filepath(output_file, index) unless index.nil?
|
104
105
|
ffmpeg(
|
105
106
|
in_f: input_file,
|
106
107
|
in_p: ['-ss', offset_seconds],
|
107
108
|
out_f: output_file,
|
108
|
-
out_p: ['-frames:v', 1, '-filter:v', "scale=#{scale}"]
|
109
|
+
out_p: ['-frames:v', 1, '-filter:v', "scale=#{scale}"]
|
110
|
+
)
|
109
111
|
return output_file
|
110
112
|
end
|
111
113
|
end
|
@@ -7,12 +7,13 @@ module Aspera
|
|
7
7
|
module Products
|
8
8
|
class Connect
|
9
9
|
include Singleton
|
10
|
+
|
10
11
|
APP_NAME = 'IBM Aspera Connect'
|
11
12
|
|
12
13
|
class << self
|
13
14
|
# standard folder locations
|
14
15
|
def locations
|
15
|
-
case Aspera::Environment.os
|
16
|
+
case Aspera::Environment.instance.os
|
16
17
|
when Aspera::Environment::OS_WINDOWS then [{
|
17
18
|
app_root: File.join(ENV.fetch('LOCALAPPDATA', nil), 'Programs', 'Aspera', 'Aspera Connect'),
|
18
19
|
log_root: File.join(ENV.fetch('LOCALAPPDATA', nil), 'Aspera', 'Aspera Connect', 'var', 'log'),
|
@@ -11,7 +11,7 @@ module Aspera
|
|
11
11
|
class << self
|
12
12
|
# standard folder locations
|
13
13
|
def locations
|
14
|
-
case Aspera::Environment.os
|
14
|
+
case Aspera::Environment.instance.os
|
15
15
|
when Aspera::Environment::OS_MACOS then [{
|
16
16
|
app_root: File.join('', 'Applications', 'IBM Aspera.app'),
|
17
17
|
log_root: File.join(Dir.home, 'Library', 'Logs', APP_IDENTIFIER),
|
@@ -21,7 +21,7 @@ module Aspera
|
|
21
21
|
# :log_root O location of log files (Linux uses syslog)
|
22
22
|
# :run_root O only for Connect Client, location of http port file
|
23
23
|
# :sub_bin O subfolder with executables, default : bin
|
24
|
-
LOCATION_ON_THIS_OS = case Aspera::Environment.os
|
24
|
+
LOCATION_ON_THIS_OS = case Aspera::Environment.instance.os
|
25
25
|
when Aspera::Environment::OS_WINDOWS then [{
|
26
26
|
expected: CLI_V3,
|
27
27
|
app_root: File.join('C:', 'Program Files', 'Aspera', 'cli'),
|
@@ -61,7 +61,7 @@ module Aspera
|
|
61
61
|
next false unless Dir.exist?(item[:app_root])
|
62
62
|
Log.log.debug{"Found #{item[:expected]}"}
|
63
63
|
sub_bin = item[:sub_bin] || 'bin'
|
64
|
-
item[:ascp_path] = File.join(item[:app_root], sub_bin, Environment.exe_file('ascp'))
|
64
|
+
item[:ascp_path] = File.join(item[:app_root], sub_bin, Environment.instance.exe_file('ascp'))
|
65
65
|
# skip if no ascp
|
66
66
|
next false unless File.exist?(item[:ascp_path])
|
67
67
|
# read info from product info file if present
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'aspera/log'
|
4
|
+
require 'aspera/assert'
|
3
5
|
module Aspera
|
4
6
|
module Products
|
5
7
|
class Transferd
|
@@ -19,9 +21,9 @@ module Aspera
|
|
19
21
|
end
|
20
22
|
|
21
23
|
# location of SDK files
|
22
|
-
def sdk_directory=(
|
23
|
-
Log.log.debug{"sdk_directory=#{
|
24
|
-
@sdk_dir =
|
24
|
+
def sdk_directory=(folder)
|
25
|
+
Log.log.debug{"sdk_directory=#{folder}"}
|
26
|
+
@sdk_dir = folder
|
25
27
|
sdk_directory
|
26
28
|
end
|
27
29
|
|
@@ -33,9 +35,9 @@ module Aspera
|
|
33
35
|
end
|
34
36
|
|
35
37
|
def transferd_path
|
36
|
-
v1_path = File.join(sdk_directory, Environment.exe_file(V1_DAEMON_NAME))
|
38
|
+
v1_path = File.join(sdk_directory, Environment.instance.exe_file(V1_DAEMON_NAME))
|
37
39
|
return v1_path if File.exist?(v1_path)
|
38
|
-
return File.join(sdk_directory, Environment.exe_file(V2_DAEMON_NAME))
|
40
|
+
return File.join(sdk_directory, Environment.instance.exe_file(V2_DAEMON_NAME))
|
39
41
|
end
|
40
42
|
|
41
43
|
# Well, the port number is only in log file
|
@@ -51,7 +53,7 @@ module Aspera
|
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
54
|
-
|
56
|
+
Aspera.assert(!result.nil?){'Port not found in daemon logs'}
|
55
57
|
Log.log.debug{"Got port #{result} from log"}
|
56
58
|
return result
|
57
59
|
end
|
@@ -13,7 +13,7 @@ module URI
|
|
13
13
|
def register_proxy_finder
|
14
14
|
Aspera.assert(block_given?)
|
15
15
|
# overload the method in URI : call user's provided block and fallback to original method
|
16
|
-
define_method(:find_proxy){ |env_vars=ENV| yield(to_s) || find_proxy_orig(env_vars)}
|
16
|
+
define_method(:find_proxy){ |env_vars = ENV| yield(to_s) || find_proxy_orig(env_vars)}
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|