aspera-cli 4.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +3592 -0
  3. data/bin/ascli +7 -0
  4. data/bin/asession +89 -0
  5. data/docs/Makefile +59 -0
  6. data/docs/README.erb.md +3012 -0
  7. data/docs/README.md +13 -0
  8. data/docs/diagrams.txt +49 -0
  9. data/docs/secrets.make +38 -0
  10. data/docs/test_env.conf +117 -0
  11. data/docs/transfer_spec.html +99 -0
  12. data/examples/aoc.rb +17 -0
  13. data/examples/proxy.pac +60 -0
  14. data/examples/transfer.rb +115 -0
  15. data/lib/aspera/api_detector.rb +60 -0
  16. data/lib/aspera/ascmd.rb +151 -0
  17. data/lib/aspera/ats_api.rb +43 -0
  18. data/lib/aspera/cli/basic_auth_plugin.rb +38 -0
  19. data/lib/aspera/cli/extended_value.rb +88 -0
  20. data/lib/aspera/cli/formater.rb +238 -0
  21. data/lib/aspera/cli/listener/line_dump.rb +17 -0
  22. data/lib/aspera/cli/listener/logger.rb +20 -0
  23. data/lib/aspera/cli/listener/progress.rb +52 -0
  24. data/lib/aspera/cli/listener/progress_multi.rb +91 -0
  25. data/lib/aspera/cli/main.rb +304 -0
  26. data/lib/aspera/cli/manager.rb +440 -0
  27. data/lib/aspera/cli/plugin.rb +90 -0
  28. data/lib/aspera/cli/plugins/alee.rb +24 -0
  29. data/lib/aspera/cli/plugins/ats.rb +231 -0
  30. data/lib/aspera/cli/plugins/bss.rb +71 -0
  31. data/lib/aspera/cli/plugins/config.rb +806 -0
  32. data/lib/aspera/cli/plugins/console.rb +62 -0
  33. data/lib/aspera/cli/plugins/cos.rb +106 -0
  34. data/lib/aspera/cli/plugins/faspex.rb +377 -0
  35. data/lib/aspera/cli/plugins/faspex5.rb +93 -0
  36. data/lib/aspera/cli/plugins/node.rb +438 -0
  37. data/lib/aspera/cli/plugins/oncloud.rb +937 -0
  38. data/lib/aspera/cli/plugins/orchestrator.rb +169 -0
  39. data/lib/aspera/cli/plugins/preview.rb +464 -0
  40. data/lib/aspera/cli/plugins/server.rb +216 -0
  41. data/lib/aspera/cli/plugins/shares.rb +63 -0
  42. data/lib/aspera/cli/plugins/shares2.rb +114 -0
  43. data/lib/aspera/cli/plugins/sync.rb +65 -0
  44. data/lib/aspera/cli/plugins/xnode.rb +115 -0
  45. data/lib/aspera/cli/transfer_agent.rb +251 -0
  46. data/lib/aspera/cli/version.rb +5 -0
  47. data/lib/aspera/colors.rb +39 -0
  48. data/lib/aspera/command_line_builder.rb +137 -0
  49. data/lib/aspera/fasp/aoc.rb +24 -0
  50. data/lib/aspera/fasp/connect.rb +99 -0
  51. data/lib/aspera/fasp/error.rb +21 -0
  52. data/lib/aspera/fasp/error_info.rb +60 -0
  53. data/lib/aspera/fasp/http_gw.rb +81 -0
  54. data/lib/aspera/fasp/installation.rb +240 -0
  55. data/lib/aspera/fasp/listener.rb +11 -0
  56. data/lib/aspera/fasp/local.rb +377 -0
  57. data/lib/aspera/fasp/manager.rb +69 -0
  58. data/lib/aspera/fasp/node.rb +88 -0
  59. data/lib/aspera/fasp/parameters.rb +235 -0
  60. data/lib/aspera/fasp/resume_policy.rb +76 -0
  61. data/lib/aspera/fasp/uri.rb +51 -0
  62. data/lib/aspera/faspex_gw.rb +196 -0
  63. data/lib/aspera/hash_ext.rb +28 -0
  64. data/lib/aspera/log.rb +80 -0
  65. data/lib/aspera/nagios.rb +71 -0
  66. data/lib/aspera/node.rb +14 -0
  67. data/lib/aspera/oauth.rb +319 -0
  68. data/lib/aspera/on_cloud.rb +421 -0
  69. data/lib/aspera/open_application.rb +72 -0
  70. data/lib/aspera/persistency_action_once.rb +42 -0
  71. data/lib/aspera/persistency_folder.rb +91 -0
  72. data/lib/aspera/preview/file_types.rb +300 -0
  73. data/lib/aspera/preview/generator.rb +258 -0
  74. data/lib/aspera/preview/image_error.png +0 -0
  75. data/lib/aspera/preview/options.rb +35 -0
  76. data/lib/aspera/preview/utils.rb +131 -0
  77. data/lib/aspera/preview/video_error.png +0 -0
  78. data/lib/aspera/proxy_auto_config.erb.js +287 -0
  79. data/lib/aspera/proxy_auto_config.rb +34 -0
  80. data/lib/aspera/rest.rb +296 -0
  81. data/lib/aspera/rest_call_error.rb +13 -0
  82. data/lib/aspera/rest_error_analyzer.rb +98 -0
  83. data/lib/aspera/rest_errors_aspera.rb +58 -0
  84. data/lib/aspera/ssh.rb +53 -0
  85. data/lib/aspera/sync.rb +82 -0
  86. data/lib/aspera/temp_file_manager.rb +37 -0
  87. data/lib/aspera/uri_reader.rb +25 -0
  88. metadata +288 -0
