aspera-cli 4.6.0 → 4.7.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
- 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
|