aspera-cli 4.0.0.pre3 → 4.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +695 -205
  3. data/bin/dascli +13 -0
  4. data/docs/README.erb.md +615 -157
  5. data/docs/test_env.conf +23 -5
  6. data/docs/transfer_spec.html +1 -1
  7. data/examples/aoc.rb +14 -3
  8. data/examples/faspex4.rb +78 -0
  9. data/lib/aspera/aoc.rb +87 -108
  10. data/lib/aspera/cli/formater.rb +2 -0
  11. data/lib/aspera/cli/main.rb +46 -34
  12. data/lib/aspera/cli/plugin.rb +9 -4
  13. data/lib/aspera/cli/plugins/alee.rb +1 -1
  14. data/lib/aspera/cli/plugins/aoc.rb +207 -182
  15. data/lib/aspera/cli/plugins/ats.rb +2 -2
  16. data/lib/aspera/cli/plugins/config.rb +173 -117
  17. data/lib/aspera/cli/plugins/console.rb +2 -2
  18. data/lib/aspera/cli/plugins/faspex.rb +51 -36
  19. data/lib/aspera/cli/plugins/faspex5.rb +82 -41
  20. data/lib/aspera/cli/plugins/node.rb +3 -3
  21. data/lib/aspera/cli/plugins/preview.rb +35 -25
  22. data/lib/aspera/cli/plugins/server.rb +23 -8
  23. data/lib/aspera/cli/transfer_agent.rb +7 -6
  24. data/lib/aspera/cli/version.rb +1 -1
  25. data/lib/aspera/cos_node.rb +33 -28
  26. data/lib/aspera/environment.rb +2 -2
  27. data/lib/aspera/fasp/connect.rb +28 -21
  28. data/lib/aspera/fasp/http_gw.rb +140 -28
  29. data/lib/aspera/fasp/installation.rb +101 -53
  30. data/lib/aspera/fasp/local.rb +88 -45
  31. data/lib/aspera/fasp/manager.rb +15 -0
  32. data/lib/aspera/fasp/node.rb +4 -4
  33. data/lib/aspera/fasp/parameters.rb +6 -18
  34. data/lib/aspera/fasp/resume_policy.rb +13 -12
  35. data/lib/aspera/log.rb +1 -1
  36. data/lib/aspera/node.rb +61 -1
  37. data/lib/aspera/oauth.rb +49 -46
  38. data/lib/aspera/persistency_folder.rb +9 -4
  39. data/lib/aspera/preview/file_types.rb +53 -21
  40. data/lib/aspera/preview/generator.rb +3 -3
  41. data/lib/aspera/rest.rb +29 -18
  42. data/lib/aspera/secrets.rb +20 -0
  43. data/lib/aspera/temp_file_manager.rb +19 -0
  44. data/lib/aspera/web_auth.rb +105 -0
  45. metadata +42 -22
@@ -1,9 +1,11 @@
1
- require 'mimemagic'
2
- require 'mimemagic/overlay'
1
+ require 'aspera/log'
2
+ require 'singleton'
3
3
 
4
4
  module Aspera
5
5
  module Preview
6
+ # function conversion_type returns one of the types: CONVERSION_TYPES
6
7
  class FileTypes
8
+ include Singleton
7
9
  # values for conversion_type : input format
8
10
  CONVERSION_TYPES=[
9
11
  :image,
@@ -148,6 +150,7 @@ module Aspera
148
150
  'dif' => :office,
149
151
  'divx' => :video,
150
152
  'dng' => :image,
153
+ 'docx' => :office,
151
154
  'dpx' => :image,
152
155
  'epdf' => :image,
153
156
  'epi' => :image,
@@ -204,6 +207,7 @@ module Aspera
204
207
  'pam' => :image,
205
208
  'pcd' => :image,
206
209
  'pcds' => :image,
210
+ 'pdf' => :pdf,
207
211
  'pef' => :image,
208
212
  'picon' => :image,
209
213
  'pict' => :image,
@@ -261,39 +265,67 @@ module Aspera
261
265
  'x3f' => :image,
262
266
  'xcf' => :image,
263
267
  'xlk' => :office,
268
+ 'xlsx' => :office,
269
+ 'xls' => :office,
264
270
  'ycbcr' => :image,
265
271
  'ycbcra' => :image,
266
272
  'yuv' => :image,
267
273
  'zabw' => :office}