@@ -0,0 +1,35 @@
1
+ module Aspera
2
+ module Preview
3
+ # generator options. Used as parameter to preview generator object.
4
+ # also settable by command line.
5
+ class Options
6
+ # types of generation for video files
7
+ VIDEO_CONVERSION_METHODS=[:reencode,:blend,:clips]
8
+ VIDEO_THUMBNAIL_METHODS=[:fixed,:animated]
9
+ # options used in generator
10
+ # for scaling see: https://trac.ffmpeg.org/wiki/Scaling
11
+ # iw/ih : input width or height
12
+ # -x : keep aspect ratio, having value a multiple of x
13
+ DESCRIPTIONS = [
14
+ { name: :max_size, default: 1<<24, description: "maximum size (in bytes) of preview file" },
15
+ { name: :thumb_vid_scale, default: "-1:'min(ih,100)'", description: "png: video: size (ffmpeg scale argument)" },
16
+ { name: :thumb_vid_fraction, default: 0.1, description: "png: video: position of snapshot" },
17
+ { name: :thumb_img_size, default: 800, description: "png: non-video: height (and width)" },
18
+ { name: :video_conversion, default: :reencode, description: "mp4: method for preview generation", :values => VIDEO_CONVERSION_METHODS },
19
+ { name: :video_png_conv, default: :fixed, description: "mp4: method for thumbnail generation", :values => VIDEO_THUMBNAIL_METHODS },
20
+ { name: :video_start_sec, default: 10, description: "mp4: start offset (seconds) of video preview" },
21
+ { name: :video_scale, default: "'min(iw,360)':-2", description: "mp4: video scale (ffmpeg)" },
22
+ { name: :blend_keyframes, default: 30, description: "mp4: blend: # key frames" },
23
+ { name: :blend_pauseframes, default: 3, description: "mp4: blend: # pause frames" },
24
+ { name: :blend_transframes, default: 5, description: "mp4: blend: # transition blend frames" },
25
+ { name: :blend_fps, default: 15, description: "mp4: blend: frame per second" },
26
+ { name: :clips_count, default: 5, description: "mp4: clips: number of clips" },
27
+ { name: :clips_length, default: 5, description: "mp4: clips: length in seconds of each clips" },
28
+ ]
29
+ # add accessors
30
+ DESCRIPTIONS.each do |opt|
31
+ attr_accessor opt[:name]
32
+ end
33
+ end # Options
34
+ end # Preview
35
+ end # Aspera
@@ -0,0 +1,131 @@
1
+ require 'tmpdir'
2
+ require 'fileutils'
3
+ require 'aspera/log'
4
+ require 'open3'
5
+
6
+ module Aspera
7
+ module Preview
8
+ class Utils
9
+ # from bash manual: meta-character need to be escaped
10
+ BASH_SPECIAL_CHARACTERS="|&;()<> \t#\n"
11
+ # shell exit code when command is not found
12
+ BASH_EXIT_NOT_FOUND=127
13
+ # external binaries used
14
+ EXPERNAL_TOOLS=[:ffmpeg,:ffprobe,:convert,:composite,:optipng,:unoconv]
15
+ private_constant :BASH_SPECIAL_CHARACTERS,:BASH_EXIT_NOT_FOUND,:EXPERNAL_TOOLS
16
+
17
+ # returns string with single quotes suitable for bash if there is any bash metacharacter
18
+ def self.shell_quote(argument)
19
+ return argument unless argument.split('').any?{|c|BASH_SPECIAL_CHARACTERS.include?(c)}
20
+ return "'"+argument.gsub(/'/){|s| "'\"'\"'"}+"'"
21
+ end
22
+
23
+ # check that external tools can be executed
24
+ def self.check_tools(skip_types=[])
25
+ EXPERNAL_TOOLS.delete(:unoconv) if skip_types.include?(:office)
26
+ # Check for binaries
27
+ EXPERNAL_TOOLS.map{|i|i.to_s}.each do |bin|
28
+ `#{bin} -h 2>&1`
29
+ raise "Error: #{bin} is not in the PATH" if $?.exitstatus.eql?(BASH_EXIT_NOT_FOUND)
30
+ end
31
+ end
32
+
33
+ # execute external command
34
+ # one could use "system", but we would need to redirect stdout/err
35
+ # @return true if su
36
+ def self.external_command(command_symb,command_args,stdout_return=nil)
37
+ raise "unexpected command #{command_symb}" unless EXPERNAL_TOOLS.include?(command_symb)
38
+ # build command line, and quote special characters
39
+ command=command_args.clone.unshift(command_symb).map{|i| shell_quote(i.to_s)}.join(' ')
40
+ Log.log.debug("cmd=#{command}".blue)
41
+ # capture3: only in ruby2+
42
+ if Open3.respond_to?('capture3') then
43
+ stdout, stderr, exit_status = Open3.capture3(command)
44
+ else
45
+ stderr='<merged with stdout>'
46
+ stdout=%x[#{command} 2>&1]
47
+ exit_status=$?
48
+ end
49
+ if BASH_EXIT_NOT_FOUND.eql?(exit_status)
50
+ raise "Error: #{bin} is not in the PATH"
51
+ end
52
+ unless exit_status.success?
53
+ Log.log.error("commandline: #{command}")
54
+ Log.log.error("Error code: #{exit_status}")
55
+ Log.log.error("stdout: #{stdout}")
56
+ Log.log.error("stderr: #{stderr}")
57
+ raise "command returned error"
58
+ end
59
+ stdout_return.replace(stdout) unless stdout_return.nil?
60
+ return exit_status.success?
61
+ end
62
+
63
+ def self.ffmpeg(a)
64
+ raise "error: hash expected" unless a.is_a?(Hash)
65
+ #input_file,input_args,output_file,output_args
66
+ a[:gl_p]||=[
67
+ '-y', # overwrite output without asking
68
+ '-loglevel','error', # show only errors and up]
69
+ ]
70
+ a[:in_p]||=[]
71
+ a[:out_p]||=[]
72
+ raise "wrong params (#{a.keys.sort})" unless [:gl_p, :in_f, :in_p, :out_f, :out_p].eql?(a.keys.sort)
73
+ external_command(:ffmpeg,[a[:gl_p],a[:in_p],'-i',a[:in_f],a[:out_p],a[:out_f]].flatten)
74
+ end
75
+
76
+ def self.video_get_duration(input_file)
77
+ result = String.new
78
+ external_command(:ffprobe,[
79
+ '-loglevel','error',
80
+ '-show_entries','format=duration',
81
+ '-print_format','default=noprint_wrappers=1:nokey=1',
82
+ input_file],result)
83
+ result.to_f
84
+ end
85
+
86
+ TMPFMT='img%04d.jpg'
87
+
88
+ def self.ffmpeg_fmt(temp_folder)
89
+ return File.join(temp_folder,TMPFMT)
90
+ end
91
+
92
+ def self.get_tmp_num_filepath(temp_folder, file_number)
93
+ return File.join(temp_folder,sprintf(TMPFMT,file_number))
94
+ end
95
+
96
+ def self.video_dupe_frame(temp_folder, index, count)
97
+ input_file=get_tmp_num_filepath(temp_folder,index)
98
+ 1.upto(count) do |i|
99
+ FileUtils.ln_s(input_file,get_tmp_num_filepath(temp_folder,index+i))
100
+ end
101
+ end
102
+
103
+ def self.video_blend_frames(temp_folder, index1, index2)
104
+ img1=get_tmp_num_filepath(temp_folder,index1)
105
+ img2=get_tmp_num_filepath(temp_folder,index2)
106
+ count=index2-index1-1
107
+ 1.upto(count) do |i|
108
+ percent = 100 * i / (count + 1)
109
+ filename = get_tmp_num_filepath(temp_folder, index1 + i)
110
+ external_command(:composite,['-blend',percent,img2,img1,filename])
111
+ end
112
+ end
113
+
114
+ def self.video_dump_frame(input_file, offset_seconds, scale, output_file, index=nil)
115
+ output_file=get_tmp_num_filepath(output_file,index) unless index.nil?
116
+ ffmpeg(
117
+ in_f: input_file,
118
+ in_p: ['-ss',offset_seconds],
119
+ out_f: output_file,
120
+ out_p: ['-frames:v',1,'-filter:v',"scale=#{scale}"])
121
+ return output_file
122
+ end
123
+
124
+ def message_to_png(message)
125
+ # convert -size 400x -background '#666666' -fill '#ffffff' -interword-spacing 10 -kerning 4 -pointsize 10 -gravity West -size x22 label:"Lorem dolor sit amet" -flatten xxx.png
126
+ external_command(:convert,[
127
+ ])
128
+ end
129
+ end # Options
130
+ end # Preview
131
+ end # Aspera
@@ -0,0 +1,287 @@
1
+ // inspired by PACSuppport.js, 2003-2004 by Apple Computer, Inc., all rights reserved
2
+ function dnsResolve(host) {
3
+ if (host == '<%=context_host%>' || host == '<%=context_ip%>')
4
+ return '<%=context_ip%>';
5
+ throw 'only DNS for initial host, not '+host;
6
+ }
7
+ function myIpAddress() {
8
+ return '<%=context_self%>';
9
+ }
10
+ function isPlainHostName(host) {
11
+ return (host.indexOf('.') == -1 ? true : false);
12
+ }
13
+ function dnsDomainIs(host, domain) {
14
+ var h = host.toLowerCase();
15
+ var d = domain.toLowerCase();
16
+ var sub = h.substring(h.length - d.length, h.length);
17
+ if (sub == d)
18
+ return true;
19
+ return false;
20
+ }
21
+ function localHostOrDomainIs(host, hostdom) {
22
+ var h1 = host.toLowerCase();
23
+ var h2 = hostdom.toLowerCase();
24
+ return ((h1 == h2) || (isPlainHostName(h1) & !isPlainHostName(h2))) ? true : false;
25
+ }
26
+ function isResolvable(host) {
27
+ var ip = dnsResolve(host);
28
+ return ((typeof ip == "string") && ip.length) ? true : false;
29
+ }
30
+ function isInNet(host, pattern, mask) {
31
+ var ip = dnsResolve(host);
32
+ if (ip) {
33
+ var p = pattern.split('.');
34
+ var m = mask.split('.');
35
+ var a = ip.split('.');
36
+ if ((p.length == m.length) && (m.length == a.length)) {
37
+ for (i = 0; i < p.length; i++) {
38
+ if ((p[i]& m[i]) != (m[i]& a[i]))
39
+ return false;
40
+ }
41
+ return true;
42
+ }
43
+ }
44
+ return false;
45
+ }
46
+ function dnsDomainLevels(host) {
47
+ var parts = host.split('.');
48
+ return parts.length - 1;
49
+ }
50
+ function shExpMatch(str, shexp) {
51
+ if (typeof str != "string" || typeof shexp != "string")
52
+ return false;
53
+ if (shexp == "*")
54
+ return true;
55
+ if (str == "" && shexp == "")
56
+ return true;
57
+ str = str.toLowerCase();
58
+ shexp = shexp.toLowerCase();
59
+ var len = str.length;
60
+ var pieces = shexp.split('*');
61
+ var start = 0;
62
+ for (i = 0; i < pieces.length; i++) {
63
+ if (pieces[i] == "")
64
+ continue;
65
+ if (start > len)
66
+ return false;
67
+ start = str.indexOf(pieces[i]);
68
+ if (start == -1)
69
+ return false;
70
+ start += pieces[i].length;
71
+ str = str.substring(start, len);
72
+ len = str.length;
73
+ }
74
+ i--;
75
+ if ((pieces[i] == "") || (str == ""))
76
+ return true;
77
+ return false;
78
+ }
79
+ function weekdayRange(wd1, wd2, gmt) {
80
+ var today = new Date();
81
+ var days = "SUNMONTUEWEDTHUFRISAT";
82
+ wd1 = wd1.toUpperCase();
83
+ if (wd2 == undefined)
84
+ wd2 = wd1;
85
+ else
86
+ wd2 = wd2.toUpperCase();
87
+ var d1 = days.indexOf(wd1);
88
+ var d2 = days.indexOf(wd2);
89
+ if ((d2 == -1) && (wd2 == "GMT")) {
90
+ gmt = wd2;
91
+ d2 = d1;
92
+ }
93
+ if ((d1 == -1) || (d2 == -1))
94
+ return false;
95
+ d1 = d1 / 3;
96
+ d2 = d2 / 3;
97
+ if (gmt == "GMT")
98
+ today = today.getUTCDay();
99
+ else
100
+ today = today.getDay();
101
+ if ((d1 <= d2) && (today >= d1) && (today <= d2))
102
+ return true;
103
+ if ((d2 < d1) && ((today <= d2) || (today >= d1)))
104
+ return true;
105
+ return false;
106
+ }
107
+ function dateRange() {
108
+ var today = new Date();
109
+ var num = arguments.length;
110
+ var gmt = arguments[num - 1];
111
+ if (typeof gmt != "string")
112
+ gmt = false;
113
+ else {
114
+ gmt = gmt.toUpperCase();
115
+ if (gmt != "GMT")
116
+ gmt = false;
117
+ else {
118
+ gmt = true;
119
+ num--;
120
+ }
121
+ }
122
+ if (!num || (num > 6))
123
+ return false;
124
+ var d1 = 0;
125
+ var d2 = 0;
126
+ var m1 = 0;
127
+ var m2 = 0;
128
+ var y1 = 0;
129
+ var y2 = 0;
130
+ for (i = 0; i < num; i++) {
131
+ var arg = arguments[i];
132
+ if (typeof arg == "number") {
133
+ if (arg > 31) {
134
+ if (!y1)
135
+ y1 = arg;
136
+ else if (!y2)
137
+ y2 = arg;
138
+ else
139
+ return false;
140
+ }
141
+ else if (!arg)
142
+ return false;
143
+ else if (!d1)
144
+ d1 = arg;
145
+ else if (!d2)
146
+ d2 = arg;
147
+ else
148
+ return false;
149
+ }
150
+ else if (typeof arg == "string") {
151
+ var months = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
152
+ arg = arg.toUpperCase();
153
+ arg = months.indexOf(arg);
154
+ if (arg == -1)
155
+ return false;
156
+ arg /= 3;
157
+ arg += 1;
158
+ if (!m1)
159
+ m1 = arg;
160
+ else if (!m2)
161
+ m2 = arg;
162
+ else
163
+ return false;
164
+ }
165
+ else
166
+ return false;
167
+ }
168
+ if (!y1) y1 = gmt ? today.getUTCFullYear() : today.getFullYear();
169
+ if (!y2) y2 = y1;
170
+ if (!m1) m1 = (gmt ? today.getUTCMonth() : today.getMonth()) + 1;
171
+ if (!m2) m2 = m1;
172
+ if (!d1) d1 = gmt ? today.getUTCDate() : today.getDate();
173
+ if (!d2) d2 = d1;
174
+ var date1;
175
+ var date2;
176
+ if (gmt) {
177
+ date1 = Date.UTC(y1, m1 - 1, d1, 0, 0, 0, 0);
178
+ date2 = Date.UTC(y2, m2 - 1, d2, 23, 59, 59, 999);
179
+ }
180
+ else {
181
+ date1 = (Date(y1, m1 - 1, d1, 0, 0, 0, 0)).valueOf();
182
+ date2 = (Date(y2, m2 - 1, d2, 23, 59, 59, 999)).valueOf();
183
+ }
184
+ today = today.valueOf();
185
+ return ((date1 <= today) && (today <= date2));
186
+ }
187
+ function timeRange() {
188
+ var date1 = new Date();
189
+ var today = new Date();
190
+ var date2 = new Date();
191
+ var num = arguments.length;
192
+ var gmt = arguments[num - 1];
193
+ if (typeof gmt != "string")
194
+ gmt = false;
195
+ else {
196
+ gmt = gmt.toUpperCase();
197
+ if (gmt != "GMT")
198
+ gmt = false;
199
+ else {
200
+ gmt = true;
201
+ num--;
202
+ }
203
+ }
204
+ if (!num || (num > 6) || ((num % 2) && (num != 1)))
205
+ return false;
206
+ date1.setMinutes(0);
207
+ date1.setSeconds(0);
208
+ date1.setMilliseconds(0);
209
+ date2.setMinutes(59);
210
+ date2.setSeconds(59);
211
+ date2.setMilliseconds(999);
212
+ for (i = 0; i < (num / 2); i++) {
213
+ var arg = arguments[i];
214
+ if (gmt) {
215
+ switch (i) {
216
+ case 0:
217
+ date1.setUTCHours(arg);
218
+ date2.setUTCHours(arg);
219
+ break;
220
+ case 1:
221
+ date1.setUTCMinutes(arg);
222
+ date2.setUTCMinutes(arg);
223
+ break;
224
+ case 2:
225
+ date1.setUTCSeconds(arg);
226
+ date2.setUTCSeconds(arg);
227
+ break;
228
+ }
229
+ }
230
+ else {
231
+ switch (i) {
232
+ case 0:
233
+ date1.setHours(arg);
234
+ date2.setHours(arg);
235
+ break;
236
+ case 1:
237
+ date1.setMinutes(arg);
238
+ date2.setMinutes(arg);
239
+ break;
240
+ case 2:
241
+ date1.setSeconds(arg);
242
+ date2.setSeconds(arg);
243
+ break;
244
+ }
245
+ }
246
+ }
247
+ if (num != 1) {
248
+ date2.setMinutes(0);
249
+ date2.setSeconds(0);
250
+ date2.setMilliseconds(0);
251
+ for (i = 0; i < (num / 2); i++) {
252
+ var arg = arguments[(num / 2) + i];
253
+ if (gmt) {
254
+ switch (i) {
255
+ case 0:
256
+ date2.setUTCHours(arg);
257
+ break;
258
+ case 1:
259
+ date2.setUTCMinutes(arg);
260
+ break;
261
+ case 2:
262
+ date2.setUTCSeconds(arg);
263
+ break;
264
+ }
265
+ }
266
+ else {
267
+ switch (i) {
268
+ case 0:
269
+ date2.setHours(arg);
270
+ break;
271
+ case 1:
272
+ date2.setMinutes(arg);
273
+ break;
274
+ case 2:
275
+ date2.setSeconds(arg);
276
+ break;
277
+ }
278
+ }
279
+ }
280
+ }
281
+ today = today.valueOf();
282
+ date1 = date1.valueOf();
283
+ date2 = date2.valueOf();
284
+ if (date2 < date1)
285
+ date2 += 86400000;
286
+ return ((date1 <= today) && (today <= date2));
287
+ }