atlas_rb 1.21.0 → 1.22.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: 0650d39388fca9d7fbdc0134ee4e76e4a82ed3c659f8c44ea96aac62a397d0c1
4
- data.tar.gz: ab674da7f6274991b11921b60c43a93ea6e3e9f3a5ef121109fd3bc99c970cdc
3
+ metadata.gz: 547ea9704ea6c2845a7573bd9518cca8d96b3a65eb3792642e3944f99ae1853a
4
+ data.tar.gz: 6c3754d4d4a6c509599e66c9062268b3c30c1b967a536b0231249a0010567c19
5
5
  SHA512:
6
- metadata.gz: 2c23136adc3f95ccf1b9e0e739f95a2a86b3ee33a1cf5a52f72af625fe5c2ab77cf63c9c78990d2b36ff0d285445f56bae620da21d86af0994d590f867defe51
7
- data.tar.gz: edac22a77b8d592ae2e3a0d77117b9ac60d7516d3a13469747ff5cb7f90a782e774d5514218bb5d368818defc538d58158ed608abd400d2cca4aaa606bff9939
6
+ metadata.gz: b259694bf763b09743fc3c64fcd7f612202dec0249f35a8f3c1e211007235425de0c8d1f4c6235a5c9d3256022adb87cfffa9a43275eb25e29f2051579cc128e
7
+ data.tar.gz: 8e09316edfca23f4d966ca9c4e49d7d410711241e420fa0c4f01dfa1541c66d07907e6263640b1749b2b19203709441d3282f494b5526218c583116cc19b24e5
data/.version CHANGED
@@ -1 +1 @@
1
- 1.21.0
1
+ 1.22.0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.22.0
4
+
5
+ These bindings need Atlas 0.6.211 or later.
6
+
7
+ ### Added — `Blob.update(original_filename:)`, renaming the file on a replace
8
+
9
+ ```ruby
10
+ AtlasRb::Blob.update(blob_id, "/tmp/upload.tmp", original_filename: "report.pdf")
11
+ ```
12
+
13
+ A replacement of a different type used to keep the old name, so a `.docx`
14
+ replaced by a `.pdf` downloaded as `.docx`. Atlas now records the name for the
15
+ new revision and re-derives the MIME type from it. For the original file it also
16
+ re-derives the label and the FileSet's classification. Omit the keyword to keep
17
+ the current name. `Blob.rollback` needs no change: Atlas restores the revision's
18
+ own name.
19
+
20
+ ### Added — `language:` and `track_label:` on `Blob.create` and `Blob.update`
21
+
22
+ ```ruby
23
+ AtlasRb::Blob.create(work_id, "/tmp/es.vtt", "es.vtt", language: "es", track_label: "Español")
24
+ ```
25
+
26
+ A caption's BCP 47 language and the name a player shows for it. Each is sent
27
+ only when given, so an update keeps a value it does not mention, and `""`
28
+ clears one. Atlas refuses a malformed value with a `422`, which raises
29
+ `ResourceError`. `Work.assets` and `Work.file_sets` return both fields on Blob
30
+ entries with no reader change.
31
+
32
+ ### Documented — tombstoning a FileSet, and the `original` image tier
33
+
34
+ - `Resource.tombstone` and `Admin::Resource.restore` accept a FileSet id. That
35
+ withdraws a caption or other attached file reversibly. Atlas allows it for the
36
+ admin and devolved-admin tiers only. Despite its namespace,
37
+ `Admin::Resource.restore` is called by delegates too.
38
+ - `Work.set_derivative_permissions` documents the image floor as `original`, not
39
+ `master`. Atlas accepts `master` on write for one release and stores it as
40
+ `original`.
41
+
3
42
  ## 1.21.0
4
43
 
5
44
  ### Added — `System::Work.remove_linked_member`, unlinking a showcase Work
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- atlas_rb (1.21.0)
4
+ atlas_rb (1.22.0)
5
5
  faraday (~> 2.7)
6
6
  faraday-follow_redirects (~> 0.3.0)
7
7
  faraday-multipart (~> 1)
@@ -53,6 +53,13 @@ module AtlasRb
53
53
  # stub. No `confirm:` marker — restoring is itself reversible, by
54
54
  # tombstoning again.
55
55
  #
56
+ # Accepts a FileSet id too (Atlas 0.6.211 or later), which puts a withdrawn
57
+ # caption or other attached file back in {Work.assets}.
58
+ #
59
+ # The devolved-admin tier calls this as well, although the namespace reads
60
+ # as admin-only. Atlas owns the gate; this namespace only marks the call as
61
+ # an operator action.
62
+ #
56
63
  # @param id [String] the resource's NOID.
57
64
  # @param nuid [String, nil] optional acting user's NUID.
58
65
  # @param on_behalf_of [String, nil] optional NUID for the `On-Behalf-Of`
data/lib/atlas_rb/blob.rb CHANGED
@@ -144,6 +144,12 @@ module AtlasRb
144
144
  # @param blob_path [String] path to the binary file on disk to upload.
