aspera-cli 4.0.0 → 4.2.2

Sign up to get free protection for your applications and to get access to all the features.
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