aspera-cli 4.6.0 → 4.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +427 -300
- data/bin/ascli +2 -1
- data/bin/asession +1 -0
- data/docs/test_env.conf +2 -0
- data/examples/aoc.rb +4 -3
- data/examples/faspex4.rb +21 -19
- data/examples/proxy.pac +1 -1
- data/examples/transfer.rb +15 -15
- data/lib/aspera/aoc.rb +135 -124
- data/lib/aspera/ascmd.rb +85 -75
- data/lib/aspera/ats_api.rb +11 -10
- data/lib/aspera/cli/basic_auth_plugin.rb +13 -14
- data/lib/aspera/cli/extended_value.rb +42 -33
- data/lib/aspera/cli/formater.rb +138 -111
- data/lib/aspera/cli/info.rb +17 -0
- data/lib/aspera/cli/listener/line_dump.rb +3 -2
- data/lib/aspera/cli/listener/logger.rb +2 -1
- data/lib/aspera/cli/listener/progress.rb +16 -18
- data/lib/aspera/cli/listener/progress_multi.rb +13 -16
- data/lib/aspera/cli/main.rb +122 -130
- data/lib/aspera/cli/manager.rb +146 -154
- data/lib/aspera/cli/plugin.rb +38 -34
- data/lib/aspera/cli/plugins/alee.rb +6 -6
- data/lib/aspera/cli/plugins/aoc.rb +273 -276
- data/lib/aspera/cli/plugins/ats.rb +82 -76
- data/lib/aspera/cli/plugins/bss.rb +14 -16
- data/lib/aspera/cli/plugins/config.rb +350 -306
- data/lib/aspera/cli/plugins/console.rb +23 -19
- data/lib/aspera/cli/plugins/cos.rb +18 -18
- data/lib/aspera/cli/plugins/faspex.rb +180 -159
- data/lib/aspera/cli/plugins/faspex5.rb +64 -54
- data/lib/aspera/cli/plugins/node.rb +147 -140
- data/lib/aspera/cli/plugins/orchestrator.rb +68 -66
- data/lib/aspera/cli/plugins/preview.rb +92 -96
- data/lib/aspera/cli/plugins/server.rb +79 -75
- data/lib/aspera/cli/plugins/shares.rb +23 -24
- data/lib/aspera/cli/plugins/sync.rb +20 -22
- data/lib/aspera/cli/transfer_agent.rb +40 -39
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +35 -27
- data/lib/aspera/command_line_builder.rb +48 -34
- data/lib/aspera/cos_node.rb +29 -21
- data/lib/aspera/data_repository.rb +3 -2
- data/lib/aspera/environment.rb +50 -45
- data/lib/aspera/fasp/agent_base.rb +22 -20
- data/lib/aspera/fasp/agent_connect.rb +13 -11
- data/lib/aspera/fasp/agent_direct.rb +48 -59
- data/lib/aspera/fasp/agent_httpgw.rb +33 -39
- data/lib/aspera/fasp/agent_node.rb +15 -13
- data/lib/aspera/fasp/agent_trsdk.rb +12 -14
- data/lib/aspera/fasp/error.rb +2 -1
- data/lib/aspera/fasp/error_info.rb +68 -52
- data/lib/aspera/fasp/installation.rb +106 -94
- data/lib/aspera/fasp/listener.rb +1 -0
- data/lib/aspera/fasp/parameters.rb +83 -92
- data/lib/aspera/fasp/parameters.yaml +305 -249
- data/lib/aspera/fasp/resume_policy.rb +11 -14
- data/lib/aspera/fasp/transfer_spec.rb +26 -0
- data/lib/aspera/fasp/uri.rb +22 -21
- data/lib/aspera/faspex_gw.rb +55 -90
- data/lib/aspera/hash_ext.rb +4 -3
- data/lib/aspera/id_generator.rb +8 -7
- data/lib/aspera/keychain/encrypted_hash.rb +17 -16
- data/lib/aspera/keychain/macos_security.rb +6 -10
- data/lib/aspera/log.rb +25 -20
- data/lib/aspera/nagios.rb +13 -12
- data/lib/aspera/node.rb +30 -22
- data/lib/aspera/oauth.rb +175 -226
- data/lib/aspera/open_application.rb +4 -3
- data/lib/aspera/persistency_action_once.rb +6 -6
- data/lib/aspera/persistency_folder.rb +5 -9
- data/lib/aspera/preview/file_types.rb +6 -5
- data/lib/aspera/preview/generator.rb +25 -24
- data/lib/aspera/preview/options.rb +16 -14
- data/lib/aspera/preview/utils.rb +98 -98
- data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
- data/lib/aspera/proxy_auto_config.rb +111 -20
- data/lib/aspera/rest.rb +115 -113
- data/lib/aspera/rest_call_error.rb +2 -2
- data/lib/aspera/rest_error_analyzer.rb +23 -25
- data/lib/aspera/rest_errors_aspera.rb +15 -14
- data/lib/aspera/ssh.rb +12 -10
- data/lib/aspera/sync.rb +42 -41
- data/lib/aspera/temp_file_manager.rb +18 -14
- data/lib/aspera/timer_limiter.rb +2 -1
- data/lib/aspera/uri_reader.rb +7 -5
- data/lib/aspera/web_auth.rb +79 -76
- metadata +64 -21
- data/docs/Makefile +0 -65
- data/docs/README.erb.md +0 -4424
- data/docs/README.md +0 -13
- data/docs/diagrams.txt +0 -49
- data/docs/doc_tools.rb +0 -58
- data/lib/aspera/cli/plugins/shares2.rb +0 -114
- data/lib/aspera/fasp/default.rb +0 -17
data/lib/aspera/cli/formater.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require 'terminal-table'
|
3
|
-
|
4
|
-
#require 'fileutils'
|
5
3
|
require 'yaml'
|
6
4
|
require 'pp'
|
7
5
|
|
@@ -12,41 +10,96 @@ module Aspera
|
|
12
10
|
FIELDS_ALL='ALL'
|
13
11
|
FIELDS_DEFAULT='DEF'
|
14
12
|
# supported output formats
|
15
|
-
DISPLAY_FORMATS
|
13
|
+
DISPLAY_FORMATS=%i[table ruby json jsonpp yaml csv nagios]
|
16
14
|
# user output levels
|
17
15
|
DISPLAY_LEVELS=[:info,:data,:error]
|
18
16
|
CSV_RECORD_SEPARATOR="\n"
|
19
|
-
CSV_FIELD_SEPARATOR=
|
17
|
+
CSV_FIELD_SEPARATOR=','
|
18
|
+
HIDDEN_PASSWORD='🔑'
|
19
|
+
SECRET_KEYWORDS=%w[password secret private_key]
|
20
|
+
|
21
|
+
private_constant :FIELDS_ALL,:FIELDS_DEFAULT,:DISPLAY_FORMATS,:DISPLAY_LEVELS,:CSV_RECORD_SEPARATOR,:CSV_FIELD_SEPARATOR,:HIDDEN_PASSWORD
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
+
class<<self
|
24
|
+
# @param source [Hash] hash to modify
|
25
|
+
# @param keep_last [bool]
|
26
|
+
def flatten_object(source,keep_last)
|
27
|
+
newval={}
|
28
|
+
flatten_sub_hash_rec(source,keep_last,'',newval)
|
29
|
+
source.clear
|
30
|
+
source.merge!(newval)
|
31
|
+
end
|
23
32
|
|
33
|
+
# recursive function to modify a hash
|
34
|
+
# @param source [Hash] to be modified
|
35
|
+
# @param keep_last [bool] truer if last level is not
|
36
|
+
# @param prefix [String] true if last level is not
|
37
|
+
# @param dest [Hash] new hash flattened
|
38
|
+
def flatten_sub_hash_rec(source,keep_last,prefix,dest)
|
39
|
+
#is_simple_hash=source.is_a?(Hash) and source.values.inject(true){|m,v| xxx=!v.respond_to?(:each) and m;puts("->#{xxx}>#{v.respond_to?(:each)} #{v}-");xxx}
|
40
|
+
is_simple_hash=false
|
41
|
+
Log.log.debug("(#{keep_last})[#{is_simple_hash}] -#{source.values}- \n-#{source}-")
|
42
|
+
return source if keep_last && is_simple_hash
|
43
|
+
source.each do |k,v|
|
44
|
+
if v.is_a?(Hash) && (!keep_last || !is_simple_hash)
|
45
|
+
flatten_sub_hash_rec(v,keep_last,prefix+k.to_s+'.',dest)
|
46
|
+
else
|
47
|
+
dest[prefix+k.to_s]=v
|
48
|
+
end
|
49
|
+
end
|
50
|
+
return nil
|
51
|
+
end
|
52
|
+
|
53
|
+
# special for Aspera on Cloud display node
|
54
|
+
# {"param" => [{"name"=>"foo","value"=>"bar"}]} will be expanded to {"param.foo" : "bar"}
|
55
|
+
def flatten_name_value_list(hash)
|
56
|
+
hash.keys.each do |k|
|
57
|
+
v=hash[k]
|
58
|
+
next unless v.is_a?(Array) && v.map(&:class).uniq.eql?([Hash]) && v.map(&:keys).flatten.sort.uniq.eql?(['name', 'value'])
|
59
|
+
v.each do |pair|
|
60
|
+
hash["#{k}.#{pair['name']}"]=pair['value']
|
61
|
+
end
|
62
|
+
hash.delete(k)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
attr_accessor :option_flat_hash,:option_transpose_single,:option_format,:option_display,:option_fields,:option_table_style,:option_select,:option_show_secrets
|
68
|
+
|
69
|
+
# adds options but does not parse
|
24
70
|
def initialize(opt_mgr)
|
71
|
+
@option_format=:table
|
72
|
+
@option_display=:info
|
73
|
+
@option_fields=FIELDS_DEFAULT
|
74
|
+
@option_select=nil
|
75
|
+
@option_table_style=':.:'
|
25
76
|
@option_flat_hash=true
|
26
77
|
@option_transpose_single=true
|
27
|
-
@
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
78
|
+
@option_show_secrets=true
|
79
|
+
opt_mgr.set_obj_attr(:format,self,:option_format)
|
80
|
+
opt_mgr.set_obj_attr(:display,self,:option_display)
|
81
|
+
opt_mgr.set_obj_attr(:fields,self,:option_fields)
|
82
|
+
opt_mgr.set_obj_attr(:select,self,:option_select)
|
83
|
+
opt_mgr.set_obj_attr(:table_style,self,:option_table_style)
|
84
|
+
opt_mgr.set_obj_attr(:flat_hash,self,:option_flat_hash)
|
85
|
+
opt_mgr.set_obj_attr(:transpose_single,self,:option_transpose_single)
|
86
|
+
opt_mgr.set_obj_attr(:show_secrets,self,:option_show_secrets)
|
87
|
+
opt_mgr.add_opt_list(:format,DISPLAY_FORMATS,'output format')
|
88
|
+
opt_mgr.add_opt_list(:display,DISPLAY_LEVELS,'output only some information')
|
89
|
+
opt_mgr.add_opt_simple(:fields,"comma separated list of fields, or #{FIELDS_ALL}, or #{FIELDS_DEFAULT}")
|
90
|
+
opt_mgr.add_opt_simple(:select,'select only some items in lists, extended value: hash (column, value)')
|
91
|
+
opt_mgr.add_opt_simple(:table_style,'table display style')
|
92
|
+
opt_mgr.add_opt_boolean(:flat_hash,'display hash values as additional keys')
|
93
|
+
opt_mgr.add_opt_boolean(:transpose_single,'single object fields output vertically')
|
94
|
+
opt_mgr.add_opt_boolean(:show_secrets,'show secrets on command output')
|
41
95
|
end
|
42
96
|
|
43
97
|
# main output method
|
44
98
|
def display_message(message_level,message)
|
45
|
-
display_level=@opt_mgr.get_option(:display,:mandatory)
|
46
99
|
case message_level
|
47
|
-
when :info
|
48
|
-
when :data
|
49
|
-
when :error
|
100
|
+
when :info then $stdout.puts(message) if @option_display.eql?(:info)
|
101
|
+
when :data then $stdout.puts(message) unless @option_display.eql?(:error)
|
102
|
+
when :error then $stderr.puts(message)
|
50
103
|
else raise "wrong message_level:#{message_level}"
|
51
104
|
end
|
52
105
|
end
|
@@ -55,77 +108,51 @@ module Aspera
|
|
55
108
|
display_message(:info,status)
|
56
109
|
end
|
57
110
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
source.merge!(newval)
|
65
|
-
end
|
66
|
-
|
67
|
-
# recursive function to modify a hash
|
68
|
-
# @param source [Hash] to be modified
|
69
|
-
# @param keep_last [bool] truer if last level is not
|
70
|
-
# @param prefix [String] true if last level is not
|
71
|
-
# @param dest [Hash] new hash flattened
|
72
|
-
def self.flatten_sub_hash_rec(source,keep_last,prefix,dest)
|
73
|
-
#is_simple_hash=source.is_a?(Hash) and source.values.inject(true){|m,v| xxx=!v.respond_to?(:each) and m;puts("->#{xxx}>#{v.respond_to?(:each)} #{v}-");xxx}
|
74
|
-
is_simple_hash=false
|
75
|
-
Log.log.debug("(#{keep_last})[#{is_simple_hash}] -#{source.values}- \n-#{source}-")
|
76
|
-
return source if keep_last and is_simple_hash
|
77
|
-
source.each do |k,v|
|
78
|
-
if v.is_a?(Hash) and ( !keep_last or !is_simple_hash )
|
79
|
-
flatten_sub_hash_rec(v,keep_last,prefix+k.to_s+'.',dest)
|
80
|
-
else
|
81
|
-
dest[prefix+k.to_s]=v
|
111
|
+
def result_default_fields(results,table_rows_hash_val)
|
112
|
+
unless results[:fields].nil?
|
113
|
+
raise "internal error: [fields] must be Array, not #{results[:fields].class}" unless results[:fields].is_a?(Array)
|
114
|
+
if results[:fields].first.eql?(:all_but) && !table_rows_hash_val.empty?
|
115
|
+
filter=results[:fields][1..-1]
|
116
|
+
return table_rows_hash_val.first.keys.reject{|i|filter.include?(i)}
|
82
117
|
end
|
118
|
+
return results[:fields]
|
83
119
|
end
|
84
|
-
return
|
120
|
+
return ['empty'] if table_rows_hash_val.empty?
|
121
|
+
return table_rows_hash_val.first.keys
|
85
122
|
end
|
86
123
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
v=hash[k]
|
92
|
-
if v.is_a?(Array) and v.map{|i|i.class}.uniq.eql?([Hash]) and v.map{|i|i.keys}.flatten.sort.uniq.eql?(["name", "value"])
|
93
|
-
v.each do |pair|
|
94
|
-
hash["#{k}.#{pair["name"]}"]=pair["value"]
|
95
|
-
end
|
96
|
-
hash.delete(k)
|
97
|
-
end
|
98
|
-
end
|
124
|
+
def result_all_fields(_results,table_rows_hash_val)
|
125
|
+
raise 'internal error: must be array' unless table_rows_hash_val.is_a?(Array)
|
126
|
+
# get the list of all column names used in all lines, not just frst one, as all lines may have different columns
|
127
|
+
return table_rows_hash_val.each_with_object({}){|v,m|v.keys.each{|c|m[c]=true};}.keys
|
99
128
|
end
|
100
129
|
|
101
|
-
def
|
102
|
-
if
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
130
|
+
def deep_remove_secret(obj)
|
131
|
+
return if @option_show_secrets
|
132
|
+
case obj
|
133
|
+
when Array then obj.each{|i|deep_remove_secret(i)}
|
134
|
+
when Hash
|
135
|
+
obj.keys.each do |k|
|
136
|
+
next if %w[show_secrets log_secrets].any?{|kw|kw.eql?(k)}
|
137
|
+
if k.is_a?(String) && SECRET_KEYWORDS.any?{|kw|k.include?(kw)}
|
138
|
+
obj[k]=HIDDEN_PASSWORD
|
139
|
+
elsif obj[k].is_a?(Hash)
|
140
|
+
deep_remove_secret(obj[k])
|
141
|
+
end
|
109
142
|
end
|
110
143
|
end
|
111
144
|
end
|
112
145
|
|
113
|
-
def result_all_fields(results,table_rows_hash_val)
|
114
|
-
raise "internal error: must be array" unless table_rows_hash_val.is_a?(Array)
|
115
|
-
# get the list of all column names used in all lines, not just frst one, as all lines may have different columns
|
116
|
-
return table_rows_hash_val.inject({}){|m,v|v.keys.each{|c|m[c]=true};m}.keys
|
117
|
-
end
|
118
|
-
|
119
146
|
# this method displays the results, especially the table format
|
120
147
|
def display_results(results)
|
121
148
|
raise "INTERNAL ERROR, result must be Hash (got: #{results.class}: #{results})" unless results.is_a?(Hash)
|
122
|
-
raise
|
123
|
-
raise
|
149
|
+
raise 'INTERNAL ERROR, result must have type' unless results.has_key?(:type)
|
150
|
+
raise 'INTERNAL ERROR, result must have data' unless results.has_key?(:data) || [:empty,:nothing].include?(results[:type])
|
124
151
|
res_data=results[:data]
|
152
|
+
deep_remove_secret(res_data)
|
125
153
|
# comma separated list in string format
|
126
|
-
user_asked_fields_list_str=@
|
127
|
-
|
128
|
-
case display_format
|
154
|
+
user_asked_fields_list_str=@option_fields
|
155
|
+
case @option_format
|
129
156
|
when :nagios
|
130
157
|
Nagios.process(res_data)
|
131
158
|
when :ruby
|
@@ -137,7 +164,7 @@ module Aspera
|
|
137
164
|
when :yaml
|
138
165
|
display_message(:data,res_data.to_yaml)
|
139
166
|
when :table,:csv
|
140
|
-
if !@option_transpose_single
|
167
|
+
if !@option_transpose_single && results[:type].eql?(:single_object)
|
141
168
|
results[:type]=:object_list
|
142
169
|
res_data=[res_data]
|
143
170
|
end
|
@@ -152,14 +179,15 @@ module Aspera
|
|
152
179
|
self.class.flatten_object(obj,results[:option_expand_last])
|
153
180
|
end
|
154
181
|
end
|
155
|
-
final_table_columns=
|
156
|
-
|
157
|
-
when
|
182
|
+
final_table_columns=
|
183
|
+
case user_asked_fields_list_str
|
184
|
+
when FIELDS_DEFAULT then result_default_fields(results,table_rows_hash_val)
|
185
|
+
when FIELDS_ALL then result_all_fields(results,table_rows_hash_val)
|
158
186
|
else
|
159
187
|
if user_asked_fields_list_str.start_with?('+')
|
160
188
|
result_default_fields(results,table_rows_hash_val).push(*user_asked_fields_list_str.gsub(/^\+/,'').split(','))
|
161
189
|
elsif user_asked_fields_list_str.start_with?('-')
|
162
|
-
result_default_fields(results,table_rows_hash_val).
|
190
|
+
result_default_fields(results,table_rows_hash_val).reject{|i| user_asked_fields_list_str.gsub(/^-/,'').split(',').include?(i)}
|
163
191
|
else
|
164
192
|
user_asked_fields_list_str.split(',')
|
165
193
|
end
|
@@ -172,13 +200,14 @@ module Aspera
|
|
172
200
|
self.class.flatten_object(res_data,results[:option_expand_last])
|
173
201
|
self.class.flatten_name_value_list(res_data)
|
174
202
|
end
|
175
|
-
asked_fields=
|
176
|
-
|
177
|
-
when
|
178
|
-
|
203
|
+
asked_fields=
|
204
|
+
case user_asked_fields_list_str
|
205
|
+
when FIELDS_DEFAULT then results[:fields]||res_data.keys
|
206
|
+
when FIELDS_ALL then res_data.keys
|
207
|
+
else user_asked_fields_list_str.split(',')
|
179
208
|
end
|
180
209
|
table_rows_hash_val=asked_fields.map { |i| { final_table_columns.first => i, final_table_columns.last => res_data[i] } }
|
181
|
-
when :value_list
|
210
|
+
when :value_list # goes to table display
|
182
211
|
# :value_list is a simple array of values, name of column provided in the :name
|
183
212
|
final_table_columns = [results[:name]]
|
184
213
|
table_rows_hash_val=res_data.map { |i| { results[:name] => i } }
|
@@ -186,7 +215,7 @@ module Aspera
|
|
186
215
|
display_message(:info,'empty')
|
187
216
|
return
|
188
217
|
when :nothing # no result expected
|
189
|
-
Log.log.debug(
|
218
|
+
Log.log.debug('no result expected')
|
190
219
|
return
|
191
220
|
when :status # no table
|
192
221
|
# :status displays a simple message
|
@@ -204,39 +233,37 @@ module Aspera
|
|
204
233
|
raise "unknown data type: #{results[:type]}"
|
205
234
|
end
|
206
235
|
# here we expect: table_rows_hash_val and final_table_columns
|
207
|
-
raise
|
236
|
+
raise 'no field specified' if final_table_columns.nil?
|
208
237
|
if table_rows_hash_val.empty?
|
209
|
-
display_message(:info,'empty'.gray) unless
|
238
|
+
display_message(:info,'empty'.gray) unless @option_format.eql?(:csv)
|
210
239
|
return
|
211
240
|
end
|
212
241
|
# convert to string with special function. here table_rows_hash_val is an array of hash
|
213
242
|
table_rows_hash_val=results[:textify].call(table_rows_hash_val) if results.has_key?(:textify)
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
filter.each{|k,v|table_rows_hash_val.select!{|i|i[k].eql?(v)}}
|
243
|
+
unless @option_select.nil? || (@option_select.respond_to?('empty?') && @option_select.empty?)
|
244
|
+
raise CliBadArgument,"expecting hash for select, have #{@option_select.class}: #{@option_select}" unless @option_select.is_a?(Hash)
|
245
|
+
@option_select.each{|k,v|table_rows_hash_val.select!{|i|i[k].eql?(v)}}
|
218
246
|
end
|
219
|
-
|
220
247
|
# convert data to string, and keep only display fields
|
221
248
|
final_table_rows=table_rows_hash_val.map { |r| final_table_columns.map { |c| r[c].to_s } }
|
222
249
|
# here : final_table_columns : list of column names
|
223
250
|
# here: final_table_rows : array of list of value
|
224
|
-
case
|
251
|
+
case @option_format
|
225
252
|
when :table
|
226
|
-
style=@
|
253
|
+
style=@option_table_style.chars
|
227
254
|
# display the table !
|
228
255
|
#display_message(:data,Text::Table.new(
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
256
|
+
#head: final_table_columns,
|
257
|
+
#rows: final_table_rows,
|
258
|
+
#horizontal_boundary: style[0],
|
259
|
+
#vertical_boundary: style[1],
|
260
|
+
#boundary_intersection: style[2]))
|
234
261
|
display_message(:data,Terminal::Table.new(
|
235
|
-
:
|
236
|
-
:
|
237
|
-
:
|
238
|
-
:
|
239
|
-
:
|
262
|
+
headings: final_table_columns,
|
263
|
+
rows: final_table_rows,
|
264
|
+
border_x: style[0],
|
265
|
+
border_y: style[1],
|
266
|
+
border_i: style[2]))
|
240
267
|
when :csv
|
241
268
|
display_message(:data,final_table_rows.map{|t| t.join(CSV_FIELD_SEPARATOR)}.join(CSV_RECORD_SEPARATOR))
|
242
269
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Aspera
|
3
|
+
module Cli
|
4
|
+
# name of command line tool, also used as foldername where config is stored
|
5
|
+
PROGRAM_NAME = 'ascli'
|
6
|
+
# name of the containing gem, same as in <gem name>.gemspec
|
7
|
+
GEM_NAME = 'aspera-cli'
|
8
|
+
DOC_URL = "https://www.rubydoc.info/gems/#{GEM_NAME}"
|
9
|
+
GEM_URL = "https://rubygems.org/gems/#{GEM_NAME}"
|
10
|
+
SRC_URL = 'https://github.com/IBM/aspera-cli'
|
11
|
+
# set this to warn in advance when minimum required ruby version will increase
|
12
|
+
# for example currently minimum version is 2.4 in gemspec, but future minimum will be 2.5
|
13
|
+
# set to currenmt minimum if there is no deprecation
|
14
|
+
# the actual current minimum required version is in gemspec at required_ruby_version
|
15
|
+
RUBY_FUTURE_MINIMUM_VERSION='2.5'
|
16
|
+
end
|
17
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'aspera/fasp/listener'
|
2
3
|
require 'json'
|
3
4
|
|
@@ -8,8 +9,8 @@ module Aspera
|
|
8
9
|
# FASP event listener display management events as JSON
|
9
10
|
class LineDump < Fasp::Listener
|
10
11
|
def event_enhanced(data)
|
11
|
-
|
12
|
-
|
12
|
+
$stdout.puts(JSON.generate(data))
|
13
|
+
$stdout.flush
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'aspera/fasp/listener'
|
2
3
|
require 'aspera/log'
|
3
4
|
|
@@ -8,7 +9,7 @@ module Aspera
|
|
8
9
|
class Logger < Fasp::Listener
|
9
10
|
def event_struct(data)
|
10
11
|
Log.log.debug(data.to_s)
|
11
|
-
Log.log.error(
|
12
|
+
Log.log.error((data['Description']).to_s) if data['Type'].eql?('FILEERROR')
|
12
13
|
end
|
13
14
|
|
14
15
|
def event_enhanced(data)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'aspera/fasp/listener'
|
2
3
|
require 'ruby-progressbar'
|
3
4
|
|
@@ -7,42 +8,39 @@ module Aspera
|
|
7
8
|
# a listener to FASP event that displays a progress bar
|
8
9
|
class Progress < Fasp::Listener
|
9
10
|
def initialize
|
11
|
+
super
|
10
12
|
@progress=nil
|
11
13
|
@cumulative=0
|
12
14
|
end
|
13
15
|
|
14
|
-
BYTE_PER_MEGABIT=1024*1024/8
|
16
|
+
BYTE_PER_MEGABIT=(1024*1024)/8
|
15
17
|
|
16
18
|
def event_struct(data)
|
17
19
|
case data['Type']
|
18
20
|
when 'NOTIFICATION'
|
19
|
-
if data.has_key?('PreTransferBytes')
|
21
|
+
if data.has_key?('PreTransferBytes')
|
20
22
|
@progress=ProgressBar.create(
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
23
|
+
format: '%a %B %p%% %r Mbps %e',
|
24
|
+
rate_scale: lambda{|rate|rate/BYTE_PER_MEGABIT},
|
25
|
+
title: 'progress',
|
26
|
+
total: data['PreTransferBytes'].to_i)
|
25
27
|
end
|
26
28
|
when 'STOP'
|
27
29
|
# stop event when one file is completed
|
28
|
-
@cumulative
|
30
|
+
@cumulative+=data['Size'].to_i
|
29
31
|
when 'STATS'
|
30
|
-
if
|
31
|
-
if data.has_key?('Bytescont')
|
32
|
-
@progress.progress=@cumulative+data['Bytescont'].to_i
|
33
|
-
else
|
34
|
-
@progress.progress=data['TransferBytes'].to_i
|
35
|
-
end
|
36
|
-
else
|
32
|
+
if @progress.nil?
|
37
33
|
puts '.'
|
34
|
+
else
|
35
|
+
@progress.progress=data.has_key?('Bytescont') ? @cumulative+data['Bytescont'].to_i : data['TransferBytes'].to_i
|
38
36
|
end
|
39
37
|
when 'DONE'
|
40
|
-
if
|
41
|
-
@progress.progress=@progress.total
|
42
|
-
@progress=nil
|
43
|
-
else
|
38
|
+
if @progress.nil?
|
44
39
|
# terminate progress by going to next line
|
45
40
|
puts "\n"
|
41
|
+
else
|
42
|
+
@progress.progress=@progress.total
|
43
|
+
@progress=nil
|
46
44
|
end
|
47
45
|
end
|
48
46
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'aspera/fasp/listener'
|
2
3
|
require 'aspera/fasp/agent_base'
|
3
4
|
require 'ruby-progressbar'
|
@@ -8,6 +9,7 @@ module Aspera
|
|
8
9
|
# a listener to FASP event that displays a progress bar
|
9
10
|
class ProgressMulti < Fasp::Listener
|
10
11
|
def initialize
|
12
|
+
super
|
11
13
|
@progress_bar=nil
|
12
14
|
@sessions={}
|
13
15
|
end
|
@@ -22,7 +24,7 @@ module Aspera
|
|
22
24
|
def update_total
|
23
25
|
begin
|
24
26
|
@progress_bar.total=@sessions.values.inject(0){|m,s|m+=s[:job_size].to_i;m;}
|
25
|
-
rescue
|
27
|
+
rescue StandardError
|
26
28
|
nil
|
27
29
|
end
|
28
30
|
end
|
@@ -30,7 +32,7 @@ module Aspera
|
|
30
32
|
def update_progress
|
31
33
|
begin
|
32
34
|
@progress_bar.progress=@sessions.values.inject(0){|m,s|m+=s[:current].to_i;m;}
|
33
|
-
rescue
|
35
|
+
rescue StandardError
|
34
36
|
nil
|
35
37
|
end
|
36
38
|
end
|
@@ -38,10 +40,10 @@ module Aspera
|
|
38
40
|
def event_enhanced(data)
|
39
41
|
if @progress_bar.nil?
|
40
42
|
@progress_bar=ProgressBar.create(
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
43
|
+
format: '%t %a %B %p%% %r Mbps %e',
|
44
|
+
rate_scale: lambda{|rate|rate/BYTE_PER_MEGABIT},
|
45
|
+
title: '',
|
46
|
+
total: nil)
|
45
47
|
end
|
46
48
|
if !data.has_key?(Fasp::AgentBase::LISTENER_SESSION_ID_S)
|
47
49
|
Log.log.error("Internal error: no #{Fasp::AgentBase::LISTENER_SESSION_ID_S} in event: #{data}")
|
@@ -58,21 +60,16 @@ module Aspera
|
|
58
60
|
when 'INIT' # connection to ascp (get id)
|
59
61
|
when 'SESSION' # session information
|
60
62
|
when 'NOTIFICATION' # sent from remote
|
61
|
-
if data.has_key?('pre_transfer_bytes')
|
63
|
+
if data.has_key?('pre_transfer_bytes')
|
62
64
|
session[:job_size]=data['pre_transfer_bytes']
|
63
65
|
update_total
|
64
66
|
end
|
65
67
|
when 'STATS' # during transfer
|
66
|
-
if
|
67
|
-
if data.has_key?('bytescont')
|
68
|
-
session[:current]=session[:cumulative]+data['bytescont'].to_i
|
69
|
-
update_progress
|
70
|
-
else
|
71
|
-
session[:current]=data['transfer_bytes'].to_i
|
72
|
-
update_progress
|
73
|
-
end
|
74
|
-
else
|
68
|
+
if @progress_bar.total.nil?
|
75
69
|
@progress_bar.increment
|
70
|
+
else
|
71
|
+
session[:current]=data.has_key?('bytescont') ? session[:cumulative]+data['bytescont'].to_i : data['transfer_bytes'].to_i
|
72
|
+
update_progress
|
76
73
|
end
|
77
74
|
when 'STOP'
|
78
75
|
# stop event when one file is completed
|