aspera-cli 4.4.0 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2095 -1503
  3. data/bin/ascli +2 -1
  4. data/bin/asession +4 -5
  5. data/docs/test_env.conf +3 -0
  6. data/examples/aoc.rb +4 -3
  7. data/examples/faspex4.rb +25 -25
  8. data/examples/proxy.pac +1 -1
  9. data/examples/transfer.rb +17 -17
  10. data/lib/aspera/aoc.rb +238 -185
  11. data/lib/aspera/ascmd.rb +93 -83
  12. data/lib/aspera/ats_api.rb +11 -10
  13. data/lib/aspera/cli/basic_auth_plugin.rb +13 -14
  14. data/lib/aspera/cli/extended_value.rb +42 -33
  15. data/lib/aspera/cli/formater.rb +142 -108
  16. data/lib/aspera/cli/info.rb +17 -0
  17. data/lib/aspera/cli/listener/line_dump.rb +3 -2
  18. data/lib/aspera/cli/listener/logger.rb +2 -1
  19. data/lib/aspera/cli/listener/progress.rb +16 -18
  20. data/lib/aspera/cli/listener/progress_multi.rb +18 -21
  21. data/lib/aspera/cli/main.rb +173 -149
  22. data/lib/aspera/cli/manager.rb +163 -168
  23. data/lib/aspera/cli/plugin.rb +43 -31
  24. data/lib/aspera/cli/plugins/alee.rb +6 -6
  25. data/lib/aspera/cli/plugins/aoc.rb +405 -370
  26. data/lib/aspera/cli/plugins/ats.rb +86 -79
  27. data/lib/aspera/cli/plugins/bss.rb +14 -16
  28. data/lib/aspera/cli/plugins/config.rb +580 -362
  29. data/lib/aspera/cli/plugins/console.rb +23 -19
  30. data/lib/aspera/cli/plugins/cos.rb +18 -18
  31. data/lib/aspera/cli/plugins/faspex.rb +201 -158
  32. data/lib/aspera/cli/plugins/faspex5.rb +80 -57
  33. data/lib/aspera/cli/plugins/node.rb +183 -166
  34. data/lib/aspera/cli/plugins/orchestrator.rb +71 -67
  35. data/lib/aspera/cli/plugins/preview.rb +92 -96
  36. data/lib/aspera/cli/plugins/server.rb +79 -75
  37. data/lib/aspera/cli/plugins/shares.rb +35 -19
  38. data/lib/aspera/cli/plugins/sync.rb +20 -22
  39. data/lib/aspera/cli/transfer_agent.rb +76 -113
  40. data/lib/aspera/cli/version.rb +2 -1
  41. data/lib/aspera/colors.rb +35 -27
  42. data/lib/aspera/command_line_builder.rb +48 -34
  43. data/lib/aspera/cos_node.rb +29 -21
  44. data/lib/aspera/data_repository.rb +3 -2
  45. data/lib/aspera/environment.rb +50 -45
  46. data/lib/aspera/fasp/{manager.rb → agent_base.rb} +28 -25
  47. data/lib/aspera/fasp/{connect.rb → agent_connect.rb} +52 -43
  48. data/lib/aspera/fasp/{local.rb → agent_direct.rb} +58 -72
  49. data/lib/aspera/fasp/{http_gw.rb → agent_httpgw.rb} +37 -43
  50. data/lib/aspera/fasp/{node.rb → agent_node.rb} +35 -16
  51. data/lib/aspera/fasp/agent_trsdk.rb +104 -0
  52. data/lib/aspera/fasp/error.rb +2 -1
  53. data/lib/aspera/fasp/error_info.rb +68 -52
  54. data/lib/aspera/fasp/installation.rb +152 -124
  55. data/lib/aspera/fasp/listener.rb +1 -0
  56. data/lib/aspera/fasp/parameters.rb +87 -92
  57. data/lib/aspera/fasp/parameters.yaml +305 -249
  58. data/lib/aspera/fasp/resume_policy.rb +11 -14
  59. data/lib/aspera/fasp/transfer_spec.rb +26 -0
  60. data/lib/aspera/fasp/uri.rb +22 -21
  61. data/lib/aspera/faspex_gw.rb +55 -89
  62. data/lib/aspera/hash_ext.rb +4 -3
  63. data/lib/aspera/id_generator.rb +8 -7
  64. data/lib/aspera/keychain/encrypted_hash.rb +121 -0
  65. data/lib/aspera/keychain/macos_security.rb +90 -0
  66. data/lib/aspera/log.rb +55 -37
  67. data/lib/aspera/nagios.rb +13 -12
  68. data/lib/aspera/node.rb +30 -25
  69. data/lib/aspera/oauth.rb +175 -226
  70. data/lib/aspera/open_application.rb +4 -3
  71. data/lib/aspera/persistency_action_once.rb +6 -6
  72. data/lib/aspera/persistency_folder.rb +5 -9
  73. data/lib/aspera/preview/file_types.rb +6 -5
  74. data/lib/aspera/preview/generator.rb +25 -24
  75. data/lib/aspera/preview/options.rb +16 -14
  76. data/lib/aspera/preview/utils.rb +98 -98
  77. data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
  78. data/lib/aspera/proxy_auto_config.rb +111 -20
  79. data/lib/aspera/rest.rb +154 -135
  80. data/lib/aspera/rest_call_error.rb +2 -2
  81. data/lib/aspera/rest_error_analyzer.rb +23 -25
  82. data/lib/aspera/rest_errors_aspera.rb +15 -14
  83. data/lib/aspera/ssh.rb +12 -10
  84. data/lib/aspera/sync.rb +42 -41
  85. data/lib/aspera/temp_file_manager.rb +18 -14
  86. data/lib/aspera/timer_limiter.rb +2 -1
  87. data/lib/aspera/uri_reader.rb +7 -5
  88. data/lib/aspera/web_auth.rb +79 -76
  89. metadata +116 -29
  90. data/docs/Makefile +0 -66
  91. data/docs/README.erb.md +0 -3973
  92. data/docs/README.md +0 -13
  93. data/docs/diagrams.txt +0 -49
  94. data/docs/doc_tools.rb +0 -58
  95. data/lib/aspera/api_detector.rb +0 -60
  96. data/lib/aspera/cli/plugins/shares2.rb +0 -114
  97. data/lib/aspera/secrets.rb +0 -20
