aspera-cli 4.27.3 → 4.27.5

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 (79) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +118 -0
  4. data/CONTRIBUTING.md +5 -2
  5. data/bin/ascli +1 -0
  6. data/docs/README.md +224 -42
  7. data/lib/aspera/agent/base.rb +7 -2
  8. data/lib/aspera/agent/connect.rb +0 -4
  9. data/lib/aspera/agent/desktop.rb +0 -4
  10. data/lib/aspera/agent/direct.rb +49 -21
  11. data/lib/aspera/agent/node.rb +6 -5
  12. data/lib/aspera/agent/transferd.rb +2 -2
  13. data/lib/aspera/api/faspex.rb +2 -0
  14. data/lib/aspera/api/httpgw.rb +1 -2
  15. data/lib/aspera/api/node.rb +3 -3
  16. data/lib/aspera/ascp/installation.rb +1 -1
  17. data/lib/aspera/cli/async_transfer_store.rb +10 -9
  18. data/lib/aspera/cli/bootstrapper.rb +3 -1
  19. data/lib/aspera/cli/command_registry.rb +69 -7
  20. data/lib/aspera/cli/command_spec.rb +1 -1
  21. data/lib/aspera/cli/extended_value.rb +4 -3
  22. data/lib/aspera/cli/formatter.rb +10 -8
  23. data/lib/aspera/cli/http.rb +8 -20
  24. data/lib/aspera/cli/option_types.rb +3 -1
  25. data/lib/aspera/cli/option_value.rb +16 -19
  26. data/lib/aspera/cli/options.schema.yaml +86 -10
  27. data/lib/aspera/cli/parser.rb +30 -18
  28. data/lib/aspera/cli/plugins/aoc.rb +133 -156
  29. data/lib/aspera/cli/plugins/ats.rb +1 -7
  30. data/lib/aspera/cli/plugins/base.rb +40 -34
  31. data/lib/aspera/cli/plugins/config.rb +24 -11
  32. data/lib/aspera/cli/plugins/console.rb +1 -1
  33. data/lib/aspera/cli/plugins/faspex5.rb +30 -11
  34. data/lib/aspera/cli/plugins/faspio.rb +1 -1
  35. data/lib/aspera/cli/plugins/node.rb +26 -19
  36. data/lib/aspera/cli/plugins/orchestrator.rb +73 -44
  37. data/lib/aspera/cli/plugins/preview.rb +21 -19
  38. data/lib/aspera/cli/plugins/server.rb +3 -4
  39. data/lib/aspera/cli/plugins/shares.rb +21 -24
  40. data/lib/aspera/cli/preset_actions.rb +28 -18
  41. data/lib/aspera/cli/preset_manager.rb +34 -19
  42. data/lib/aspera/cli/prompt.rb +2 -1
  43. data/lib/aspera/cli/result.rb +33 -22
  44. data/lib/aspera/cli/runner.rb +1 -5
  45. data/lib/aspera/cli/sync_actions.rb +17 -16
  46. data/lib/aspera/cli/transfer_actions.rb +14 -3
  47. data/lib/aspera/cli/transfer_agent.rb +6 -4
  48. data/lib/aspera/cli/transfer_progress.rb +290 -55
  49. data/lib/aspera/cli/version.rb +1 -1
  50. data/lib/aspera/cli/wizard.rb +1 -1
  51. data/lib/aspera/coverage.rb +0 -1
  52. data/lib/aspera/environment.rb +29 -5
  53. data/lib/aspera/keychain/encrypted_hash.rb +1 -1
  54. data/lib/aspera/keychain/factory.rb +2 -1
  55. data/lib/aspera/log.rb +25 -2
  56. data/lib/aspera/node_emulator.rb +759 -0
  57. data/lib/aspera/oauth/base.rb +2 -1
  58. data/lib/aspera/oauth/factory.rb +6 -3
  59. data/lib/aspera/oauth/json_credentials.rb +34 -0
  60. data/lib/aspera/oauth/jwt.rb +3 -4
  61. data/lib/aspera/oauth.rb +1 -0
  62. data/lib/aspera/persistency_folder.rb +1 -3
  63. data/lib/aspera/preview/generator.rb +4 -1
  64. data/lib/aspera/preview/options.schema.yaml +119 -0
  65. data/lib/aspera/rest/aspera_errors.rb +12 -0
  66. data/lib/aspera/rest/client.rb +28 -19
  67. data/lib/aspera/rest/list.rb +14 -8
  68. data/lib/aspera/rest/parameters.rb +2 -2
  69. data/lib/aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml +0 -20
  70. data/lib/aspera/schema/IBM Aspera Orchestrator API-v1.yaml +1784 -0
  71. data/lib/aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml +1230 -137
  72. data/lib/aspera/schema/IBM_Aspera_Shares.yaml +14 -13
  73. data/lib/aspera/schema/reader.rb +12 -18
  74. data/lib/aspera/schema/registry.rb +6 -1
  75. data.tar.gz.sig +0 -0
  76. metadata +5 -3
  77. metadata.gz.sig +0 -0
  78. data/lib/aspera/node_simulator.rb +0 -345
  79. data/lib/aspera/preview/options.rb +0 -45
