aspera-cli 4.18.0 → 4.18.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -2
- data/CHANGELOG.md +10 -0
- data/README.md +96 -59
- data/examples/build_package.sh +28 -0
- data/lib/aspera/agent/alpha.rb +4 -4
- data/lib/aspera/agent/connect.rb +3 -4
- data/lib/aspera/agent/httpgw.rb +1 -1
- data/lib/aspera/api/httpgw.rb +4 -1
- data/lib/aspera/api/node.rb +110 -77
- data/lib/aspera/ascp/products.rb +1 -1
- data/lib/aspera/cli/extended_value.rb +27 -14
- data/lib/aspera/cli/formatter.rb +11 -10
- data/lib/aspera/cli/main.rb +11 -11
- data/lib/aspera/cli/manager.rb +99 -84
- data/lib/aspera/cli/plugin.rb +2 -5
- data/lib/aspera/cli/plugins/aoc.rb +15 -14
- data/lib/aspera/cli/plugins/config.rb +20 -19
- data/lib/aspera/cli/plugins/faspex.rb +5 -4
- data/lib/aspera/cli/plugins/faspex5.rb +16 -13
- data/lib/aspera/cli/plugins/node.rb +46 -38
- data/lib/aspera/cli/plugins/orchestrator.rb +3 -2
- data/lib/aspera/cli/plugins/preview.rb +1 -1
- data/lib/aspera/cli/plugins/server.rb +1 -1
- data/lib/aspera/cli/special_values.rb +13 -0
- data/lib/aspera/cli/sync_actions.rb +4 -4
- data/lib/aspera/cli/transfer_agent.rb +2 -2
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/environment.rb +64 -4
- data/lib/aspera/oauth/web.rb +2 -2
- data/lib/aspera/rest.rb +46 -15
- data.tar.gz.sig +0 -0
- metadata +4 -3
- metadata.gz.sig +0 -0
- data/lib/aspera/open_application.rb +0 -69
data/lib/aspera/rest.rb
CHANGED
@@ -12,7 +12,7 @@ require 'json'
|
|
12
12
|
require 'base64'
|
13
13
|
require 'cgi'
|
14
14
|
|
15
|
-
#
|
15
|
+
# Cancel method for HTTP
|
16
16
|
class Net::HTTP::Cancel < Net::HTTPRequest # rubocop:disable Style/ClassAndModuleChildren
|
17
17
|
METHOD = 'CANCEL'
|
18
18
|
REQUEST_HAS_BODY = false
|
@@ -24,12 +24,16 @@ module Aspera
|
|
24
24
|
# rest call errors are raised as exception RestCallError
|
25
25
|
# and error are analyzed in RestErrorAnalyzer
|
26
26
|
class Rest
|
27
|
-
#
|
27
|
+
# Global settings also valid for any subclass
|
28
|
+
# @param user_agent [String] HTTP request header: 'User-Agent'
|
29
|
+
# @param download_partial_suffix [String] suffix for partial download
|
30
|
+
# @param session_cb [lambda] lambda called on new HTTP session. Takes the Net::HTTP as arg. Used to change parameters on creation.
|
31
|
+
# @param progress_bar [Object] progress bar object
|
28
32
|
@@global = { # rubocop:disable Style/ClassVars
|
29
|
-
user_agent: '
|
30
|
-
download_partial_suffix: '.http_partial',
|
31
|
-
session_cb: nil,
|
32
|
-
progress_bar: nil
|
33
|
+
user_agent: 'RubyAsperaRest',
|
34
|
+
download_partial_suffix: '.http_partial',
|
35
|
+
session_cb: nil,
|
36
|
+
progress_bar: nil
|
33
37
|
}
|
34
38
|
|
35
39
|
# flag for array parameters prefixed with []
|
@@ -44,9 +48,10 @@ module Aspera
|
|
44
48
|
JSON_DECODE = ['application/json', 'application/vnd.api+json', 'application/x-javascript'].freeze
|
45
49
|
|
46
50
|
class << self
|
51
|
+
# @return [String] Basic auth token
|
47
52
|
def basic_token(user, pass); return "Basic #{Base64.strict_encode64("#{user}:#{pass}")}"; end
|
48
53
|
|
49
|
-
#
|
54
|
+
# Build a parameter list prefixed with "[]"
|
50
55
|
# @param values [Array] list of values
|
51
56
|
def array_params(values)
|
52
57
|
return [ARRAY_PARAMS].concat(values)
|
@@ -56,7 +61,7 @@ module Aspera
|
|
56
61
|
return values.first.eql?(ARRAY_PARAMS)
|
57
62
|
end
|
58
63
|
|
59
|
-
#
|
64
|
+
# Build URI from URL and parameters and check it is http or https, encode array [] parameters
|
60
65
|
def build_uri(url, query_hash=nil)
|
61
66
|
uri = URI.parse(url)
|
62
67
|
Aspera.assert(%w[http https].include?(uri.scheme)){"REST endpoint shall be http/s not #{uri.scheme}"}
|
@@ -82,8 +87,16 @@ module Aspera
|
|
82
87
|
return uri
|
83
88
|
end
|
84
89
|
|
90
|
+
# decode query string as hash
|
91
|
+
# Does not support arrays in query string, no standard, e.g. PHP's way is p[]=1&p[]=2
|
92
|
+
# @param query [String] query string
|
93
|
+
# @return [Hash] decoded query
|
85
94
|
def decode_query(query)
|
86
|
-
URI.decode_www_form(query).each_with_object({})
|
95
|
+
URI.decode_www_form(query).each_with_object({}) do |pair, h|
|
96
|
+
key = pair.first
|
97
|
+
raise "Array not supported in query string: #{key}" if key.include?('[]') || h.key?(key)
|
98
|
+
h[key] = pair.last
|
99
|
+
end
|
87
100
|
end
|
88
101
|
|
89
102
|
# Start a HTTP/S session, also used for web sockets
|
@@ -141,6 +154,17 @@ module Aspera
|
|
141
154
|
def user_agent
|
142
155
|
return @@global[:user_agent]
|
143
156
|
end
|
157
|
+
|
158
|
+
def parse_header(header)
|
159
|
+
type, *params = header.split(/;\s*/)
|
160
|
+
parameters = params.map do |param|
|
161
|
+
one = param.split(/=\s*/)
|
162
|
+
one[0] = one[0].to_sym
|
163
|
+
one[1] = one[1].gsub(/\A"|"\z/, '')
|
164
|
+
one
|
165
|
+
end.to_h
|
166
|
+
{ type: type.downcase, parameters: parameters }
|
167
|
+
end
|
144
168
|
end
|
145
169
|
|
146
170
|
private
|
@@ -185,8 +209,12 @@ module Aspera
|
|
185
209
|
headers: nil
|
186
210
|
)
|
187
211
|
Aspera.assert_type(base_url, String)
|
188
|
-
# base url with
|
189
|
-
@base_url = base_url.gsub(%r{
|
212
|
+
# base url with no trailing slashes (note: string may be frozen)
|
213
|
+
@base_url = base_url.gsub(%r{/+$}, '')
|
214
|
+
# remove trailing port if it is 443 and scheme is https
|
215
|
+
@base_url = @base_url.gsub(/:443$/, '') if @base_url.start_with?('https://')
|
216
|
+
@base_url = @base_url.gsub(/:80$/, '') if @base_url.start_with?('http://')
|
217
|
+
Log.log.debug{"Rest.new(#{@base_url})"}
|
190
218
|
# default is no auth
|
191
219
|
@auth_params = auth.nil? ? {type: :none} : auth
|
192
220
|
Aspera.assert_type(@auth_params, Hash)
|
@@ -265,7 +293,7 @@ module Aspera
|
|
265
293
|
begin
|
266
294
|
# TODO: shall we percent encode subpath (spaces) test with access key delete with space in id
|
267
295
|
# URI.escape()
|
268
|
-
separator =
|
296
|
+
separator = ['', '/'].include?(subpath) ? '' : '/'
|
269
297
|
uri = self.class.build_uri("#{@base_url}#{separator}#{subpath}", query)
|
270
298
|
Log.log.debug{"URI=#{uri}"}
|
271
299
|
begin
|
@@ -305,7 +333,7 @@ module Aspera
|
|
305
333
|
# make http request (pipelined)
|
306
334
|
http_session.request(req) do |response|
|
307
335
|
result[:http] = response
|
308
|
-
result_mime = (result[:http]['Content-Type'] || 'text/plain')
|
336
|
+
result_mime = self.class.parse_header(result[:http]['Content-Type'] || 'text/plain')[:type]
|
309
337
|
# JSON data needs to be parsed, in case it contains an error code
|
310
338
|
if !save_to_file.nil? &&
|
311
339
|
result[:http].code.to_s.start_with?('2') &&
|
@@ -315,8 +343,11 @@ module Aspera
|
|
315
343
|
Log.log.debug('before write file')
|
316
344
|
target_file = save_to_file
|
317
345
|
# override user's path to path in header
|
318
|
-
if !response['Content-Disposition'].nil?
|
319
|
-
|
346
|
+
if !response['Content-Disposition'].nil?
|
347
|
+
disposition = self.class.parse_header(response['Content-Disposition'])
|
348
|
+
if disposition[:parameters].key?(:filename)
|
349
|
+
target_file = File.join(File.dirname(target_file), disposition[:parameters][:filename])
|
350
|
+
end
|
320
351
|
end
|
321
352
|
# download with temp filename
|
322
353
|
target_file_tmp = "#{target_file}#{@@global[:download_partial_suffix]}"
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aspera-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.18.
|
4
|
+
version: 4.18.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laurent Martin
|
@@ -37,7 +37,7 @@ cert_chain:
|
|
37
37
|
eTf9kxhVM40wGQOECVNA8UsEEZHD48eF+csUYZtAJOF5oxTI8UyV9T/o6CgO0c9/
|
38
38
|
Gzz+Qm5ULOUcPiJLjSpaiTrkiIVYiDGnqNSr6R1Hb1c=
|
39
39
|
-----END CERTIFICATE-----
|
40
|
-
date: 2024-
|
40
|
+
date: 2024-08-21 00:00:00.000000000 Z
|
41
41
|
dependencies:
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: blankslate
|
@@ -390,6 +390,7 @@ files:
|
|
390
390
|
- README.md
|
391
391
|
- bin/ascli
|
392
392
|
- bin/asession
|
393
|
+
- examples/build_package.sh
|
393
394
|
- examples/dascli
|
394
395
|
- examples/proxy.pac
|
395
396
|
- examples/rubyc
|
@@ -435,6 +436,7 @@ files:
|
|
435
436
|
- lib/aspera/cli/plugins/preview.rb
|
436
437
|
- lib/aspera/cli/plugins/server.rb
|
437
438
|
- lib/aspera/cli/plugins/shares.rb
|
439
|
+
- lib/aspera/cli/special_values.rb
|
438
440
|
- lib/aspera/cli/sync_actions.rb
|
439
441
|
- lib/aspera/cli/transfer_agent.rb
|
440
442
|
- lib/aspera/cli/transfer_progress.rb
|
@@ -468,7 +470,6 @@ files:
|
|
468
470
|
- lib/aspera/oauth/jwt.rb
|
469
471
|
- lib/aspera/oauth/url_json.rb
|
470
472
|
- lib/aspera/oauth/web.rb
|
471
|
-
- lib/aspera/open_application.rb
|
472
473
|
- lib/aspera/persistency_action_once.rb
|
473
474
|
- lib/aspera/persistency_folder.rb
|
474
475
|
- lib/aspera/preview/file_types.rb
|
metadata.gz.sig
CHANGED
Binary file
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'aspera/log'
|
4
|
-
require 'aspera/environment'
|
5
|
-
require 'rbconfig'
|
6
|
-
require 'singleton'
|
7
|
-
|
8
|
-
module Aspera
|
9
|
-
# Allows a user to open a Url
|
10
|
-
# if method is "text", then URL is displayed on terminal
|
11
|
-
# if method is "graphical", then the URL will be opened with the default browser.
|
12
|
-
class OpenApplication
|
13
|
-
include Singleton
|
14
|
-
USER_INTERFACES = %i[text graphical].freeze
|
15
|
-
class << self
|
16
|
-
def default_gui_mode
|
17
|
-
# assume not remotely connected on macos and windows
|
18
|
-
return :graphical if [Environment::OS_WINDOWS, Environment::OS_X].include?(Environment.os)
|
19
|
-
# unix family
|
20
|
-
return :graphical if ENV.key?('DISPLAY') && !ENV['DISPLAY'].empty?
|
21
|
-
return :text
|
22
|
-
end
|
23
|
-
|
24
|
-
# command must be non blocking
|
25
|
-
def uri_graphical(uri)
|
26
|
-
case Environment.os
|
27
|
-
when Environment::OS_X then return system('open', uri.to_s)
|
28
|
-
when Environment::OS_WINDOWS then return system('start', 'explorer', %Q{"#{uri}"})
|
29
|
-
when Environment::OS_LINUX then return system('xdg-open', uri.to_s)
|
30
|
-
else
|
31
|
-
raise "no graphical open method for #{Environment.os}"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def editor(file_path)
|
36
|
-
if ENV.key?('EDITOR')
|
37
|
-
system(ENV['EDITOR'], file_path.to_s)
|
38
|
-
elsif Environment.os.eql?(Environment::OS_WINDOWS)
|
39
|
-
system('notepad.exe', %Q{"#{file_path}"})
|
40
|
-
else
|
41
|
-
uri_graphical(file_path.to_s)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
attr_accessor :url_method
|
47
|
-
|
48
|
-
def initialize
|
49
|
-
@url_method = self.class.default_gui_mode
|
50
|
-
end
|
51
|
-
|
52
|
-
# this is non blocking
|
53
|
-
def uri(the_url)
|
54
|
-
case @url_method
|
55
|
-
when :graphical
|
56
|
-
self.class.uri_graphical(the_url)
|
57
|
-
when :text
|
58
|
-
case the_url.to_s
|
59
|
-
when /^http/
|
60
|
-
puts "USER ACTION: please enter this url in a browser:\n#{the_url.to_s.red}\n"
|
61
|
-
else
|
62
|
-
puts "USER ACTION: open this:\n#{the_url.to_s.red}\n"
|
63
|
-
end
|
64
|
-
else
|
65
|
-
raise StandardError, "unsupported url open method: #{@url_method}"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|