aspera-cli 4.9.0 → 4.11.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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/BUGS.md +20 -0
  4. data/CHANGELOG.md +509 -0
  5. data/CONTRIBUTING.md +118 -0
  6. data/README.md +1241 -916
  7. data/bin/ascli +4 -4
  8. data/bin/asession +11 -11
  9. data/docs/test_env.conf +32 -21
  10. data/examples/aoc.rb +4 -4
  11. data/examples/dascli +16 -9
  12. data/examples/faspex4.rb +8 -8
  13. data/examples/node.rb +12 -12
  14. data/examples/server.rb +10 -10
  15. data/lib/aspera/aoc.rb +273 -266
  16. data/lib/aspera/ascmd.rb +56 -54
  17. data/lib/aspera/ats_api.rb +4 -4
  18. data/lib/aspera/cli/basic_auth_plugin.rb +15 -12
  19. data/lib/aspera/cli/extended_value.rb +5 -5
  20. data/lib/aspera/cli/formater.rb +64 -64
  21. data/lib/aspera/cli/info.rb +2 -2
  22. data/lib/aspera/cli/listener/line_dump.rb +1 -1
  23. data/lib/aspera/cli/listener/logger.rb +1 -1
  24. data/lib/aspera/cli/listener/progress.rb +5 -6
  25. data/lib/aspera/cli/listener/progress_multi.rb +14 -19
  26. data/lib/aspera/cli/main.rb +66 -67
  27. data/lib/aspera/cli/manager.rb +112 -110
  28. data/lib/aspera/cli/plugin.rb +57 -36
  29. data/lib/aspera/cli/plugins/alee.rb +4 -4
  30. data/lib/aspera/cli/plugins/aoc.rb +309 -670
  31. data/lib/aspera/cli/plugins/ats.rb +44 -46
  32. data/lib/aspera/cli/plugins/bss.rb +10 -10
  33. data/lib/aspera/cli/plugins/config.rb +497 -378
  34. data/lib/aspera/cli/plugins/console.rb +12 -12
  35. data/lib/aspera/cli/plugins/cos.rb +18 -20
  36. data/lib/aspera/cli/plugins/faspex.rb +112 -114
  37. data/lib/aspera/cli/plugins/faspex5.rb +71 -46
  38. data/lib/aspera/cli/plugins/node.rb +379 -283
  39. data/lib/aspera/cli/plugins/orchestrator.rb +46 -46
  40. data/lib/aspera/cli/plugins/preview.rb +122 -114
  41. data/lib/aspera/cli/plugins/server.rb +137 -83
  42. data/lib/aspera/cli/plugins/shares.rb +30 -29
  43. data/lib/aspera/cli/plugins/sync.rb +13 -33
  44. data/lib/aspera/cli/transfer_agent.rb +60 -59
  45. data/lib/aspera/cli/version.rb +1 -1
  46. data/lib/aspera/colors.rb +3 -3
  47. data/lib/aspera/command_line_builder.rb +27 -27
  48. data/lib/aspera/cos_node.rb +22 -20
  49. data/lib/aspera/data_repository.rb +1 -1
  50. data/lib/aspera/environment.rb +35 -15
  51. data/lib/aspera/fasp/agent_base.rb +15 -15
  52. data/lib/aspera/fasp/agent_connect.rb +23 -21
  53. data/lib/aspera/fasp/agent_direct.rb +66 -64
  54. data/lib/aspera/fasp/agent_httpgw.rb +141 -78
  55. data/lib/aspera/fasp/agent_node.rb +23 -21
  56. data/lib/aspera/fasp/agent_trsdk.rb +20 -20
  57. data/lib/aspera/fasp/error.rb +3 -2
  58. data/lib/aspera/fasp/error_info.rb +11 -8
  59. data/lib/aspera/fasp/installation.rb +79 -79
  60. data/lib/aspera/fasp/listener.rb +1 -1
  61. data/lib/aspera/fasp/parameters.rb +86 -71
  62. data/lib/aspera/fasp/parameters.yaml +7 -4
  63. data/lib/aspera/fasp/resume_policy.rb +8 -8
  64. data/lib/aspera/fasp/transfer_spec.rb +35 -2
  65. data/lib/aspera/fasp/uri.rb +7 -7
  66. data/lib/aspera/faspex_gw.rb +7 -5
  67. data/lib/aspera/hash_ext.rb +3 -3
  68. data/lib/aspera/id_generator.rb +5 -5
  69. data/lib/aspera/keychain/encrypted_hash.rb +38 -105
  70. data/lib/aspera/keychain/macos_security.rb +128 -57
  71. data/lib/aspera/log.rb +7 -7
  72. data/lib/aspera/nagios.rb +19 -18
  73. data/lib/aspera/node.rb +209 -35
  74. data/lib/aspera/oauth.rb +37 -36
  75. data/lib/aspera/open_application.rb +19 -11
  76. data/lib/aspera/persistency_action_once.rb +4 -4
  77. data/lib/aspera/persistency_folder.rb +16 -15
  78. data/lib/aspera/preview/file_types.rb +8 -8
  79. data/lib/aspera/preview/generator.rb +67 -67
  80. data/lib/aspera/preview/utils.rb +27 -27
  81. data/lib/aspera/proxy_auto_config.js +41 -41
  82. data/lib/aspera/proxy_auto_config.rb +21 -14
  83. data/lib/aspera/rest.rb +72 -67
  84. data/lib/aspera/rest_call_error.rb +2 -1
  85. data/lib/aspera/rest_error_analyzer.rb +18 -17
  86. data/lib/aspera/rest_errors_aspera.rb +16 -16
  87. data/lib/aspera/secret_hider.rb +15 -13
  88. data/lib/aspera/ssh.rb +11 -10
  89. data/lib/aspera/sync.rb +158 -44
  90. data/lib/aspera/temp_file_manager.rb +2 -2
  91. data/lib/aspera/uri_reader.rb +4 -4
  92. data/lib/aspera/web_auth.rb +14 -13
  93. data.tar.gz.sig +0 -0
  94. metadata +11 -36
  95. metadata.gz.sig +0 -0