@@ -2930,21 +2930,25 @@ components:
2930
2930
  name:
2931
2931
  type: string
2932
2932
  minLength: 1
2933
- description:
2934
- type: string
2935
2933
  node_id:
2936
2934
  type: integer
2937
- path:
2935
+ directory:
2938
2936
  type: string
2937
+ description: Path of share folder on node
2938
+ create_directory:
2939
+ type: boolean
2940
+ description: Create the share folder on node
2939
2941
  ShareUpdate:
2940
2942
  type: object
2941
2943
  properties:
2942
2944
  name:
2943
2945
  type: string
2944
- description:
2945
- type: string
2946
- path:
2946
+ node_id:
2947
+ type: integer
2948
+ description: Admin only
2949
+ directory:
2947
2950
  type: string
2951
+ description: Path of share folder on node (admin only)
2948
2952
  # Node Schemas
2949
2953
  Node:
2950
2954
  type: object
@@ -3206,9 +3210,10 @@ components:
3206
3210
  name:
3207
3211
  type: string
3208
3212
  example: engineers
3209
- description:
3210
- type: string
3211
- nullable: true
3213
+ group_id:
3214
+ type: integer
3215
+ format: int32
3216
+ description: Identifier in groups from all sources
3212
3217
  created_at:
3213
3218
  type: string
3214
3219
  format: date-time
@@ -3224,16 +3229,12 @@ components:
3224
3229
  name:
3225
3230
  type: string
3226
3231
  example: engineers
3227
- description:
3228
- type: string
3229
3232
  LocalGroupUpdate:
3230
3233
  type: object
3231
3234
  properties:
3232
3235
  name:
3233
3236
  type: string
3234
3237
  example: engineers
3235
- description:
3236
- type: string
3237
3238
  LdapConfig:
3238
3239
  type: object
3239
3240
  properties:
@@ -116,15 +116,12 @@ module Aspera
116
116
  # Yield current property to block
117
117
  yield(property_schema, name, property_full_name)
118
118
 
119
- # Recursively process nested structures
120
- case node['type']
121
- when 'object'
122
- property_schema.each_property("#{property_full_name}.", on_variant: on_variant, &block) if node['properties']
123
- when 'array'
124
- if node['items']
125
- array_item_schema = property_schema.dig('items')
126
- array_item_schema.each_property("#{property_full_name}[].", on_variant: on_variant, &block) if array_item_schema.current['properties']
127
- end
119
+ # Recursively process nested structures (`type` is a list for a nullable value, e.g. `[array, 'null']`)
120
+ types = Array(node['type'])
121
+ property_schema.each_property("#{property_full_name}.", on_variant: on_variant, &block) if types.include?('object') && node['properties']
122
+ if types.include?('array') && node['items']
123
+ array_item_schema = property_schema.dig('items')
124
+ array_item_schema.each_property("#{property_full_name}[].", on_variant: on_variant, &block) if array_item_schema.current['properties']
128
125
  end
129
126
  # allOf without explicit type: object — recurse to merge all branches
130
127
  property_schema.each_property("#{property_full_name}.", on_variant: on_variant, &block) if node['allOf']
@@ -180,15 +177,12 @@ module Aspera
180
177
  row['default'] = node['default'] if node.key?('default')
181
178
  row['enum'] = node['enum'] if node.key?('enum')
182
179
  rows << row
