sdr-client 0.7.1 → 0.8.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: 85bf3bb61e2edeca3fd59c4bcb72e65c0ca8a6fa2555095059c774d6adbb5cd9
4
- data.tar.gz: 29ef71e2e7778c28b8db875e7c910ee4f477857422d61d59774ab09b0fdb5852
3
+ metadata.gz: d4ac0ef485cd0ede90e6bcb2b99dcf001f92f3f296720520e6f1d4f5dcccef47
4
+ data.tar.gz: 52d7af6780779c41dcb67d87b9f87a139568132e612c2118ae5170617b023d06
5
5
  SHA512:
6
- metadata.gz: 61cc5ce0d28aeddbcd20273a7086d9b4dc0482b76f91b19002496b80e4db7d32471f9b8e827ffc800c58172fb3cf7d1f2ccdf920ca11bd88f5ac141002406703
7
- data.tar.gz: c2149a463c52831fee474f8c43e00982fce4ea9f56da629f8b87f1889bb59630419ed6c8c5296b56b6985324195ff1bb700277cbdfa91e9de89388319689b461
6
+ metadata.gz: 48f9cb820ed8e23aada68d2bd65fe676b94941bb47e618832449df5bbcfe53ffb632fc961e1f5d3279d5fc9a8d6458dc32f28fd5b6e3ba240911cc50a9f137c8
7
+ data.tar.gz: 6ad9e1dd66c890a2ae771c95d53c3204872fc8c8fc3eb851863f021c1150748134a426b6aedd511b378a9bba29566d828c4eefa9b027462fedeeea0a170c9df7
@@ -13,6 +13,9 @@ module SdrClient
13
13
  else
14
14
  raise "Unknown command #{command}"
15
15
  end
16
+ rescue SdrClient::Credentials::NoCredentialsError
17
+ puts 'Log in first'
18
+ exit(1)
16
19
  end
17
20
  end
18
21
  end
@@ -3,6 +3,8 @@
3
3
  module SdrClient
4
4
  # The stored credentials
5
5
  class Credentials
6
+ class NoCredentialsError < StandardError; end
7
+
6
8
  # @param [String] a json string that contains a field 'token'
7
9
  def self.write(body)
8
10
  json = JSON.parse(body)
@@ -10,14 +12,12 @@ module SdrClient
10
12
  File.open(credentials_file, 'w', 0o600) do |file|
11
13
  file.write(json.fetch('token'))
12
14
  end
13
- puts 'Signed in.'
14
15
  end
15
16
 
16
17
  def self.read
17
- return IO.readlines(credentials_file, chomp: true).first if ::File.exist?(credentials_file)
18
+ raise NoCredentialsError unless ::File.exist?(credentials_file)
18
19
 
19
- puts 'Log in first'
20
- exit(1)
20
+ IO.readlines(credentials_file, chomp: true).first
21
21
  end
22
22
 
23
23
  def self.credentials_path
@@ -39,4 +39,6 @@ require 'sdr_client/deposit/files/direct_upload_response'
39
39
  require 'sdr_client/deposit/file'
40
40
  require 'sdr_client/deposit/file_set'
41
41
  require 'sdr_client/deposit/request'
42
+ require 'sdr_client/deposit/upload_files'
43
+ require 'sdr_client/deposit/metadata_builder'
42
44
  require 'sdr_client/deposit/process'
@@ -6,12 +6,12 @@ module SdrClient
6
6
  module Deposit
7
7
  module Files
8
8
  DirectUploadRequest = Struct.new(:checksum, :byte_size, :content_type, :filename, keyword_init: true) do
9
- def self.from_file(filename)
10
- checksum = Digest::MD5.file(filename).base64digest
9
+ def self.from_file(path, file_name:, content_type:)
10
+ checksum = Digest::MD5.file(path).base64digest
11
11
  new(checksum: checksum,
12
- byte_size: ::File.size(filename),
13
- content_type: 'text/html',
14
- filename: ::File.basename(filename))
12
+ byte_size: ::File.size(path),
13
+ content_type: content_type || 'application/octet-stream',
14
+ filename: file_name)
15
15
  end
16
16
 
17
17
  def as_json
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module SdrClient
6
+ module Deposit
7
+ # Constructs the deposit metadata for the DRO
8
+ class MetadataBuilder
9
+ # @param [Request] metadata information about the object
10
+ # @param [Class] grouping_strategy class whose run method groups an array of uploads
11
+ # @param [Hash<String, Hash<String, String>>] files_metadata file name, hash of additional file metadata
12
+ # Additional metadata includes access, preserve, shelve, md5, sha1
13
+ # @param [Logger] logger the logger to use
14
+ def initialize(metadata:, grouping_strategy:, files_metadata:, logger:)
15
+ @metadata = metadata
16
+ @logger = logger
17
+ @grouping_strategy = grouping_strategy
18
+ @files_metadata = files_metadata
19
+ end
20
+
21
+ def with_uploads(upload_responses)
22
+ file_sets = build_filesets(uploads: upload_responses)
23
+ metadata.with_file_sets(file_sets)
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :metadata, :files, :logger, :grouping_strategy, :files_metadata
29
+
30
+ # @param [Array<SdrClient::Deposit::Files::DirectUploadResponse>] uploads the uploaded files to attach.
31
+ # @return [Array<SdrClient::Deposit::FileSet>] the uploads transformed to filesets
32
+ def build_filesets(uploads:)
33
+ grouped_uploads = grouping_strategy.run(uploads: uploads)
34
+ grouped_uploads.map.with_index(1) do |upload_group, i|
35
+ metadata_group = {}
36
+ upload_group.each { |upload| metadata_group[upload.filename] = files_metadata.fetch(upload.filename, {}) }
37
+ FileSet.new(uploads: upload_group, uploads_metadata: metadata_group, label: "Object #{i}")
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -6,7 +6,6 @@ module SdrClient
6
6
  module Deposit
