aspera-cli 4.10.0 → 4.12.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/BUGS.md +19 -0
- data/CHANGELOG.md +528 -0
- data/CONTRIBUTING.md +143 -0
- data/README.md +977 -589
- data/bin/ascli +4 -4
- data/bin/asession +12 -12
- data/docs/test_env.conf +29 -19
- data/examples/aoc.rb +6 -6
- data/examples/dascli +18 -16
- data/examples/faspex4.rb +15 -15
- data/examples/node.rb +12 -12
- data/examples/proxy.pac +2 -2
- data/examples/server.rb +12 -12
- data/lib/aspera/aoc.rb +344 -272
- 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 +9 -9
- data/lib/aspera/cli/{formater.rb → formatter.rb} +69 -69
- 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 +16 -21
- data/lib/aspera/cli/main.rb +72 -73
- data/lib/aspera/cli/manager.rb +112 -112
- data/lib/aspera/cli/plugin.rb +68 -48
- data/lib/aspera/cli/plugins/alee.rb +4 -4
- data/lib/aspera/cli/plugins/aoc.rb +322 -720
- data/lib/aspera/cli/plugins/ats.rb +50 -52
- data/lib/aspera/cli/plugins/bss.rb +10 -10
- data/lib/aspera/cli/plugins/config.rb +514 -410
- 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 +134 -136
- data/lib/aspera/cli/plugins/faspex5.rb +235 -70
- data/lib/aspera/cli/plugins/node.rb +378 -309
- data/lib/aspera/cli/plugins/orchestrator.rb +52 -49
- data/lib/aspera/cli/plugins/preview.rb +129 -120
- data/lib/aspera/cli/plugins/server.rb +137 -83
- data/lib/aspera/cli/plugins/shares.rb +77 -52
- data/lib/aspera/cli/plugins/sync.rb +13 -33
- data/lib/aspera/cli/transfer_agent.rb +61 -61
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +3 -3
- data/lib/aspera/command_line_builder.rb +78 -74
- data/lib/aspera/cos_node.rb +31 -29
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/environment.rb +30 -28
- data/lib/aspera/fasp/agent_base.rb +17 -15
- data/lib/aspera/fasp/agent_connect.rb +34 -32
- data/lib/aspera/fasp/agent_direct.rb +70 -73
- data/lib/aspera/fasp/agent_httpgw.rb +79 -74
- data/lib/aspera/fasp/agent_node.rb +26 -26
- 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 +80 -80
- data/lib/aspera/fasp/listener.rb +2 -2
- data/lib/aspera/fasp/parameters.rb +103 -92
- data/lib/aspera/fasp/parameters.yaml +313 -214
- data/lib/aspera/fasp/resume_policy.rb +10 -10
- data/lib/aspera/fasp/transfer_spec.rb +22 -2
- data/lib/aspera/fasp/uri.rb +7 -7
- data/lib/aspera/faspex_gw.rb +80 -159
- data/lib/aspera/faspex_postproc.rb +77 -0
- 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 +13 -13
- data/lib/aspera/nagios.rb +24 -23
- data/lib/aspera/node.rb +217 -38
- data/lib/aspera/oauth.rb +78 -74
- 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 +63 -63
- data/lib/aspera/proxy_auto_config.rb +19 -19
- data/lib/aspera/rest.rb +65 -67
- data/lib/aspera/rest_call_error.rb +2 -1
- data/lib/aspera/rest_error_analyzer.rb +22 -21
- data/lib/aspera/rest_errors_aspera.rb +16 -16
- data/lib/aspera/secret_hider.rb +17 -14
- data/lib/aspera/ssh.rb +15 -14
- data/lib/aspera/sync.rb +177 -62
- data/lib/aspera/temp_file_manager.rb +2 -2
- data/lib/aspera/uri_reader.rb +4 -4
- data/lib/aspera/web_auth.rb +13 -64
- data/lib/aspera/web_server_simple.rb +76 -0
- data.tar.gz.sig +0 -0
- metadata +11 -6
- metadata.gz.sig +0 -0
@@ -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
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// inspired by
|
1
|
+
// inspired by POCSupport.js, 2003-2004 by Apple Computer, Inc., all rights reserved
|
2
2
|
function isPlainHostName(host) {
|
3
3
|
return (host.indexOf('.') == -1 ? true : false);
|
4
4
|
}
|
@@ -10,14 +10,14 @@ function dnsDomainIs(host, domain) {
|
|
10
10
|
return true;
|
11
11
|
return false;
|
12
12
|
}
|
13
|
-
function localHostOrDomainIs(host,
|
13
|
+
function localHostOrDomainIs(host, host_domain) {
|
14
14
|
var h1 = host.toLowerCase();
|
15
|
-
var h2 =
|
15
|
+
var h2 = host_domain.toLowerCase();
|
16
16
|
return ((h1 == h2) || (isPlainHostName(h1) & !isPlainHostName(h2))) ? true : false;
|
17
17
|
}
|
18
18
|
function isResolvable(host) {
|
19
19
|
var ip = dnsResolve(host);
|
20
|
-
return ((typeof ip ==
|
20
|
+
return ((typeof ip == 'string') && ip.length) ? true : false;
|
21
21
|
}
|
22
22
|
function isInNet(host, pattern, mask) {
|
23
23
|
var ip = dnsResolve(host);
|
@@ -39,20 +39,20 @@ function dnsDomainLevels(host) {
|
|
39
39
|
var parts = host.split('.');
|
40
40
|
return parts.length - 1;
|
41
41
|
}
|
42
|
-
function shExpMatch(str,
|
43
|
-
if (typeof str !=
|
42
|
+
function shExpMatch(str, shell_expr) {
|
43
|
+
if (typeof str != 'string' || typeof shell_expr != 'string')
|
44
44
|
return false;
|
45
|
-
if (
|
45
|
+
if (shell_expr == '*')
|
46
46
|
return true;
|
47
|
-
if (str ==
|
47
|
+
if (str == '' && shell_expr == '')
|
48
48
|
return true;
|
49
49
|
str = str.toLowerCase();
|
50
|
-
|
50
|
+
shell_expr = shell_expr.toLowerCase();
|
51
51
|
var len = str.length;
|
52
|
-
var pieces =
|
52
|
+
var pieces = shell_expr.split('*');
|
53
53
|
var start = 0;
|
54
54
|
for (i = 0; i < pieces.length; i++) {
|
55
|
-
if (pieces[i] ==
|
55
|
+
if (pieces[i] == '')
|
56
56
|
continue;
|
57
57
|
if (start > len)
|
58
58
|
return false;
|
@@ -64,13 +64,13 @@ function shExpMatch(str, shexp) {
|
|
64
64
|
len = str.length;
|
65
65
|
}
|
66
66
|
i--;
|
67
|
-
if ((pieces[i] ==
|
67
|
+
if ((pieces[i] == '') || (str == ''))
|
68
68
|
return true;
|
69
69
|
return false;
|
70
70
|
}
|
71
71
|
function weekdayRange(wd1, wd2, gmt) {
|
72
72
|
var today = new Date();
|
73
|
-
var days =
|
73
|
+
var days = 'SUNMONTUEWEDTHUFRISAT';
|
74
74
|
wd1 = wd1.toUpperCase();
|
75
75
|
if (wd2 == undefined)
|
76
76
|
wd2 = wd1;
|
@@ -78,7 +78,7 @@ function weekdayRange(wd1, wd2, gmt) {
|
|
78
78
|
wd2 = wd2.toUpperCase();
|
79
79
|
var d1 = days.indexOf(wd1);
|
80
80
|
var d2 = days.indexOf(wd2);
|
81
|
-
if ((d2 == -1) && (wd2 ==
|
81
|
+
if ((d2 == -1) && (wd2 == 'GMT')) {
|
82
82
|
gmt = wd2;
|
83
83
|
d2 = d1;
|
84
84
|
}
|
@@ -86,7 +86,7 @@ function weekdayRange(wd1, wd2, gmt) {
|
|
86
86
|
return false;
|
87
87
|
d1 = d1 / 3;
|
88
88
|
d2 = d2 / 3;
|
89
|
-
if (gmt ==
|
89
|
+
if (gmt == 'GMT')
|
90
90
|
today = today.getUTCDay();
|
91
91
|
else
|
92
92
|
today = today.getDay();
|
@@ -100,11 +100,11 @@ function dateRange() {
|
|
100
100
|
var today = new Date();
|
101
101
|
var num = arguments.length;
|
102
102
|
var gmt = arguments[num - 1];
|
103
|
-
if (typeof gmt !=
|
103
|
+
if (typeof gmt != 'string')
|
104
104
|
gmt = false;
|
105
105
|
else {
|
106
106
|
gmt = gmt.toUpperCase();
|
107
|
-
if (gmt !=
|
107
|
+
if (gmt != 'GMT')
|
108
108
|
gmt = false;
|
109
109
|
else {
|
110
110
|
gmt = true;
|
@@ -121,7 +121,7 @@ function dateRange() {
|
|
121
121
|
var y2 = 0;
|
122
122
|
for (i = 0; i < num; i++) {
|
123
123
|
var arg = arguments[i];
|
124
|
-
if (typeof arg ==
|
124
|
+
if (typeof arg == 'number') {
|
125
125
|
if (arg > 31) {
|
126
126
|
if (!y1)
|
127
127
|
y1 = arg;
|
@@ -137,8 +137,8 @@ function dateRange() {
|
|
137
137
|
d2 = arg;
|
138
138
|
else
|
139
139
|
return false;
|
140
|
-
} else if (typeof arg ==
|
141
|
-
var months =
|
140
|
+
} else if (typeof arg == 'string') {
|
141
|
+
var months = 'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC';
|
142
142
|
arg = arg.toUpperCase();
|
143
143
|
arg = months.indexOf(arg);
|
144
144
|
if (arg == -1)
|
@@ -184,11 +184,11 @@ function timeRange() {
|
|
184
184
|
var date2 = new Date();
|
185
185
|
var num = arguments.length;
|
186
186
|
var gmt = arguments[num - 1];
|
187
|
-
if (typeof gmt !=
|
187
|
+
if (typeof gmt != 'string')
|
188
188
|
gmt = false;
|
189
189
|
else {
|
190
190
|
gmt = gmt.toUpperCase();
|
191
|
-
if (gmt !=
|
191
|
+
if (gmt != 'GMT')
|
192
192
|
gmt = false;
|
193
193
|
else {
|
194
194
|
gmt = true;
|
@@ -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
|
}
|