sdr-client 0.4.0 → 0.5.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: b1d76c1422877b6b5f25f0a1cb46641e32771496771576f8f7c8fd2697c14b0e
4
- data.tar.gz: eb116e73a114a3966254a0996c5d843fc960e1454146214ca68fae11eff89bda
3
+ metadata.gz: 565e7d34958ad818fcc048440816b0a360fa723ea6e62dc9437c6832ba8877c1
4
+ data.tar.gz: 14dfae8ecef2b6d05a256a8bdc7aebebfe801a278546c98bd3066169f7c98899
5
5
  SHA512:
6
- metadata.gz: acf219c807f4f22f87437f779cf4d3ab2bb8091bc810a616146a302a9e2bab4b5be99685c91ea072056344a59b5b0f37e9ed5008105d836078d1b70032720c75
7
- data.tar.gz: b6ec07336e2014a6fbf02470c08649c426384a51c40ee32a164f29c96ab75cd2057615ee5ee8081f7a70f406f794fed6c100fb93aba7848d629e8933fa91f589
6
+ metadata.gz: bc629b8837567ee95b01ce673a1f1b49596c3665810ab8d59573012b3b9b6a674db12dde7d15461a279f87a4ef88ed23d65d2457bbc7c0479330f45b3f2c1649
7
+ data.tar.gz: fe176665dadd92ae291b7dbf5b461bb40606600383ad81c9824a8a4bad83344db5e74b6568a10eced02f4fa14894188122605ac2b7ecd5176d7b25b241963da4
@@ -13,3 +13,5 @@ Layout/LineLength:
13
13
  Metrics/BlockLength:
14
14
  Exclude:
15
15
  - 'spec/**/*'
16
+ ExcludedMethods:
17
+ - 'OptionParser.new'
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)
@@ -3,13 +3,16 @@
3
3
  module SdrClient
4
4
  # The namespace for the "deposit" command
5
5
  module Deposit
6
+ # rubocop:disable Metrics/ParameterLists
6
7
  def self.run(label: nil,
7
8
  type: 'http://cocina.sul.stanford.edu/models/book.jsonld',
8
9
  apo:,
9
10
  collection:,
10
11
  catkey: nil,
11
12
  source_id:,
12
- url:, files: [])
13
+ url:,
14
+ files: [],
15
+ grouping_strategy: SingleFileGroupingStrategy)
13
16
  token = Credentials.read
14
17
 
15
18
  metadata = Request.new(label: label,
@@ -18,12 +21,14 @@ module SdrClient
18
21
  collection: collection,
19
22
  source_id: source_id,
20
23
  catkey: catkey)
21
- Process.new(metadata: metadata, url: url, token: token, files: files).run
24
+ Process.new(metadata: metadata, url: url, token: token, files: files, grouping_strategy: grouping_strategy).run
22
25
  end
26
+ # rubocop:enable Metrics/ParameterLists
23
27
  end
24
28
  end
25
29
  require 'json'
26
- require 'sdr_client/deposit/default_file_set_builder'
30
+ require 'sdr_client/deposit/single_file_grouping_strategy'
31
+ require 'sdr_client/deposit/matching_file_grouping_strategy'
27
32
  require 'sdr_client/deposit/files/direct_upload_request'
28
33
  require 'sdr_client/deposit/files/direct_upload_response'
29
34
  require 'sdr_client/deposit/file'
@@ -4,17 +4,21 @@ 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
- def initialize(external_identifier:, label:, filename:, access: 'dark', preserve: false, shelve: false)
7
+ def initialize(external_identifier:, label:, filename:, access: 'dark', preserve: false, shelve: false,
8
+ md5: nil, sha1: nil)
8
9
  @external_identifier = external_identifier
9
10
  @label = label
10
11
  @filename = filename
11
12
  @access = access
12
13
  @preserve = preserve
13
14
  @shelve = shelve
15
+ @md5 = md5
16
+ @sha1 = sha1
14
17
  end
15
18
 
19
+ # rubocop:disable Metrics/MethodLength
16
20
  def as_json
17
- {
21
+ json = {
18
22
  "type": 'http://cocina.sul.stanford.edu/models/file.jsonld',
19
23
  label: @label,
20
24
  filename: @filename,
@@ -27,6 +31,25 @@ module SdrClient
27
31
  shelve: @shelve
28
32
  }
29
33
  }
34
+ json['hasMessageDigests'] = message_digests unless message_digests.empty?
35
+ json
36
+ end
37
+ # rubocop:enable Metrics/MethodLength
38
+
39
+ private
40
+
41
+ def message_digests
42
+ @message_digests ||= [].tap do |message_digests|
43
+ message_digests << create_message_digest('md5', @md5) unless @md5.nil?
44
+ message_digests << create_message_digest('sha1', @sha1) unless @sha1.nil?
45
+ end
46
+ end
47
+
48
+ def create_message_digest(algorithm, digest)
49
+ {
50
+ "type": algorithm,
51
+ digest: digest
52
+ }
30
53
  end
31
54
  end
32
55
  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(external_identifier: upload.signed_id, label: upload.filename, filename: upload.filename)