7
7
  # The process for doing a deposit
8
8
  class Process
9
- BLOB_PATH = '/v1/direct_uploads'
10
9
  DRO_PATH = '/v1/resources'
11
10
  # @param [Request] metadata information about the object
12
11
  # @param [Class] grouping_strategy class whose run method groups an array of uploads
@@ -31,11 +30,13 @@ module SdrClient
31
30
 
32
31
  def run
33
32
  check_files_exist
34
- file_metadata = collect_file_metadata
35
- upload_responses = upload_file_metadata(file_metadata)
36
- upload_files(upload_responses)
37
- file_sets = build_filesets(uploads: upload_responses.values, files_metadata: files_metadata)
38
- request = metadata.with_file_sets(file_sets)
33
+ upload_responses = UploadFiles.new(files: files, logger: logger,
34
+ connection: connection, files_metadata: files_metadata).run
35
+ metadata_builder = MetadataBuilder.new(metadata: metadata,
36
+ grouping_strategy: grouping_strategy,
37
+ files_metadata: files_metadata,
38
+ logger: logger)
39
+ request = metadata_builder.with_uploads(upload_responses)
39
40
  upload_metadata(request.as_json)
40
41
  end
41
42
 
@@ -50,51 +51,6 @@ module SdrClient
50
51
  end
51
52
  end
52
53
 
53
- def collect_file_metadata
54
- files.each_with_object({}) do |filename, obj|
55
- obj[filename] = Files::DirectUploadRequest.from_file(filename)
56
- end
57
- end
58
-
59
- # @param [Hash<String,Files::DirectUploadRequest>] file_metadata the filenames and their upload request
60
- def upload_file_metadata(file_metadata)
61
- Hash[file_metadata.map { |filename, metadata| [filename, direct_upload(metadata.to_json)] }]
62
- end
63
-
64
- def direct_upload(metadata_json)
65
- logger.info("Starting an upload request: #{metadata_json}")
66
- response = connection.post(BLOB_PATH, metadata_json, 'Content-Type' => 'application/json')
67
- raise "unexpected response: #{response.inspect}" unless response.status == 200
68
-
69
- logger.info("Response from server: #{response.body}")
70
-
71
- Files::DirectUploadResponse.new(JSON.parse(response.body))
72
- end
73
-
74
- # @param [Hash<String,Files::DirectUploadResponse>] upload_responses the filenames and their upload response
75
- def upload_files(upload_responses)
76
- upload_responses.each do |filename, response|
77
- upload_file(filename: filename,
78
- url: response.direct_upload.fetch('url'),
79
- content_type: response.content_type,
80
- content_length: response.byte_size)
81
-
82
- logger.info('Upload complete')
83
- end
84
- end
85
-
86
- def upload_file(filename:, url:, content_type:, content_length:)
87
- logger.info("Uploading `#{filename}' to #{url}")
88
-
89
- upload_response = connection.put(url) do |req|
90
- req.body = ::File.open(filename)
91
- req.headers['Content-Type'] = content_type
92
- req.headers['Content-Length'] = content_length.to_s
93
- end
94
-
95
- raise "unexpected response: #{upload_response.inspect}" unless upload_response.status == 204
96
- end
97
-
98
54
  # @return [Hash<Symbol,String>] the result of the metadata call
99
55
  def upload_metadata(metadata)
100
56
  logger.info("Starting upload metadata: #{metadata}")
@@ -122,16 +78,20 @@ module SdrClient
122
78
  end
123
79
 
124
80
  # @param [Array<SdrClient::Deposit::Files::DirectUploadResponse>] uploads the uploaded files to attach.
125
- # @param [Hash<String,Hash<String, String>>] files_metadata filename, hash of additional file metadata.
126
81
  # @return [Array<SdrClient::Deposit::FileSet>] the uploads transformed to filesets
127
- def build_filesets(uploads:, files_metadata:)
82
+ def build_filesets(uploads:)
128
83
  grouped_uploads = grouping_strategy.run(uploads: uploads)
129
84
  grouped_uploads.map.with_index(1) do |upload_group, i|
130
85
  metadata_group = {}
131
- upload_group.each { |upload| metadata_group[upload.filename] = files_metadata.fetch(upload.filename, {}) }
86
+ upload_group.each { |upload| metadata_group[upload.filename] = file_metadata_for(upload.filename) }
132
87
  FileSet.new(uploads: upload_group, uploads_metadata: metadata_group, label: "Object #{i}")