@@ -1,7 +1,5 @@
1
- #require 'text-table'
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,38 +10,96 @@ module Aspera
12
10
  FIELDS_ALL='ALL'
13
11
  FIELDS_DEFAULT='DEF'
14
12
  # supported output formats
15
- DISPLAY_FORMATS=[:table,:ruby,:json,:jsonpp,:yaml,:csv,:nagios]
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
- private_constant :FIELDS_ALL,:FIELDS_DEFAULT,:DISPLAY_FORMATS,:DISPLAY_LEVELS,:CSV_RECORD_SEPARATOR,:CSV_FIELD_SEPARATOR
22
- attr_accessor :option_flat_hash
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
- @opt_mgr=opt_mgr
27
- @opt_mgr.set_obj_attr(:flat_hash,self,:option_flat_hash)
28
- @opt_mgr.add_opt_list(:format,DISPLAY_FORMATS,"output format")
29
- @opt_mgr.add_opt_list(:display,DISPLAY_LEVELS,"output only some information")
30
- @opt_mgr.add_opt_simple(:fields,"comma separated list of fields, or #{FIELDS_ALL}, or #{FIELDS_DEFAULT}")
31
- @opt_mgr.add_opt_simple(:select,"select only some items in lists, extended value: hash (column, value)")
32
- @opt_mgr.add_opt_simple(:table_style,"table display style")
33
- @opt_mgr.add_opt_boolean(:flat_hash,"display hash values as additional keys")
34
- @opt_mgr.set_option(:format,:table)
35
- @opt_mgr.set_option(:display,:info)
36
- @opt_mgr.set_option(:fields,FIELDS_DEFAULT)
37
- @opt_mgr.set_option(:table_style,':.:')
77
+ @option_transpose_single=true
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')
38
95
  end
