sdr-client 0.3.1 → 0.7.1
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 +4 -4
- data/.rubocop.yml +6 -0
- data/.rubocop_todo.yml +0 -5
- data/README.md +4 -0
- data/exe/sdr +15 -1
- data/lib/sdr-client.rb +3 -0
- data/lib/sdr_client/deposit.rb +13 -2
- data/lib/sdr_client/deposit/file.rb +29 -1
- data/lib/sdr_client/deposit/file_set.rb +12 -3
- data/lib/sdr_client/deposit/matching_file_grouping_strategy.rb +17 -0
- data/lib/sdr_client/deposit/process.rb +24 -3
- data/lib/sdr_client/deposit/request.rb +5 -13
- data/lib/sdr_client/deposit/single_file_grouping_strategy.rb +14 -0
- data/lib/sdr_client/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85bf3bb61e2edeca3fd59c4bcb72e65c0ca8a6fa2555095059c774d6adbb5cd9
|
4
|
+
data.tar.gz: 29ef71e2e7778c28b8db875e7c910ee4f477857422d61d59774ab09b0fdb5852
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61cc5ce0d28aeddbcd20273a7086d9b4dc0482b76f91b19002496b80e4db7d32471f9b8e827ffc800c58172fb3cf7d1f2ccdf920ca11bd88f5ac141002406703
|
7
|
+
data.tar.gz: c2149a463c52831fee474f8c43e00982fce4ea9f56da629f8b87f1889bb59630419ed6c8c5296b56b6985324195ff1bb700277cbdfa91e9de89388319689b461
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
data/README.md
CHANGED
data/exe/sdr
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
$LOAD_PATH.unshift 'lib'
|
5
5
|
require 'optparse'
|
6
|
+
require 'sdr_client'
|
6
7
|
|
7
8
|
options = {}
|
8
9
|
global = OptionParser.new do |opts|
|
@@ -60,6 +61,20 @@ subcommands = {
|
|
60
61
|
options[:source_id] = source_id
|
61
62
|
end
|
62
63
|
|
64
|
+
opts.on('--strategy STRATEGY',
|
65
|
+
'The strategy to use for distributing files into filesets. Either "default" or "filename"') do |strategy|
|
66
|
+
strategy_class = case strategy
|
67
|
+
when 'filename'
|
68
|
+
SdrClient::Deposit::MatchingFileGroupingStrategy
|
69
|
+
when 'default'
|
70
|
+
SdrClient::Deposit::SingleFileGroupingStrategy
|
71
|
+
else
|
72
|
+
warn "Unknown strategy #{strategy}"
|
73
|
+
exit(1)
|
74
|
+
end
|
75
|
+
options[:grouping_strategy] = strategy_class
|
76
|
+
end
|
77
|
+
|
63
78
|
opts.on('-h', '--help', 'Display this screen') do
|
64
79
|
puts opts
|
65
80
|
exit
|
@@ -75,6 +90,5 @@ end
|
|
75
90
|
|
76
91
|
subcommands[command].order!
|
77
92
|
|
78
|
-
require 'sdr_client'
|
79
93
|
options[:files] = ARGV unless ARGV.empty?
|
80
94
|
SdrClient::CLI.start(command, options)
|
data/lib/sdr-client.rb
ADDED
data/lib/sdr_client/deposit.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'logger'
|
4
|
+
|
3
5
|
module SdrClient
|
4
6
|
# The namespace for the "deposit" command
|
5
7
|
module Deposit
|
8
|
+
# rubocop:disable Metrics/ParameterLists
|
6
9
|
def self.run(label: nil,
|
7
10
|
type: 'http://cocina.sul.stanford.edu/models/book.jsonld',
|
8
11
|
apo:,
|
9
12
|
collection:,
|
10
13
|
catkey: nil,
|
11
14
|
source_id:,
|
12
|
-
url:,
|
15
|
+
url:,
|
16
|
+
files: [],
|
17
|
+
files_metadata: {},
|
18
|
+
grouping_strategy: SingleFileGroupingStrategy,
|
19
|
+
logger: Logger.new(STDOUT))
|
13
20
|
token = Credentials.read
|
14
21
|
|
15
22
|
metadata = Request.new(label: label,
|
@@ -18,11 +25,15 @@ module SdrClient
|
|
18
25
|
collection: collection,
|
19
26
|
source_id: source_id,
|
20
27
|
catkey: catkey)
|
21
|
-
Process.new(metadata: metadata, url: url, token: token, files: files
|
28
|
+
Process.new(metadata: metadata, url: url, token: token, files: files,
|
29
|
+
files_metadata: files_metadata, grouping_strategy: grouping_strategy, logger: logger).run
|
22
30
|
end
|
31
|
+
# rubocop:enable Metrics/ParameterLists
|
23
32
|
end
|
24
33
|
end
|
25
34
|
require 'json'
|
35
|
+
require 'sdr_client/deposit/single_file_grouping_strategy'
|
36
|
+
require 'sdr_client/deposit/matching_file_grouping_strategy'
|
26
37
|
require 'sdr_client/deposit/files/direct_upload_request'
|
27
38
|
require 'sdr_client/deposit/files/direct_upload_response'
|
28
39
|
require 'sdr_client/deposit/file'
|
@@ -4,15 +4,23 @@ module SdrClient
|
|
4
4
|
module Deposit
|
5
5
|
# This represents the File metadata that we send to the server for doing a deposit
|
6
6
|
class File
|
7
|
-
|
7
|
+
# rubocop:disable Metrics/ParameterLists
|
8
|
+
def initialize(external_identifier:, label:, filename:,
|
9
|
+
access: 'dark', preserve: false, shelve: false,
|
10
|
+
mime_type: nil, md5: nil, sha1: nil)
|
8
11
|
@external_identifier = external_identifier
|
9
12
|
@label = label
|
10
13
|
@filename = filename
|
11
14
|
@access = access
|
12
15
|
@preserve = preserve
|
13
16
|
@shelve = shelve
|
17
|
+
@mime_type = mime_type
|
18
|
+
@md5 = md5
|
19
|
+
@sha1 = sha1
|
14
20
|
end
|
21
|
+
# rubocop:enable Metrics/ParameterLists
|
15
22
|
|
23
|
+
# rubocop:disable Metrics/MethodLength
|
16
24
|
def as_json
|
17
25
|
{
|
18
26
|
"type": 'http://cocina.sul.stanford.edu/models/file.jsonld',
|
@@ -26,6 +34,26 @@ module SdrClient
|
|
26
34
|
sdrPreserve: @preserve,
|
27
35
|
shelve: @shelve
|
28
36
|
}
|
37
|
+
}.tap do |json|
|
38
|
+
json['hasMessageDigests'] = message_digests unless message_digests.empty?
|
39
|
+
json['hasMimeType'] = @mime_type if @mime_type
|
40
|
+
end
|
41
|
+
end
|
42
|
+
# rubocop:enable Metrics/MethodLength
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def message_digests
|
47
|
+
@message_digests ||= [].tap do |message_digests|
|
48
|
+
message_digests << create_message_digest('md5', @md5) unless @md5.nil?
|
49
|
+
message_digests << create_message_digest('sha1', @sha1) unless @sha1.nil?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_message_digest(algorithm, digest)
|
54
|
+
{
|
55
|
+
"type": algorithm,
|
56
|
+
digest: digest
|
29
57
|
}
|
30
58
|
end
|
31
59
|
end
|
@@ -4,11 +4,11 @@ module SdrClient
|
|
4
4
|
module Deposit
|
5
5
|
# This represents the FileSet metadata that we send to the server for doing a deposit
|
6
6
|
class FileSet
|
7
|
-
def initialize(uploads: [], files: [], label:)
|
7
|
+
def initialize(uploads: [], uploads_metadata: {}, files: [], label:)
|
8
8
|
@label = label
|
9
9
|
@files = if !uploads.empty?
|
10
10
|
uploads.map do |upload|
|
11
|
-
File.new(
|
11
|
+
File.new(file_args(upload, uploads_metadata.fetch(upload.filename, {})))
|
12
12
|
end
|
13
13
|
else
|
14
14
|
files
|
@@ -20,7 +20,7 @@ module SdrClient
|
|
20
20
|
"type": 'http://cocina.sul.stanford.edu/models/fileset.jsonld',
|
21
21
|
"label": label,
|
22
22
|
structural: {
|
23
|
-
|
23
|
+
contains: files.map(&:as_json)
|
24
24
|
}
|
25
25
|
}
|
26
26
|
end
|
@@ -28,6 +28,15 @@ module SdrClient
|
|
28
28
|
private
|
29
29
|
|
30
30
|
attr_reader :files, :label
|
31
|
+
|
32
|
+
def file_args(upload, upload_metadata)
|
33
|
+
args = {
|
34
|
+
external_identifier: upload.signed_id,
|
35
|
+
label: upload.filename,
|
36
|
+
filename: upload.filename
|
37
|
+
}
|
38
|
+
args.merge(upload_metadata)
|
39
|
+
end
|
31
40
|
end
|
32
41
|
end
|
33
42
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SdrClient
|
4
|
+
module Deposit
|
5
|
+
# This strategy is for building one file set per set of similarly prefixed uploaded files
|
6
|
+
class MatchingFileGroupingStrategy
|
7
|
+
# @param [Array<SdrClient::Deposit::Files::DirectUploadResponse>] uploads the uploaded files to attach.
|
8
|
+
# @return [Array<Array<SdrClient::Deposit::Files::DirectUploadResponse>>] uploads the grouped uploaded files.
|
9
|
+
def self.run(uploads: [])
|
10
|
+
# Call `#values` on the result of the grouping operation because 1)
|
11
|
+
# `Process#build_filesets` expects an array of arrays, not an array of
|
12
|
+
# hashes, and 2) the keys aren't used anywhere
|
13
|
+
uploads.group_by { |ul| ::File.basename(ul.filename, '.*') }.values
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -9,30 +9,39 @@ module SdrClient
|
|
9
9
|
BLOB_PATH = '/v1/direct_uploads'
|
10
10
|
DRO_PATH = '/v1/resources'
|
11
11
|
# @param [Request] metadata information about the object
|
12
|
+
# @param [Class] grouping_strategy class whose run method groups an array of uploads
|
12
13
|
# @param [String] url the server to send to
|
13
14
|
# @param [String] token the bearer auth token for the server
|
14
15
|
# @param [Array<String>] files a list of file names to upload
|
16
|
+
# @param [Hash<String, Hash<String, String>>] files_metadata file name, hash of additional file metadata
|
17
|
+
# Additional metadata includes access, preserve, shelve, md5, sha1
|
15
18
|
# @param [Logger] logger the logger to use
|
16
|
-
|
19
|
+
# rubocop:disable Metrics/ParameterLists
|
20
|
+
def initialize(metadata:, grouping_strategy: SingleFileGroupingStrategy, url:,
|
21
|
+
token:, files: [], files_metadata: {}, logger: Logger.new(STDOUT))
|
17
22
|
@files = files
|
18
23
|
@url = url
|
19
24
|
@token = token
|
20
25
|
@metadata = metadata
|
21
26
|
@logger = logger
|
27
|
+
@grouping_strategy = grouping_strategy
|
28
|
+
@files_metadata = files_metadata
|
22
29
|
end
|
30
|
+
# rubocop:enable Metrics/ParameterLists
|
23
31
|
|
24
32
|
def run
|
25
33
|
check_files_exist
|
26
34
|
file_metadata = collect_file_metadata
|
27
35
|
upload_responses = upload_file_metadata(file_metadata)
|
28
36
|
upload_files(upload_responses)
|
29
|
-
|
37
|
+
file_sets = build_filesets(uploads: upload_responses.values, files_metadata: files_metadata)
|
38
|
+
request = metadata.with_file_sets(file_sets)
|
30
39
|
upload_metadata(request.as_json)
|
31
40
|
end
|
32
41
|
|
33
42
|
private
|
34
43
|
|
35
|
-
attr_reader :metadata, :files, :url, :token, :logger
|
44
|
+
attr_reader :metadata, :files, :url, :token, :logger, :grouping_strategy, :files_metadata
|
36
45
|
|
37
46
|
def check_files_exist
|
38
47
|
logger.info('checking to see if files exist')
|
@@ -111,6 +120,18 @@ module SdrClient
|
|
111
120
|
conn.adapter :net_http
|
112
121
|
end
|
113
122
|
end
|
123
|
+
|
124
|
+
# @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
|
+
# @return [Array<SdrClient::Deposit::FileSet>] the uploads transformed to filesets
|
127
|
+
def build_filesets(uploads:, files_metadata:)
|
128
|
+
grouped_uploads = grouping_strategy.run(uploads: uploads)
|
129
|
+
grouped_uploads.map.with_index(1) do |upload_group, i|
|
130
|
+
metadata_group = {}
|
131
|
+
upload_group.each { |upload| metadata_group[upload.filename] = files_metadata.fetch(upload.filename, {}) }
|
132
|
+
FileSet.new(uploads: upload_group, uploads_metadata: metadata_group, label: "Object #{i}")
|
133
|
+
end
|
134
|
+
end
|
114
135
|
end
|
115
136
|
end
|
116
137
|
end
|
@@ -7,6 +7,7 @@ module SdrClient
|
|
7
7
|
# @param [String] label the required object label
|
8
8
|
# @param [String] type (http://cocina.sul.stanford.edu/models/object.jsonld) the required object type.
|
9
9
|
# @param [Array<FileSet>] file_sets the file sets to attach.
|
10
|
+
# rubocop:disable Metrics/ParameterLists
|
10
11
|
def initialize(label: nil,
|
11
12
|
apo:,
|
12
13
|
collection:,
|
@@ -22,6 +23,7 @@ module SdrClient
|
|
22
23
|
@apo = apo
|
23
24
|
@file_sets = file_sets
|
24
25
|
end
|
26
|
+
# rubocop:enable Metrics/ParameterLists
|
25
27
|
|
26
28
|
def as_json
|
27
29
|
{
|
@@ -35,13 +37,8 @@ module SdrClient
|
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
38
|
-
# @
|
39
|
-
|
40
|
-
def with_uploads(uploads)
|
41
|
-
file_sets = uploads.each_with_index.map do |upload, i|
|
42
|
-
FileSet.new(uploads: [upload], label: "Object #{i + 1}")
|
43
|
-
end
|
44
|
-
|
40
|
+
# @return [Request] a clone of this request with the file_sets added
|
41
|
+
def with_file_sets(file_sets)
|
45
42
|
Request.new(label: label,
|
46
43
|
apo: apo,
|
47
44
|
collection: collection,
|
@@ -51,11 +48,6 @@ module SdrClient
|
|
51
48
|
file_sets: file_sets)
|
52
49
|
end
|
53
50
|
|
54
|
-
# In this case there is a 1-1 mapping between Files and FileSets,
|
55
|
-
# but this doesn't always have to be the case. We could change this in the
|
56
|
-
# future so that we have one FileSet that has an Image and its OCR file.
|
57
|
-
def add_uploads_each_as_resource(uploads); end
|
58
|
-
|
59
51
|
private
|
60
52
|
|
61
53
|
attr_reader :label, :file_sets, :source_id, :catkey, :apo, :collection, :type
|
@@ -75,7 +67,7 @@ module SdrClient
|
|
75
67
|
def structural
|
76
68
|
{
|
77
69
|
isMemberOf: collection,
|
78
|
-
|
70
|
+
contains: file_sets.map(&:as_json)
|
79
71
|
}
|
80
72
|
end
|
81
73
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SdrClient
|
4
|
+
module Deposit
|
5
|
+
# This strategy is for building one file set per uploaded file
|
6
|
+
class SingleFileGroupingStrategy
|
7
|
+
# @param [Array<SdrClient::Deposit::Files::DirectUploadResponse>] uploads the uploaded files to attach.
|
8
|
+
# @return [Array<Array<SdrClient::Deposit::Files::DirectUploadResponse>>] uploads the grouped uploaded files.
|
9
|
+
def self.run(uploads: [])
|
10
|
+
uploads.map { |upload| [upload] }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/sdr_client/version.rb
CHANGED
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.
|
4
|
+
version: 0.7.1
|
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-
|
11
|
+
date: 2020-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-monads
|
@@ -158,6 +158,7 @@ files:
|
|
158
158
|
- bin/console
|
159
159
|
- bin/setup
|
160
160
|
- exe/sdr
|
161
|
+
- lib/sdr-client.rb
|
161
162
|
- lib/sdr_client.rb
|
162
163
|
- lib/sdr_client/cli.rb
|
163
164
|
- lib/sdr_client/credentials.rb
|
@@ -166,8 +167,10 @@ files:
|
|
166
167
|
- lib/sdr_client/deposit/file_set.rb
|
167
168
|
- lib/sdr_client/deposit/files/direct_upload_request.rb
|
168
169
|
- lib/sdr_client/deposit/files/direct_upload_response.rb
|
170
|
+
- lib/sdr_client/deposit/matching_file_grouping_strategy.rb
|
169
171
|
- lib/sdr_client/deposit/process.rb
|
170
172
|
- lib/sdr_client/deposit/request.rb
|
173
|
+
- lib/sdr_client/deposit/single_file_grouping_strategy.rb
|
171
174
|
- lib/sdr_client/login.rb
|
172
175
|
- lib/sdr_client/login_prompt.rb
|
173
176
|
- lib/sdr_client/version.rb
|
@@ -193,7 +196,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
193
196
|
- !ruby/object:Gem::Version
|
194
197
|
version: '0'
|
195
198
|
requirements: []
|
196
|
-
rubygems_version: 3.
|
199
|
+
rubygems_version: 3.1.2
|
197
200
|
signing_key:
|
198
201
|
specification_version: 4
|
199
202
|
summary: The CLI for https://github.com/sul-dlss/sdr-api
|