@@ -14,7 +14,7 @@ module Aspera
14
14
  # @param :format Optional dump method (default to JSON)
15
15
  # @param :merge Optional merge data from file to current data
16
16
  def initialize(options)
17
- Log.log.debug("persistency: #{options}")
17
+ Log.log.debug{"persistency: #{options}"}
18
18
  raise 'options shall be Hash' unless options.is_a?(Hash)
19
19
  raise 'mandatory :manager' if options[:manager].nil?
20
20
  raise 'mandatory :data' if options[:data].nil?
@@ -27,16 +27,16 @@ module Aspera
27
27
  @delete_condition = options[:delete] || lambda{|d|d.empty?}
28
28
  @persist_format = options[:format] || lambda {|h| JSON.generate(h)}
29
29
  persist_parse = options[:parse] || lambda {|t| JSON.parse(t)}
30
- persist_merge = options[:merge] || lambda {|current,file| current.concat(file).uniq rescue current}
30
+ persist_merge = options[:merge] || lambda {|current, file| current.concat(file).uniq rescue current}
31
31
  value = @manager.get(@object_id)
32
- persist_merge.call(@persisted_object,persist_parse.call(value)) unless value.nil?
32
+ persist_merge.call(@persisted_object, persist_parse.call(value)) unless value.nil?
33
33
  end
34
34
 
35
35
  def save
36
36
  if @delete_condition.call(@persisted_object)
37
37
  @manager.delete(@object_id)
38
38
  else
39
- @manager.put(@object_id,@persist_format.call(@persisted_object))
39
+ @manager.put(@object_id, @persist_format.call(@persisted_object))
40
40
  end
41
41
  end
42
42
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'fileutils'
4
4
  require 'aspera/log'
5
+ require 'aspera/environment'
5
6
 
6
7
  # search: persistency_folder PersistencyFolder
7
8
 
@@ -13,17 +14,17 @@ module Aspera
13
14
  def initialize(folder)
14
15
  @cache = {}
15
16
  @folder = folder
16
- Log.log.debug("persistency folder: #{@folder}")
17
+ Log.log.debug{"persistency folder: #{@folder}"}
17
18
  end
18
19
 
19
20
  # @return String or nil string on existing persist, else nil
20
21
  def get(object_id)
21
- Log.log.debug("persistency get: #{object_id}")
22
- if @cache.has_key?(object_id)
22
+ Log.log.debug{"persistency get: #{object_id}"}
23
+ if @cache.key?(object_id)
23
24
  Log.log.debug('got from memory cache')
24
25
  else
25
26
  persist_filepath = id_to_filepath(object_id)
26
- Log.log.debug("persistency = #{persist_filepath}")
27
+ Log.log.debug{"persistency = #{persist_filepath}"}
27
28
  if File.exist?(persist_filepath)
28
29
  Log.log.debug('got from file cache')
29
30
  @cache[object_id] = File.read(persist_filepath)
