sdr-client 0.16.1 → 0.19.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6d44bbb8b087e0045328a2b8625654ad9f7eaadf7c968c5ee5402683dc04d26
4
- data.tar.gz: 9808626f7cad4548ccce883253245c80fc18fac9cd14353dcb008cb8c1cf365a
3
+ metadata.gz: 1ae3d332b62dd4908555f961ffa5f9ebc12e0388836f36f855672731d8b940a1
4
+ data.tar.gz: 97c3c18fc7e4ed98b5577ea24390eef9f2ecbf8c24970c92fd3d3097a13b5492
5
5
  SHA512:
6
- metadata.gz: e14bf4032db046e886a7ef02cc1183fab23806bf0b450527ad8e33f396d3cac1f2d254644e9f9e2179d38c04d200a4cdf09eb07515aabf0e8a7a2c7ad9367fd1
7
- data.tar.gz: 39e311b8bb036dd2abff468086103be8e55516b1490d219c4c34e5b68b0c80322af47efd0dcc198ee11e3e24e484d7d206102f20e415ccfa171abd7d61d6fde5
6
+ metadata.gz: f03baa42607cd68d3b814e46df38dda0567ca78082292faaf5ec47dfe518b68e0399f25305a89bed835bf68cde2e680f553646b4c921490ae06c7e426a812c5f
7
+ data.tar.gz: d392e1bfda994e6266ca4e6e1834036e76a5cfd37008c6ceda87ed6c20d4cbae9becef1fe8f47e3631f824dae7ae883735e0718dec7161488763d891f9d57121
@@ -13,6 +13,7 @@ Layout/LineLength:
13
13
  Metrics/BlockLength:
14
14
  Exclude:
15
15
  - 'spec/**/*'
16
+ - 'sdr-client.gemspec'
16
17
  ExcludedMethods:
17
18
  - 'OptionParser.new'
18
19
 
@@ -2,13 +2,17 @@
2
2
 
3
3
  require 'dry/monads'
4
4
  require 'faraday'
5
+ require 'active_support'
6
+ require 'active_support/core_ext/object/json'
5
7
 
6
8
  require 'sdr_client/version'
7
9
  require 'sdr_client/deposit'
10
+ require 'sdr_client/model_deposit'
8
11
  require 'sdr_client/credentials'
9
12
  require 'sdr_client/login'
10
13
  require 'sdr_client/login_prompt'
11
14
  require 'sdr_client/cli'
15
+ require 'sdr_client/connection'
12
16
 
13
17
  module SdrClient
14
18
  class Error < StandardError; end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SdrClient
4
+ # The connection to the server
5
+ class Connection
6
+ def initialize(url:, token: Credentials.read)
7
+ @url = url
8
+ @token = token
9
+ end
10
+
11
+ def connection
12
+ @connection ||= Faraday.new(url: url) do |conn|
13
+ conn.authorization :Bearer, token
14
+ conn.adapter :net_http
15
+ end
16
+ end
17
+
18
+ delegate :put, :post, to: :connection
19
+
20
+ private
21
+
22
+ attr_reader :url, :token
23
+ end
24
+ end
@@ -25,8 +25,6 @@ module SdrClient
25
25
  files_metadata: {},
26
26
  grouping_strategy: SingleFileGroupingStrategy,
27
27
  logger: Logger.new(STDOUT))
28
- token = Credentials.read
29
-
30
28
  augmented_metadata = FileMetadataBuilder.build(files: files, files_metadata: files_metadata)
31
29
  metadata = Request.new(label: label,
32
30
  type: type,
@@ -41,7 +39,8 @@ module SdrClient
41
39
  embargo_access: embargo_access,
42
40
  viewing_direction: viewing_direction,
43
41
  files_metadata: augmented_metadata)
