aspera-cli 4.0.0 → 4.2.2

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +843 -304
  3. data/bin/dascli +13 -0
  4. data/docs/Makefile +4 -4
  5. data/docs/README.erb.md +805 -172
  6. data/docs/test_env.conf +22 -3
  7. data/examples/aoc.rb +14 -3
  8. data/examples/faspex4.rb +89 -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 +89 -49
  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 +188 -173
  15. data/lib/aspera/cli/plugins/ats.rb +2 -2
  16. data/lib/aspera/cli/plugins/config.rb +218 -145
  17. data/lib/aspera/cli/plugins/console.rb +2 -2
  18. data/lib/aspera/cli/plugins/faspex.rb +114 -61
  19. data/lib/aspera/cli/plugins/faspex5.rb +85 -43
  20. data/lib/aspera/cli/plugins/node.rb +3 -3
  21. data/lib/aspera/cli/plugins/preview.rb +59 -45
  22. data/lib/aspera/cli/plugins/server.rb +23 -8
  23. data/lib/aspera/cli/transfer_agent.rb +77 -49
  24. data/lib/aspera/cli/version.rb +1 -1
  25. data/lib/aspera/command_line_builder.rb +49 -31
  26. data/lib/aspera/cos_node.rb +33 -28
  27. data/lib/aspera/environment.rb +2 -2
  28. data/lib/aspera/fasp/connect.rb +28 -21
  29. data/lib/aspera/fasp/http_gw.rb +140 -28
  30. data/lib/aspera/fasp/installation.rb +93 -46
  31. data/lib/aspera/fasp/local.rb +88 -45
  32. data/lib/aspera/fasp/manager.rb +15 -0
  33. data/lib/aspera/fasp/node.rb +4 -4
  34. data/lib/aspera/fasp/parameters.rb +59 -101
  35. data/lib/aspera/fasp/parameters.yaml +531 -0
  36. data/lib/aspera/fasp/resume_policy.rb +13 -12
  37. data/lib/aspera/fasp/uri.rb +1 -1
  38. data/lib/aspera/log.rb +1 -1
  39. data/lib/aspera/node.rb +61 -1
  40. data/lib/aspera/oauth.rb +49 -46
  41. data/lib/aspera/persistency_folder.rb +9 -4
  42. data/lib/aspera/preview/file_types.rb +53 -21
  43. data/lib/aspera/preview/generator.rb +3 -3
  44. data/lib/aspera/rest.rb +29 -18
  45. data/lib/aspera/secrets.rb +20 -0
  46. data/lib/aspera/sync.rb +40 -35
  47. data/lib/aspera/temp_file_manager.rb +19 -0
  48. data/lib/aspera/web_auth.rb +105 -0
  49. metadata +54 -20
  50. data/docs/transfer_spec.html +0 -99
