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