145
145
  # @param original_filename [String] the user-facing filename Atlas
146
146
  # should record (e.g. `"final_thesis.pdf"`).
147
+ # @param language [String, nil] optional BCP 47 language of a caption or
148
+ # other text track (e.g. `"en"`, `"es-MX"`). Atlas checks the shape of the
149
+ # tag, not the registry, and refuses a malformed one with `422`
150
+ # `invalid_language` before storing anything. Needs Atlas 0.6.211 or later.
151
+ # @param track_label [String, nil] optional name a player shows for the track
152
+ # (e.g. `"Español"`), at most 64 characters (`422 invalid_track_label`).
147
153
  # @param idempotency_key [String, nil] optional UUID. A repeat call with
148
154
  # the same key returns the originally-created Blob instead of creating
149
155
  # a new one. See {AtlasRb::Work.create} for full semantics.
@@ -178,11 +184,15 @@ module AtlasRb
178
184
  # key = SecureRandom.uuid
179
185
  # AtlasRb::Blob.create("w-789", "/tmp/upload.tmp", "thesis.pdf",
180
186
  # idempotency_key: key, expected_digest: "sha256:#{sha}")
181
- def self.create(id, blob_path, original_filename, expected_digest: nil,
187
+ #
188
+ # @example A Spanish caption track
189
+ # AtlasRb::Blob.create("w-789", "/tmp/es.vtt", "es.vtt", language: "es", track_label: "Español")
190
+ def self.create(id, blob_path, original_filename, expected_digest: nil, language: nil, track_label: nil,
182
191
  idempotency_key: nil, nuid: nil, on_behalf_of: nil)
183
192
  with_file_part(blob_path) do |part|
193
+ # compact drops only nil, so an empty string still reaches Atlas.
184
194
  payload = { work_id: id, original_filename: original_filename, binary: part }
185
- payload[:expected_digest] = expected_digest if expected_digest
195
+ .merge({ expected_digest: expected_digest, language: language, track_label: track_label }.compact)
186
196
 
187
197
  AtlasRb::Mash.new(write_resource(
188
198
  multipart(nuid, on_behalf_of: on_behalf_of, idempotency_key: idempotency_key)
@@ -215,12 +225,22 @@ module AtlasRb
215
225
 
216
226
  # Replace the bytes of an existing Blob in-place.
217
227
  #
218
- # The Blob ID is preserved; only the underlying content changes. The
219
- # original filename is *not* updated by this call — use a new
220
- # {.create} if you need a different `original_filename`.
228
+ # The Blob ID is preserved and a new revision is appended. Pass
229
+ # `original_filename` when the replacement is a different file, above all a
230
+ # different type: Atlas records the name for this revision, and re-derives
231
+ # the MIME type from it. For the original file it also re-derives the label
232
+ # and the FileSet's classification; a derivative keeps its tier label.
233
+ # {.rollback} restores a revision's own name, so it needs no name.
221
234
  #
222
235
  # @param id [String] the Blob ID.
223
236
  # @param blob_path [String] path to the replacement binary on disk.
237
+ # @param original_filename [String, nil] the replacement's own filename.
238
+ # Omit it to keep the current name. Needs Atlas 0.6.211 or later; an older
239
+ # Atlas ignores it and keeps the name.
240
+ # @param language [String, nil] a new BCP 47 language for the track. Omit it
241
+ # to keep the current one; pass `""` to clear it. See {.create}.
242
+ # @param track_label [String, nil] a new display name for the track. Omit it
243
+ # to keep the current one; pass `""` to clear it.
224
244
  # @param expected_digest [String, nil] optional verify-on-ingest checksum,
225
245
  # `"<algorithm>:<hexvalue>"`. 422 ({AtlasRb::FixityMismatchError}) on mismatch.
226
246
  # @param idempotency_key [String, nil] optional UUID. A double-submit of the
@@ -249,10 +269,15 @@ module AtlasRb
249
269
  #
250
270
  # @example Retry-safe replace
251
271
  # AtlasRb::Blob.update("b-321", "/tmp/revised.pdf", idempotency_key: SecureRandom.uuid)
252
- def self.update(id, blob_path, expected_digest: nil, idempotency_key: nil, nuid: nil, on_behalf_of: nil)
272
+ #
273
+ # @example Replace a Word file with a PDF
274
+ # AtlasRb::Blob.update("b-321", "/tmp/upload.tmp", original_filename: "report.pdf")
275
+ def self.update(id, blob_path, original_filename: nil, expected_digest: nil, language: nil, track_label: nil,
276
+ idempotency_key: nil, nuid: nil, on_behalf_of: nil)
253
277
  with_file_part(blob_path) do |part|
254
- payload = { binary: part }
255
- payload[:expected_digest] = expected_digest if expected_digest
278
+ # compact drops only nil, so `""` still reaches Atlas and clears a field.
279
+ payload = { binary: part, original_filename: original_filename, expected_digest: expected_digest,
280
+ language: language, track_label: track_label }.compact
256
281
 
257
282
  AtlasRb::Mash.new(write_resource(
258
283
  multipart(nuid, on_behalf_of: on_behalf_of, idempotency_key: idempotency_key)
@@ -268,7 +293,8 @@ module AtlasRb
268
293
  # envelope: one descriptor per retained content revision, each carrying its
269
294
  # OCFL `version_id` label, the `file_identifier` appended for that revision,
270
295
  # the `created` timestamp, the `digest`/`size` recorded at that version,
271
- # the stable `original_filename`, and actor attribution (`actor_nuid` /
296
+ # that revision's own `original_filename` (a replace can rename the file),
297
+ # and actor attribution (`actor_nuid` /
272
298
  # `on_behalf_of_nuid`, null when no audit event correlates).
273
299
  #
274
300
  # Server admin-gates this endpoint (it exposes edit attribution), so
@@ -138,6 +138,12 @@ module AtlasRb
138
138
  # `has_live_children` — a legitimate answer the caller has to read, not an
139
139
  # error. Reversible via {.restore}.
140
140
  #
141
+ # Accepts a FileSet id as well as a Community, Collection or Work (Atlas
142
+ # 0.6.211 or later). That withdraws an attached file, such as a caption,
143
+ # reversibly: its Blobs ride along and it drops out of {Work.assets} and
144
+ # {Work.file_sets}. Atlas refuses a FileSet from anyone outside the admin and
145
+ # devolved-admin tiers with `403`, even a user who can edit the Work.
146
+ #
141
147
  # @param id [String] the resource's NOID.
142
148
  # @param nuid [String, nil] the acting user's NUID, stamped on the resource
143
149
  # as `tombstoned_by`.
data/lib/atlas_rb/work.rb CHANGED
@@ -328,7 +328,7 @@ module AtlasRb
328
328
  # Grouper group names, `[]` = private). Two media families:
329
329
  #
330
330
  # * the image ladder `small` / `medium` / `large` / `service` (deep-zoom) /
331
- # `master` (the original image), and
331
+ # `original` (the deposited image), and
332
332
  # * independent media `audio` / `video` / `pdf`.
333
333
  #
334
334
  # Unlike {.set_image_derivatives} (which upserts URIs) this is a whole-object
@@ -340,18 +340,20 @@ module AtlasRb
340
340
  #
341
341
  # Atlas enforces: a tier may not be more visible than the Work, and — within
342
342
  # the image ladder — visibility must narrow as resolution grows
343
- # (`master` ⊆ `service` ⊆ `large` ⊆ `medium` ⊆ `small`; independent media
343
+ # (`original` ⊆ `service` ⊆ `large` ⊆ `medium` ⊆ `small`; independent media
344
344
  # impose no ordering). The gate is advisory — it surfaces on {.assets} as
345
- # `gated` / `permission` for BOTH Delegate (image tier) and Blob (master /
345
+ # `gated` / `permission` for BOTH Delegate (image tier) and Blob (original /
346
346
  # pdf / audio / video, classified by media type) entries, for the display
347
347
  # layer (Cerberus / the IIIF auth service; Cerberus's download :read check)
348
348
  # to enforce.
349
349
  #
350
350
  # @param id [String] the Work ID.
351
351
  # @param policy [Hash] tier => Array(read groups), e.g.
352
- # `{ large: ["northeastern:drs:repository:archives"], master: [...] }`.
352
+ # `{ large: ["northeastern:drs:repository:archives"], original: [...] }`.
353
353
  # Keys may be strings or symbols; recognized keys are `small` / `medium` /
354
- # `large` / `service` / `master` / `audio` / `video` / `pdf`.
354
+ # `large` / `service` / `original` / `audio` / `video` / `pdf`. Atlas
355
+ # 0.6.211 renamed the image floor from `master`; for one release it still
356
+ # accepts `master` on write and stores it as `original`.
355
357
  # @param nuid [String, nil] optional acting user's NUID. On the relay-signing
356
358
  # path it is signed into the assertion `sub`; on the BYO-JWT (`ATLAS_JWT`)
357
359
  # path it is ignored (identity lives in the token).
@@ -435,6 +437,11 @@ module AtlasRb
435
437
  # authorized rather than fetched directly) and `permission` (the effective
436
438
  # read-group set, or `nil` for guests, to whom group names are withheld).
437
439
  #
440
+ # A Blob entry also carries `language` and `track_label`, set by {Blob.create}
441
+ # and {Blob.update} for a caption or other text track and `nil` otherwise
442
+ # (Atlas 0.6.211 or later). A FileSet withdrawn with {Resource.tombstone}
443
+ # drops out of this listing and {.file_sets}.
444
+ #
438
445
  # @param id [String] the Work ID.
439
446
  # @param nuid [String, nil] optional acting user's NUID. On the relay-signing
440
447
  # path it is signed into the assertion `sub`; on the BYO-JWT (`ATLAS_JWT`)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atlas_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.21.0
4
+ version: 1.22.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cliff