sdr-client 0.7.1 → 0.8.0

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