268
274
 
269
- #private_constant :SUPPORTED_MIME_TYPES, :SUPPORTED_EXTENSIONS
275
+ private_constant :SUPPORTED_MIME_TYPES, :SUPPORTED_EXTENSIONS
270
276
 
271
- def self.mime_from_file(filepath)
277
+ # @attr use_mimemagic [bool] true to use mimemagic to determine real mime type based on file content
278
+ attr_accessor :use_mimemagic
279
+
280
+ def initialize
281
+ @use_mimemagic=false
282
+ end
283
+
284
+ # use mime magic to find mime type based on file content (magic numbers)
285
+ def mime_from_file(filepath)
286
+ # moved here, as mimemagic can cause installation issues
287
+ require 'mimemagic'
288
+ require 'mimemagic/version'
289
+ require 'mimemagic/overlay' if MimeMagic::VERSION.start_with?('0.3.')
290
+ # check magic number inside file (empty string if not found)
272
291
  detected_mime=MimeMagic.by_magic(File.open(filepath)).to_s
273
- detected_mime=MimeMagic.by_path(filepath).to_s if detected_mime.empty?
292
+ # check extension only
293
+ if !SUPPORTED_MIME_TYPES.has_key?(detected_mime)
294
+ Log.log.debug("no conversion for #{detected_mime}, trying extension")
295
+ detected_mime=MimeMagic.by_extension(File.extname(filepath)).to_s
296
+ end
274
297
  detected_mime=nil if detected_mime.empty?
298
+ Log.log.debug("mimemagic: #{detected_mime.class.name} [#{detected_mime}]")
275
299
  return detected_mime
276
300
  end
277
301
 
278
- def self.conversion_type(filepath,mimetype,try_local_mime)
279
- detected_mime=nil
280
- if try_local_mime
302
+ # return file type, one of enum CONVERSION_TYPES
303
+ # @param filepath [String] full path to file
304
+ # @param mimetype [String] provided by node api
305
+ def conversion_type(filepath,mimetype)
306
+ Log.log.debug("conversion_type(#{filepath},m=#{mimetype},t=#{@use_mimemagic})")
307
+ # 1- get type from provided mime type, using local mapping
308
+ conv_type=SUPPORTED_MIME_TYPES[mimetype] if ! mimetype.nil?
309
+ # 2- else, from computed mime type (if available)
310
+ if conv_type.nil? and @use_mimemagic
281
311
  detected_mime=mime_from_file(filepath)
282
- if mimetype.eql?(detected_mime)
283
- Log.log.debug("matching mime type per magic number")
284
- else
285
- # note: detected can be nil
286
- Log.log.debug("non matching mime types: node=[#{mimetype}], magic=[#{detected_mime}]")
312
+ if ! detected_mime.nil?
313
+ conv_type=SUPPORTED_MIME_TYPES[detected_mime]
314
+ if ! mimetype.nil?
315
+ if mimetype.eql?(detected_mime)
316
+ Log.log.debug("matching mime type per magic number")
317
+ else
318
+ # note: detected can be nil
319
+ Log.log.debug("non matching mime types: node=[#{mimetype}], magic=[#{detected_mime}]")
320
+ end
321
+ end
287
322
  end
288
323
  end
289
- # 1- get type from provided mime type
290
- result=FileTypes::SUPPORTED_MIME_TYPES[mimetype] unless mimetype.nil?
291
- # 2- else, from computed mime type
292
- result||=FileTypes::SUPPORTED_MIME_TYPES[detected_mime] unless detected_mime.nil?
293
- extension = File.extname(filepath).downcase.gsub(/^\./,'')
294
- # 3- else, from local extensions
295
- result||=FileTypes::SUPPORTED_EXTENSIONS[extension]
296
- return result
324
+ # 3- else, from extensions, using local mapping
325
+ extension = File.extname(filepath.downcase)[1..-1]
326
+ conv_type=SUPPORTED_EXTENSIONS[extension] if conv_type.nil?
327
+ Log.log.debug("conversion_type(#{extension}): #{conv_type.class.name} [#{conv_type}]")
328
+ return conv_type
297
329
  end
298
330
  end
299
331
  end
@@ -15,7 +15,7 @@ module Aspera
15
15
 
16
16
  # @param src source file path