39
96
 
40
97
  # main output method
41
98
  def display_message(message_level,message)
42
- display_level=@opt_mgr.get_option(:display,:mandatory)
43
99
  case message_level
44
- when :info; STDOUT.puts(message) if display_level.eql?(:info)
45
- when :data; STDOUT.puts(message) unless display_level.eql?(:error)
46
- when :error; STDERR.puts(message)
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)
47
103
  else raise "wrong message_level:#{message_level}"
48
104
  end
49
105
  end
@@ -52,77 +108,51 @@ module Aspera
52
108
  display_message(:info,status)
53
109
  end
54
110
 
55
- # @param source [Hash] hash to modify
56
- # @param keep_last [bool]
57
- def self.flatten_object(source,keep_last)
58
- newval={}
59
- flatten_sub_hash_rec(source,keep_last,'',newval)
60
- source.clear
61
- source.merge!(newval)
62
- end
63
-
64
- # recursive function to modify a hash
65
- # @param source [Hash] to be modified
66
- # @param keep_last [bool] truer if last level is not
67
- # @param prefix [String] true if last level is not
68
- # @param dest [Hash] new hash flattened
69
- def self.flatten_sub_hash_rec(source,keep_last,prefix,dest)
70
- #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}
71
- is_simple_hash=false
72
- Log.log.debug("(#{keep_last})[#{is_simple_hash}] -#{source.values}- \n-#{source}-")
73
- return source if keep_last and is_simple_hash
74
- source.each do |k,v|
75
- if v.is_a?(Hash) and ( !keep_last or !is_simple_hash )
76
- flatten_sub_hash_rec(v,keep_last,prefix+k.to_s+'.',dest)
77
- else
78
- 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)}
79
117
  end
118
+ return results[:fields]
80
119
  end
81
- return nil
120
+ return ['empty'] if table_rows_hash_val.empty?
121
+ return table_rows_hash_val.first.keys
82
122
  end
83
123
 
84
- # special for Aspera on Cloud display node
85
- # {"param" => [{"name"=>"foo","value"=>"bar"}]} will be expanded to {"param.foo" : "bar"}
86
- def self.flatten_name_value_list(hash)
87
- hash.keys.each do |k|
88
- v=hash[k]
89
- 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"])
90
- v.each do |pair|
91
- hash["#{k}.#{pair["name"]}"]=pair["value"]
92
- end
93
- hash.delete(k)
94
- end
95
- 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
96
128
  end
97
129
 
98
- def result_default_fields(results,table_rows_hash_val)
99
- if results.has_key?(:fields) and !results[:fields].nil?
100
- final_table_columns=results[:fields]
101
- else
102
- if !table_rows_hash_val.empty?
103
- final_table_columns=table_rows_hash_val.first.keys
104
- else
105
- final_table_columns=['empty']
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
106
142
  end
107
143
  end
108
144
  end
109
145
 
110
- def result_all_fields(results,table_rows_hash_val)
111
- raise "internal error: must be array" unless table_rows_hash_val.is_a?(Array)
112
- # get the list of all column names used in all lines, not just frst one, as all lines may have different columns
113
- return table_rows_hash_val.inject({}){|m,v|v.keys.each{|c|m[c]=true};m}.keys
114
- end
115
-
116
146
  # this method displays the results, especially the table format
117
147
  def display_results(results)
118
148
  raise "INTERNAL ERROR, result must be Hash (got: #{results.class}: #{results})" unless results.is_a?(Hash)
119
- raise "INTERNAL ERROR, result must have type" unless results.has_key?(:type)
120
- raise "INTERNAL ERROR, result must have data" unless results.has_key?(:data) or [:empty,:nothing].include?(results[:type])
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])
121
151
  res_data=results[:data]
152
+ deep_remove_secret(res_data)
122
153
  # comma separated list in string format
123
- user_asked_fields_list_str=@opt_mgr.get_option(:fields,:mandatory)
124
- display_format=@opt_mgr.get_option(:format,:mandatory)
125
- case display_format
154
+ user_asked_fields_list_str=@option_fields
155
+ case @option_format
126
156
  when :nagios