@@ -0,0 +1,531 @@
1
+ ---
2
+ cipher:
3
+ :cltype: :opt_with_arg
4
+ :option_switch: "-c"
5
+ :enum:
6
+ - aes128
7
+ - aes192
8
+ - aes256
9
+ - aes128cfb
10
+ - aes192cfb
11
+ - aes256cfb
12
+ - aes128gcm
13
+ - aes192gcm
14
+ - aes256gcm
15
+ :encode: Aspera::Fasp::Parameters
16
+ :default: none
17
+ :desc: "In transit encryption type.\nnone, aes-128, aes-256"
18
+ content_protection:
19
+ :cltype: :ignore
20
+ :option_switch: "--file-crypt"
21
+ :enum:
22
+ - encrypt
23
+ - decrypt
24
+ :desc: Enable client-side content protection. (encryption at rest)
25
+ content_protection_password:
26
+ :accepted_types: :string
27
+ :desc: "Specifies CSEAR password."
28
+ cookie:
29
+ :cltype: :envvar
30
+ :clvarname: ASPERA_SCP_COOKIE
31
+ :desc: Metadata for transfer (older,string)
32
+ create_dir:
33
+ :cltype: :opt_without_arg
34
+ :option_switch: "-d"
35
+ :accepted_types: :bool
36
+ :desc: Specifies whether to create new directories.
37
+ delete_before_transfer:
38
+ :cltype: :opt_without_arg
39
+ delete_source:
40
+ :accepted_types: :bool
41
+ :context:
42
+ - :node
43
+ :desc: Remove SRC files after transfer success
44
+ destination_root_id:
45
+ :cltype: :ignore
46
+ :accepted_types: :string
47
+ :context:
48
+ - :sdk
49
+ direction:
50
+ :cltype: :opt_with_arg
51
+ :option_switch: "--mode"
52
+ :enum:
53
+ - send
54
+ - receive
55
+ :translate_values:
56
+ receive: recv
57
+ send: send
58
+ :required: true
59
+ :desc: 'Direction of transfer (on client side)'
60
+ exclude_newer_than:
61
+ :cltype: :opt_with_arg
62
+ :accepted_types: :int
63
+ :context:
64
+ - :direct
65
+ :desc: skip src files with mtime > arg
66
+ exclude_older_than:
67
+ :cltype: :opt_with_arg
68
+ :accepted_types: :int
69
+ :context:
70
+ - :direct
71
+ :desc: skip src files with mtime < arg
72
+ fasp_port:
73
+ :cltype: :opt_with_arg
74
+ :option_switch: "-O"
75
+ :accepted_types: :int
76
+ :default: 33001
77
+ :desc: Specifies fasp (UDP) port.
78
+ http_fallback:
79
+ :cltype: :opt_with_arg
80
+ :option_switch: "-y"
81
+ :accepted_types:
82
+ - :string
83
+ - :bool
84
+ :translate_values:
85
+ force: F
86
+ true: 1
87
+ false: 0
88
+ :desc: When true(1), attempts to perform an HTTP transfer if a fasp transfer cannot
89
+ be performed.
90
+ http_fallback_port:
91
+ :cltype: :opt_with_arg
92
+ :option_switch: "-t"
93
+ :accepted_types: :int
94
+ :context:
95
+ - :direct
96
+ :desc: Specifies http port.
97
+ https_fallback_port:
98
+ :cltype: :ignore
99
+ :accepted_types: :int
100
+ :desc: Specifies https port.
101
+ move_after_transfer:
102
+ :cltype: :opt_with_arg
103
+ multi_session:
104
+ :cltype: :ignore
105
+ :option_switch: "-C"
106
+ :accepted_types: :int
107
+ :desc: "Use multi-session transfer. max 128.\n
108
+ Each participant on one host needs an independent UDP (-O) port.\n
109
+ Large files are split between sessions only when transferring with resume_policy=none."
110
+ multi_session_threshold:
111
+ :cltype: :opt_with_arg
112
+ :accepted_types: :int
113
+ :context:
114
+ - :direct
115
+ - :node
116
+ :desc: in bytes
117
+ overwrite:
118
+ :cltype: :opt_with_arg
119
+ :default: diff
120
+ :enum:
121
+ - never
122
+ - always
123
+ - diff
124
+ - older
125
+ - diff+older
126
+ :desc: "Overwrite destination files with the source files of the same name."
127
+ paths:
128
+ :cltype: :defer
129
+ :accepted_types: :array
130
+ :desc: Required. Contains a path to the source (required) and a path to the destination.
131
+ precalculate_job_size:
132
+ :cltype: :opt_without_arg
133
+ :accepted_types: :bool
134
+ :desc: Specifies whether to precalculate the job size.
135
+ preserve_access_time:
136
+ :cltype: :opt_without_arg
137
+ preserve_creation_time:
138
+ :cltype: :opt_without_arg
139
+ preserve_modification_time:
140
+ :cltype: :opt_without_arg
141
+ preserve_times:
142
+ :cltype: :opt_without_arg
143
+ rate_policy:
144
+ :cltype: :opt_with_arg
145
+ :option_switch: "--policy"
146
+ :enum:
147
+ - low
148
+ - fair
149
+ - high
150
+ - fixed
151
+ :desc: The transfer rate policy to use when sharing bandwidth.
152
+ remote_access_key:
153
+ :accepted_types: :string
154
+ :desc: Node only?
155
+ remote_host:
156
+ :cltype: :opt_with_arg
157
+ :option_switch: "--host"
158
+ :required: true
159
+ :desc: IP or fully qualified domain name of the remote server
160
+ remote_user:
161
+ :cltype: :opt_with_arg
162
+ :option_switch: "--user"
163
+ :required: true
164
+ :desc: Remote user. Default value is "xfer" on node or connect.
165
+ remote_password:
166
+ :cltype: :envvar
167
+ :clvarname: ASPERA_SCP_PASS
168
+ :desc: SSH session password
169
+ remove_after_transfer:
170
+ :cltype: :opt_without_arg
171
+ :accepted_types: :bool
172
+ :context:
173
+ - :direct
174
+ - :node
175
+ :desc: Remove SRC files after transfer success
176
+ remove_empty_directories:
177
+ :cltype: :opt_without_arg
178
+ :accepted_types: :bool
179
+ :context:
180
+ - :direct
181
+ - :node
182
+ :desc: Specifies whether to remove empty directories.
183
+ remove_skipped:
184
+ :cltype: :ignore
185
+ :accepted_types: :bool
186
+ :context:
187
+ - :sdk
188
+ proxy:
189
+ :cltype: :opt_with_arg
190
+ :context:
191
+ - :direct
192
+ - :sdk
193
+ :desc: "Specify the address of the Aspera high-speed proxy server.\n
194
+ dnat(s)://[user[:password]@]server:port\n
195
+ Default ports for DNAT and DNATS protocols are 9091 and 9092.\n
196
+ Password, if specified here, overrides the value of environment variable ASPERA_PROXY_PASS."
197
+ resume_policy:
198
+ :cltype: :opt_with_arg
199
+ :option_switch: "-k"
200
+ :default: faspmgr:none;other:sparse_csum
201
+ :enum:
202
+ - none
203
+ - attrs
204
+ - sparse_csum
205
+ - full_csum
206
+ :translate_values:
207
+ none: 0
208
+ attrs: 1
209
+ sparse_csum: 2
210
+ full_csum: 3
211
+ :desc: If a transfer is interrupted or fails to finish, resume without re-transferring the whole files.
212
+ retry_duration:
213
+ :accepted_types:
214
+ - :string
215
+ - :int
216
+ :context:
217
+ - :node
218
+ - :connect
219
+ - :sdk
220
+ :desc: Specifies how long to wait before retrying transfer. (e.g. "5min")
221
+ source_root_id:
222
+ :cltype: :ignore
223
+ :accepted_types: :string
224
+ :context:
225
+ - :sdk
226
+ ssh_port:
227
+ :cltype: :opt_with_arg
228
+ :option_switch: "-P"
229
+ :accepted_types: :int
230
+ :desc: "Specifies ssh (TCP) port. Default: local:22, other:33001"
231
+ ssh_private_key:
232
+ :cltype: :envvar
233
+ :clvarname: ASPERA_SCP_KEY
234
+ :context:
235
+ - :direct
236
+ - :sdk
237
+ :desc: "Private key used for SSH authentication.\n
238
+ Shall look like: -----BEGIN RSA PRIVATE KEY-----\\nMII...\n
239
+ Note the JSON encoding: \\n for newlines."
240
+ ssh_private_key_passphrase:
241
+ :cltype: :ignore
242
+ :accepted_types: :string
243
+ :context:
244
+ - :sdk
245
+ ssh_args:
246
+ :cltype: :ignore
247
+ :accepted_types: :string
248
+ :context:
249
+ - :sdk
250
+ symlink_policy:
251
+ :cltype: :opt_with_arg
252
+ :option_switch: "--symbolic-links"
253
+ :default: follow
254
+ :enum:
255
+ - follow
256
+ - copy
257
+ - copy+force
258
+ - skip
259
+ :desc: "Handle source side symbolic links by:\n
260
+ following the link (follow),\n
261
+ copying the link itself (copy),\n
262
+ skipping (skip),\n
263
+ or forcibly copying the link itself (copy+force).\n
264
+ Default: follow"
265
+ checksum_type:
266
+ :cltype: :ignore
267
+ :accepted_types: :string
268
+ :context:
269
+ - :sdk
270
+ :desc: "Enable checksum reporting for transferred files by specifying the hash to use.\n
271
+ Allowable values: sha-512, sha-384, sha-256, sha1, md5. (Default: none)"
272
+ file_checksum:
273
+ :cltype: :ignore
274
+ :accepted_types: :string
275
+ :context:
276
+ - :sdk
277
+ tags:
278
+ :cltype: :opt_with_arg
279
+ :option_switch: "--tags64"
280
+ :accepted_types: :hash
281
+ :encode: Aspera::Fasp::Parameters
282
+ :desc: Metadata for transfer
283
+ target_rate_cap_kbps:
284
+ :cltype: :ignore
285
+ :accepted_types: :int
286
+ :context:
287
+ - :connect
288
+ :desc: Returned by upload/download_setup node api.
289
+ target_rate_kbps:
290
+ :cltype: :opt_with_arg
291
+ :option_switch: "-l"
292
+ :accepted_types: :int
293
+ :desc: Specifies desired speed for the transfer.
294
+ title:
295
+ :accepted_types: :string
296
+ :context:
297
+ - :node
298
+ - :connect
299
+ :desc: Title of the transfer
300
+ token:
301
+ :cltype: :envvar
302
+ :clvarname: ASPERA_SCP_TOKEN
303
+ :desc: 'Authorization token: Bearer, Basic or ATM (Also arg -W)'
304
+ use_ascp4:
305
+ :cltype: :defer
306
+ :accepted_types: :bool
307
+ :default: false
308
+ :context:
309
+ - :direct
310
+ - :node
311
+ - :sdk
312
+ :desc: specify version of protocol
313
+ use_system_ssh:
314
+ :cltype: :ignore
315
+ :option_switch: "-SSH"
316
+ :accepted_types: :string
317
+ :context:
318
+ - :sdk
319
+ destination_root:
320
+ :cltype: :defer
321
+ :required: true
322
+ :desc: Destination root directory.
323
+ source_root:
324
+ :cltype: :opt_with_arg
325
+ :option_switch: "--source-prefix64"
326
+ :encode: Aspera::Fasp::Parameters
327
+ :desc: "Path to be prepended to each source path.\n
328
+ This is either a conventional path or it can be a URI but only if there is no root defined."
329
+ min_rate_cap_kbps:
330
+ :cltype: :ignore
331
+ :accepted_types: :int
332
+ lock_rate_policy:
333
+ :cltype: :ignore
334
+ :accepted_types: :bool
335
+ lock_target_rate_kbps:
336
+ :cltype: :ignore
337
+ :accepted_types: :bool
338
+ lock_min_rate_kbps:
339
+ :cltype: :ignore
340
+ :accepted_types: :bool
341
+ apply_local_docroot:
342
+ :cltype: :opt_without_arg
343
+ :context:
344
+ - :direct
345
+ - :sdk
346
+ preserve_acls:
347
+ :cltype: :opt_with_arg
348
+ :context:
349
+ - :direct
350
+ - :sdk
351
+ :desc: "Preserve access control lists.\nAllowable values: none, native, metafile"
352
+ preserve_remote_acls:
353
+ :cltype: :ignore
354
+ :accepted_types: :string
355
+ :context:
356
+ - :sdk
357
+ :desc: "Preserve remote access control lists.\n
358
+ Allowable values: none, native, metafile"
359
+ preserve_file_owner_uid:
360
+ :cltype: :ignore
361
+ :accepted_types: :bool
362
+ :context:
363
+ - :sdk
364
+ preserve_file_owner_gid:
365
+ :cltype: :ignore
366
+ :accepted_types: :bool
367
+ :context:
368
+ - :sdk
369
+ preserve_extended_attrs:
370
+ :cltype: :ignore
371
+ :accepted_types: :string
372
+ :context:
373
+ - :sdk
374
+ :desc: "Preserve the extended attributes.\n
375
+ Allowable values: none, native, metafile"
376
+ preserve_source_access_time:
377
+ :cltype: :ignore
378
+ :accepted_types: :bool
379
+ :context:
380
+ - :sdk
381
+ remove_empty_source_directory:
382
+ :cltype: :opt_without_arg
383
+ :context:
384
+ - :direct
385
+ :desc: "TODO: check node, sdk"
386
+ EX_at_rest_password:
387
+ :cltype: :envvar
388
+ :clvarname: ASPERA_SCP_FILEPASS
389
+ :context:
390
+ - :direct
391
+ :desc: Passphrase used for at rest encryption or decryption
392
+ EX_proxy_password:
393
+ :cltype: :envvar
394
+ :clvarname: ASPERA_PROXY_PASS
395
+ :context:
396
+ - :direct
397
+ :desc: "Password used for Aspera proxy server authentication.\n
398
+ May be overridden by password in URL EX_fasp_proxy_url."
399
+ EX_license_text:
400
+ :cltype: :envvar
401
+ :clvarname: ASPERA_SCP_LICENSE
402
+ :context:
403
+ - :direct
404
+ :desc: "License file text override.\nBy default ascp looks for license file near executable."
405
+ keepalive:
406
+ :cltype: :opt_without_arg
407
+ :context:
408
+ - :none
409
+ dgram_size:
410
+ :cltype: :opt_with_arg
411
+ :option_switch: "-Z"
412
+ :accepted_types: :int
413
+ :desc: in bytes
414
+ min_rate_kbps:
415
+ :cltype: :opt_with_arg
416
+ :option_switch: "-m"
417
+ :accepted_types: :int
418
+ :default: 0
419
+ :desc: Set the minimum transfer rate in kilobits per second.
420
+ sshfp:
421
+ :cltype: :opt_with_arg
422
+ :option_switch: "--check-sshfp"
423
+ :desc: Check it against server SSH host key fingerprint
424
+ EX_http_proxy_url:
425
+ :cltype: :opt_with_arg
426
+ :option_switch: "-x"
427
+ :context:
428
+ - :direct
429
+ :desc: Specify the proxy server address used by HTTP Fallback
430
+ EX_ssh_key_paths:
431
+ :cltype: :opt_with_arg
432
+ :option_switch: "-i"
433
+ :accepted_types: :array
434
+ :context:
435
+ - :direct
436
+ :desc: Use public key authentication for SSH and specify the private key file paths
437
+ EX_http_transfer_jpeg:
438
+ :cltype: :opt_with_arg
439
+ :option_switch: "-j"
440
+ :accepted_types: :int
441
+ :default: '0'
442
+ :context:
443
+ - :direct
444
+ :desc: HTTP transfers as JPEG file
445
+ EX_no_read:
446
+ :cltype: :opt_without_arg
447
+ :option_switch: "--no-read"
448
+ :context:
449
+ - :direct
450
+ :desc: no read source
451
+ EX_no_write:
452
+ :cltype: :opt_without_arg
453
+ :option_switch: "--no-write"
454
+ :context:
455
+ - :direct
456
+ :desc: no write on destination
457
+ target_rate_percentage:
458
+ :cltype: :ignore
459
+ rate_policy_allowed:
460
+ :cltype: :ignore
461
+ :context:
462
+ - :connect
463
+ :enum:
464
+ - low
465
+ - fair
466
+ - high
467
+ - fixed
468
+ :desc: "Specifies most aggressive rate policy that is allowed.\n
469
+ Returned by node API."
470
+ fasp_url:
471
+ :cltype: :ignore
472
+ :context:
473
+ - :unknown
474
+ lock_min_rate:
475
+ :cltype: :ignore
476
+ :accepted_types: :bool
477
+ lock_target_rate:
478
+ :cltype: :ignore
479
+ :accepted_types: :bool
480
+ authentication:
481
+ :cltype: :ignore
482
+ :context:
483
+ - :connect
484
+ :desc: 'value=token for SSH bypass keys, else password asked if not provided.'
485
+ cipher_allowed:
486
+ :cltype: :ignore
487
+ :desc: returned by node API. Valid literals include "aes-128" and "none".
488
+ obfuscate_file_names:
489
+ :cltype: :ignore
490
+ :accepted_types: :bool
491
+ :context:
492
+ - :unknown
493
+ EX_file_list:
494
+ :cltype: :defer
495
+ :option_switch: "--file-list"
496
+ :context:
497
+ - :direct
498
+ :desc: source file list
499
+ EX_file_pair_list:
500
+ :cltype: :defer
501
+ :option_switch: "--file-pair-list"
502
+ :context:
503
+ - :direct
504
+ :desc: source file pair list
505
+ EX_ascp_args:
506
+ :cltype: :defer
507
+ :accepted_types: :array
508
+ :context:
509
+ - :direct
510
+ :desc: Add command line arguments to ascp
511
+ wss_enabled:
512
+ :cltype: :defer
513
+ :accepted_types: :bool
514
+ wss_port:
515
+ :cltype: :defer
516
+ :accepted_types: :int
517
+ compression:
518
+ :accepted_types: :int
519
+ :context:
520
+ - :unknown
521
+ :desc: ascp4 only, 0 / 1?
522
+ read_threads:
523
+ :accepted_types: :int
524
+ :context:
525
+ - :unknown
526
+ :desc: ascp4 only
527
+ write_threads:
528
+ :accepted_types: :int
529
+ :context:
530
+ - :unknown
531
+ :desc: ascp4 only
@@ -14,17 +14,21 @@ module Aspera
14
14
  :sleep_max => 60