44
- Process.new(metadata: metadata, url: url, token: token, files: files,
42
+ connection = Connection.new(url: url)
43
+ Process.new(metadata: metadata, connection: connection, files: files,
45
44
  grouping_strategy: grouping_strategy, logger: logger).run
46
45
  end
47
46
  # rubocop:enable Metrics/MethodLength
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module SdrClient
6
+ module Deposit
7
+ # The process for doing a deposit from a Cocina Model
8
+ class ModelProcess
9
+ DRO_PATH = '/v1/resources'
10
+ # @param [Cocina::Model::RequestDRO] request_dro for depositing
11
+ # @param [String] url the server to send to
12
+ # @param [String] token the bearer auth token for the server
13
+ # @param [Array<String>] files a list of file names to upload
14
+ # @param [Logger] logger the logger to use
15
+ def initialize(request_dro:, url:,
16
+ token:, files: [], logger: Logger.new(STDOUT))
17
+ @files = files
18
+ @url = url
19
+ @token = token
20
+ @request_dro = request_dro
21
+ @logger = logger
22
+ end
23
+
24
+ def run
25
+ check_files_exist
26
+ child_files_match
27
+
28
+ upload_responses = UploadFiles.new(files: files,
29
+ logger: logger,
30
+ connection: connection,
31
+ mime_types: mime_types).run
32
+ new_request_dro = with_external_identifiers(upload_responses)
33
+ upload_request_dro(new_request_dro.to_json)
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :request_dro, :files, :url, :token, :logger
39
+
40
+ def check_files_exist
41
+ logger.info('checking to see if files exist')
42
+ files.each do |file_name|
43
+ raise Errno::ENOENT, file_name unless ::File.exist?(file_name)
44
+ end
45
+ end
46
+
47
+ def child_files_match
48
+ # Files without request files.
49
+ files.each do |filepath|
50
+ filename = ::File.basename(filepath)
51
+
52
+ raise "Request file not provided for #{filepath}" if request_files[filename].nil?
53
+ end
54
+
55
+ # Request files without files
56
+ filenames = files.map { |filepath| ::File.basename(filepath) }
57
+ request_files.keys.each do |request_filename|
58
+ raise "File not provided for request file #{request_filename}" unless filenames.include?(request_filename)
59
+ end
60
+ end
61
+
62
+ # @return [Hash<Symbol,String>] the result of the metadata call
63
+ def upload_request_dro(request_json)
64
+ logger.info("Starting upload metadata: #{request_json}")
65
+ response = connection.post(DRO_PATH, request_json, 'Content-Type' => 'application/json')
66
+ unexpected_response(response) unless response.status == 201
67
+
68
+ logger.info("Response from server: #{response.body}")
69
+
70
+ { druid: JSON.parse(response.body)['druid'], background_job: response.headers['Location'] }
71
+ end
72
+
73
+ def unexpected_response(response)
74
+ raise "There was an error with your request: #{response.body}" if response.status == 400
75
+ raise 'There was an error with your credentials. Perhaps they have expired?' if response.status == 401
76
+
77
+ raise "unexpected response: #{response.status} #{response.body}"
78
+ end
79
+
80
+ def connection
81
+ @connection ||= Faraday.new(url: url) do |conn|
82
+ conn.authorization :Bearer, token
83
+ conn.adapter :net_http
84
+ end
85
+ end
86
+
87
+ # Map of filenames to mimetypes
88
+ def mime_types
89
+ @mime_types ||=
90
+ Hash[
91
+ request_files.map do |filename, file|
92
+ [filename, file.hasMimeType || 'application/octet-stream']
93
+ end
94
+ ]
95
+ end
96
+
97
+ # Map of filenames to request files
98
+ def request_files
99
+ @request_files ||=
100
+ Hash[
101
+ request_dro.structural.contains.map do |file_set|
102
+ file_set.structural.contains.map do |file|
103
+ [file.filename, file]
104
+ end
105
+ end.flatten(1)
106
+ ]
107
+ end
108
+
109
+ def with_external_identifiers(upload_responses)
110
+ signed_id_map = Hash[upload_responses.map { |response| [response.filename, response.signed_id] }]
111
+
112
+ # Manipulating request_dro as hash since immutable
113
+ request_dro_hash = request_dro.to_h
114
+ request_dro_hash[:structural][:contains].each do |file_set|
115
+ file_set[:structural][:contains].each do |file|
116
+ file[:externalIdentifier] = signed_id_map[file[:filename]]
117
+ end
118
+ end
119
+
120
+ Cocina::Models::RequestDRO.new(request_dro_hash)
121
+ end
122
+ end
123
+ end
124
+ end
@@ -9,28 +9,24 @@ module SdrClient
9
9
  DRO_PATH = '/v1/resources'
10
10
  # @param [Request] metadata information about the object
11
11
  # @param [Class] grouping_strategy class whose run method groups an array of uploads
12
- # @param [String] url the server to send to
13
- # @param [String] token the bearer auth token for the server
12
+ # @param [String] connection the server connection to use
14
13
  # @param [Array<String>] files a list of file names to upload
15
14
  # @param [Logger] logger the logger to use
16
- # rubocop:disable Metrics/ParameterLists
17
- def initialize(metadata:, grouping_strategy: SingleFileGroupingStrategy, url:,
18
- token:, files: [], logger: Logger.new(STDOUT))
15
+ def initialize(metadata:, grouping_strategy: SingleFileGroupingStrategy,
16
+ connection:, files: [], logger: Logger.new(STDOUT))
19
17
  @files = files
20
- @url = url
21
- @token = token
18
+ @connection = connection
22
19
  @metadata = metadata
23
20
  @logger = logger
24
21
  @grouping_strategy = grouping_strategy
25
22
  end
26
- # rubocop:enable Metrics/ParameterLists
27
23
 
28
24
  def run
29
25
  check_files_exist
30
26
  upload_responses = UploadFiles.new(files: files,
31
27
  logger: logger,
32
28
  connection: connection,
33
- metadata: metadata).run
29
+ mime_types: mime_types).run
34
30
  metadata_builder = MetadataBuilder.new(metadata: metadata,
35
31
  grouping_strategy: grouping_strategy,
36
32
  logger: logger)