127
157
  Nagios.process(res_data)
128
158
  when :ruby
@@ -134,6 +164,10 @@ module Aspera
134
164
  when :yaml
135
165
  display_message(:data,res_data.to_yaml)
136
166
  when :table,:csv
167
+ if !@option_transpose_single && results[:type].eql?(:single_object)
168
+ results[:type]=:object_list
169
+ res_data=[res_data]
170
+ end
137
171
  case results[:type]
138
172
  when :object_list # goes to table display
139
173
  raise "internal error: unexpected type: #{res_data.class}, expecting Array" unless res_data.is_a?(Array)
@@ -145,14 +179,15 @@ module Aspera
145
179
  self.class.flatten_object(obj,results[:option_expand_last])
146
180
  end
147
181
  end
148
- final_table_columns=case user_asked_fields_list_str
149
- when FIELDS_DEFAULT; result_default_fields(results,table_rows_hash_val)
150
- when FIELDS_ALL; result_all_fields(results,table_rows_hash_val)
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)
151
186
  else
152
187
  if user_asked_fields_list_str.start_with?('+')
153
188
  result_default_fields(results,table_rows_hash_val).push(*user_asked_fields_list_str.gsub(/^\+/,'').split(','))
154
189
  elsif user_asked_fields_list_str.start_with?('-')
155
- result_default_fields(results,table_rows_hash_val).select{|i| ! user_asked_fields_list_str.gsub(/^\-/,'').split(',').include?(i)}
190
+ result_default_fields(results,table_rows_hash_val).reject{|i| user_asked_fields_list_str.gsub(/^-/,'').split(',').include?(i)}
156
191
  else
157
192
  user_asked_fields_list_str.split(',')
158
193
  end
@@ -165,13 +200,14 @@ module Aspera
165
200
  self.class.flatten_object(res_data,results[:option_expand_last])
166
201
  self.class.flatten_name_value_list(res_data)
167
202
  end
168
- asked_fields=case user_asked_fields_list_str
169
- when FIELDS_DEFAULT; results[:fields]||res_data.keys
170
- when FIELDS_ALL; res_data.keys
171
- else user_asked_fields_list_str.split(',')
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(',')
172
208
  end
173
209
  table_rows_hash_val=asked_fields.map { |i| { final_table_columns.first => i, final_table_columns.last => res_data[i] } }
174
- when :value_list # goes to table display
210
+ when :value_list # goes to table display
175
211
  # :value_list is a simple array of values, name of column provided in the :name
176
212
  final_table_columns = [results[:name]]
177
213
  table_rows_hash_val=res_data.map { |i| { results[:name] => i } }
@@ -179,7 +215,7 @@ module Aspera
179
215
  display_message(:info,'empty')
180
216
  return
181
217
  when :nothing # no result expected
182
- Log.log.debug("no result expected")
218
+ Log.log.debug('no result expected')
183
219
  return
184
220
  when :status # no table
185
221
  # :status displays a simple message
@@ -197,39 +233,37 @@ module Aspera
197
233
  raise "unknown data type: #{results[:type]}"
198
234
  end
199
235
  # here we expect: table_rows_hash_val and final_table_columns
200
- raise "no field specified" if final_table_columns.nil?
236
+ raise 'no field specified' if final_table_columns.nil?
201
237
  if table_rows_hash_val.empty?
202
- display_message(:info,'empty'.gray) unless display_format.eql?(:csv)
238
+ display_message(:info,'empty'.gray) unless @option_format.eql?(:csv)
203
239
  return
204
240
  end
205
241
  # convert to string with special function. here table_rows_hash_val is an array of hash
206
242
  table_rows_hash_val=results[:textify].call(table_rows_hash_val) if results.has_key?(:textify)
207
- filter=@opt_mgr.get_option(:select,:optional)
208
- unless filter.nil?
209
- raise CliBadArgument,"expecting hash for select" unless filter.is_a?(Hash)
210
- 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)}}
211
246
  end