183
- # Recurse into nested object or array-of-objects
184
- case node['type']
185
- when 'object'
186
- collect_rows(rows, prop_reader, "#{full_name}.") if node['properties']
187
- when 'array'
188
- if node['items']
189
- item_reader = prop_reader.dig('items')
190
- collect_rows(rows, item_reader, "#{full_name}[].") if item_reader.current['properties']
191
- end
180
+ # Recurse into nested object or array-of-objects (`type` is a list for a nullable value)
181
+ types = Array(node['type'])
182
+ collect_rows(rows, prop_reader, "#{full_name}.") if types.include?('object') && node['properties']
183
+ if types.include?('array') && node['items']
184
+ item_reader = prop_reader.dig('items')
185
+ collect_rows(rows, item_reader, "#{full_name}[].") if item_reader.current['properties']
192
186
  end
193
187
  collect_rows(rows, prop_reader, "#{full_name}.") if node['allOf']
194
188
  end
@@ -58,6 +58,7 @@ module Aspera
58
58
  args: 'aspera/sync/args.schema.yaml',
59
59
  conf: 'aspera/sync/conf.schema.yaml',
60
60
  opts: 'aspera/cli/options.schema.yaml',
61
+ preview: 'aspera/preview/options.schema.yaml',
61
62
  aoc: 'aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml',
62
63
  automation: 'aspera/schema/IBM Aspera on Cloud Automation API-1.0.5-enhanced.yaml',
63
64
  faspex: 'aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml',
@@ -65,27 +66,31 @@ module Aspera
65
66
  console: 'aspera/schema/IBM Aspera Console-enhanced.yaml',
66
67
  node: 'aspera/schema/IBM Aspera Node API-4.4.6.yaml',
67
68
  shares: 'aspera/schema/IBM_Aspera_Shares.yaml',
69
+ orchestrator: 'aspera/schema/IBM Aspera Orchestrator API-v1.yaml',
68
70
  async_tables: 'aspera/schema/async_tables.yaml'
69
71
  }
70
72
 
71
73
  # Schemas owned by ascli: values are validated against them (vendor API schemas are validated by the API)
72
- OWNED = %i[spec args conf opts async_tables].freeze
74
+ OWNED = %i[spec args conf opts preview async_tables].freeze
73
75
 
74
76
  OPTIONS = 'opts'
75
77
  TRANSFER_SPEC = 'spec'
76
78
  SYNC_CONF = 'conf'
77
79
  SYNC_ARGS = 'args'
80
+ PREVIEW_OPTIONS = 'preview'
78
81
  AOC = 'aoc'
79
82
  AUTOMATION = 'automation'
80
83
  FASPEX = 'faspex'
81
84
  FASPIO = 'faspio'
82
85
  CONSOLE = 'console'
83
86
  NODE = 'node'
87
+ ORCHESTRATOR = 'orchestrator'
84
88
  SHARES = 'shares+/api/v1'
85
89
  ASYNC_TABLES = 'async_tables'
86
90
  LOG_OPTIONS = "#{OPTIONS}:components.schemas.LogOptions"
87
91
  DIRECT_AGENT_OPTIONS = "#{OPTIONS}:components.schemas.DirectAgentOptions"
88
92
  NODE_AGENT_OPTIONS = "#{OPTIONS}:components.schemas.NodeAgentOptions"
93
+ NODE_EMULATOR_OPTIONS = "#{OPTIONS}:components.schemas.NodeEmulatorOptions"
89
94
  HTTPGW_AGENT_OPTIONS = "#{OPTIONS}:components.schemas.HttpgwAgentOptions"
90
95
  TRANSFERD_AGENT_OPTIONS = "#{OPTIONS}:components.schemas.TransferdAgentOptions"
91
96
  TRANSFER_AGENT_OPTIONS = "#{OPTIONS}:components.schemas.TransferAgentOptions"
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.27.3
4
+ version: 4.27.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurent Martin
@@ -452,12 +452,13 @@ files:
452
452
  - lib/aspera/markdown.rb
453
453
  - lib/aspera/mime.rb
454
454
  - lib/aspera/nagios.rb
455
- - lib/aspera/node_simulator.rb
455
+ - lib/aspera/node_emulator.rb
456
456
  - lib/aspera/oauth.rb
457
457
  - lib/aspera/oauth/base.rb
458
458
  - lib/aspera/oauth/boot.rb
459
459
  - lib/aspera/oauth/factory.rb
460
460
  - lib/aspera/oauth/generic.rb
