purl_fetcher-client 1.2.2 → 1.4.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: 5acaaa62d71bc3971cf608280ed164c905c643a883a03abd51c1ddc6f4efb943
4
- data.tar.gz: a067e49e7eb1d75b66ba27cdb21bbbcb2dfc83bf9fa6885a8afaf01167d5823e
3
+ metadata.gz: 8acef0951b0c30808be01de74a0be92e5926d8aa749844517cb559df253b9809
4
+ data.tar.gz: 7bc3b857be71f2ef660956e1b5db1bd9411fc391fefa8b7d52f128a8743a2b34
5
5
  SHA512:
6
- metadata.gz: ebc5cd6e69bf54c81fc74aa0fca8ffc06b4f32007fcdaab58a9c04ef7030e2dfeeb4820b3e0fd60d61b54abc8e9af2f9ea3fd5c19219355e62aee4f23d907fc1
7
- data.tar.gz: c6d4931fd315dc5c4c30ee407a009d2698950f09b05c286efd81413579a9d02a5a0682b97332ed42471da2e9b2bf5c43925b70f2ce575031610a2ec153e497d8
6
+ metadata.gz: c87d8d90b38301ca7879cae8d95acf44ea0b4b54a1cf954040cc06f3dc8cc36420757a19f95d7a05b7e4acd77bd46f91e3469ec4aef04ba804833ede2006c2d7
7
+ data.tar.gz: bd9cadb99c2db016b91627d35b4928bc5e1fc1fecbb204ab82f217ee58a652baa0b593499f0358eaf46bb975fac093bcf745fddbb27b739a01bf522c00d281bb
data/Gemfile CHANGED
@@ -7,3 +7,4 @@ gemspec
7
7
 
8
8
  gem "rubocop-rails-omakase", require: false, group: [ :development ]
9
9
  gem "debug"
10
+ gem "cocina-models"
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PurlFetcher
4
+ class Client
5
+ # Create a MODS represenation of Cocina JSON
6
+ class Mods
7
+ # @param [Cocina::Models::Dro] cocina the Cocina JSON representation of the object
8
+ def self.create(cocina:)
9
+ new(cocina:).create
10
+ end
11
+
12
+ # @param [Cocina::Models::Dro] cocina the Cocina JSON representation of the object
13
+ def initialize(cocina:)
14
+ @cocina = cocina
15
+ end
16
+
17
+ def create
18
+ response = client.post(path:, body:)
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :cocina
24
+
25
+ def body
26
+ cocina.to_json
27
+ end
28
+
29
+ def client
30
+ Client.instance
31
+ end
32
+
33
+ def path
34
+ "/v1/mods"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PurlFetcher
4
+ class Client
5
+ # Publish (metadata-only) to the purl cache
6
+ class Publish
7
+ def self.publish(...)
8
+ new(...).publish
9
+ end
10
+
11
+ # @param [Cocina::Models::DRO,Cocina::Models::Collection] cocina the Cocina data object
12
+ # @param [Hash<String,String>] file_uploads map of filenames to signed_ids
13
+ def initialize(cocina:, file_uploads:)
14
+ @cocina = cocina
15
+ @file_uploads = file_uploads
16
+ end
17
+
18
+ def publish
19
+ logger.debug("Starting a publish request for: #{druid}")
20
+ client.post(path:, body:)
21
+ logger.debug("Publish request complete")
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :cocina, :file_uploads
27
+
28
+ def druid
29
+ cocina.externalIdentifier
30
+ end
31
+
32
+ def body
33
+ {
34
+ object: cocina.to_h,
35
+ file_uploads: file_uploads
36
+ }.to_json
37
+ end
38
+
39
+ def logger
40
+ Client.config.logger
41
+ end
42
+
43
+ def client
44
+ Client.instance
45
+ end
46
+
47
+ def path
48
+ "/v1/resources"
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PurlFetcher
4
+ class Client
5
+ # High-level client for publishing and shelving.
6
+ class PublishShelve
7
+ def self.publish_and_shelve(...)
8
+ new(...).publish_and_shelve
9
+ end
10
+
11
+ # @param [Cocina::Models::DRO,Cocina::Models::Collection] cocina the Cocina data object
12
+ # @param [Hash<String,String>] filepath_map map of relative filepaths to absolute filepaths
13
+ def initialize(cocina:, filepath_map:)
14
+ @cocina = cocina
15
+ @filepath_map = filepath_map
16
+ end
17
+
18
+ def publish_and_shelve
19
+ logger.debug("Starting publish and shelve for: #{cocina.externalIdentifier}")
20
+
21
+ direct_upload_responses = PurlFetcher::Client::UploadFiles.upload(file_metadata: file_metadata, filepath_map: filepath_map)
22
+ file_uploads = direct_upload_responses.map { |response| [ response.filename, response.signed_id ] }.to_h
23
+
24
+ PurlFetcher::Client::Publish.publish(cocina: cocina, file_uploads: file_uploads)
25
+ logger.debug("Publish and shelve complete")
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :cocina, :filepath_map
31
+
32
+ def file_metadata
33
+ cocina.structural.contains.flat_map do |fileset|
34
+ fileset.structural.contains.select { |file| filepath_map.include?(file.filename) }.map do |file|
35
+ direct_upload_request_for(file)
36
+ end
37
+ end
38
+ end
39
+
40
+ def direct_upload_request_for(cocina_file)
41
+ PurlFetcher::Client::DirectUploadRequest.from_file(
42
+ hexdigest: md5_for(cocina_file),
43
+ byte_size: size_for(cocina_file),
44
+ content_type: "application/octet-stream",
45
+ file_name: cocina_file.filename
46
+ )
47
+ end
48
+
49
+ def md5_for(cocina_file)
50
+ cocina_file.hasMessageDigests.find { |digest| digest.type == "md5" }.digest
51
+ end
52
+
53
+ def size_for(cocina_file)
54
+ return cocina_file.size if cocina_file.size.present? && cocina_file.size.positive?
55
+
56
+ File.size(filepath_map[cocina_file.filename])
57
+ end
58
+
59
+ def logger
60
+ Client.config.logger
61
+ end
62
+ end
63
+ end
64
+ end
@@ -10,7 +10,7 @@ module PurlFetcher
10
10
  new(file_metadata: file_metadata, filepath_map: filepath_map).upload
