sdr-client 0.4.0 → 0.5.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: 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