461
+ - lib/aspera/oauth/json_credentials.rb
461
462
  - lib/aspera/oauth/jwt.rb
462
463
  - lib/aspera/oauth/url_json.rb
463
464
  - lib/aspera/oauth/web.rb
@@ -466,7 +467,7 @@ files:
466
467
  - lib/aspera/preview/file_types.rb
467
468
  - lib/aspera/preview/generator.rb
468
469
  - lib/aspera/preview/image_error.png
469
- - lib/aspera/preview/options.rb
470
+ - lib/aspera/preview/options.schema.yaml
470
471
  - lib/aspera/preview/terminal.rb
471
472
  - lib/aspera/preview/utils.rb
472
473
  - lib/aspera/preview/video_error.png
@@ -488,6 +489,7 @@ files:
488
489
  - lib/aspera/schema/IBM Aspera Console-enhanced.yaml
489
490
  - lib/aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml
490
491
  - lib/aspera/schema/IBM Aspera Node API-4.4.6.yaml
492
+ - lib/aspera/schema/IBM Aspera Orchestrator API-v1.yaml
491
493
  - lib/aspera/schema/IBM Aspera faspio Gateway API-1.0.0.yaml
492
494
  - lib/aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml
493
495
  - lib/aspera/schema/IBM Aspera on Cloud Automation API-1.0.5-enhanced.yaml