17
17
  # @param dst destination file path
18
- # @param api_mime_type optional mime type as provided by node api
18
+ # @param api_mime_type optional mime type as provided by node api (or nil)
19
19
  # node API mime types are from: http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
20
20
  # supported preview type is one of Preview::PREVIEW_FORMATS
21
21
  # the resulting preview file type is taken from destination file extension.
@@ -25,14 +25,14 @@ module Aspera
25
25
  # -> preview_format is one of Generator::PREVIEW_FORMATS
26
26
  # the conversion video->mp4 is implemented in methods: convert_video_to_mp4_using_<video_conversion>
27
27
  # -> conversion method is one of Generator::VIDEO_CONVERSION_METHODS
28
- def initialize(options,src,dst,main_temp_dir,api_mime_type=nil,try_local_mime=true)
28
+ def initialize(options,src,dst,main_temp_dir,api_mime_type)
29
29
  @options=options
30
30
  @source_file_path=src
31
31
  @destination_file_path=dst
32
32
  @temp_folder=File.join(main_temp_dir,@source_file_path.split('/').last.gsub(/\s/, '_').gsub(/\W/, ''))
33
33
  # extract preview format from extension of target file
34
34
  @preview_format_symb=File.extname(@destination_file_path).gsub(/^\./,'').to_sym
35
- @conversion_type=FileTypes.conversion_type(@source_file_path,api_mime_type,try_local_mime)
35
+ @conversion_type=FileTypes.instance.conversion_type(@source_file_path,api_mime_type)
36
36
  end
37
37
 
38
38
  # name of processing method in this object
data/lib/aspera/rest.rb CHANGED
@@ -7,6 +7,7 @@ require 'net/http'
7
7
  require 'net/https'
8
8
  require 'json'
9
9
  require 'base64'
10
+ require 'cgi'
10
11
  require 'ruby-progressbar'
11
12
 
12
13
  # add cancel method to http
@@ -33,6 +34,7 @@ module Aspera
33
34
  # true if https ignore certificate
34
35
  @@insecure=false
35
36
  @@user_agent='Ruby'
37
+ @@download_partial_suffix='.http_partial'
36
38
 
37
39
  public
38
40
  def self.insecure=(v); @@insecure=v;Log.log.debug("insecure => #{@@insecure}".red);end
@@ -98,9 +100,10 @@ module Aspera
98
100
  public
99
101
 
100
102
  attr_reader :params
103
+ attr_reader :oauth
101
104
 
102
- # @param a_rest_params default call parameters and authentication (:auth) :
103
- # :type (:basic, :oauth2, :url)
105
+ # @param a_rest_params default call parameters (merged at call) and (+) authentication (:auth) :
106
+ # :type (:basic, :oauth2, :url, :none)
104
107
  # :username [:basic]
105
108
  # :password [:basic]
106
109
  # :url_creds [:url]
@@ -117,16 +120,6 @@ module Aspera
117
120
  # default is no auth
118
121
  @params[:auth]||={:type=>:none}
119
122
  @params[:not_auth_codes]||=['401']
120
- # translate old auth parameters, remove prefix, place in auth
121
- [:auth,:basic,:oauth].each do |p_sym|
122
- p_str=p_sym.to_s+'_'
123
- @params.keys.select{|k|k.to_s.start_with?(p_str)}.each do |k_sym|
124
- name=k_sym.to_s[p_str.length..-1]
125
- name='grant' if k_sym.eql?(:oauth_type)
126
- @params[:auth][name.to_sym]=@params[k_sym]
127
- @params.delete(k_sym)
128
- end
129
- end
130
123
  @oauth=Oauth.new(@params[:auth]) if @params[:auth][:type].eql?(:oauth2)
131
124
  Log.dump('REST params(2)',@params)
132
125
  end
@@ -153,6 +146,7 @@ module Aspera
153
146
  Log.log.debug("accessing #{call_data[:subpath]}".red.bold.bg_green)
154
147
  call_data[:headers]||={}
155
148
  call_data[:headers]['User-Agent'] ||= @@user_agent
149
+ # defaults from @params are overriden by call dataz
156
150
  call_data=@params.deep_merge(call_data)
157
151
  case call_data[:auth][:type]
158
152
  when :none
@@ -206,10 +200,13 @@ module Aspera
206
200
 
