aspera-cli 4.18.0 → 4.18.1
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.
- 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
|