metadata.gz.sig CHANGED
Binary file
@@ -1,345 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'aspera/assert'
4
- require 'aspera/mime'
5
- require 'aspera/ascp/installation'
6
- require 'aspera/agent/direct'
7
- require 'aspera/log'
8
- require 'webrick'
9
- require 'json'
10
-
11
- module Aspera
12
- class NodeSimulator
13
- def initialize
14
- @agent = Agent::Direct.new(management_cb: ->(event) { process_event(event) })
15
- @sessions = {}
16
- end
17
-
18
- def start(ts)
19
- @agent.start_transfer(ts)
20
- end
21
-
22
- def all_sessions
23
- @agent.sessions.map { |session| session[:job_id] }.uniq.each.map { |job_id| job_to_transfer(job_id) }
24
- end
25
-
26
- # status: ('waiting', 'partially_completed', 'unknown', 'waiting(read error)',] 'running', 'completed', 'failed'
27
- def job_to_transfer(job_id)
28
- jobs = @agent.sessions_by_job(job_id)
29
- ts = nil
30
- sessions = jobs.map do |j|
31
- ts ||= j[:ts]
32
- {
33
- id: j[:id],
34
- client_node_id: '',
35
- server_node_id: '2bbdcc39-f789-4d47-8163-6767fc14f421',
36
- client_ip_address: '192.168.0.100',
37
- server_ip_address: '5.10.114.4',
38
- status: 'running',
39
- retry_timeout: 3600,
40
- retry_count: 0,
41
- start_time_usec: 1701094040000000,
42
- end_time_usec: nil,
43
- elapsed_usec: 405312,
44
- bytes_transferred: 26,
45
- bytes_written: 26,
46
- bytes_lost: 0,
47
- files_completed: 1,
48
- directories_completed: 0,
49
- target_rate_kbps: 500000,
50
- min_rate_kbps: 0,
51
- calc_rate_kbps: 9900,
52
- network_delay_usec: 40000,
53
- avg_rate_kbps: 0.51,
54
- error_code: 0,
55
- error_desc: '',
56
- source_statistics: {
57
- args_scan_attempted: 1,
58
- args_scan_completed: 1,
59
- paths_scan_attempted: 1,
60
- paths_scan_failed: 0,
61
- paths_scan_skipped: 0,
62
- paths_scan_excluded: 0,
63
- dirs_scan_completed: 0,
64
- files_scan_completed: 1,
65
- dirs_xfer_attempted: 0,
66
- dirs_xfer_fail: 0,
67
- files_xfer_attempted: 1,
68
- files_xfer_fail: 0,
69
- files_xfer_noxfer: 0
70
- },
71
- precalc: {
72
- enabled: true,
73
- status: 'ready',
74
- bytes_expected: 0,
75
- directories_expected: 0,
76
- files_expected: 0,
77
- files_excluded: 0,
78
- files_special: 0,
79
- files_failed: 1
80
- }
81
- }
82
- end
83
- ts ||= {}
84
- result = {
85
- id: job_id,
86
- status: 'running',
87
- start_spec: ts,
88
- sessions: sessions,
89
- bytes_transferred: 26,
90
- bytes_written: 26,
91
- bytes_lost: 0,
92
- avg_rate_kbps: 0.51,
93
- files_completed: 1,
94
- files_skipped: 0,
95
- directories_completed: 0,
96
- start_time_usec: 1701094040000000,
97
- end_time_usec: 1701094040405312,
98
- elapsed_usec: 405312,
99
- error_code: 0,
100
- error_desc: '',
101
- precalc: {
102
- status: 'ready',
103
- bytes_expected: 0,
104
- files_expected: 0,
105
- directories_expected: 0,
106
- files_special: 0,
107
- files_failed: 1
108
- },
109
- files: [{
110
- id: 'd1b5c112-82b75425-860745fc-93851671-64541bdd',
111
- path: '/workspaces/45071/packages/bYA_ilq73g.asp-package/contents/data_file.bin',
112
- start_time_usec: 1701094040000000,
113
- elapsed_usec: 105616,
114
- end_time_usec: 1701094040001355,
115
- status: 'completed',
116
- error_code: 0,
117
- error_desc: '',
118
- size: 26,
119
- type: 'file',
120
- checksum_type: 'none',
121
- checksum: nil,
122
- start_byte: 0,
123
- bytes_written: 26,
124
- session_id: 'bafc72b8-366c-4501-8095-47208183d6b8'
125
- }]
126
- }
127
- Log.dump(:job, result, level: :trace2)
128
- return result
129
- end
130
-
131
- # Process event from management port
132
- def process_event(event)
133
- # Code duplicated on purpose, as implementation goes, blocks will be replaced
134
- case event['Type']
135
- when 'NOP' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
136
- # rubocop:disable Lint/DuplicateBranch
137
- when 'START' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
138
- when 'QUERY' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
139
- when 'QUERYRSP' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
140
- when 'STATS' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
141
- when 'STOP' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
142
- when 'ERROR' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
143
- when 'CANCEL' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
144
- when 'DONE' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
145
- when 'RATE' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
146
- when 'FILEERROR' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
147
- when 'SESSION' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
148
- when 'NOTIFICATION' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
149
- when 'INIT' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
150
- when 'VLINK' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
151
- when 'PUT' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
152
- when 'WRITE' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
153
- when 'CLOSE' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
154
- when 'SKIP' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
155
- when 'ARGSTOP' then Aspera.Log.debug { "event not managed: #{event['Type']}" }
156
- # rubocop:enable Lint/DuplicateBranch
157
- else Aspera.error_unreachable_line
158
- end
159
- end
160
- end
161
-
162
- # this class answers the Faspex /send API and creates a package on Aspera on Cloud
163
- # a new instance is created for each request
164
- class NodeSimulatorServlet < WEBrick::HTTPServlet::AbstractServlet
165
- PATH_TRANSFERS = '/ops/transfers'
166
- PATH_ONE_TRANSFER = %r{/ops/transfers/(.+)$}
167
- PATH_BROWSE = '/files/browse'
168
- # @param credentials [Hash]
169
- # @param simulator [NodeSimulator]
170
- def initialize(server, credentials, simulator)
171
- super(server)
172
- @credentials = credentials
173
- @simulator = simulator
174
- # Resolve once at startup; default to current working directory
175
- @browse_root = File.realpath(credentials[:browse_root] || Dir.pwd)
176
- end
177
-
178
- require 'json'
179
- require 'time'
180
-
181
- def folder_to_structure(folder_path)
182
- # Resolve and confine to browse_root (prevents path traversal via client-supplied path)
183
- resolved = File.realpath(folder_path)
184
- Aspera.assert(resolved.start_with?("#{@browse_root}/") || resolved.eql?(@browse_root)) { 'Browse path traversal attempt detected' }
185
- Aspera.assert(Dir.exist?(resolved)) { "Path does not exist or is not a directory: #{resolved}" }
186
- folder_path = resolved
187
-
188
- # Build self structure
189
- folder_stat = File.stat(folder_path)
190
- structure = {
191
- 'self' => {
192
- 'path' => folder_path,
193
- 'basename' => File.basename(folder_path),
194
- 'type' => 'directory',
195
- 'size' => folder_stat.size,
196
- 'mtime' => folder_stat.mtime.utc.iso8601,
197
- 'permissions' => [
198
- {'name' => 'view'},
199
- {'name' => 'edit'},
200
- {'name' => 'delete'}
201
- ]
202
- },
203
- 'items' => []
204
- }
205
-
206
- # Iterate over folder contents
207
- Dir.foreach(folder_path) do |entry|
208
- next if entry == '.' || entry == '..' # Skip current and parent directory
209
-
210
- item_path = File.join(folder_path, entry)
211
- item_type = File.ftype(item_path) rescue 'unknown' # Get the type of file
212
- item_stat = File.lstat(item_path) # Use lstat to handle symbolic links correctly
213
-
214
- item = {
215
- 'path' => item_path,
216
- 'basename' => entry,
217
- 'type' => item_type,
218
- 'size' => item_stat.size,
219
- 'mtime' => item_stat.mtime.utc.iso8601,
220
- 'permissions' => [
221
- {'name' => 'view'},
222
- {'name' => 'edit'},
223
- {'name' => 'delete'}
224
- ]
225
- }
226
-
227
- # Add additional details for specific types
228
- case item_type
229
- when 'file'
230
- item['partial_file'] = false
231
- when 'link'
232
- item['target'] = File.readlink(item_path) rescue nil # Add the target of the symlink
233
- when 'unknown'
234
- item['note'] = 'File type could not be determined'
235
- end
236
-
237
- structure['items'] << item
238
- end
239
-
240
- structure
241
- end
242
-
243
- def do_POST(request, response)
244
- case request.path
245
- when PATH_TRANSFERS
246
- job_id = @simulator.start(JSON.parse(request.body))
247
- sleep(0.5)
248
- set_json_response(request, response, @simulator.job_to_transfer(job_id))
249
- when PATH_BROWSE
250
- req = JSON.parse(request.body)
251
- # req['count']
252
- set_json_response(request, response, folder_to_structure(req['path'] || @browse_root))
253
- else
254
- set_json_response(request, response, [{error: 'Bad request'}], code: 400)
255
- end
256
- end
257
-
258
- def do_GET(request, response)
259
- case request.path
260
- when '/info'
261
- info = Ascp::Installation.instance.ascp_info
262
- set_json_response(request, response, {
263
- application: 'node',
264
- current_time: Time.now.utc.iso8601(0),
265
- version: info['sdk_ascp_version'].gsub(/ .*$/, ''),
266
- license_expiration_date: info['expiration_date'],
267
- license_max_rate: info['maximum_bandwidth'],
268
- os: %x(uname -srv).chomp,
269
- aej_status: 'disconnected',
270
- async_reporting: 'no',
271
- transfer_activity_reporting: 'no',
272
- transfer_user: 'xfer',
273
- docroot: 'file:////data/aoc/eudemo-sedemo',
274
- node_id: '2bbdcc39-f789-4d47-8163-6767fc14f421',
275
- cluster_id: '6dae2844-d1a9-47a5-916d-9b3eac3ea466',
276
- acls: ['impersonation'],
277
- access_key_configuration_capabilities: {
278
- transfer: %w[
279
- cipher
280
- policy
281
- target_rate_cap_kbps
282
- target_rate_kbps
283
- preserve_timestamps
284
- content_protection_secret
285
- aggressiveness
286
- token_encryption_key
287
- byok_enabled
288
- bandwidth_flow_network_rc_module
289
- file_checksum_type
290
- ],
291
- server: %w[
292
- activity_event_logging
293
- activity_file_event_logging
294
- recursive_counts
295
- aej_logging
296
- wss_enabled
297
- activity_transfer_ignore_skipped_files
298
- activity_files_max
299
- access_key_credentials_encryption_type
300
- discovery
301
- auto_delete
302
- allow
303
- deny
304
- ]
305
- },
306
- capabilities: [
307
- {name: 'sync', value: true},
308
- {name: 'watchfolder', value: true},
309
- {name: 'symbolic_links', value: true},
310
- {name: 'move_file', value: true},
311
- {name: 'move_directory', value: true},
312
- {name: 'filelock', value: false},
313
- {name: 'ssh_fingerprint', value: false},
314
- {name: 'aej_version', value: '1.0'},
315
- {name: 'page', value: true},
316
- {name: 'file_id_version', value: '2.0'},
317
- {name: 'auto_delete', value: false}
318
- ],
319
- settings: [
320
- {name: 'content_protection_required', value: false},
321
- {name: 'content_protection_strong_pass_required', value: false},
322
- {name: 'filelock_restriction', value: 'none'},
323
- {name: 'ssh_fingerprint', value: nil},
324
- {name: 'wss_enabled', value: false},
325
- {name: 'wss_port', value: 443}
326
- ]
327
- })
328
- when PATH_TRANSFERS
329
- set_json_response(request, response, @simulator.all_sessions)
330
- when PATH_ONE_TRANSFER
331
- job_id = request.path.match(PATH_ONE_TRANSFER)[1]
332
- set_json_response(request, response, @simulator.job_to_transfer(job_id))
333
- else
334
- set_json_response(request, response, [{error: 'Unknown request'}], code: 400)
335
- end
336
- end
337
-
338
- def set_json_response(request, response, json, code: 200)
339
- response.status = code
340
- response['Content-Type'] = Mime::JSON
341
- response.body = json.to_json
342
- Log.log.trace1 { Log.obj_dump("response for #{request.request_method} #{request.path}", json) }
343
- end
344
- end
345
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # cspell:ignore reencode conv transframes pauseframes
4
-
5
- module Aspera
6
- module Preview
7
- # generator options. Used as parameter to preview generator object.
8
- # also settable by command line.
9
- class Options
10
- # types of generation for video files
11
- VIDEO_CONVERSION_METHODS = %i[reencode blend clips].freeze
12
- VIDEO_THUMBNAIL_METHODS = %i[fixed animated].freeze
13
- # @type [Array<Symbol>] methods for office document conversion
14
- OFFICE_CONVERSION_METHODS = %i[soffice unoconv].freeze
15
- # Options used in generator
16
- # For scaling see: https://trac.ffmpeg.org/wiki/Scaling
17
- # iw/ih : input width or height
18
- # -x : keep aspect ratio, having value a multiple of x
19
- DESCRIPTIONS = [
20
- {name: :office_conversion, default: :soffice, description: 'office: method for office document conversion', values: OFFICE_CONVERSION_METHODS},
21
- {name: :max_size, default: 1 << 24, description: 'maximum size (in bytes) of preview file'},
22
- {name: :thumb_vid_scale, default: '-1:min(ih,100)', description: 'png: video: size (ffmpeg scale argument)'},
23
- {name: :thumb_vid_fraction, default: 0.1, description: 'png: video: time percent position of snapshot'},
24
- {name: :thumb_img_size, default: 800, description: 'png: non-video: height (and width)'},
25
- {name: :thumb_text_font, default: 'Courier', description: 'png: plaintext: font for text rendering: `magick identify -list font`'},
26
- {name: :video_conversion, default: :reencode, description: 'mp4: method for preview generation', values: VIDEO_CONVERSION_METHODS},
27
- {name: :video_png_conv, default: :fixed, description: 'mp4: method for thumbnail generation', values: VIDEO_THUMBNAIL_METHODS},
28
- {name: :video_scale, default: 'min(iw,360):-2', description: 'mp4: all: video scale (ffmpeg scale argument)'},
29
- {name: :video_start_sec, default: 10, description: 'mp4: all: start offset (seconds) of video preview'},
30
- {name: :video_codec, default: nil, description: 'mp4: reencode: video codec for ffmpeg (e.g. libx264, h264_videotoolbox, h264_nvenc), default: auto-detect'},
31
- {name: :reencode_ffmpeg, default: {}, description: 'mp4: reencode: options to ffmpeg, keys: `in`, `out`'},
32
- {name: :blend_keyframes, default: 30, description: 'mp4: blend: # key frames'},
33
- {name: :blend_pauseframes, default: 3, description: 'mp4: blend: # pause frames'},
34
- {name: :blend_transframes, default: 5, description: 'mp4: blend: # transition blend frames'},
35
- {name: :blend_fps, default: 15, description: 'mp4: blend: frame per second'},
36
- {name: :clips_count, default: 5, description: 'mp4: clips: number of clips'},
37
- {name: :clips_length, default: 5, description: 'mp4: clips: length in seconds of each clips'}
38
- ].freeze
39
- # add accessors
40
- DESCRIPTIONS.each do |opt|
41
- attr_accessor opt[:name]
42
- end
43
- end
44
- end
45
- end