1111require 'aspera/api/node'
1212require 'aspera/oauth'
1313require 'aspera/node_simulator'
14+ require 'aspera/rest_list'
1415require 'aspera/assert'
1516require 'base64'
1617require 'zlib'
@@ -166,7 +167,7 @@ def wizard(wizard, app_url)
166167 # @param api [Rest] an existing API object for the Node API
167168 # @param prefix_path [String,nil] for Faspex 4, allows browsing a package without full path in node (removes storage prefix)
168169 def initialize ( context :, api : nil , prefix_path : nil )
169- @prefixer = prefix_path ? NodePathPrefix . new ( prefix_path ) : nil
170+ @node_path_prefix = prefix_path ? NodePathPrefix . new ( prefix_path ) : nil
170171 super ( context : context , basic_options : api . nil? )
171172 Node . declare_options ( options )
172173 return if context . only_manual?
@@ -196,11 +197,11 @@ def initialize(context:, api: nil, prefix_path: nil)
196197 # Gen3 API
197198 def browse_gen3
198199 folders_to_process = options . get_next_argument ( 'path' , validation : String )
199- folders_to_process = @prefixer . add_to_path ( folders_to_process ) unless @prefixer . nil?
200+ folders_to_process = @node_path_prefix . add_to_path ( folders_to_process ) unless @node_path_prefix . nil?
200201 folders_to_process = [ folders_to_process ]
201202 query = options . get_option ( :query ) || { }
202203 # special parameter: max number of entries in result
203- max_items = query . delete ( MAX_ITEMS )
204+ max_items = query . delete ( RestList :: MAX_ITEMS )
204205 # special parameter: recursive browsing
205206 recursive = query . delete ( 'recursive' )
206207 # special parameter: only return one entry for the path, even if folder
@@ -221,7 +222,7 @@ def browse_gen3
221222 response = @api_node . create ( 'files/browse' , query )
222223 # 'file','symbolic_link'
223224 if !Node . gen3_entry_folder? ( response [ 'self' ] ) || only_path
224- @prefixer &.remove_in_object_list! ( [ response [ 'self' ] ] )
225+ @node_path_prefix &.remove_in_object_list! ( [ response [ 'self' ] ] )
225226 return Main . result_single_object ( response [ 'self' ] )
226227 end
227228 items = response [ 'items' ]
@@ -243,7 +244,7 @@ def browse_gen3
243244 end
244245 query . delete ( 'skip' )
245246 end
246- @prefixer &.remove_in_object_list! ( all_items )
247+ @node_path_prefix &.remove_in_object_list! ( all_items )
247248 return Main . result_object_list ( all_items )
248249 ensure
249250 RestParameters . instance . spinner_cb . call ( action : :success )
@@ -286,12 +287,12 @@ def execute_command_gen3(command)
286287 when :delete
287288 # TODO: add query for recursive
288289 paths_to_delete = options . get_next_argument ( 'file list' , multiple : true )
289- @prefixer &.add_to_paths! ( paths_to_delete )
290+ @node_path_prefix &.add_to_paths! ( paths_to_delete )
290291 resp = @api_node . create ( 'files/delete' , { paths : paths_to_delete . map { |i | { 'path' => i . start_with? ( '/' ) ? i : "/#{ i } " } } } )
291292 return cli_result_from_paths_response ( resp , 'file deleted' )
292293 when :search
293294 search_root = options . get_next_argument ( 'search root' , validation : String )
294- search_root = @prefixer . add_to_path ( search_root ) unless @prefixer . nil?
295+ search_root = @node_path_prefix . add_to_path ( search_root ) unless @node_path_prefix . nil?
295296 parameters = { 'path' => search_root }
296297 other_options = options . get_option ( :query )
297298 parameters . merge! ( other_options ) unless other_options . nil?
@@ -300,40 +301,40 @@ def execute_command_gen3(command)
300301 fields = resp [ 'items' ] . first . keys . reject { |i | SEARCH_REMOVE_FIELDS . include? ( i ) }
301302 formatter . display_item_count ( resp [ 'item_count' ] , resp [ 'total_count' ] )
302303 formatter . display_status ( "params: #{ resp [ 'parameters' ] . keys . map { |k | "#{ k } :#{ resp [ 'parameters' ] [ k ] } " } . join ( ',' ) } " )
303- @prefixer &.remove_in_object_list! ( resp [ 'items' ] )
304+ @node_path_prefix &.remove_in_object_list! ( resp [ 'items' ] )
304305 return Main . result_object_list ( resp [ 'items' ] , fields : fields )
305306 when :space
306307 path_list = options . get_next_argument ( 'folder path or ext.val. list' , multiple : true )
307- @prefixer &.add_to_paths! ( path_list )
308+ @node_path_prefix &.add_to_paths! ( path_list )
308309 resp = @api_node . create ( 'space' , { 'paths' => path_list . map { |i | { path : i } } } )
309- @prefixer &.remove_in_object_list! ( resp [ 'paths' ] )
310+ @node_path_prefix &.remove_in_object_list! ( resp [ 'paths' ] )
310311 return Main . result_object_list ( resp [ 'paths' ] )
311312 when :mkdir
312313 path_list = options . get_next_argument ( 'folder path or ext.val. list' , multiple : true )
313- @prefixer &.add_to_paths! ( path_list )
314+ @node_path_prefix &.add_to_paths! ( path_list )
314315 resp = @api_node . create ( 'files/create' , { 'paths' => path_list . map { |i | { type : :directory , path : i } } } )
315316 return cli_result_from_paths_response ( resp , 'folder created' )
316317 when :mklink
317318 target = options . get_next_argument ( 'target' , validation : String )
318- target = @prefixer . add_to_path ( target ) unless @prefixer . nil?
319+ target = @node_path_prefix . add_to_path ( target ) unless @node_path_prefix . nil?
319320 one_path = options . get_next_argument ( 'link path' , validation : String )
320- one_path = @prefixer . add_to_path ( one_path ) unless @prefixer . nil?
321+ one_path = @node_path_prefix . add_to_path ( one_path ) unless @node_path_prefix . nil?
321322 resp = @api_node . create ( 'files/create' , { 'paths' => [ { type : :symbolic_link , path : one_path , target : { path : target } } ] } )
322323 return cli_result_from_paths_response ( resp , 'link created' )
323324 when :mkfile
324325 one_path = options . get_next_argument ( 'file path' , validation : String )
325- one_path = @prefixer . add_to_path ( one_path ) unless @prefixer . nil?
326+ one_path = @node_path_prefix . add_to_path ( one_path ) unless @node_path_prefix . nil?
326327 contents64 = Base64 . strict_encode64 ( options . get_next_argument ( 'contents' ) )
327328 resp = @api_node . create ( 'files/create' , { 'paths' => [ { type : :file , path : one_path , contents : contents64 } ] } )
328329 return cli_result_from_paths_response ( resp , 'file created' )
329330 when :rename
330331 # TODO: multiple ?
331332 path_base = options . get_next_argument ( 'path_base' , validation : String )
332- path_base = @prefixer . add_to_path ( path_base ) unless @prefixer . nil?
333+ path_base = @node_path_prefix . add_to_path ( path_base ) unless @node_path_prefix . nil?
333334 path_src = options . get_next_argument ( 'path_src' , validation : String )
334- path_src = @prefixer . add_to_path ( path_src ) unless @prefixer . nil?
335+ path_src = @node_path_prefix . add_to_path ( path_src ) unless @node_path_prefix . nil?
335336 path_dst = options . get_next_argument ( 'path_dst' , validation : String )
336- path_dst = @prefixer . add_to_path ( path_dst ) unless @prefixer . nil?
337+ path_dst = @node_path_prefix . add_to_path ( path_dst ) unless @node_path_prefix . nil?
337338 resp = @api_node . create ( 'files/rename' , { 'paths' => [ { 'path' => path_base , 'source' => path_src , 'destination' => path_dst } ] } )
338339 return cli_result_from_paths_response ( resp , 'entry moved' )
339340 when :browse
@@ -378,7 +379,7 @@ def execute_command_gen3(command)
378379 return Main . result_transfer ( transfer . start ( transfer_spec ) )
379380 when :cat
380381 remote_path = options . get_next_argument ( 'remote path' , validation : String )
381- remote_path = @prefixer . add_to_path ( remote_path ) unless @prefixer . nil?
382+ remote_path = @node_path_prefix . add_to_path ( remote_path ) unless @node_path_prefix . nil?
382383 File . basename ( remote_path )
383384 http = @api_node . read ( "files/#{ URI . encode_www_form_component ( remote_path ) } /contents" , ret : :resp )
384385 return Main . result_text ( http . body )
@@ -882,10 +883,10 @@ def execute_action(command = nil)
882883 iteration_persistency . save
883884 return Main . result_status ( 'Persistency reset' )
884885 end
886+ else
887+ Aspera . assert ( !transfer_filter . key? ( 'reset' ) , type : Cli ::BadArgument ) { 'reset only with once_only' }
885888 end
886- raise Cli ::BadArgument , 'reset only with once_only' if transfer_filter . key? ( 'reset' ) && iteration_persistency . nil?
887- max_items = transfer_filter . delete ( MAX_ITEMS )
888- transfers_data = call_with_iteration ( api : @api_node , operation : 'GET' , subpath : 'ops/transfers' , max : max_items , query : transfer_filter , iteration : iteration_persistency &.data )
889+ transfers_data = @api_node . read_with_paging ( 'ops/transfers' , transfer_filter , iteration : iteration_persistency &.data )
889890 iteration_persistency &.save
890891 return Main . result_object_list ( transfers_data , fields : %w[ id status start_spec.direction start_spec.remote_user start_spec.remote_host start_spec.destination_path ] )
891892 when :sessions
@@ -1092,7 +1093,7 @@ def execute_action(command = nil)
10921093 }
10931094 loop do
10941095 timestamp = Time . now
1095- transfers_data = call_with_iteration ( api : @api_node , operation : 'GET' , subpath : ' ops/transfers', query : { active_only : true } )
1096+ transfers_data = @api_node . read_with_paging ( ' ops/transfers', { active_only : true } )
10961097 datapoint [ :asInt ] = transfers_data . length
10971098 datapoint [ :timeUnixNano ] = timestamp . to_i * 1_000_000_000 + timestamp . nsec
10981099 Log . log . info ( "#{ datapoint [ :asInt ] } active transfers" )
@@ -1130,50 +1131,9 @@ def response_to_result(response, success_msg)
11301131 # Translates paths results into CLI result, and removes prefix
11311132 def cli_result_from_paths_response ( response , success_msg )
11321133 obj_list = response_to_result ( response , success_msg )
1133- @prefixer &.remove_in_object_list! ( obj_list )
1134+ @node_path_prefix &.remove_in_object_list! ( obj_list )
11341135 return Main . result_object_list ( obj_list , fields : %w[ path result ] )
11351136 end
1136-
1137- # Executes the provided API call in loop
1138- # @param api [Rest] the API to call
1139- # @param iteration [Array] a single element array with the iteration token or nil
1140- # @param max [Integer] maximum number of items to return, or nil for no limit
1141- # @param query [Hash] query parameters to use for the API call
1142- # @param call_args [Hash] additional arguments to pass to the API call
1143- # @return [Array] list of items returned by the API call
1144- def call_with_iteration ( api :, iteration : nil , max : nil , query : nil , **call_args )
1145- Aspera . assert_type ( iteration , Array , NilClass ) { 'iteration' }
1146- Aspera . assert_type ( query , Hash , NilClass ) { 'query' }
1147- query_token = query &.dup || { }
1148- item_list = [ ]
1149- query_token [ :iteration_token ] = iteration [ 0 ] unless iteration . nil?
1150- loop do
1151- data , http = api . call ( **call_args , query : query_token , ret : :both )
1152- Aspera . assert_type ( data , Array ) { "Expected data to be an Array, got: #{ data . class } " }
1153- # no data
1154- break if data . empty?
1155- # get next iteration token from link
1156- next_iteration_token = nil
1157- link_info = http [ 'Link' ]
1158- unless link_info . nil?
1159- m = link_info . match ( /<([^>]+)>/ )
1160- Aspera . assert ( m ) { "Cannot parse iteration in Link: #{ link_info } " }
1161- next_iteration_token = Rest . query_to_h ( URI . parse ( m [ 1 ] ) . query ) [ 'iteration_token' ]
1162- end
1163- # same as last iteration: stop
1164- break if next_iteration_token &.eql? ( query_token [ :iteration_token ] )
1165- query_token [ :iteration_token ] = next_iteration_token
1166- item_list . concat ( data )
1167- if max &.<=( item_list . length )
1168- item_list = item_list . slice ( 0 , max )
1169- break
1170- end
1171- break if next_iteration_token . nil?
1172- end
1173- # save iteration token if needed
1174- iteration [ 0 ] = query_token [ :iteration_token ] unless iteration . nil?
1175- item_list
1176- end
11771137 end
11781138 end
11791139 end
0 commit comments