15
15
  }
16
16
 
17
- def initialize(params={})
17
+ # @param params see DEFAULTS
18
+ def initialize(params=nil)
18
19
  @parameters=DEFAULTS.clone
19
- return if params.nil?
20
- raise "expecting Hash (or nil), but have #{params.class}" unless params.is_a?(Hash)
21
- params.each do |k,v|
22
- if DEFAULTS.has_key?(k)
23
- @parameters[k]=v
24
- else
25
- raise "unknown resume parameter: #{k}, expect one of #{DEFAULTS.keys.map{|i|i.to_s}.join(",")}"
20
+ if !params.nil?
21
+ raise "expecting Hash (or nil), but have #{params.class}" unless params.is_a?(Hash)
22
+ params.each do |k,v|
23
+ if DEFAULTS.has_key?(k)
24
+ raise "#{k} must be Integer" unless v.is_a?(Integer)
25
+ @parameters[k]=v
26
+ else
27
+ raise "unknown resume parameter: #{k}, expect one of #{DEFAULTS.keys.map{|i|i.to_s}.join(",")}"
28
+ end
26
29
  end
27
30
  end
31
+ Log.log.debug("resume params=#{@parameters}")
28
32
  end
29
33
 
30
34
  # calls block a number of times (resumes) until success or limit reached
