purl_fetcher-client 1.2.2 → 1.4.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: 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