212
-
213
247
  # convert data to string, and keep only display fields
214
248
  final_table_rows=table_rows_hash_val.map { |r| final_table_columns.map { |c| r[c].to_s } }
215
249
  # here : final_table_columns : list of column names
216
250
  # here: final_table_rows : array of list of value
217
- case display_format
251
+ case @option_format
218
252
  when :table
219
- style=@opt_mgr.get_option(:table_style,:mandatory).split('')
253
+ style=@option_table_style.chars
220
254
  # display the table !
221
255
  #display_message(:data,Text::Table.new(
222
- #:head => final_table_columns,
223
- #:rows => final_table_rows,
224
- #:horizontal_boundary => style[0],
225
- #:vertical_boundary => style[1],
226
- #:boundary_intersection => style[2]))
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]))
227
261
  display_message(:data,Terminal::Table.new(
228
- :headings => final_table_columns,
229
- :rows => final_table_rows,
230
- :border_x => style[0],
231
- :border_y => style[1],
232
- :border_i => style[2]))
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]))
233
267
  when :csv
234
268
  display_message(:data,final_table_rows.map{|t| t.join(CSV_FIELD_SEPARATOR)}.join(CSV_RECORD_SEPARATOR))
235
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
- STDOUT.puts(JSON.generate(data))
12
- STDOUT.flush
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("#{data['Description']}") if data['Type'].eql?('FILEERROR')
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') then
21
+ if data.has_key?('PreTransferBytes')
20
22
  @progress=ProgressBar.create(
21
- :format => '%a %B %p%% %r Mbps %e',
22
- :rate_scale => lambda{|rate|rate/BYTE_PER_MEGABIT},
23
- :title => 'progress',
24
- :total => data['PreTransferBytes'].to_i)
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=@cumulative+data['Size'].to_i
30
+ @cumulative+=data['Size'].to_i
29
31
  when 'STATS'
30
- if !@progress.nil? then
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 !@progress.nil? then
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,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require 'aspera/fasp/listener'
2
- require 'aspera/fasp/manager'
3
+ require 'aspera/fasp/agent_base'
3
4
  require 'ruby-progressbar'
4
5
 
5
6
  module Aspera
@@ -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,18 +40,18 @@ module Aspera
38
40
  def event_enhanced(data)
39
41
  if @progress_bar.nil?
40
42
  @progress_bar=ProgressBar.create(
41
- :format => '%t %a %B %p%% %r Mbps %e',
42
- :rate_scale => lambda{|rate|rate/BYTE_PER_MEGABIT},
43
- :title => '',
44
- :total => nil)
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
- if !data.has_key?(Fasp::Manager::LISTENER_SESSION_ID_S)
47
- Log.log.error("Internal error: no #{Fasp::Manager::LISTENER_SESSION_ID_S} in event: #{data}")
48
+ if !data.has_key?(Fasp::AgentBase::LISTENER_SESSION_ID_S)
49
+ Log.log.error("Internal error: no #{Fasp::AgentBase::LISTENER_SESSION_ID_S} in event: #{data}")
48
50
  return
49
51
  end
50
52
  newtitle=@sessions.length < 2 ? '' : "multi=#{@sessions.length}"
51
53
  @progress_bar.title=newtitle unless @progress_bar.title.eql?(newtitle)
52
- session=@sessions[data[Fasp::Manager::LISTENER_SESSION_ID_S]]||={
54
+ session=@sessions[data[Fasp::AgentBase::LISTENER_SESSION_ID_S]]||={
53
55
  cumulative: 0,
54
56
  job_size: 0,
55
57
  current: 0
@@ -58,27 +60,22 @@ 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') then
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 !@progress_bar.total.nil? then
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
79
76
  session[:cumulative]=session[:cumulative]+data['size'].to_i
80
77
  when 'DONE' # end of session
81
- @sessions.delete(data[Fasp::Manager::LISTENER_SESSION_ID_S])
78
+ @sessions.delete(data[Fasp::AgentBase::LISTENER_SESSION_ID_S])
82
79
  update_progress
83
80
  update_total
84
81
  else