@@ -45,10 +49,7 @@ module Aspera
45
49
  # failure in ascp
46
50
  if e.retryable? then
47
51
  # exit if we exceed the max number of retry
48
- unless remaining_resumes > 0
49
- Log.log.error "Maximum number of retry reached"
50
- raise Fasp::Error,"max retry after: [#{status[:message]}]"
51
- end
52
+ raise Fasp::Error,'Maximum number of retry reached' if remaining_resumes <= 0
52
53
  else
53
54
  # give one chance only to non retryable errors
54
55
  unless remaining_resumes.eql?(@parameters[:iter_max])
@@ -6,7 +6,7 @@ module Aspera
6
6
  # translates a "faspe:" URI (used in Faspex) into transfer spec hash
7
7
  class Uri
8
8
  def initialize(fasplink)
9
- @fasp_uri=URI.parse(fasplink)
9
+ @fasp_uri=URI.parse(fasplink.gsub(' ','%20'))
10
10
  # TODO: check scheme is faspe
11
11
  end
12
12
 
data/lib/aspera/log.rb CHANGED
@@ -14,7 +14,7 @@ module Aspera
14
14
  attr_reader :logger
15
15
  attr_reader :logger_type
16
16
  # levels are :debug,:info,:warn,:error,fatal,:unknown
