aspera-cli 4.4.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.
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