207
201
  Log.log.debug("call_data = #{call_data}")
208
202
  result={:http=>nil}
203
+ # start a block to be able to retry the actual HTTP request
209
204
  begin
210
205
  # we try the call, and will retry only if oauth, as we can, first with refresh, and then re-auth if refresh is bad
211
206
  oauth_tries ||= 2
207
+ tries_remain_redirect||=4
212
208
  Log.log.debug("send request")
209
+ # make http request (pipelined)
213
210
  http_session.request(req) do |response|
214
211
  result[:http] = response
215
212
  if call_data.has_key?(:save_to_file)
@@ -223,12 +220,12 @@ module Aspera
223
220
  target_file=call_data[:save_to_file]
224
221
  # override user's path to path in header
225
222
  if !response['Content-Disposition'].nil? and m=response['Content-Disposition'].match(/filename="([^"]+)"/)
226
- target_file=m[1]
223
+ target_file=File.join(File.dirname(target_file),m[1])
227
224
  end
228
225
  # download with temp filename
229
- target_file_tmp=target_file+'.http.partial'
226
+ target_file_tmp="#{target_file}#{@@download_partial_suffix}"
230
227
  Log.log.debug("saving to: #{target_file}")
231
- File.open(target_file_tmp, "wb") do |file|
228
+ File.open(target_file_tmp, 'wb') do |file|
232
229
  result[:http].read_body do |fragment|
233
230
  file.write(fragment)
234
231
  new_process=progress.progress+fragment.length
@@ -239,7 +236,7 @@ module Aspera
239
236
  # rename at the end
240
237
  File.rename(target_file_tmp, target_file)
241
238
  progress=nil
242
- end
239
+ end # save_to_file
243
240
  end
244
241
  # sometimes there is a ITF8 char (e.g. (c) )
245
242
  result[:http].body.force_encoding("UTF-8") if result[:http].body.is_a?(String)
@@ -267,10 +264,24 @@ module Aspera
267
264
  end
268
265
  Log.log.debug("using new token=#{call_data[:headers]['Authorization']}")
269
266
  retry unless (oauth_tries -= 1).zero?
270
- end # if
267
+ end # if oauth
268
+ # moved ?
269
+ if e.response.is_a?(Net::HTTPRedirection)
270
+ if tries_remain_redirect > 0
271
+ tries_remain_redirect-=1
272
+ Log.log.info("URL is moved: #{e.response['location']}")
273
+ raise e
274
+ # TODO: rebuild request with new location
275
+ #retry
276
+ else
277
+ raise "too many redirect"
278
+ end
279
+ else
280
+ raise e
281
+ end
271
282
  # raise exception if could not retry and not return error in result
272
283
  raise e unless call_data[:return_error]
273
- end
284
+ end # begin request
274
285
  Log.log.debug("result=#{result}")
275
286
  return result
276
287
 
@@ -0,0 +1,20 @@
1
+ module Aspera
2
+ # Manage secrets in CLI using secure way (encryption, wallet, etc...)
3
+ class Secrets
4
+ attr_accessor :default_secret,:all_secrets
5
+ def initialize()
6
+ @default_secret=nil
7
+ @all_secrets={}
8
+ end
9
+
10
+ def get_secret(id=nil,mandatory=true)
11
+ secret=@default_secret || @all_secrets[id]
12
+ raise "please provide secret for #{id}" if secret.nil? and mandatory
13
+ return secret
14
+ end
15
+
16
+ def get_secrets
17
+ return @all_secrets
18
+ end
19
+ end
20
+ end
@@ -6,6 +6,11 @@ module Aspera
6
6
  # create a temp file name for a given folder
7
7
  # files can be deleted on process exit by calling cleanup
8
8
  class TempFileManager
9
+ SEC_IN_DAY=86400
10
+ # assume no transfer last longer than this
11
+ # (garbage collect file list which were not deleted after transfer)
12
+ FILE_LIST_AGE_MAX_SEC=5*SEC_IN_DAY
13
+ private_constant :SEC_IN_DAY,:FILE_LIST_AGE_MAX_SEC
9
14
  include Singleton
10
15
  def initialize
11
16
  @created_files=[]
@@ -33,5 +38,19 @@ module Aspera
33
38
  username = Etc.getlogin || Etc.getpwuid(Process.uid).name || 'unknown_user' rescue 'unknown_user'
