aspera-cli 4.25.0.pre → 4.25.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +23 -17
- data/CONTRIBUTING.md +119 -47
- data/README.md +325 -239
- data/lib/aspera/agent/direct.rb +14 -12
- data/lib/aspera/agent/factory.rb +9 -6
- data/lib/aspera/agent/transferd.rb +8 -8
- data/lib/aspera/api/aoc.rb +33 -24
- data/lib/aspera/api/ats.rb +1 -0
- data/lib/aspera/api/faspex.rb +11 -5
- data/lib/aspera/ascmd.rb +1 -1
- data/lib/aspera/ascp/installation.rb +7 -7
- data/lib/aspera/ascp/management.rb +9 -5
- data/lib/aspera/assert.rb +3 -3
- data/lib/aspera/cli/extended_value.rb +10 -2
- data/lib/aspera/cli/formatter.rb +15 -62
- data/lib/aspera/cli/manager.rb +9 -43
- data/lib/aspera/cli/plugins/aoc.rb +71 -66
- data/lib/aspera/cli/plugins/ats.rb +30 -36
- data/lib/aspera/cli/plugins/base.rb +11 -6
- data/lib/aspera/cli/plugins/config.rb +21 -16
- data/lib/aspera/cli/plugins/console.rb +2 -1
- data/lib/aspera/cli/plugins/faspex.rb +7 -4
- data/lib/aspera/cli/plugins/faspex5.rb +12 -9
- data/lib/aspera/cli/plugins/faspio.rb +5 -2
- data/lib/aspera/cli/plugins/httpgw.rb +2 -1
- data/lib/aspera/cli/plugins/node.rb +10 -6
- data/lib/aspera/cli/plugins/oauth.rb +12 -11
- data/lib/aspera/cli/plugins/orchestrator.rb +2 -1
- data/lib/aspera/cli/plugins/preview.rb +2 -2
- data/lib/aspera/cli/plugins/server.rb +3 -2
- data/lib/aspera/cli/plugins/shares.rb +59 -20
- data/lib/aspera/cli/transfer_agent.rb +1 -2
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/command_line_builder.rb +5 -5
- data/lib/aspera/coverage.rb +5 -1
- data/lib/aspera/dot_container.rb +108 -0
- data/lib/aspera/environment.rb +69 -89
- data/lib/aspera/faspex_postproc.rb +1 -1
- data/lib/aspera/id_generator.rb +7 -10
- data/lib/aspera/keychain/macos_security.rb +2 -2
- data/lib/aspera/log.rb +2 -1
- data/lib/aspera/oauth/base.rb +25 -38
- data/lib/aspera/oauth/factory.rb +5 -6
- data/lib/aspera/oauth/generic.rb +1 -1
- data/lib/aspera/oauth/jwt.rb +1 -1
- data/lib/aspera/oauth/url_json.rb +4 -3
- data/lib/aspera/oauth/web.rb +2 -2
- data/lib/aspera/preview/file_types.rb +1 -1
- data/lib/aspera/preview/terminal.rb +95 -29
- data/lib/aspera/preview/utils.rb +6 -5
- data/lib/aspera/rest.rb +5 -2
- data/lib/aspera/ssh.rb +6 -5
- data/lib/aspera/sync/conf.schema.yaml +2 -2
- data/lib/aspera/sync/operations.rb +3 -3
- data/lib/aspera/transfer/parameters.rb +6 -6
- data/lib/aspera/transfer/spec.schema.yaml +4 -4
- data/lib/aspera/transfer/spec_doc.rb +11 -21
- data/lib/aspera/uri_reader.rb +17 -3
- data.tar.gz.sig +0 -0
- metadata +17 -2
- metadata.gz.sig +0 -0
|
@@ -3,11 +3,87 @@
|
|
|
3
3
|
# cspell:words Magick MAGICKCORE ITERM mintty winsize termcap
|
|
4
4
|
|
|
5
5
|
require 'rainbow'
|
|
6
|
+
require 'base64'
|
|
6
7
|
require 'io/console'
|
|
7
8
|
require 'aspera/log'
|
|
8
9
|
require 'aspera/environment'
|
|
10
|
+
|
|
9
11
|
module Aspera
|
|
10
12
|
module Preview
|
|
13
|
+
module Backend
|
|
14
|
+
# provides image pixels scaled to terminal
|
|
15
|
+
class Base
|
|
16
|
+
def initialize(reserve:, double:, font_ratio:)
|
|
17
|
+
@reserve = reserve
|
|
18
|
+
@height_ratio = double ? 2.0 : 1.0
|
|
19
|
+
@font_ratio = font_ratio
|
|
20
|
+
end
|
|
21
|
+
Aspera.require_method!(:terminal_pixels)
|
|
22
|
+
# compute scaling to fit terminal
|
|
23
|
+
def terminal_scaling(rows, columns)
|
|
24
|
+
(term_rows, term_columns) = IO.console.winsize || [24, 80]
|
|
25
|
+
term_rows = [term_rows - @reserve, 2].max
|
|
26
|
+
fit_term_ratio = [term_rows.to_f * @font_ratio / rows.to_f, term_columns.to_f / columns.to_f].min
|
|
27
|
+
[(columns * fit_term_ratio).to_i, (rows * fit_term_ratio * @height_ratio / @font_ratio).to_i]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class RMagick < Base
|
|
32
|
+
def initialize(blob, **kwargs)
|
|
33
|
+
super(**kwargs)
|
|
34
|
+
# do not require statically, as the package is optional
|
|
35
|
+
require 'rmagick' # https://rmagick.github.io/index.html
|
|
36
|
+
@image = Magick::ImageList.new.from_blob(blob)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def terminal_pixels
|
|
40
|
+
# quantum depth is 8 or 16, see: `magick xc: -format "%q" info:`
|
|
41
|
+
shift_for_8_bit = Magick::MAGICKCORE_QUANTUM_DEPTH - 8
|
|
42
|
+
# get all pixel colors, adjusted for Rainbow
|
|
43
|
+
pixel_colors = []
|
|
44
|
+
@image.scale(*terminal_scaling(@image.rows, @image.columns)).each_pixel do |pixel, col, row|
|
|
45
|
+
pixel_rgb = [pixel.red, pixel.green, pixel.blue]
|
|
46
|
+
pixel_rgb = pixel_rgb.map{ |color| color >> shift_for_8_bit} unless shift_for_8_bit.eql?(0)
|
|
47
|
+
# init 2-dim array
|
|
48
|
+
pixel_colors[row] ||= []
|
|
49
|
+
pixel_colors[row][col] = pixel_rgb
|
|
50
|
+
end
|
|
51
|
+
pixel_colors
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
class ChunkyPNG < Base
|
|
56
|
+
def initialize(blob, **kwargs)
|
|
57
|
+
super(**kwargs)
|
|
58
|
+
require 'chunky_png'
|
|
59
|
+
@png = ::ChunkyPNG::Image.from_blob(blob)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def terminal_pixels
|
|
63
|
+
src_w = @png.width
|
|
64
|
+
src_h = @png.height
|
|
65
|
+
dst_w, dst_h = terminal_scaling(src_h, src_w)
|
|
66
|
+
dst_w = [dst_w, 1].max
|
|
67
|
+
dst_h = [dst_h, 1].max
|
|
68
|
+
pixel_colors = Array.new(dst_h){Array.new(dst_w)}
|
|
69
|
+
x_ratio = src_w.to_f / dst_w
|
|
70
|
+
y_ratio = src_h.to_f / dst_h
|
|
71
|
+
dst_h.times do |dy|
|
|
72
|
+
sy = (dy * y_ratio).floor
|
|
73
|
+
sy = src_h - 1 if sy >= src_h
|
|
74
|
+
dst_w.times do |dx|
|
|
75
|
+
sx = (dx * x_ratio).floor
|
|
76
|
+
sx = src_w - 1 if sx >= src_w
|
|
77
|
+
rgba = @png.get_pixel(sx, sy)
|
|
78
|
+
# ChunkyPNG stores as 0xRRGGBBAA; extract 8-bit channels
|
|
79
|
+
pixel_colors[dy][dx] = %i[r g b].map{ |i| ::ChunkyPNG::Color.send(i, rgba)}
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
pixel_colors
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
11
87
|
# Display a picture in the terminal.
|
|
12
88
|
# Either use coloured characters or iTerm2 protocol.
|
|
13
89
|
class Terminal
|
|
@@ -22,41 +98,31 @@ module Aspera
|
|
|
22
98
|
private_constant :TERM_ENV_VARS, :ITERM_NAMES, :DEFAULT_FONT_RATIO
|
|
23
99
|
class << self
|
|
24
100
|
# @param blob [String] The image as a binary string
|
|
25
|
-
# @param reserve [Integer] Number of lines to reserve for other text than the image
|
|
26
101
|
# @param text [Boolean] `true` to display the image as text, `false` to use iTerm2 if supported
|
|
102
|
+
# @param reserve [Integer] Number of lines to reserve for other text than the image
|
|
27
103
|
# @param double [Boolean] `true` to use colors on half lines, `false` to use colors on full lines
|
|
28
104
|
# @param font_ratio [Float] ratio = font height / font width
|
|
29
105
|
# @return [String] The image as text, or the iTerm2 escape sequence
|
|
30
|
-
def build(blob,
|
|
106
|
+
def build(blob, text: false, reserve: 3, double: true, font_ratio: DEFAULT_FONT_RATIO)
|
|
31
107
|
return '[Image display requires a terminal]' unless Environment.terminal?
|
|
32
108
|
return iterm_display_image(blob) if iterm_supported? && !text
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
109
|
+
pixel_colors =
|
|
110
|
+
begin
|
|
111
|
+
Log.log.debug('Trying chunky_png')
|
|
112
|
+
Backend::ChunkyPNG.new(blob, reserve: reserve, double: double, font_ratio: font_ratio).terminal_pixels
|
|
113
|
+
rescue => e
|
|
114
|
+
Log.log.debug(e.message)
|
|
115
|
+
begin
|
|
116
|
+
Log.log.debug('Trying rmagick')
|
|
117
|
+
Backend::RMagick.new(blob, reserve: reserve, double: double, font_ratio: font_ratio).terminal_pixels
|
|
118
|
+
rescue => e
|
|
119
|
+
Log.log.debug(e.message)
|
|
120
|
+
nil
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
if pixel_colors.nil?
|
|
39
124
|
return iterm_display_image(blob) if iterm_supported?
|
|
40
|
-
|
|
41
|
-
raise e
|
|
42
|
-
end
|
|
43
|
-
image = Magick::ImageList.new.from_blob(blob)
|
|
44
|
-
(term_rows, term_columns) = IO.console.winsize
|
|
45
|
-
term_rows -= reserve
|
|
46
|
-
# compute scaling to fit terminal
|
|
47
|
-
fit_term_ratio = [term_rows.to_f * font_ratio / image.rows.to_f, term_columns.to_f / image.columns.to_f].min
|
|
48
|
-
height_ratio = double ? 2.0 : 1.0
|
|
49
|
-
image = image.scale((image.columns * fit_term_ratio).to_i, (image.rows * fit_term_ratio * height_ratio / font_ratio).to_i)
|
|
50
|
-
# quantum depth is 8 or 16, see: `magick xc: -format "%q" info:`
|
|
51
|
-
shift_for_8_bit = Magick::MAGICKCORE_QUANTUM_DEPTH - 8
|
|
52
|
-
# get all pixel colors, adjusted for Rainbow
|
|
53
|
-
pixel_colors = []
|
|
54
|
-
image.each_pixel do |pixel, col, row|
|
|
55
|
-
pixel_rgb = [pixel.red, pixel.green, pixel.blue]
|
|
56
|
-
pixel_rgb = pixel_rgb.map{ |color| color >> shift_for_8_bit} unless shift_for_8_bit.eql?(0)
|
|
57
|
-
# init 2-dim array
|
|
58
|
-
pixel_colors[row] ||= []
|
|
59
|
-
pixel_colors[row][col] = pixel_rgb
|
|
125
|
+
raise 'Cannot decode picture.'
|
|
60
126
|
end
|
|
61
127
|
# now generate text
|
|
62
128
|
text_pixels = []
|
|
@@ -88,7 +154,7 @@ module Aspera
|
|
|
88
154
|
}.map{ |k, v| "#{k}=#{v}"}.join(';')
|
|
89
155
|
# \a is BEL, \e is ESC : https://github.com/ruby/ruby/blob/master/doc/syntax/literals.rdoc#label-Strings
|
|
90
156
|
# escape sequence for iTerm2 image display
|
|
91
|
-
return "\e]1337;File=#{arguments}:#{Base64.
|
|
157
|
+
return "\e]1337;File=#{arguments}:#{Base64.strict_encode64(blob)}\a"
|
|
92
158
|
end
|
|
93
159
|
|
|
94
160
|
# @return [Boolean] true if the terminal supports iTerm2 image display
|
data/lib/aspera/preview/utils.rb
CHANGED
|
@@ -44,17 +44,18 @@ module Aspera
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# @return nil
|
|
47
|
+
# Execute external command
|
|
48
|
+
# @return [nil]
|
|
50
49
|
def external_command(command_sym, command_args)
|
|
51
50
|
Aspera.assert_values(command_sym, EXTERNAL_TOOLS){'command'}
|
|
52
|
-
Environment.secure_execute(
|
|
51
|
+
Environment.secure_execute(command_sym.to_s, *command_args.map(&:to_s), out: File::NULL, err: File::NULL)
|
|
53
52
|
end
|
|
54
53
|
|
|
54
|
+
# Execute external command and capture output
|
|
55
|
+
# @return [String]
|
|
55
56
|
def external_capture(command_sym, command_args)
|
|
56
57
|
Aspera.assert_values(command_sym, EXTERNAL_TOOLS){'command'}
|
|
57
|
-
return Environment.
|
|
58
|
+
return Environment.secure_execute(command_sym.to_s, *command_args.map(&:to_s), mode: :capture)
|
|
58
59
|
end
|
|
59
60
|
|
|
60
61
|
def ffmpeg(gl_p: FFMPEG_DEFAULT_PARAMS, in_p: [], in_f:, out_p: [], out_f:)
|
data/lib/aspera/rest.rb
CHANGED
|
@@ -307,9 +307,12 @@ module Aspera
|
|
|
307
307
|
# @param body [Hash, String] body parameters
|
|
308
308
|
# @param headers [Hash] additional headers (override Content-Type)
|
|
309
309
|
# @param save_to_file [String, nil](filepath)
|
|
310
|
-
# @param exception [
|
|
310
|
+
# @param exception [Boolean] `true`, error raise exception
|
|
311
311
|
# @param ret [:data, :resp, :both] Tell to return only data, only http response, or both
|
|
312
|
-
# @return [
|
|
312
|
+
# @return [(HTTPResponse,Hash)] If ret is :both
|
|
313
|
+
# @return [HTTPResponse] If ret is :resp
|
|
314
|
+
# @return [Hash] If ret is :data
|
|
315
|
+
# @raise [RestCallError] on error if `exception` is true
|
|
313
316
|
def call(
|
|
314
317
|
operation:,
|
|
315
318
|
subpath: nil,
|
data/lib/aspera/ssh.rb
CHANGED
|
@@ -35,16 +35,17 @@ module Aspera
|
|
|
35
35
|
# ssh_options: same as Net::SSH.start
|
|
36
36
|
# see: https://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
|
|
37
37
|
def initialize(host, username, ssh_options)
|
|
38
|
-
Log.log.debug{"ssh:#{username}@#{host}"}
|
|
39
|
-
Log.log.debug{"ssh_options:#{ssh_options}"}
|
|
40
38
|
Aspera.assert_type(host, String)
|
|
41
39
|
Aspera.assert_type(username, String)
|
|
42
40
|
Aspera.assert_type(ssh_options, Hash)
|
|
43
|
-
ssh_options[:use_agent] = false unless ssh_options.key?(:use_agent)
|
|
44
41
|
@host = host
|
|
45
42
|
@username = username
|
|
46
|
-
@ssh_options = ssh_options
|
|
47
|
-
@ssh_options[:logger] = Log.log
|
|
43
|
+
@ssh_options = ssh_options.dup
|
|
44
|
+
@ssh_options[:logger] = Log.log unless @ssh_options.key?(:logger)
|
|
45
|
+
@ssh_options[:verbose] = :warn unless @ssh_options.key?(:verbose)
|
|
46
|
+
@ssh_options[:use_agent] = false unless @ssh_options.key?(:use_agent)
|
|
47
|
+
Log.log.debug{"ssh:#{@username}@#{@host}"}
|
|
48
|
+
Log.dump(:ssh_options, @ssh_options)
|
|
48
49
|
end
|
|
49
50
|
|
|
50
51
|
# Anything on stderr raises an exception
|
|
@@ -4,8 +4,8 @@ description: Async session description, identical to `asyncs` Node API.
|
|
|
4
4
|
$comment: >-
|
|
5
5
|
This is a YAML version of the original JSON schema from asyncs API.
|
|
6
6
|
It is modified with special `x-` fields.
|
|
7
|
-
x-ts-name [
|
|
8
|
-
x-ts-convert [String]
|
|
7
|
+
x-ts-name [Boolean,String] `true` if same name in transfer spec, else real name in transfer spec
|
|
8
|
+
x-ts-convert [String] Name of methods to convert value from transfer spec to `conf`
|
|
9
9
|
`x-` fields are also documented in `command_line_builder.rb`
|
|
10
10
|
type: object
|
|
11
11
|
required:
|
|
@@ -146,7 +146,7 @@ module Aspera
|
|
|
146
146
|
session_builder.process_params
|
|
147
147
|
session_builder.add_env_args(env_args)
|
|
148
148
|
end
|
|
149
|
-
Environment.secure_execute(
|
|
149
|
+
Environment.secure_execute(Ascp::Installation.instance.path(:async), *env_args[:args], env: env_args[:env])
|
|
150
150
|
end
|
|
151
151
|
return
|
|
152
152
|
end
|
|
@@ -174,7 +174,7 @@ module Aspera
|
|
|
174
174
|
# @return [Hash] parsed output of asyncadmin
|
|
175
175
|
def admin_status(sync_info)
|
|
176
176
|
Aspera.assert(PARAM_KEYS.any?{ |k| sync_info.key?(k)}, type: Error){'At least one of `local` or `sessions` must be present in async parameters'}
|
|
177
|
-
arguments = ['--quiet']
|
|
177
|
+
arguments = [ASYNC_ADMIN_EXECUTABLE, '--quiet']
|
|
178
178
|
if sync_info.key?('local')
|
|
179
179
|
# `conf` format
|
|
180
180
|
arguments.push("--name=#{sync_info['name']}")
|
|
@@ -197,7 +197,7 @@ module Aspera
|
|
|
197
197
|
raise Error, 'Missing either local_db_dir or local_dir'
|
|
198
198
|
end
|
|
199
199
|
end
|
|
200
|
-
stdout = Environment.
|
|
200
|
+
stdout = Environment.secure_execute(*arguments, mode: :capture)
|
|
201
201
|
return parse_status(stdout)
|
|
202
202
|
end
|
|
203
203
|
|
|
@@ -45,12 +45,12 @@ module Aspera
|
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
# @param job_spec [Hash]
|
|
49
|
-
# @param ascp_args [Array]
|
|
50
|
-
# @param quiet [
|
|
51
|
-
# @param trusted_certs [Array]
|
|
52
|
-
# @param client_ssh_key [
|
|
53
|
-
# @param check_ignore_cb [Proc]
|
|
48
|
+
# @param job_spec [Hash] Transfer spec
|
|
49
|
+
# @param ascp_args [Array] Other ascp args
|
|
50
|
+
# @param quiet [Boolean] Remove ascp output
|
|
51
|
+
# @param trusted_certs [Array] Trusted certificates
|
|
52
|
+
# @param client_ssh_key [:rsa,:dsa] :rsa or :dsa
|
|
53
|
+
# @param check_ignore_cb [Proc] Callback
|
|
54
54
|
def initialize(
|
|
55
55
|
job_spec,
|
|
56
56
|
ascp_args: nil,
|
|
@@ -7,8 +7,8 @@ $comment: >-
|
|
|
7
7
|
The following extensions are used for mapping to ascp arguments.
|
|
8
8
|
x-cli-envvar [String] Name of env var
|
|
9
9
|
x-cli-option [String] Command line option (starts with "-"), or `true`: same as ts, or `false`: not an option
|
|
10
|
-
x-cli-switch [
|
|
11
|
-
x-cli-special [
|
|
10
|
+
x-cli-switch [Boolean] `true` if option has no arg, else by default option has a value
|
|
11
|
+
x-cli-special [Boolean] `true` if not anaged by command line generator (special handling: option or argument)
|
|
12
12
|
x-cli-convert [String,Hash] Method name for Convert object or Conversion Hash for enum: ts to arg
|
|
13
13
|
x-agents [Array] Supported agents (for doc only), if not specified: all
|
|
14
14
|
x-deprecation [String] Deprecation message for doc
|
|
@@ -106,7 +106,7 @@ properties:
|
|
|
106
106
|
delete_source:
|
|
107
107
|
$comment: "TODO: implement"
|
|
108
108
|
description: >-
|
|
109
|
-
Remove
|
|
109
|
+
Remove transferred source files after transfer success.
|
|
110
110
|
Equivalent to `remove_after_transfer` + `remove_empty_directories` + `remove_empty_source_directory`.
|
|
111
111
|
Take precedence over those.
|
|
112
112
|
type: boolean
|
|
@@ -881,7 +881,7 @@ properties:
|
|
|
881
881
|
xfer_max_retries:
|
|
882
882
|
description: >-
|
|
883
883
|
Maximum number of retries, for node API initiated transfers.
|
|
884
|
-
Shall not exceed aspera.conf `transfer_manager_max_retries` (default 5).
|
|
884
|
+
Shall not exceed `aspera.conf` parameter `transfer_manager_max_retries` (default 5).
|
|
885
885
|
type: integer
|
|
886
886
|
x-agents:
|
|
887
887
|
- node
|
|
@@ -8,20 +8,14 @@ module Aspera
|
|
|
8
8
|
# Generate documentation from Schema, for Transfer Spec, or async Conf spec
|
|
9
9
|
class SpecDoc
|
|
10
10
|
class << self
|
|
11
|
-
#
|
|
12
|
-
def agent_to_short(agent_sym)
|
|
13
|
-
agent_sym.to_sym.eql?(:direct) ? :a : agent_sym.to_s[0].to_sym
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# @param formatter [Cli::Formatter] Formatter to use, methods: markdown, tick, check_row
|
|
11
|
+
# @param formatter [Cli::Formatter] Formatter to use, methods: markdown_text, tick, check_row
|
|
17
12
|
# @param include_option [Boolean] `true` : include CLI options
|
|
18
13
|
# @param agent_columns [Boolean] `true` : include agents columns
|
|
19
14
|
# @param schema [Hash] The JSON spec
|
|
20
15
|
# @return [Array] a table suitable to display in manual
|
|
21
16
|
def man_table(formatter, include_option: false, agent_columns: true, schema: Spec::SCHEMA)
|
|
22
|
-
col_local = agent_to_short(:direct)
|
|
23
17
|
cols = %i[name type description]
|
|
24
|
-
cols.insert(-2, *
|
|
18
|
+
cols.insert(-2, *Agent::Factory::ALL.values.map{ |i| i[:short]}.sort) if agent_columns
|
|
25
19
|
rows = []
|
|
26
20
|
schema['properties'].each do |name, info|
|
|
27
21
|
rows.concat(man_table(formatter, include_option: include_option, agent_columns: agent_columns, schema: info).last.map{ |h| h.merge(name: "#{name}.#{h[:name]}")}) if info['type'].eql?('object') && info['properties']
|
|
@@ -35,25 +29,25 @@ module Aspera
|
|
|
35
29
|
# Render Markdown formatting and split lines
|
|
36
30
|
columns[:description] =
|
|
37
31
|
info['description']
|
|
38
|
-
.gsub(Markdown::FORMATS){formatter.
|
|
32
|
+
.gsub(Markdown::FORMATS){formatter.markdown_text(Regexp.last_match)}
|
|
39
33
|
.split("\n") if info.key?('description')
|
|
40
34
|
columns[:description].unshift("DEPRECATED: #{info['x-deprecation']}") if info.key?('x-deprecation')
|
|
41
35
|
# Add flags for supported agents in doc
|
|
42
36
|
agents = []
|
|
43
|
-
|
|
44
|
-
agents.push(
|
|
37
|
+
Agent::Factory::ALL.each_key do |sym|
|
|
38
|
+
agents.push(sym) if info['x-agents'].nil? || info['x-agents'].include?(sym.to_s)
|
|
45
39
|
end
|
|
46
|
-
Aspera.assert(agents.include?(
|
|
40
|
+
Aspera.assert(agents.include?(:direct)){"#{name}: x-cli-option requires agent direct (or nil)"} if info['x-cli-option']
|
|
47
41
|
if agent_columns
|
|
48
|
-
|
|
49
|
-
columns[
|
|
42
|
+
Agent::Factory::ALL.each do |sym, names|
|
|
43
|
+
columns[names[:short]] = formatter.tick(agents.include?(sym))
|
|
50
44
|
end
|
|
51
45
|
else
|
|
52
|
-
columns[:description].push("(#{agents.map
|
|
46
|
+
columns[:description].push("(#{agents.map{ |i| Agent::Factory::ALL[i][:short].to_s.upcase}.sort.join(', ')})") unless agents.length.eql?(Agent::Factory::ALL.length)
|
|
53
47
|
end
|
|
54
48
|
# Only keep lines that are usable in supported agents
|
|
55
49
|
next false if agents.empty?
|
|
56
|
-
columns[:description].push("Allowed values: #{info['enum'].map{ |v| formatter.
|
|
50
|
+
columns[:description].push("Allowed values: #{info['enum'].map{ |v| formatter.markdown_text("`#{v}`")}.join(', ')}") if info.key?('enum')
|
|
57
51
|
if include_option
|
|
58
52
|
envvar_prefix = ''
|
|
59
53
|
cli_option =
|
|
@@ -70,17 +64,13 @@ module Aspera
|
|
|
70
64
|
"#{info['x-cli-option']}#{sep}#{"(#{conversion_tag})" if conversion_tag}#{arg_type}"
|
|
71
65
|
end
|
|
72
66
|
short = info.key?('x-cli-short') ? "(#{info['x-cli-short']})" : nil
|
|
73
|
-
columns[:description].push("(#{'special:' if info['x-cli-special']}#{envvar_prefix}#{formatter.
|
|
67
|
+
columns[:description].push("(#{'special:' if info['x-cli-special']}#{envvar_prefix}#{formatter.markdown_text("`#{cli_option}`")})#{short}") if cli_option
|
|
74
68
|
end
|
|
75
69
|
rows.push(formatter.check_row(columns))
|
|
76
70
|
end
|
|
77
71
|
[cols, rows.sort_by{ |i| i[:name]}]
|
|
78
72
|
end
|
|
79
73
|
end
|
|
80
|
-
# Agents shown in manual for parameters (sub list)
|
|
81
|
-
AGENT_LIST = Agent::Factory.instance.list.map do |agent_sym|
|
|
82
|
-
[agent_sym, agent_sym.to_s.capitalize, agent_to_short(agent_sym)]
|
|
83
|
-
end.sort_by(&:last).freeze
|
|
84
74
|
end
|
|
85
75
|
end
|
|
86
76
|
end
|
data/lib/aspera/uri_reader.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'uri'
|
|
4
|
+
require 'base64'
|
|
4
5
|
require 'aspera/assert'
|
|
5
6
|
require 'aspera/rest'
|
|
6
7
|
require 'aspera/temp_file_manager'
|
|
@@ -19,6 +20,13 @@ module Aspera
|
|
|
19
20
|
case uri.scheme
|
|
20
21
|
when 'http', 'https'
|
|
21
22
|
return Rest.new(base_url: uri_to_read, redirect_max: 5).read(nil, headers: {'Accept' => '*/*'})
|
|
23
|
+
when 'data'
|
|
24
|
+
metadata, encoded_data = uri.opaque.split(',', 2)
|
|
25
|
+
if metadata.end_with?(';base64')
|
|
26
|
+
Base64.decode64(encoded_data)
|
|
27
|
+
else
|
|
28
|
+
URI.decode_www_form_component(encoded_data)
|
|
29
|
+
end
|
|
22
30
|
when SCHEME_FILE, NilClass
|
|
23
31
|
local_file_path = uri.path
|
|
24
32
|
raise Error, 'URL shall have a path, check syntax' if local_file_path.nil?
|
|
@@ -35,12 +43,18 @@ module Aspera
|
|
|
35
43
|
# require specific file scheme: the path part is "relative", or absolute if there are 4 slash
|
|
36
44
|
raise "use format: #{SCHEME_FILE_PFX2}<path>" unless url.start_with?(SCHEME_FILE_PFX2)
|
|
37
45
|
return File.expand_path(url[SCHEME_FILE_PFX2.length..-1])
|
|
46
|
+
elsif url.start_with?('data:')
|
|
47
|
+
# download to temp file
|
|
48
|
+
# auto-delete on exit
|
|
49
|
+
temp_file = TempFileManager.instance.new_file_path_global('uri_reader')
|
|
50
|
+
File.write(temp_file, read(url), binmode: true)
|
|
51
|
+
return temp_file
|
|
38
52
|
else
|
|
39
53
|
# download to temp file
|
|
40
54
|
# auto-delete on exit
|
|
41
|
-
|
|
42
|
-
Aspera::Rest.new(base_url: url, redirect_max: 3).call(operation: 'GET', save_to_file:
|
|
43
|
-
return
|
|
55
|
+
temp_file = TempFileManager.instance.new_file_path_global(suffix: File.basename(url))
|
|
56
|
+
Aspera::Rest.new(base_url: url, redirect_max: 3).call(operation: 'GET', save_to_file: temp_file)
|
|
57
|
+
return temp_file
|
|
44
58
|
end
|
|
45
59
|
end
|
|
46
60
|
end
|
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.25.0
|
|
4
|
+
version: 4.25.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Laurent Martin
|
|
@@ -52,6 +52,20 @@ dependencies:
|
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '3.1'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: chunky_png
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '1.4'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '1.4'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
70
|
name: csv
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -353,6 +367,7 @@ files:
|
|
|
353
367
|
- lib/aspera/data/5
|
|
354
368
|
- lib/aspera/data/6
|
|
355
369
|
- lib/aspera/data_repository.rb
|
|
370
|
+
- lib/aspera/dot_container.rb
|
|
356
371
|
- lib/aspera/environment.rb
|
|
357
372
|
- lib/aspera/faspex_gw.rb
|
|
358
373
|
- lib/aspera/faspex_postproc.rb
|
|
@@ -442,7 +457,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
442
457
|
version: '0'
|
|
443
458
|
requirements:
|
|
444
459
|
- Read the manual for any requirement
|
|
445
|
-
rubygems_version:
|
|
460
|
+
rubygems_version: 4.0.3
|
|
446
461
|
specification_version: 4
|
|
447
462
|
summary: 'Execute actions using command line on IBM Aspera Server products: Aspera
|
|
448
463
|
on Cloud, Faspex, Shares, Node, Console, Orchestrator, High Speed Transfer Server'
|
metadata.gz.sig
CHANGED
|
Binary file
|