133
88
  end
134
89
  end
90
+
91
+ # @return [Hash<Symbol,String>] the file metadata for this file
92
+ def file_metadata_for(filename)
93
+ files_metadata.fetch(filename, {})
94
+ end
135
95
  end
136
96
  end
137
97
  end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module SdrClient
6
+ module Deposit
7
+ # The file uploading part of a deposit
8
+ class UploadFiles
9
+ BLOB_PATH = '/v1/direct_uploads'
10
+ # @param [Array<String>] files a list of file names to upload
11
+ # @param [Logger] logger the logger to use
12
+ # @param [Faraday::Connection] connection
13
+ # @param [Hash<String, Hash<String, String>>] files_metadata file name, hash of additional file metadata
14
+ def initialize(files:, files_metadata:, logger:, connection:)
15
+ @files = files
16
+ @files_metadata = files_metadata
17
+ @logger = logger
18
+ @connection = connection
19
+ end
20
+
21
+ # @return [Array<SdrClient::Deposit::Files::DirectUploadResponse>] the responses from the server for the uploads
22
+ def run
23
+ file_metadata = collect_file_metadata
24
+ upload_responses = upload_file_metadata(file_metadata)
25
+ upload_files(upload_responses)
26
+ upload_responses.values
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :files, :files_metadata, :logger, :connection
32
+
33
+ def collect_file_metadata
34
+ files.each_with_object({}) do |path, obj|
35
+ file_name = ::File.basename(path)
36
+ obj[path] = Files::DirectUploadRequest.from_file(path,
37
+ file_name: file_name,
38
+ content_type: file_metadata_for(file_name)[:mime_type])
39
+ end
40
+ end
41
+
42
+ # @param [Hash<String,Files::DirectUploadRequest>] file_metadata the filenames and their upload request
43
+ def upload_file_metadata(file_metadata)
44
+ Hash[file_metadata.map { |filename, metadata| [filename, direct_upload(metadata.to_json)] }]
45
+ end
46
+
47
+ def direct_upload(metadata_json)
48
+ logger.info("Starting an upload request: #{metadata_json}")
49
+ response = connection.post(BLOB_PATH, metadata_json, 'Content-Type' => 'application/json')
50
+ raise "unexpected response: #{response.inspect}" unless response.status == 200
51
+
52
+ logger.info("Response from server: #{response.body}")
53
+
54
+ Files::DirectUploadResponse.new(JSON.parse(response.body))
55
+ end
56
+
57
+ # @param [Hash<String,Files::DirectUploadResponse>] upload_responses the filenames and their upload response
58
+ def upload_files(upload_responses)
59
+ upload_responses.each do |filename, response|
60
+ upload_file(filename: filename,
61
+ url: response.direct_upload.fetch('url'),
62
+ content_type: response.content_type,
63
+ content_length: response.byte_size)
64
+
65
+ logger.info('Upload complete')
66
+ end
67
+ end
68
+
69
+ def upload_file(filename:, url:, content_type:, content_length:)
70
+ logger.info("Uploading `#{filename}' to #{url}")
71
+
72
+ upload_response = connection.put(url) do |req|
73
+ req.body = ::File.open(filename)
74
+ req.headers['Content-Type'] = content_type
75
+ req.headers['Content-Length'] = content_length.to_s
76
+ end
77
+
78
+ raise "unexpected response: #{upload_response.inspect}" unless upload_response.status == 204
79
+ end
80
+
81
+ # @return [Hash<Symbol,String>] the file metadata for this file
82
+ def file_metadata_for(filename)
83
+ files_metadata.fetch(filename, {})
84
+ end
85
+ end
86
+ end
87
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SdrClient
4
- VERSION = '0.7.1'
4
+ VERSION = '0.8.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sdr-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.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-01-30 00:00:00.000000000 Z
11
+ date: 2020-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-monads
@@ -168,9 +168,11 @@ files:
168
168
  - lib/sdr_client/deposit/files/direct_upload_request.rb
169
169
  - lib/sdr_client/deposit/files/direct_upload_response.rb
170
170
  - lib/sdr_client/deposit/matching_file_grouping_strategy.rb
171
+ - lib/sdr_client/deposit/metadata_builder.rb
171
172
  - lib/sdr_client/deposit/process.rb
172
173
  - lib/sdr_client/deposit/request.rb
173
174
  - lib/sdr_client/deposit/single_file_grouping_strategy.rb
175
+ - lib/sdr_client/deposit/upload_files.rb
174
176
  - lib/sdr_client/login.rb
175
177
  - lib/sdr_client/login_prompt.rb
176
178
  - lib/sdr_client/version.rb
@@ -196,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
198
  - !ruby/object:Gem::Version
197
199
  version: '0'
198
200
  requirements: []
199
- rubygems_version: 3.1.2
201
+ rubygems_version: 3.0.6
200
202
  signing_key:
201
203
  specification_version: 4
202
204
  summary: The CLI for https://github.com/sul-dlss/sdr-api