34
39
  return new_file_path_in_folder(Etc.systmpdir,base_name+'_'+username+'_')
35
40
  end
41
+
42
+ def cleanup_expired(temp_folder)
43
+ # garbage collect undeleted files
44
+ Dir.entries(temp_folder).each do |name|
45
+ file_path=File.join(temp_folder,name)
46
+ age_sec=(Time.now - File.stat(file_path).mtime).to_i
47
+ # check age of file, delete too old
48
+ if File.file?(file_path) and age_sec > FILE_LIST_AGE_MAX_SEC
49
+ Log.log.debug("garbage collecting #{name}")
50
+ File.delete(file_path)
51
+ end
52
+ end
53
+
54
+ end
36
55
  end
37
56
  end
@@ -0,0 +1,105 @@
1
+ require 'webrick'
2
+ require 'webrick/https'
3
+ require 'thread'
4
+
5
+ module Aspera
6
+ class WebAuth
7
+ # server for auth page
8
+ class FxGwServlet < WEBrick::HTTPServlet::AbstractServlet
9
+ def initialize(server,info) # additional args get here
10
+ @shared=info
11
+ end
12
+
13
+ def do_GET (request, response)
14
+ if ! request.path.eql?(@shared[:expected_path])
15
+ response.status=400
16
+ return
17
+ end
18
+ @shared[:mutex].synchronize do
19
+ @shared[:query]=request.query
20
+ @shared[:cond].signal
21
+ end
22
+ response.status=200
23
+ response.content_type = 'text/html'
24
+ response.body='<html><head><title>Ok</title></head><body><h1>Thank you !</h1><p>You can close this window.</p></body></html>'
25
+ end
26
+ end # FxGwServlet
27
+
28
+ # generates and adds self signed cert to provided webrick options
29
+ def fill_self_signed_cert(options)
30
+ key = OpenSSL::PKey::RSA.new(4096)
31
+ cert = OpenSSL::X509::Certificate.new
32
+ cert.subject = cert.issuer = OpenSSL::X509::Name.parse('/C=FR/O=Test/OU=Test/CN=Test')
33
+ cert.not_before = Time.now
34
+ cert.not_after = Time.now + 365 * 24 * 60 * 60
35
+ cert.public_key = key.public_key
36
+ cert.serial = 0x0
37
+ cert.version = 2
38
+ ef = OpenSSL::X509::ExtensionFactory.new
39
+ ef.issuer_certificate = cert
40
+ ef.subject_certificate = cert
41
+ cert.extensions = [
42
+ ef.create_extension('basicConstraints','CA:TRUE', true),
43
+ ef.create_extension('subjectKeyIdentifier', 'hash'),
44
+ # ef.create_extension('keyUsage', 'cRLSign,keyCertSign', true),
45
+ ]
46
+ cert.add_extension(ef.create_extension('authorityKeyIdentifier','keyid:always,issuer:always'))
47
+ cert.sign(key, OpenSSL::Digest::SHA256.new)
48
+ options[:SSLPrivateKey] = key
49
+ options[:SSLCertificate] = cert
50
+ end
51
+
52
+ def initialize(endpoint_url)
53
+ uri=URI.parse(endpoint_url)
54
+ webrick_options = {
55
+ :app => WebAuth,
56
+ :Port => uri.port,
57
+ :Logger => Log.log
58
+ }
59
+ uri_path=uri.path.empty? ? '/' : uri.path
60
+ case uri.scheme
61
+ when 'http'
62
+ Log.log.debug('HTTP mode')
63
+ when 'https'
64
+ webrick_options[:SSLEnable]=true
65
+ webrick_options[:SSLVerifyClient]=OpenSSL::SSL::VERIFY_NONE
66
+ case 0
67
+ when 0
68
+ # generate self signed cert
69
+ fill_self_signed_cert(webrick_options)
70
+ when 1
71
+ # short
72
+ webrick_options[:SSLCertName] = [ [ 'CN',WEBrick::Utils::getservername ] ]
73
+ Log.log.error(">>>#{webrick_options[:SSLCertName]}")
74
+ when 2
75
+ # good cert
76
+ webrick_options[:SSLPrivateKey] =OpenSSL::PKey::RSA.new(File.read('/Users/laurent/workspace/Tools/certificate/myserver.key'))
77
+ webrick_options[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read('/Users/laurent/workspace/Tools/certificate/myserver.crt'))
78
+ end
79
+ end
80
+ # parameters for servlet
81
+ @shared_info={
82
+ expected_path: uri_path,
83
+ mutex: Mutex.new,
84
+ cond: ConditionVariable.new
85
+ }
86
+ @server = WEBrick::HTTPServer.new(webrick_options)
87
+ @server.mount(uri_path, FxGwServlet, @shared_info) # additional args provided to constructor
88
+ Thread.new { @server.start }
89
+ end
90
+
91
+ # wait for request on web server
92
+ # @return Hash the query
93
+ def get_request
94
+ Log.log.debug('get_request')
95
+ # called only once
96
+ raise "error, called twice ?" if @server.nil?
97
+ @shared_info[:mutex].synchronize do
98
+ @shared_info[:cond].wait(@shared_info[:mutex])
99
+ end
100
+ @server.shutdown
101
+ @server=nil
102
+ return @shared_info[:query]
103
+ end
104
+ end
105
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aspera-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.pre3
4
+ version: 4.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurent Martin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-18 00:00:00.000000000 Z
11
+ date: 2021-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xml-simple
@@ -58,28 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '4.0'
61
+ version: '6.0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '4.0'
69
- - !ruby/object:Gem::Dependency
70
- name: mimemagic
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '0.3'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '0.3'
68
+ version: '6.0'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: execjs
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +122,34 @@ dependencies:
136
122
  - - "~>"