11
11
  end
12
12
 
13
- # @param [Hash<String,DirectUploadRequest>] file_metadata map of relative filepaths to file metadata
13
+ # @param [Array<DirectUploadRequest>] file_metadata array of DirectUploadRequests for the files to be uploaded
14
14
  # @param [Hash<String,String>] filepath_map map of relative filepaths to absolute filepaths
15
15
  def initialize(file_metadata:, filepath_map:)
16
16
  @file_metadata = file_metadata
@@ -19,10 +19,10 @@ module PurlFetcher
19
19
 
20
20
  # @return [Array<DirectUploadResponse>] the responses from the server for the uploads
21
21
  def upload
22
- file_metadata.map do |filepath, metadata|
23
- direct_upload(metadata.to_json).tap do |response|
24
- # ActiveStorage modifies the filename provided in response, so setting here with the relative filename
25
- response = response.with_filename(filepath)
22
+ file_metadata.map do |metadata|
23
+ filepath = metadata.filename
24
+ # ActiveStorage modifies the filename provided in response, so setting here with the relative filename
25
+ direct_upload(metadata.to_json).with_filename(filepath).tap do |response|
26
26
  upload_file(response)
27
27
  logger.info("Upload of #{filepath} complete")
28
28
  end
@@ -1,5 +1,5 @@
1
1
  module PurlFetcher
2
2
  class Client
3
- VERSION = "1.2.2"
3
+ VERSION = "1.4.0"
4
4
  end
5
5
  end
@@ -6,12 +6,15 @@ require "logger"
6
6
 
7
7
  require "purl_fetcher/client/version"
8
8
  require "purl_fetcher/client/reader"
9
+ require "purl_fetcher/client/mods"
9
10
  require "purl_fetcher/client/upload_files"
10
11
  require "purl_fetcher/client/direct_upload_request"
11
12
  require "purl_fetcher/client/direct_upload_response"
12
13
  require "purl_fetcher/client/legacy_publish"
14
+ require "purl_fetcher/client/publish"
13
15
  require "purl_fetcher/client/release_tags"
14
16
  require "purl_fetcher/client/unpublish"
17
+ require "purl_fetcher/client/publish_shelve"
15
18
 
16
19
  module PurlFetcher
17
20
  class Client
@@ -87,7 +90,8 @@ module PurlFetcher
87
90
  def connection
88
91
  Faraday.new(
89
92
  url: config.url,
90
- headers: default_headers
93
+ headers: default_headers,
94
+ request: default_request_options
91
95
  ) do |conn|
92
96
  conn.response :json
93
97
  end
@@ -101,6 +105,14 @@ module PurlFetcher
101
105
  }.compact
102
106
  end
103
107
 
108
+ def default_request_options
109
+ # To allow transfer of large files.
110
+ {
111
+ read_timeout: 900,
112
+ timeout: 900
113
+ }
114
+ end
115
+
104
116
  def auth_header
105
117
  "Bearer #{config.token}" if config.token
106
118
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: purl_fetcher-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Beer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-07 00:00:00.000000000 Z
11
+ date: 2024-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -129,6 +129,9 @@ files:
129
129
  - lib/purl_fetcher/client/direct_upload_request.rb
130
130
  - lib/purl_fetcher/client/direct_upload_response.rb
131
131
  - lib/purl_fetcher/client/legacy_publish.rb
132
+ - lib/purl_fetcher/client/mods.rb
133
+ - lib/purl_fetcher/client/publish.rb
134
+ - lib/purl_fetcher/client/publish_shelve.rb
132
135
  - lib/purl_fetcher/client/reader.rb
133
136
  - lib/purl_fetcher/client/release_tags.rb
134
137
  - lib/purl_fetcher/client/unpublish.rb
@@ -153,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
156
  - !ruby/object:Gem::Version
154
157
  version: '0'
155
158
  requirements: []
156
- rubygems_version: 3.5.10
159
+ rubygems_version: 3.4.19
157
160
  signing_key:
158
161
  specification_version: 4
159
162
  summary: Traject-compatible reader implementation for streaming data from purl-fetcher