@@ -40,7 +36,7 @@ module SdrClient
40
36
 
41
37
  private
42
38
 
43
- attr_reader :metadata, :files, :url, :token, :logger, :grouping_strategy
39
+ attr_reader :metadata, :files, :connection, :logger, :grouping_strategy
44
40
 
45
41
  def check_files_exist
46
42
  logger.info('checking to see if files exist')
@@ -68,11 +64,14 @@ module SdrClient
68
64
  raise "unexpected response: #{response.status} #{response.body}"
69
65
  end
70
66
 
71
- def connection
72
- @connection ||= Faraday.new(url: url) do |conn|
73
- conn.authorization :Bearer, token
74
- conn.adapter :net_http
75
- end
67
+ def mime_types
68
+ @mime_types ||=
69
+ Hash[
70
+ files.map do |filepath|
71
+ filename = ::File.basename(filepath)
72
+ [filename, metadata.for(filename)['mime_type']]
73
+ end
74
+ ]
76
75
  end
77
76
  end
78
77
  end
@@ -7,13 +7,13 @@ module SdrClient
7
7
  # The file uploading part of a deposit
8
8
  class UploadFiles
9
9
  BLOB_PATH = '/v1/direct_uploads'
10
- # @param [Array<String>] files a list of file names to upload
10
+ # @param [Array<String>] files a list of filepaths to upload
11
11
  # @param [Logger] logger the logger to use
12
- # @param [Faraday::Connection] connection
13
- # @param [Request] metadata information about the object
14
- def initialize(files:, metadata:, logger:, connection:)
12
+ # @param [Connection] connection
13
+ # @param [Hash<String,String] mime_types a map of filenames to mime types
14
+ def initialize(files:, mime_types:, logger:, connection:)
15
15
  @files = files
16
- @metadata = metadata
16
+ @mime_types = mime_types
17
17
  @logger = logger
18
18
  @connection = connection
19
19
  end
@@ -28,14 +28,14 @@ module SdrClient
28
28
 
29
29
  private
30
30
 
31
- attr_reader :files, :metadata, :logger, :connection
31
+ attr_reader :files, :mime_types, :logger, :connection
32
32
 
33
33
  def collect_file_metadata
34
34
  files.each_with_object({}) do |path, obj|
35
35
  file_name = ::File.basename(path)
36
36
  obj[path] = Files::DirectUploadRequest.from_file(path,
37
37
  file_name: file_name,
38
- content_type: metadata.for(file_name)['mime_type'])
38
+ content_type: mime_types[file_name])
39
39
  end
40
40
  end
41
41
 
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module SdrClient
6
+ # The namespace for the "deposit" command
7
+ module Deposit
8
+ def self.model_run(request_dro:,
9
+ files: [],
10
+ url:,
11
+ logger: Logger.new(STDOUT))
12
+ token = Credentials.read
13
+
14
+ ModelProcess.new(request_dro: request_dro, url: url, token: token, files: files, logger: logger).run
15
+ end
16
+ end
17
+ end
18
+ require 'sdr_client/deposit/model_process'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SdrClient
4
- VERSION = '0.16.1'
4
+ VERSION = '0.19.0'
5
5
  end
@@ -27,6 +27,8 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
29
 
30
+ spec.add_dependency 'activesupport'
31
+ spec.add_dependency 'cocina-models', '~> 0.29.0'
30
32
  spec.add_dependency 'dry-monads'
31
33
  spec.add_dependency 'faraday', '>= 0.16'
32
34
 
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sdr-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.1
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-09 00:00:00.000000000 Z
11
+ date: 2020-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: cocina-models
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.29.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.29.0
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: dry-monads
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -161,6 +189,7 @@ files:
161
189
  - lib/sdr-client.rb
162
190
  - lib/sdr_client.rb
163
191
  - lib/sdr_client/cli.rb
192
+ - lib/sdr_client/connection.rb
164
193
  - lib/sdr_client/credentials.rb
165
194
  - lib/sdr_client/deposit.rb
166
195
  - lib/sdr_client/deposit/file.rb
@@ -173,12 +202,14 @@ files:
173
202
  - lib/sdr_client/deposit/files/direct_upload_response.rb
174
203
  - lib/sdr_client/deposit/matching_file_grouping_strategy.rb
175
204
  - lib/sdr_client/deposit/metadata_builder.rb
205
+ - lib/sdr_client/deposit/model_process.rb
176
206
  - lib/sdr_client/deposit/process.rb
177
207
  - lib/sdr_client/deposit/request.rb
178
208
  - lib/sdr_client/deposit/single_file_grouping_strategy.rb
179
209
  - lib/sdr_client/deposit/upload_files.rb
180
210
  - lib/sdr_client/login.rb
181
211
  - lib/sdr_client/login_prompt.rb
212
+ - lib/sdr_client/model_deposit.rb
182
213
  - lib/sdr_client/version.rb
183
214
  - sdr-client.gemspec
184
215
  homepage: https://github.com/sul-dlss/sdr-client