137
123
  - !ruby/object:Gem::Version
138
124
  version: '2.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: websocket
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.2'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.2'
139
+ - !ruby/object:Gem::Dependency
140
+ name: websocket-client-simple
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.3'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.3'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: bundler
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -184,12 +198,14 @@ email:
184
198
  executables:
185
199
  - ascli
186
200
  - asession
201
+ - dascli
187
202
  extensions: []
188
203
  extra_rdoc_files: []
189
204
  files:
190
205
  - README.md
191
206
  - bin/ascli
192
207
  - bin/asession
208
+ - bin/dascli
193
209
  - docs/Makefile
194
210
  - docs/README.erb.md
195
211
  - docs/README.md
@@ -197,6 +213,7 @@ files:
197
213
  - docs/test_env.conf
198
214
  - docs/transfer_spec.html
199
215
  - examples/aoc.rb
216
+ - examples/faspex4.rb
200
217
  - examples/proxy.pac
201
218
  - examples/transfer.rb
202
219
  - lib/aspera/aoc.rb
@@ -277,10 +294,12 @@ files:
277
294
  - lib/aspera/rest_call_error.rb
278
295
  - lib/aspera/rest_error_analyzer.rb
279
296
  - lib/aspera/rest_errors_aspera.rb
297
+ - lib/aspera/secrets.rb
280
298
  - lib/aspera/ssh.rb
281
299
  - lib/aspera/sync.rb
282
300
  - lib/aspera/temp_file_manager.rb
283
301
  - lib/aspera/uri_reader.rb
302
+ - lib/aspera/web_auth.rb
284
303
  homepage: https://github.com/IBM/aspera-cli
285
304
  licenses:
286
305
  - Apache-2.0
@@ -290,6 +309,7 @@ metadata:
290
309
  source_code_uri: https://github.com/IBM/aspera-cli
291
310
  changelog_uri: https://github.com/IBM/aspera-cli
292
311
  rubygems_uri: https://rubygems.org/gems/aspera-cli
312
+ documentation_uri: https://www.rubydoc.info/gems/aspera-cli
293
313
  post_install_message:
294
314
  rdoc_options: []
295
315
  require_paths:
@@ -301,12 +321,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
301
321
  version: '2.4'
302
322
  required_rubygems_version: !ruby/object:Gem::Requirement
303
323
  requirements:
304
- - - ">"
324
+ - - ">="
305
325
  - !ruby/object:Gem::Version
306
- version: 1.3.1
326
+ version: '0'
307
327
  requirements:
308
- - IBM Aspera ascp installed for the user
309
- rubygems_version: 3.0.3
328
+ - Read the manual for any requirement
329
+ rubygems_version: 3.0.3.1
310
330
  signing_key:
311
331
  specification_version: 4
312
332
  summary: 'Execute actions using command line on IBM Aspera Server products: Aspera