aspera-cli 4.10.0 → 4.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/BUGS.md +20 -0
- data/CHANGELOG.md +509 -0
- data/CONTRIBUTING.md +118 -0
- data/README.md +621 -378
- data/bin/ascli +4 -4
- data/bin/asession +11 -11
- data/docs/test_env.conf +28 -19
- data/examples/aoc.rb +4 -4
- data/examples/dascli +11 -9
- data/examples/faspex4.rb +8 -8
- data/examples/node.rb +11 -11
- data/examples/server.rb +9 -9
- data/lib/aspera/aoc.rb +273 -266
- data/lib/aspera/ascmd.rb +56 -54
- data/lib/aspera/ats_api.rb +4 -4
- data/lib/aspera/cli/basic_auth_plugin.rb +15 -12
- data/lib/aspera/cli/extended_value.rb +5 -5
- data/lib/aspera/cli/formater.rb +64 -64
- data/lib/aspera/cli/listener/line_dump.rb +1 -1
- data/lib/aspera/cli/listener/logger.rb +1 -1
- data/lib/aspera/cli/listener/progress.rb +5 -6
- data/lib/aspera/cli/listener/progress_multi.rb +14 -19
- data/lib/aspera/cli/main.rb +66 -67
- data/lib/aspera/cli/manager.rb +110 -110
- data/lib/aspera/cli/plugin.rb +54 -37
- data/lib/aspera/cli/plugins/alee.rb +4 -4
- data/lib/aspera/cli/plugins/aoc.rb +308 -669
- data/lib/aspera/cli/plugins/ats.rb +44 -46
- data/lib/aspera/cli/plugins/bss.rb +10 -10
- data/lib/aspera/cli/plugins/config.rb +447 -344
- data/lib/aspera/cli/plugins/console.rb +12 -12
- data/lib/aspera/cli/plugins/cos.rb +18 -20
- data/lib/aspera/cli/plugins/faspex.rb +110 -112
- data/lib/aspera/cli/plugins/faspex5.rb +67 -46
- data/lib/aspera/cli/plugins/node.rb +364 -288
- data/lib/aspera/cli/plugins/orchestrator.rb +46 -46
- data/lib/aspera/cli/plugins/preview.rb +122 -114
- data/lib/aspera/cli/plugins/server.rb +137 -83
- data/lib/aspera/cli/plugins/shares.rb +30 -29
- data/lib/aspera/cli/plugins/sync.rb +13 -33
- data/lib/aspera/cli/transfer_agent.rb +57 -57
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/colors.rb +3 -3
- data/lib/aspera/command_line_builder.rb +27 -27
- data/lib/aspera/cos_node.rb +22 -20
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/environment.rb +30 -28
- data/lib/aspera/fasp/agent_base.rb +15 -15
- data/lib/aspera/fasp/agent_connect.rb +23 -21
- data/lib/aspera/fasp/agent_direct.rb +65 -67
- data/lib/aspera/fasp/agent_httpgw.rb +72 -68
- data/lib/aspera/fasp/agent_node.rb +23 -21
- data/lib/aspera/fasp/agent_trsdk.rb +20 -20
- data/lib/aspera/fasp/error.rb +3 -2
- data/lib/aspera/fasp/error_info.rb +11 -8
- data/lib/aspera/fasp/installation.rb +78 -78
- data/lib/aspera/fasp/listener.rb +1 -1
- data/lib/aspera/fasp/parameters.rb +75 -72
- data/lib/aspera/fasp/parameters.yaml +2 -2
- data/lib/aspera/fasp/resume_policy.rb +8 -8
- data/lib/aspera/fasp/transfer_spec.rb +35 -2
- data/lib/aspera/fasp/uri.rb +7 -7
- data/lib/aspera/faspex_gw.rb +7 -5
- data/lib/aspera/hash_ext.rb +3 -3
- data/lib/aspera/id_generator.rb +5 -5
- data/lib/aspera/keychain/encrypted_hash.rb +23 -28
- data/lib/aspera/keychain/macos_security.rb +21 -20
- data/lib/aspera/log.rb +7 -7
- data/lib/aspera/nagios.rb +19 -18
- data/lib/aspera/node.rb +209 -35
- data/lib/aspera/oauth.rb +37 -36
- data/lib/aspera/open_application.rb +19 -11
- data/lib/aspera/persistency_action_once.rb +4 -4
- data/lib/aspera/persistency_folder.rb +13 -13
- data/lib/aspera/preview/file_types.rb +8 -8
- data/lib/aspera/preview/generator.rb +67 -67
- data/lib/aspera/preview/utils.rb +27 -27
- data/lib/aspera/proxy_auto_config.js +41 -41
- data/lib/aspera/proxy_auto_config.rb +16 -16
- data/lib/aspera/rest.rb +56 -60
- data/lib/aspera/rest_call_error.rb +2 -1
- data/lib/aspera/rest_error_analyzer.rb +18 -17
- data/lib/aspera/rest_errors_aspera.rb +16 -16
- data/lib/aspera/secret_hider.rb +15 -13
- data/lib/aspera/ssh.rb +11 -10
- data/lib/aspera/sync.rb +158 -44
- data/lib/aspera/temp_file_manager.rb +2 -2
- data/lib/aspera/uri_reader.rb +4 -4
- data/lib/aspera/web_auth.rb +14 -13
- data.tar.gz.sig +0 -0
- metadata +8 -5
- metadata.gz.sig +0 -0
@@ -286,20 +286,20 @@ module Aspera
|
|
286
286
|
# check magic number inside file (empty string if not found)
|
287
287
|
detected_mime = MimeMagic.by_magic(File.open(filepath)).to_s
|
288
288
|
# check extension only
|
289
|
-
if !SUPPORTED_MIME_TYPES.
|
290
|
-
Log.log.debug
|
289
|
+
if !SUPPORTED_MIME_TYPES.key?(detected_mime)
|
290
|
+
Log.log.debug{"no conversion for #{detected_mime}, trying extension"}
|
291
291
|
detected_mime = MimeMagic.by_extension(File.extname(filepath)).to_s
|
292
292
|
end
|
293
293
|
detected_mime = nil if detected_mime.empty?
|
294
|
-
Log.log.debug
|
294
|
+
Log.log.debug{"mimemagic: #{detected_mime.class.name} [#{detected_mime}]"}
|
295
295
|
return detected_mime
|
296
296
|
end
|
297
297
|
|
298
298
|
# return file type, one of enum CONVERSION_TYPES
|
299
299
|
# @param filepath [String] full path to file
|
300
300
|
# @param mimetype [String] provided by node api
|
301
|
-
def conversion_type(filepath,mimetype)
|
302
|
-
Log.log.debug
|
301
|
+
def conversion_type(filepath, mimetype)
|
302
|
+
Log.log.debug{"conversion_type(#{filepath},m=#{mimetype},t=#{@use_mimemagic})"}
|
303
303
|
# 1- get type from provided mime type, using local mapping
|
304
304
|
conv_type = SUPPORTED_MIME_TYPES[mimetype] if !mimetype.nil?
|
305
305
|
# 2- else, from computed mime type (if available)
|
@@ -311,8 +311,8 @@ module Aspera
|
|
311
311
|
if mimetype.eql?(detected_mime)
|
312
312
|
Log.log.debug('matching mime type per magic number')
|
313
313
|
else
|
314
|
-
#
|
315
|
-
Log.log.debug
|
314
|
+
# NOTE: detected can be nil
|
315
|
+
Log.log.debug{"non matching mime types: node=[#{mimetype}], magic=[#{detected_mime}]"}
|
316
316
|
end
|
317
317
|
end
|
318
318
|
end
|
@@ -320,7 +320,7 @@ module Aspera
|
|
320
320
|
# 3- else, from extensions, using local mapping
|
321
321
|
extension = File.extname(filepath.downcase)[1..-1]
|
322
322
|
conv_type = SUPPORTED_EXTENSIONS[extension] if conv_type.nil?
|
323
|
-
Log.log.debug
|
323
|
+
Log.log.debug{"conversion_type(#{extension}): #{conv_type.class.name} [#{conv_type}]"}
|
324
324
|
return conv_type
|
325
325
|
end
|
326
326
|
end
|
@@ -27,14 +27,14 @@ module Aspera
|
|
27
27
|
# -> preview_format is one of Generator::PREVIEW_FORMATS
|
28
28
|
# the conversion video->mp4 is implemented in methods: convert_video_to_mp4_using_<video_conversion>
|
29
29
|
# -> conversion method is one of Generator::VIDEO_CONVERSION_METHODS
|
30
|
-
def initialize(options,src,dst,main_temp_dir,api_mime_type)
|
30
|
+
def initialize(options, src, dst, main_temp_dir, api_mime_type)
|
31
31
|
@options = options
|
32
32
|
@source_file_path = src
|
33
33
|
@destination_file_path = dst
|
34
|
-
@temp_folder = File.join(main_temp_dir
|
34
|
+
@temp_folder = File.join(main_temp_dir, @source_file_path.split('/').last.gsub(/\s/, '_').gsub(/\W/, ''))
|
35
35
|
# extract preview format from extension of target file
|
36
|
-
@preview_format_symb = File.extname(@destination_file_path).gsub(/^\./,'').to_sym
|
37
|
-
@conversion_type = FileTypes.instance.conversion_type(@source_file_path,api_mime_type)
|
36
|
+
@preview_format_symb = File.extname(@destination_file_path).gsub(/^\./, '').to_sym
|
37
|
+
@conversion_type = FileTypes.instance.conversion_type(@source_file_path, api_mime_type)
|
38
38
|
end
|
39
39
|
|
40
40
|
# name of processing method in this object
|
@@ -49,7 +49,7 @@ module Aspera
|
|
49
49
|
name = "#{name}_using_#{@options.video_png_conv}"
|
50
50
|
end
|
51
51
|
end
|
52
|
-
Log.log.debug
|
52
|
+
Log.log.debug{"method: #{name}"}
|
53
53
|
return name.to_sym
|
54
54
|
end
|
55
55
|
|
@@ -57,25 +57,25 @@ module Aspera
|
|
57
57
|
# for instance, plaintext to mp4 is not supported
|
58
58
|
def supported?
|
59
59
|
return false if @conversion_type.nil?
|
60
|
-
return respond_to?(processing_method_symb,true)
|
60
|
+
return respond_to?(processing_method_symb, true)
|
61
61
|
end
|
62
62
|
|
63
63
|
# create preview as specified in constructor
|
64
64
|
def generate
|
65
65
|
raise 'could not detect type of file' if @conversion_type.nil?
|
66
66
|
method_symb = processing_method_symb
|
67
|
-
Log.log.info
|
67
|
+
Log.log.info{"#{@source_file_path}->#{@destination_file_path} (#{method_symb})"}
|
68
68
|
begin
|
69
69
|
send(method_symb)
|
70
70
|
# check that generated size does not exceed maximum
|
71
71
|
result_size = File.size(@destination_file_path)
|
72
72
|
if result_size > @options.max_size
|
73
|
-
Log.log.warn
|
73
|
+
Log.log.warn{"preview size exceeds maximum #{result_size} > #{@options.max_size}"}
|
74
74
|
end
|
75
75
|
rescue StandardError => e
|
76
|
-
Log.log.error
|
76
|
+
Log.log.error{"Ignoging: #{e.message}"}
|
77
77
|
Log.log.debug(e.backtrace.join("\n").red)
|
78
|
-
FileUtils.cp(File.expand_path(@preview_format_symb.eql?(:mp4) ? 'video_error.png' : 'image_error.png',File.dirname(__FILE__))
|
78
|
+
FileUtils.cp(File.expand_path(@preview_format_symb.eql?(:mp4) ? 'video_error.png' : 'image_error.png', File.dirname(__FILE__)), @destination_file_path)
|
79
79
|
ensure
|
80
80
|
FileUtils.rm_rf(@temp_folder)
|
81
81
|
end
|
@@ -106,10 +106,10 @@ module Aspera
|
|
106
106
|
last_keyframe = nil
|
107
107
|
current_index = 1
|
108
108
|
1.upto(p_keyframecount) do |i|
|
109
|
-
offset_seconds = get_offset(p_duration,p_start_offset,p_keyframecount,i)
|
109
|
+
offset_seconds = get_offset(p_duration, p_start_offset, p_keyframecount, i)
|
110
110
|
Utils.video_dump_frame(@source_file_path, offset_seconds, @options.video_scale, this_tmpdir, current_index)
|
111
111
|
Utils.video_dupe_frame(this_tmpdir, current_index, @options.blend_pauseframes)
|
112
|
-
Utils.video_blend_frames(this_tmpdir,last_keyframe, current_index) unless last_keyframe.nil?
|
112
|
+
Utils.video_blend_frames(this_tmpdir, last_keyframe, current_index) unless last_keyframe.nil?
|
113
113
|
# go to last dupe frame
|
114
114
|
last_keyframe = current_index + @options.blend_pauseframes
|
115
115
|
# go after last dupe frame and keep space to blend
|
@@ -117,41 +117,41 @@ module Aspera
|
|
117
117
|
end
|
118
118
|
Utils.ffmpeg(
|
119
119
|
in_f: Utils.ffmpeg_fmt(this_tmpdir),
|
120
|
-
in_p: ['-framerate'
|
120
|
+
in_p: ['-framerate', @options.blend_fps],
|
121
121
|
out_f: @destination_file_path,
|
122
122
|
out_p: [
|
123
|
-
'-filter:v',"scale='trunc(iw/2)*2:trunc(ih/2)*2'",
|
124
|
-
'-codec:v','libx264',
|
125
|
-
'-r',30,
|
126
|
-
'-pix_fmt','yuv420p'])
|
123
|
+
'-filter:v', "scale='trunc(iw/2)*2:trunc(ih/2)*2'",
|
124
|
+
'-codec:v', 'libx264',
|
125
|
+
'-r', 30,
|
126
|
+
'-pix_fmt', 'yuv420p'])
|
127
127
|
end
|
128
128
|
|
129
129
|
# generate n clips starting at offset
|
130
130
|
def convert_video_to_mp4_using_clips
|
131
131
|
p_duration = Utils.video_get_duration(@source_file_path)
|
132
|
-
filelist = File.join(this_tmpdir,'clip_files.txt')
|
132
|
+
filelist = File.join(this_tmpdir, 'clip_files.txt')
|
133
133
|
File.open(filelist, 'w+') do |f|
|
134
134
|
1.upto(@options.clips_count.to_i) do |i|
|
135
|
-
offset_seconds = get_offset(p_duration
|
136
|
-
tmpfilename = format('clip%04d.mp4',i)
|
135
|
+
offset_seconds = get_offset(p_duration, @options.video_start_sec.to_i, @options.clips_count.to_i, i)
|
136
|
+
tmpfilename = format('clip%04d.mp4', i)
|
137
137
|
Utils.ffmpeg(
|
138
138
|
in_f: @source_file_path,
|
139
|
-
in_p: ['-ss',0.9
|
140
|
-
out_f: File.join(this_tmpdir,tmpfilename),
|
139
|
+
in_p: ['-ss', offset_seconds * 0.9],
|
140
|
+
out_f: File.join(this_tmpdir, tmpfilename),
|
141
141
|
out_p: [
|
142
|
-
'-ss',0.1
|
143
|
-
'-t'
|
144
|
-
'-filter:v',"scale=#{@options.video_scale}",
|
145
|
-
'-codec:a','libmp3lame'])
|
142
|
+
'-ss', offset_seconds * 0.1,
|
143
|
+
'-t', @options.clips_length,
|
144
|
+
'-filter:v', "scale=#{@options.video_scale}",
|
145
|
+
'-codec:a', 'libmp3lame'])
|
146
146
|
f.puts("file '#{tmpfilename}'")
|
147
147
|
end
|
148
148
|
end
|
149
149
|
# concat clips
|
150
150
|
Utils.ffmpeg(
|
151
151
|
in_f: filelist,
|
152
|
-
in_p: ['-f','concat'],
|
152
|
+
in_p: ['-f', 'concat'],
|
153
153
|
out_f: @destination_file_path,
|
154
|
-
out_p: ['-codec','copy'])
|
154
|
+
out_p: ['-codec', 'copy'])
|
155
155
|
end
|
156
156
|
|
157
157
|
# do a simple reencoding
|
@@ -160,20 +160,20 @@ module Aspera
|
|
160
160
|
in_f: @source_file_path,
|
161
161
|
out_f: @destination_file_path,
|
162
162
|
out_p: [
|
163
|
-
'-t','60',
|
164
|
-
'-codec:v','libx264',
|
165
|
-
'-profile:v','high',
|
166
|
-
'-pix_fmt','yuv420p',
|
167
|
-
'-preset','slow',
|
168
|
-
'-b:v','500k',
|
169
|
-
'-maxrate','500k',
|
170
|
-
'-bufsize','1000k',
|
171
|
-
'-filter:v',"scale=#{@options.video_scale}",
|
172
|
-
'-threads','0',
|
173
|
-
'-codec:a','libmp3lame',
|
174
|
-
'-ac','2',
|
175
|
-
'-b:a','128k',
|
176
|
-
'-movflags','faststart'])
|
163
|
+
'-t', '60',
|
164
|
+
'-codec:v', 'libx264',
|
165
|
+
'-profile:v', 'high',
|
166
|
+
'-pix_fmt', 'yuv420p',
|
167
|
+
'-preset', 'slow',
|
168
|
+
'-b:v', '500k',
|
169
|
+
'-maxrate', '500k',
|
170
|
+
'-bufsize', '1000k',
|
171
|
+
'-filter:v', "scale=#{@options.video_scale}",
|
172
|
+
'-threads', '0',
|
173
|
+
'-codec:a', 'libmp3lame',
|
174
|
+
'-ac', '2',
|
175
|
+
'-b:a', '128k',
|
176
|
+
'-movflags', 'faststart'])
|
177
177
|
end
|
178
178
|
|
179
179
|
def convert_video_to_png_using_fixed
|
@@ -192,62 +192,62 @@ module Aspera
|
|
192
192
|
Utils.ffmpeg(
|
193
193
|
in_f: @source_file_path,
|
194
194
|
in_p: [
|
195
|
-
'-ss',10, # seek to input position
|
196
|
-
'-t',20 # max seconds
|
195
|
+
'-ss', 10, # seek to input position
|
196
|
+
'-t', 20 # max seconds
|
197
197
|
],
|
198
198
|
out_f: @destination_file_path,
|
199
199
|
out_p: [
|
200
|
-
'-vf','fps=5,scale=120:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse',
|
201
|
-
'-loop',0,
|
202
|
-
'-f','gif'
|
200
|
+
'-vf', 'fps=5,scale=120:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse',
|
201
|
+
'-loop', 0,
|
202
|
+
'-f', 'gif'
|
203
203
|
])
|
204
204
|
end
|
205
205
|
|
206
206
|
def convert_office_to_png
|
207
|
-
tmp_pdf_file = File.join(this_tmpdir,File.basename(@source_file_path,File.extname(@source_file_path)) + '.pdf')
|
208
|
-
Utils.external_command(:unoconv,[
|
209
|
-
'-f','pdf',
|
210
|
-
'-o',tmp_pdf_file,
|
207
|
+
tmp_pdf_file = File.join(this_tmpdir, File.basename(@source_file_path, File.extname(@source_file_path)) + '.pdf')
|
208
|
+
Utils.external_command(:unoconv, [
|
209
|
+
'-f', 'pdf',
|
210
|
+
'-o', tmp_pdf_file,
|
211
211
|
@source_file_path])
|
212
212
|
convert_pdf_to_png(tmp_pdf_file)
|
213
213
|
end
|
214
214
|
|
215
215
|
def convert_pdf_to_png(source_file_path=nil)
|
216
216
|
source_file_path ||= @source_file_path
|
217
|
-
Utils.external_command(:convert,[
|
218
|
-
'-size',"x#{@options.thumb_img_size}",
|
219
|
-
'-background','white',
|
217
|
+
Utils.external_command(:convert, [
|
218
|
+
'-size', "x#{@options.thumb_img_size}",
|
219
|
+
'-background', 'white',
|
220
220
|
'-flatten',
|
221
221
|
"#{source_file_path}[0]",
|
222
222
|
@destination_file_path])
|
223
223
|
end
|
224
224
|
|
225
225
|
def convert_image_to_png
|
226
|
-
Utils.external_command(:convert,[
|
226
|
+
Utils.external_command(:convert, [
|
227
227
|
'-auto-orient',
|
228
|
-
'-thumbnail',"#{@options.thumb_img_size}x#{@options.thumb_img_size}>",
|
229
|
-
'-quality',95,
|
228
|
+
'-thumbnail', "#{@options.thumb_img_size}x#{@options.thumb_img_size}>",
|
229
|
+
'-quality', 95,
|
230
230
|
'+dither',
|
231
|
-
'-posterize',40,
|
231
|
+
'-posterize', 40,
|
232
232
|
"#{@source_file_path}[0]",
|
233
233
|
@destination_file_path])
|
234
|
-
Utils.external_command(:optipng,[@destination_file_path])
|
234
|
+
Utils.external_command(:optipng, [@destination_file_path])
|
235
235
|
end
|
236
236
|
|
237
237
|
# text to png
|
238
238
|
def convert_plaintext_to_png
|
239
239
|
# get 100 first lines of text file
|
240
240
|
first_lines = File.open(@source_file_path){|f|Array.new(100){f.readline rescue ''}.join}
|
241
|
-
Utils.external_command(:convert,[
|
242
|
-
'-size',"#{@options.thumb_img_size}x#{@options.thumb_img_size}",
|
241
|
+
Utils.external_command(:convert, [
|
242
|
+
'-size', "#{@options.thumb_img_size}x#{@options.thumb_img_size}",
|
243
243
|
'xc:white', # define canvas with background color (xc, or canvas) of preceding size
|
244
|
-
'-font'
|
245
|
-
'-pointsize',12,
|
246
|
-
'-fill','black', # font color
|
247
|
-
'-annotate','+0+0',first_lines,
|
244
|
+
'-font', @options.thumb_text_font,
|
245
|
+
'-pointsize', 12,
|
246
|
+
'-fill', 'black', # font color
|
247
|
+
'-annotate', '+0+0', first_lines,
|
248
248
|
'-trim', # avoid large blank regions
|
249
|
-
'-bordercolor','white',
|
250
|
-
'-border',8,
|
249
|
+
'-bordercolor', 'white',
|
250
|
+
'-border', 8,
|
251
251
|
'+repage',
|
252
252
|
@destination_file_path])
|
253
253
|
end
|
data/lib/aspera/preview/utils.rb
CHANGED
@@ -16,7 +16,7 @@ module Aspera
|
|
16
16
|
# external binaries used
|
17
17
|
EXPERNAL_TOOLS = %i[ffmpeg ffprobe convert composite optipng unoconv].freeze
|
18
18
|
TMPFMT = 'img%04d.jpg'
|
19
|
-
private_constant :BASH_SPECIAL_CHARACTERS
|
19
|
+
private_constant :BASH_SPECIAL_CHARACTERS, :BASH_EXIT_NOT_FOUND, :EXPERNAL_TOOLS, :TMPFMT
|
20
20
|
|
21
21
|
class << self
|
22
22
|
# returns string with single quotes suitable for bash if there is any bash metacharacter
|
@@ -27,22 +27,22 @@ module Aspera
|
|
27
27
|
|
28
28
|
# check that external tools can be executed
|
29
29
|
def check_tools(skip_types=[])
|
30
|
-
tools_to_check=EXPERNAL_TOOLS.dup
|
30
|
+
tools_to_check = EXPERNAL_TOOLS.dup
|
31
31
|
tools_to_check.delete(:unoconv) if skip_types.include?(:office)
|
32
32
|
# Check for binaries
|
33
33
|
tools_to_check.each do |command_symb|
|
34
|
-
external_command(command_symb,['-h'])
|
34
|
+
external_command(command_symb, ['-h'])
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
# execute external command
|
39
39
|
# one could use "system", but we would need to redirect stdout/err
|
40
40
|
# @return true if su
|
41
|
-
def external_command(command_symb,command_args)
|
41
|
+
def external_command(command_symb, command_args)
|
42
42
|
raise "unexpected command #{command_symb}" unless EXPERNAL_TOOLS.include?(command_symb)
|
43
43
|
# build command line, and quote special characters
|
44
44
|
command = command_args.clone.unshift(command_symb).map{|i| shell_quote(i.to_s)}.join(' ')
|
45
|
-
Log.log.debug
|
45
|
+
Log.log.debug{"cmd=#{command}".blue}
|
46
46
|
# capture3: only in ruby2+
|
47
47
|
if Open3.respond_to?(:capture3)
|
48
48
|
stdout, stderr, exit_status = Open3.capture3(command)
|
@@ -55,10 +55,10 @@ module Aspera
|
|
55
55
|
raise "Error: #{command_symb} is not in the PATH"
|
56
56
|
end
|
57
57
|
unless exit_status.success?
|
58
|
-
Log.log.error
|
59
|
-
Log.log.error
|
60
|
-
Log.log.error
|
61
|
-
Log.log.error
|
58
|
+
Log.log.error{"commandline: #{command}"}
|
59
|
+
Log.log.error{"Error code: #{exit_status}"}
|
60
|
+
Log.log.error{"stdout: #{stdout}"}
|
61
|
+
Log.log.error{"stderr: #{stderr}"}
|
62
62
|
raise "#{command_symb} error #{exit_status}"
|
63
63
|
end
|
64
64
|
return {status: exit_status, stdout: stdout}
|
@@ -66,60 +66,60 @@ module Aspera
|
|
66
66
|
|
67
67
|
def ffmpeg(a)
|
68
68
|
raise 'error: hash expected' unless a.is_a?(Hash)
|
69
|
-
#input_file,input_args,output_file,output_args
|
69
|
+
# input_file,input_args,output_file,output_args
|
70
70
|
a[:gl_p] ||= [
|
71
71
|
'-y', # overwrite output without asking
|
72
|
-
'-loglevel','error' # show only errors and up]
|
72
|
+
'-loglevel', 'error' # show only errors and up]
|
73
73
|
]
|
74
74
|
a[:in_p] ||= []
|
75
75
|
a[:out_p] ||= []
|
76
76
|
raise "wrong params (#{a.keys.sort})" unless %i[gl_p in_f in_p out_f out_p].eql?(a.keys.sort)
|
77
|
-
external_command(:ffmpeg,[a[:gl_p],a[:in_p],'-i',a[:in_f],a[:out_p],a[:out_f]].flatten)
|
77
|
+
external_command(:ffmpeg, [a[:gl_p], a[:in_p], '-i', a[:in_f], a[:out_p], a[:out_f]].flatten)
|
78
78
|
end
|
79
79
|
|
80
80
|
# @return Float in seconds
|
81
81
|
def video_get_duration(input_file)
|
82
|
-
result = external_command(:ffprobe,[
|
83
|
-
'-loglevel','error',
|
84
|
-
'-show_entries','format=duration',
|
85
|
-
'-print_format','default=noprint_wrappers=1:nokey=1',
|
82
|
+
result = external_command(:ffprobe, [
|
83
|
+
'-loglevel', 'error',
|
84
|
+
'-show_entries', 'format=duration',
|
85
|
+
'-print_format', 'default=noprint_wrappers=1:nokey=1',
|
86
86
|
input_file])
|
87
87
|
return result[:stdout].to_f
|
88
88
|
end
|
89
89
|
|
90
90
|
def ffmpeg_fmt(temp_folder)
|
91
|
-
return File.join(temp_folder,TMPFMT)
|
91
|
+
return File.join(temp_folder, TMPFMT)
|
92
92
|
end
|
93
93
|
|
94
94
|
def get_tmp_num_filepath(temp_folder, file_number)
|
95
|
-
return File.join(temp_folder,format(TMPFMT,file_number))
|
95
|
+
return File.join(temp_folder, format(TMPFMT, file_number))
|
96
96
|
end
|
97
97
|
|
98
98
|
def video_dupe_frame(temp_folder, index, count)
|
99
|
-
input_file = get_tmp_num_filepath(temp_folder,index)
|
99
|
+
input_file = get_tmp_num_filepath(temp_folder, index)
|
100
100
|
1.upto(count) do |i|
|
101
|
-
FileUtils.ln_s(input_file,get_tmp_num_filepath(temp_folder,index + i))
|
101
|
+
FileUtils.ln_s(input_file, get_tmp_num_filepath(temp_folder, index + i))
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
105
|
def video_blend_frames(temp_folder, index1, index2)
|
106
|
-
img1 = get_tmp_num_filepath(temp_folder,index1)
|
107
|
-
img2 = get_tmp_num_filepath(temp_folder,index2)
|
106
|
+
img1 = get_tmp_num_filepath(temp_folder, index1)
|
107
|
+
img2 = get_tmp_num_filepath(temp_folder, index2)
|
108
108
|
count = index2 - index1 - 1
|
109
109
|
1.upto(count) do |i|
|
110
|
-
percent =
|
110
|
+
percent = i * 100 / (count + 1)
|
111
111
|
filename = get_tmp_num_filepath(temp_folder, index1 + i)
|
112
|
-
external_command(:composite,['-blend',percent,img2,img1,filename])
|
112
|
+
external_command(:composite, ['-blend', percent, img2, img1, filename])
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
116
|
def video_dump_frame(input_file, offset_seconds, scale, output_file, index=nil)
|
117
|
-
output_file = get_tmp_num_filepath(output_file,index) unless index.nil?
|
117
|
+
output_file = get_tmp_num_filepath(output_file, index) unless index.nil?
|
118
118
|
ffmpeg(
|
119
119
|
in_f: input_file,
|
120
|
-
in_p: ['-ss',offset_seconds],
|
120
|
+
in_p: ['-ss', offset_seconds],
|
121
121
|
out_f: output_file,
|
122
|
-
out_p: ['-frames:v',1,'-filter:v',"scale=#{scale}"])
|
122
|
+
out_p: ['-frames:v', 1, '-filter:v', "scale=#{scale}"])
|
123
123
|
return output_file
|
124
124
|
end
|
125
125
|
end
|
@@ -207,65 +207,65 @@ function timeRange() {
|
|
207
207
|
var arg = arguments[i];
|
208
208
|
if (gmt) {
|
209
209
|
switch (i) {
|
210
|
-
case 0:
|
211
|
-
date1.setUTCHours(arg);
|
212
|
-
date2.setUTCHours(arg);
|
213
|
-
break;
|
214
|
-
case 1:
|
215
|
-
date1.setUTCMinutes(arg);
|
216
|
-
date2.setUTCMinutes(arg);
|
217
|
-
break;
|
218
|
-
case 2:
|
219
|
-
date1.setUTCSeconds(arg);
|
220
|
-
date2.setUTCSeconds(arg);
|
221
|
-
break;
|
222
|
-
}
|
223
|
-
} else {
|
224
|
-
switch (i) {
|
225
|
-
case 0:
|
226
|
-
date1.setHours(arg);
|
227
|
-
date2.setHours(arg);
|
228
|
-
break;
|
229
|
-
case 1:
|
230
|
-
date1.setMinutes(arg);
|
231
|
-
date2.setMinutes(arg);
|
232
|
-
break;
|
233
|
-
case 2:
|
234
|
-
date1.setSeconds(arg);
|
235
|
-
date2.setSeconds(arg);
|
236
|
-
break;
|
237
|
-
}
|
238
|
-
}
|
239
|
-
}
|
240
|
-
if (num != 1) {
|
241
|
-
date2.setMinutes(0);
|
242
|
-
date2.setSeconds(0);
|
243
|
-
date2.setMilliseconds(0);
|
244
|
-
for (i = 0; i < (num / 2); i++) {
|
245
|
-
var arg = arguments[(num / 2) + i];
|
246
|
-
if (gmt) {
|
247
|
-
switch (i) {
|
248
210
|
case 0:
|
211
|
+
date1.setUTCHours(arg);
|
249
212
|
date2.setUTCHours(arg);
|
250
213
|
break;
|
251
214
|
case 1:
|
215
|
+
date1.setUTCMinutes(arg);
|
252
216
|
date2.setUTCMinutes(arg);
|
253
217
|
break;
|
254
218
|
case 2:
|
219
|
+
date1.setUTCSeconds(arg);
|
255
220
|
date2.setUTCSeconds(arg);
|
256
221
|
break;
|
257
|
-
|
258
|
-
|
259
|
-
|
222
|
+
}
|
223
|
+
} else {
|
224
|
+
switch (i) {
|
260
225
|
case 0:
|
226
|
+
date1.setHours(arg);
|
261
227
|
date2.setHours(arg);
|
262
228
|
break;
|
263
229
|
case 1:
|
230
|
+
date1.setMinutes(arg);
|
264
231
|
date2.setMinutes(arg);
|
265
232
|
break;
|
266
233
|
case 2:
|
234
|
+
date1.setSeconds(arg);
|
267
235
|
date2.setSeconds(arg);
|
268
236
|
break;
|
237
|
+
}
|
238
|
+
}
|
239
|
+
}
|
240
|
+
if (num != 1) {
|
241
|
+
date2.setMinutes(0);
|
242
|
+
date2.setSeconds(0);
|
243
|
+
date2.setMilliseconds(0);
|
244
|
+
for (i = 0; i < (num / 2); i++) {
|
245
|
+
var arg = arguments[(num / 2) + i];
|
246
|
+
if (gmt) {
|
247
|
+
switch (i) {
|
248
|
+
case 0:
|
249
|
+
date2.setUTCHours(arg);
|
250
|
+
break;
|
251
|
+
case 1:
|
252
|
+
date2.setUTCMinutes(arg);
|
253
|
+
break;
|
254
|
+
case 2:
|
255
|
+
date2.setUTCSeconds(arg);
|
256
|
+
break;
|
257
|
+
}
|
258
|
+
} else {
|
259
|
+
switch (i) {
|
260
|
+
case 0:
|
261
|
+
date2.setHours(arg);
|
262
|
+
break;
|
263
|
+
case 1:
|
264
|
+
date2.setMinutes(arg);
|
265
|
+
break;
|
266
|
+
case 2:
|
267
|
+
date2.setSeconds(arg);
|
268
|
+
break;
|
269
269
|
}
|
270
270
|
}
|
271
271
|
}
|
@@ -22,9 +22,9 @@ module Aspera
|
|
22
22
|
class ProxyAutoConfig
|
23
23
|
# template file is read once, it contains functions that can be used in a proxy autoconf script
|
24
24
|
# it is similar to mozilla ascii_pac_utils.inc
|
25
|
-
PAC_FUNCTIONS_FILE = __FILE__.gsub(/\.rb$/,'.js').freeze
|
25
|
+
PAC_FUNCTIONS_FILE = __FILE__.gsub(/\.rb$/, '.js').freeze
|
26
26
|
PAC_MAIN_FUNCTION = 'FindProxyForURL'
|
27
|
-
private_constant :PAC_FUNCTIONS_FILE
|
27
|
+
private_constant :PAC_FUNCTIONS_FILE, :PAC_MAIN_FUNCTION
|
28
28
|
|
29
29
|
private
|
30
30
|
|
@@ -52,7 +52,7 @@ END_OF_JAVASCRIPT
|
|
52
52
|
|
53
53
|
public
|
54
54
|
|
55
|
-
attr_writer :proxy_user
|
55
|
+
attr_writer :proxy_user, :proxy_pass
|
56
56
|
|
57
57
|
# @param proxy_auto_config the proxy auto config script to be evaluated
|
58
58
|
def initialize(proxy_auto_config)
|
@@ -60,7 +60,7 @@ END_OF_JAVASCRIPT
|
|
60
60
|
@proxy_auto_config = proxy_auto_config
|
61
61
|
# avoid multiple execution, this does not support load balancing
|
62
62
|
@cache = {}
|
63
|
-
@proxy_user
|
63
|
+
@proxy_user = @proxy_pass = @pac_functions = nil
|
64
64
|
end
|
65
65
|
|
66
66
|
def register_uri_generic
|
@@ -74,8 +74,8 @@ END_OF_JAVASCRIPT
|
|
74
74
|
def find_proxy_for_url(service_url)
|
75
75
|
uri = URI.parse(service_url)
|
76
76
|
simple_url = "#{uri.scheme}://#{uri.host}"
|
77
|
-
if !@cache.
|
78
|
-
Log.log.debug
|
77
|
+
if !@cache.key?(simple_url)
|
78
|
+
Log.log.debug{"PAC: starting javascript for #{service_url}"}
|
79
79
|
# require at runtime, in case there is no js engine
|
80
80
|
require 'execjs'
|
81
81
|
# read template lib
|
@@ -84,7 +84,7 @@ END_OF_JAVASCRIPT
|
|
84
84
|
js_to_execute = "#{pac_dns_functions(uri.host)}#{@pac_functions}#{@proxy_auto_config}"
|
85
85
|
executable_js = ExecJS.compile(js_to_execute)
|
86
86
|
@cache[simple_url] = executable_js.call(PAC_MAIN_FUNCTION, simple_url, uri.host)
|
87
|
-
Log.log.debug
|
87
|
+
Log.log.debug{"PAC: result: #{@cache[simple_url]}"}
|
88
88
|
end
|
89
89
|
return @cache[simple_url]
|
90
90
|
end
|
@@ -97,11 +97,11 @@ END_OF_JAVASCRIPT
|
|
97
97
|
# execute PAC script
|
98
98
|
proxy_list_str = find_proxy_for_url(service_url)
|
99
99
|
if !proxy_list_str.is_a?(String)
|
100
|
-
Log.log.warn
|
100
|
+
Log.log.warn{"PAC: did not return a String, returned #{proxy_list_str.class}"}
|
101
101
|
return uri_list
|
102
102
|
end
|
103
103
|
proxy_list_str.strip!
|
104
|
-
proxy_list_str.gsub!(/\s+/,' ')
|
104
|
+
proxy_list_str.gsub!(/\s+/, ' ')
|
105
105
|
proxy_list_str.split(';').each do |item|
|
106
106
|
# strip and split by space
|
107
107
|
parts = item.strip.split
|
@@ -115,21 +115,21 @@ END_OF_JAVASCRIPT
|
|
115
115
|
begin
|
116
116
|
# PAC proxy addresses are <host>:<port>
|
117
117
|
if /:[0-9]+$/.match?(addr_port)
|
118
|
-
uri=URI.parse("proxy://#{addr_port}")
|
118
|
+
uri = URI.parse("proxy://#{addr_port}")
|
119
119
|
# ruby v>2.6 allows
|
120
|
-
uri.user
|
121
|
-
uri.password
|
120
|
+
uri.user = @proxy_user
|
121
|
+
uri.password = @proxy_pass
|
122
122
|
uri_list.push(uri)
|
123
123
|
else
|
124
|
-
Log.log.warn
|
124
|
+
Log.log.warn{"PAC: PROXY must be <address>:<port>, ignoring #{addr_port}"}
|
125
125
|
end
|
126
126
|
rescue StandardError => e
|
127
|
-
Log.log.warn
|
127
|
+
Log.log.warn{"PAC: cannot parse #{addr_port} #{e}"}
|
128
128
|
end
|
129
|
-
else Log.log.warn
|
129
|
+
else Log.log.warn{"PAC: ignoring proxy type #{parts.first}: not supported"}
|
130
130
|
end
|
131
131
|
end
|
132
|
-
Log.log.debug
|
132
|
+
Log.log.debug{"Proxies: #{uri_list}"}
|
133
133
|
return uri_list
|
134
134
|
end
|
135
135
|
end
|