11
+ File.new(file_args(upload, uploads_metadata.fetch(upload.filename, {})))
12
12
  end
13
13
  else
14
14
  files
@@ -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,14 @@
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
+ uploads.group_by { |ul| ::File.basename(ul.filename, '.*') }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -9,19 +9,22 @@ 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 [#build] file_set_builder a strategy for constructing FileSets
12
+ # @param [Class] grouping_strategy class whose run method groups an array of uploads
13
13
  # @param [String] url the server to send to
14
14
  # @param [String] token the bearer auth token for the server
15
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
16
18
  # @param [Logger] logger the logger to use
17
- def initialize(metadata:, file_set_builder: DefaultFileSetBuilder, url:,
18
- token:, files: [], logger: Logger.new(STDOUT))
19
+ def initialize(metadata:, grouping_strategy: SingleFileGroupingStrategy, url:,
20
+ token:, files: [], files_metadata: {}, logger: Logger.new(STDOUT))
19
21
  @files = files
20
22
  @url = url
21
23
  @token = token
22
24
  @metadata = metadata
23
25
  @logger = logger
24
- @file_set_builder = file_set_builder
26
+ @grouping_strategy = grouping_strategy
27
+ @files_metadata = files_metadata
25
28
  end
26
29
 
27
30
  def run
@@ -29,13 +32,14 @@ module SdrClient
29
32
  file_metadata = collect_file_metadata
30
33
  upload_responses = upload_file_metadata(file_metadata)
31
34
  upload_files(upload_responses)
32
- request = file_set_builder.run(request: metadata, uploads: upload_responses.values)
35
+ file_sets = build_filesets(uploads: upload_responses.values, files_metadata: files_metadata)
36
+ request = metadata.with_file_sets(file_sets)
33
37
  upload_metadata(request.as_json)
34
38
  end
35
39
 
36
40
  private
37
41
 
38
- attr_reader :metadata, :files, :url, :token, :logger, :file_set_builder
42
+ attr_reader :metadata, :files, :url, :token, :logger, :grouping_strategy, :files_metadata
39
43
 
40
44
  def check_files_exist
41
45
  logger.info('checking to see if files exist')
@@ -114,6 +118,18 @@ module SdrClient
114
118
  conn.adapter :net_http
115
119
  end
116
120
  end
121
+
122
+ # @param [Array<SdrClient::Deposit::Files::DirectUploadResponse>] uploads the uploaded files to attach.
123
+ # @param [Hash<String,Hash<String, String>>] files_metadata filename, hash of additional file metadata.
124
+ # @return [Array<SdrClient::Deposit::FileSet>] the uploads transformed to filesets
125
+ def build_filesets(uploads:, files_metadata:)
126
+ grouped_uploads = grouping_strategy.run(uploads: uploads)
127
+ grouped_uploads.each_with_index.map do |upload_group, i|
128
+ metadata_group = {}
129
+ upload_group.each { |upload| metadata_group[upload.filename] = files_metadata.fetch(upload.filename, {}) }
130
+ FileSet.new(uploads: upload_group, uploads_metadata: metadata_group, label: "Object #{i + 1}")
131
+ end
132
+ end
117
133
  end
118
134
  end
119
135
  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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SdrClient
4
- VERSION = '0.4.0'
4
+ VERSION = '0.5.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.4.0
4
+ version: 0.5.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-24 00:00:00.000000000 Z
11
+ date: 2020-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-monads
@@ -162,13 +162,14 @@ files:
162
162
  - lib/sdr_client/cli.rb
163
163
  - lib/sdr_client/credentials.rb
164
164
  - lib/sdr_client/deposit.rb
165
- - lib/sdr_client/deposit/default_file_set_builder.rb
166
165
  - lib/sdr_client/deposit/file.rb
167
166
  - lib/sdr_client/deposit/file_set.rb
168
167
  - lib/sdr_client/deposit/files/direct_upload_request.rb
169
168
  - lib/sdr_client/deposit/files/direct_upload_response.rb
169
+ - lib/sdr_client/deposit/matching_file_grouping_strategy.rb
170
170
  - lib/sdr_client/deposit/process.rb
171
171
  - lib/sdr_client/deposit/request.rb
172
+ - lib/sdr_client/deposit/single_file_grouping_strategy.rb
172
173
  - lib/sdr_client/login.rb
173
174
  - lib/sdr_client/login_prompt.rb
174
175
  - lib/sdr_client/version.rb
@@ -1,18 +0,0 @@
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 DefaultFileSetBuilder
7
- # @return [Request] request The initial request
8
- # @param [Array<SdrClient::Deposit::Files::DirectUploadResponse>] uploads the uploaded files to attach.
9
- # @return [Request] a clone of this request with the uploads added
10
- def self.run(request:, uploads: [])
11
- file_sets = uploads.each_with_index.map do |upload, i|
12
- FileSet.new(uploads: [upload], label: "Object #{i + 1}")
13
- end
14
- request.with_file_sets(file_sets)
15
- end
16
- end
17
- end
18
- end