17
- def self.levels; Logger::Severity.constants.map{|c| c.downcase.to_sym};end
17
+ def self.levels; Logger::Severity.constants.sort{|a,b|Logger::Severity.const_get(a)<=>Logger::Severity.const_get(b)}.map{|c|c.downcase.to_sym};end
18
18
 
19
19
  # where logs are sent to
20
20
  def self.logtypes; [:stderr,:stdout,:syslog];end
data/lib/aspera/node.rb CHANGED
@@ -1,14 +1,74 @@
1
+ require 'aspera/rest'
2
+ require 'aspera/log'
1
3
  require 'zlib'
2
4
  require 'base64'
5
+
3
6
  module Aspera
4
7
  # Provides additional functions using node API.
5
8
  class Node < Rest
9
+ # permissions
10
+ ACCESS_LEVELS=['delete','list','mkdir','preview','read','rename','write']
11
+ MATCH_EXEC_PREFIX='exec:'
12
+
13
+ # for information only
6
14
  def self.decode_bearer_token(token)
7
15
  return JSON.parse(Zlib::Inflate.inflate(Base64.decode64(token)).partition('==SIGNATURE==').first)
8
16
  end
17
+
18
+ # for access keys: provide expression to match entry in folder
19
+ # if no prefix: regex
20
+ # if prefix: ruby code
21
+ # if filder is nil, then always match
22
+ def self.file_matcher(match_expression)
23
+ match_expression||="#{MATCH_EXEC_PREFIX}true"
24
+ if match_expression.start_with?(MATCH_EXEC_PREFIX)
25
+ return eval "lambda{|f|#{match_expression[MATCH_EXEC_PREFIX.length..-1]}}"
26
+ end
27
+ return lambda{|f|f['name'].match(/#{match_expression}/)}
28
+ end
29
+
9
30
  def initialize(rest_params)
10
31
  super(rest_params)
11
- # specifics here
32
+ end
33
+
34
+ # recursively crawl in a folder.
35
+ # subfolders a processed if the processing method returns true
36
+ # @param processor must provide a method to process each entry
37
+ # @param opt options
38
+ # - top_file_id file id to start at (default = access key root file id)
39
+ # - top_file_path path of top folder (default = /)
40
+ # - method processing method (default= process_entry)
41
+ def crawl(processor,opt={})
42
+ Log.log.debug("crawl1 #{opt}")
43
+ # not possible with bearer token
44
+ opt[:top_file_id] ||= read('access_keys/self')[:data]['root_file_id']
45
+ opt[:top_file_path] ||= '/'
46
+ opt[:method] ||= :process_entry
47
+ raise "processor must have #{opt[:method]}" unless processor.respond_to?(opt[:method])
48
+ Log.log.debug("crawl #{opt}")
49
+ #top_info=read("files/#{opt[:top_file_id]}")[:data]
50
+ folders_to_explore=[{id: opt[:top_file_id], relpath: opt[:top_file_path]}]
51
+ Log.dump(:folders_to_explore,folders_to_explore)
52
+ while !folders_to_explore.empty? do
53
+ current_item = folders_to_explore.shift
54
+ Log.log.debug("searching #{current_item[:relpath]}".bg_green)
55
+ # get folder content
56
+ folder_contents = begin
57
+ read("files/#{current_item[:id]}/files")[:data]
58
+ rescue => e
59
+ Log.log.warn("#{current_item[:relpath]}: #{e.class} #{e.message}")
60
+ []
61
+ end
62
+ Log.dump(:folder_contents,folder_contents)
63
+ folder_contents.each do |entry|
64
+ relative_path=File.join(current_item[:relpath],entry['name'])
65
+ Log.log.debug("looking #{relative_path}".bg_green)
66
+ # entry type is file, folder or link
67
+ if processor.send(opt[:method],entry,relative_path) and entry['type'].eql?('folder')
68
+ folders_to_explore.push({:id=>entry['id'],:relpath=>relative_path})
69
+ end
70
+ end
71
+ end
12
72
  end
13
73
  end
14
74
  end