@@ -32,32 +33,32 @@ module Aspera
32
33
  return @cache[object_id]
33
34
  end
34
35
 
35
- def put(object_id,value)
36
+ def put(object_id, value)
36
37
  raise 'value: only String supported' unless value.is_a?(String)
37
38
  persist_filepath = id_to_filepath(object_id)
38
- Log.log.debug("persistency saving: #{persist_filepath}")
39
+ Log.log.debug{"persistency saving: #{persist_filepath}"}
39
40
  File.delete(persist_filepath) if File.exist?(persist_filepath)
40
- File.write(persist_filepath,value)
41
- File.chmod(0400,persist_filepath)
41
+ File.write(persist_filepath, value)
42
+ Environment.restrict_file_access(persist_filepath)
42
43
  @cache[object_id] = value
43
44
  end
44
45
 
45
46
  def delete(object_id)
46
47
  persist_filepath = id_to_filepath(object_id)
47
- Log.log.debug("persistency deleting: #{persist_filepath}")
48
+ Log.log.debug{"persistency deleting: #{persist_filepath}"}
48
49
  File.delete(persist_filepath) if File.exist?(persist_filepath)
49
50
  @cache.delete(object_id)
50
51
  end
51
52
 
52
- def garbage_collect(persist_category,max_age_seconds=nil)
53
- garbage_files = Dir[File.join(@folder,persist_category + '*' + FILE_SUFFIX)]
53
+ def garbage_collect(persist_category, max_age_seconds=nil)
54
+ garbage_files = Dir[File.join(@folder, persist_category + '*' + FILE_SUFFIX)]
54
55
  if !max_age_seconds.nil?
55
56
  current_time = Time.now
56
57
  garbage_files.select! { |filepath| (current_time - File.stat(filepath).mtime).to_i > max_age_seconds}
57
58
  end
58
59
  garbage_files.each do |filepath|
59
60
  File.delete(filepath)
60
- Log.log.debug("persistency deleted expired: #{filepath}")
61
+ Log.log.debug{"persistency deleted expired: #{filepath}"}
61
62
  end
62
63
  return garbage_files
63
64
  end
@@ -68,9 +69,9 @@ module Aspera
68
69
  def id_to_filepath(object_id)
69
70
  raise 'object_id: only String supported' unless object_id.is_a?(String)
70
71
  FileUtils.mkdir_p(@folder)
71
- File.chmod(0700,@folder)
72
- return File.join(@folder,"#{object_id}#{FILE_SUFFIX}")
73
- #.gsub(/[^a-z]+/,FILE_FIELD_SEPARATOR)
72
+ Environment.restrict_file_access(@folder)
73
+ return File.join(@folder, "#{object_id}#{FILE_SUFFIX}")
74
+ # .gsub(/[^a-z]+/,FILE_FIELD_SEPARATOR)
74
75
  end
75
76
  end # PersistencyFolder
76
77
  end # Aspera
@@ -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.has_key?(detected_mime)
290
- Log.log.debug("no conversion for #{detected_mime}, trying extension")
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("mimemagic: #{detected_mime.class.name} [#{detected_mime}]")
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("conversion_type(#{filepath},m=#{mimetype},t=#{@use_mimemagic})")
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
- # note: detected can be nil
315
- Log.log.debug("non matching mime types: node=[#{mimetype}], magic=[#{detected_mime}]")
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("conversion_type(#{extension}): #{conv_type.class.name} [#{conv_type}]")
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,@source_file_path.split('/').last.gsub(/\s/, '_').gsub(/\W/, ''))
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("method: #{name}")
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("#{@source_file_path}->#{@destination_file_path} (#{method_symb})")
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("preview size exceeds maximum #{result_size} > #{@options.max_size}")
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("Ignoging: #{e.message}")
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__)),@destination_file_path)
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',@options.blend_fps],
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,@options.video_start_sec.to_i,@options.clips_count.to_i,i)
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 * offset_seconds],
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 * offset_seconds,
143
- '-t',@options.clips_length,
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',@options.thumb_text_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
@@ -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,:BASH_EXIT_NOT_FOUND,:EXPERNAL_TOOLS,:TMPFMT
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("cmd=#{command}".blue)
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("commandline: #{command}")
59
- Log.log.error("Error code: #{exit_status}")
60
- Log.log.error("stdout: #{stdout}")
61
- Log.log.error("stderr: #{stderr}")
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 = 100 * i / (count + 1)
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
- } else {
259
- switch (i) {
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
  }