aspera-cli 4.2.1 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1580 -946
  3. data/bin/ascli +1 -1
  4. data/bin/asession +3 -5
  5. data/docs/Makefile +8 -11
  6. data/docs/README.erb.md +1521 -829
  7. data/docs/doc_tools.rb +58 -0
  8. data/docs/test_env.conf +3 -1
  9. data/examples/faspex4.rb +28 -19
  10. data/examples/transfer.rb +2 -2
  11. data/lib/aspera/aoc.rb +157 -134
  12. data/lib/aspera/cli/listener/progress_multi.rb +5 -5
  13. data/lib/aspera/cli/main.rb +106 -48
  14. data/lib/aspera/cli/manager.rb +19 -20
  15. data/lib/aspera/cli/plugin.rb +22 -7
  16. data/lib/aspera/cli/plugins/aoc.rb +260 -208
  17. data/lib/aspera/cli/plugins/ats.rb +11 -10
  18. data/lib/aspera/cli/plugins/bss.rb +2 -2
  19. data/lib/aspera/cli/plugins/config.rb +360 -189
  20. data/lib/aspera/cli/plugins/faspex.rb +119 -56
  21. data/lib/aspera/cli/plugins/faspex5.rb +32 -17
  22. data/lib/aspera/cli/plugins/node.rb +72 -31
  23. data/lib/aspera/cli/plugins/orchestrator.rb +5 -3
  24. data/lib/aspera/cli/plugins/preview.rb +94 -68
  25. data/lib/aspera/cli/plugins/server.rb +16 -5
  26. data/lib/aspera/cli/plugins/shares.rb +17 -0
  27. data/lib/aspera/cli/transfer_agent.rb +64 -82
  28. data/lib/aspera/cli/version.rb +1 -1
  29. data/lib/aspera/command_line_builder.rb +48 -31
  30. data/lib/aspera/cos_node.rb +4 -3
  31. data/lib/aspera/environment.rb +4 -4
  32. data/lib/aspera/fasp/{manager.rb → agent_base.rb} +7 -6
  33. data/lib/aspera/fasp/{connect.rb → agent_connect.rb} +46 -39
  34. data/lib/aspera/fasp/{local.rb → agent_direct.rb} +42 -38
  35. data/lib/aspera/fasp/{http_gw.rb → agent_httpgw.rb} +50 -29
  36. data/lib/aspera/fasp/{node.rb → agent_node.rb} +43 -4
  37. data/lib/aspera/fasp/agent_trsdk.rb +106 -0
  38. data/lib/aspera/fasp/default.rb +17 -0
  39. data/lib/aspera/fasp/installation.rb +64 -48
  40. data/lib/aspera/fasp/parameters.rb +78 -91
  41. data/lib/aspera/fasp/parameters.yaml +531 -0
  42. data/lib/aspera/fasp/uri.rb +1 -1
  43. data/lib/aspera/faspex_gw.rb +12 -11
  44. data/lib/aspera/id_generator.rb +22 -0
  45. data/lib/aspera/keychain/encrypted_hash.rb +120 -0
  46. data/lib/aspera/keychain/macos_security.rb +94 -0
  47. data/lib/aspera/log.rb +45 -32
  48. data/lib/aspera/node.rb +9 -4
  49. data/lib/aspera/oauth.rb +116 -100
  50. data/lib/aspera/persistency_action_once.rb +11 -7
  51. data/lib/aspera/persistency_folder.rb +6 -26
  52. data/lib/aspera/rest.rb +66 -50
  53. data/lib/aspera/sync.rb +40 -35
  54. data/lib/aspera/timer_limiter.rb +22 -0
  55. metadata +86 -29
  56. data/docs/transfer_spec.html +0 -99
  57. data/lib/aspera/api_detector.rb +0 -60
  58. data/lib/aspera/fasp/aoc.rb +0 -24
  59. data/lib/aspera/secrets.rb +0 -20
@@ -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
@@ -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
 
@@ -1,5 +1,6 @@
1
1
  require 'aspera/log'
2
2
  require 'aspera/aoc'
3
+ require 'aspera/fasp/default'
3
4
  require 'aspera/cli/main'
4
5
  require 'webrick'
5
6
  require 'webrick/https'
@@ -73,16 +74,16 @@ module Aspera
73
74
  "xfer_retry" => 3600 } }
74
75
  # this transfer spec is for transfer to AoC
75
76
  faspex_transfer_spec={
76
- 'direction' => 'send',
77
- 'remote_user' => 'xfer',
77
+ 'direction' => 'send',
78
78
  'remote_host' => node_info['host'],
79
- 'ssh_port' => 33001,
80
- 'fasp_port' => 33001,
81
- 'tags' => ts_tags,
82
- 'token' => node_auth_bearer_token,
83
- 'paths' => [{'destination' => '/'}],
84
- 'cookie' => 'unused',
85
- 'create_dir' => true,
79
+ 'remote_user' => Fasp::Default::ACCESS_KEY_TRANSFER_USER,
80
+ 'ssh_port' => Fasp::Default::SSH_PORT,
81
+ 'fasp_port' => Fasp::Default::UDP_PORT,
82
+ 'tags' => ts_tags,
83
+ 'token' => node_auth_bearer_token,
84
+ 'paths' => [{'destination' => '/'}],
85
+ 'cookie' => 'unused',
86
+ 'create_dir' => true,
86
87
  'rate_policy' => 'fair',
87
88
  'rate_policy_allowed' => 'fixed',
88
89
  'min_rate_cap_kbps' => nil,
@@ -94,8 +95,8 @@ module Aspera
94
95
  'lock_rate_policy' => true,
95
96
  'source_root' => '',
96
97
  'content_protection' => nil,
97
- 'target_rate_cap_kbps' => 20000, # TODO
98
- 'target_rate_kbps' => 10000, # TODO
98
+ 'target_rate_cap_kbps' => 20000, # TODO: is this value useful ?
99
+ 'target_rate_kbps' => 10000, # TODO: get from where?
99
100
  'cipher' => 'aes-128',
100
101
  'cipher_allowed' => nil,
101
102
  'http_fallback' => false,
@@ -0,0 +1,22 @@
1
+ require 'uri'
2
+
3
+ module Aspera
4
+ class IdGenerator
5
+ ID_SEPARATOR='_'
6
+ WINDOWS_PROTECTED_CHAR=%r{[/:"<>\\\*\?]}
7
+ PROTECTED_CHAR_REPLACE='_'
8
+ private_constant :ID_SEPARATOR,:PROTECTED_CHAR_REPLACE,:WINDOWS_PROTECTED_CHAR
9
+ def self.from_list(object_id)
10
+ if object_id.is_a?(Array)
11
+ object_id=object_id.select{|i|!i.nil?}.map do |i|
12
+ (i.is_a?(String) and i.start_with?('https://')) ? URI.parse(i).host : i.to_s
13
+ end.join(ID_SEPARATOR)
14
+ end
15
+ raise "id must be a String" unless object_id.is_a?(String)
16
+ return object_id.
17
+ gsub(WINDOWS_PROTECTED_CHAR,PROTECTED_CHAR_REPLACE). # remove windows forbidden chars
18
+ gsub('.',PROTECTED_CHAR_REPLACE). # keep dot for extension only (nicer)
19
+ downcase
20
+ end
21
+ end
22
+ end