atlas_rb 1.3.2 → 1.3.3

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: 54691ff87af06d611d63a27333682abfd284c67d6990d0c8400ea2b9b80adb92
4
- data.tar.gz: 7d3119d56763694dad36c69ded4cbf975af62d6eb070baf36c0df02f422259f1
3
+ metadata.gz: a36183e05b8c32292a5b0201db841ad961bcffcd51d546c0203d591cfbcfefce
4
+ data.tar.gz: 81d85278032e45d983dd5007b25ca3688cea9f23e3c8b5ce94a04727ef5d9497
5
5
  SHA512:
6
- metadata.gz: 86dc095d2be7db4fdefe997cc6b33fabd0d3c1826804b0521fda48b06d17ec4cd3fde492a3926114965d4354823f55043ea7559d4ce82dcc06a288b7fa8afecd
7
- data.tar.gz: c31c2bea0442ec082ede4a2328c6f7471eb02151021c6e08620b4fef5b254996ad424816493e8d955e202f5c5444e800393b85064dc9feb58a61cbaf126a9e08
6
+ metadata.gz: f4866c59b9c8a8321a0cc440139a5382ac03129e29e0130447da6ade868059dd484bed4029de404a61292058a0f32407266b20f707aa8757e65112d231c57374
7
+ data.tar.gz: ff821a348a98120bfe12da5f0e0de0594810ab93848f3db20e549951eabb205b330df5954d2e375836dab316d50178e80545cd1b69133165aee46567600f02b7
data/.version CHANGED
@@ -1 +1 @@
1
- 1.3.2
1
+ 1.3.3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.3.3
4
+
5
+ ### Added — multipage bindings (FileSet ordinality)
6
+
7
+ Bindings for Atlas's FileSet-ordinality surface (Atlas v0.6.53) — the
8
+ primitive behind multipage Works (postcards, scanned books, photo albums):
9
+ one Work, N ordered page FileSets.
10
+
11
+ ```ruby
12
+ # Ordered create — one FileSet per page
13
+ page = AtlasRb::FileSet.create("w-789", "image", position: 1)
14
+ AtlasRb::FileSet.update(page["id"], "/tmp/page-001.tiff")
15
+
16
+ # Ordered listing — the read a IIIF manifest assembler needs
17
+ AtlasRb::Work.file_sets("w-789")
18
+ # => [{ "noid" => ..., "position" => 1, "assets" => [...] }, ...]
19
+
20
+ # Preservation-record view — the Work-level METS physical structMap
21
+ AtlasRb::Work.mets("w-789").mets.pages.map(&:order)
22
+ # => [1, 2, 3]
23
+ ```
24
+
25
+ - `FileSet.create` gains an optional `position:` kwarg — 1-based page
26
+ order, set at create time only; omitted = unordered (every existing
27
+ call is unaffected). Sequence validation (contiguity, uniqueness) stays
28
+ the caller's job — Atlas stores what it is given.
29
+ - `Work.file_sets` wraps `GET /works/<id>/file_sets`: one entry per
30
+ page-bearing FileSet, `position` ascending with unordered FileSets
31
+ last, each nesting its downloadable assets (content Blobs + per-page
32
+ IIIF Delegates). **Unpaginated** by design — the whole page sequence
33
+ arrives in one call. Grouped sibling of `.assets`, which flattens.
34
+ - `Work.mets` wraps `GET /works/<id>/mets`: the Work-level METS JSON
35
+ projection; `mets.pages` carries the preserved page order. Atlas builds
36
+ the document at `Work.complete`, so a never-completed Work has no METS
37
+ yet — the binding returns `nil` on the 404, matching
38
+ `User.find_by_nuid`'s convention.
39
+
3
40
  ## 1.3.2
4
41
 
5
42
  ### Added — `AtlasRb::User` (read-only user directory)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- atlas_rb (1.3.2)
4
+ atlas_rb (1.3.3)
5
5
  faraday (~> 2.7)
6
6
  faraday-follow_redirects (~> 0.3.0)
7
7
  faraday-multipart (~> 1)
@@ -39,6 +39,12 @@ module AtlasRb
39
39
  # @param classification [String] role tag for the FileSet — e.g.
40
40
  # `"primary"`, `"supplemental"`, `"thumbnail"`. The exact set is
41
41
  # defined by the Atlas server.
42
+ # @param position [Integer, nil] optional 1-based page order within the
43
+ # parent Work, for multipage Works (one FileSet per page). Omit for
44
+ # unordered FileSets — every non-multipage FileSet stays unordered.
45
+ # Set at create time only; Atlas stores what it is given (sequence
46
+ # validation — contiguity, uniqueness — is the caller's job, e.g. the
47
+ # Cerberus loader rejecting bad manifests before any create).
42
48
  # @param idempotency_key [String, nil] optional UUID. A repeat call with
43
49
  # the same key returns the originally-created FileSet instead of
44
50
  # creating a new one. See {AtlasRb::Work.create} for full semantics.
@@ -49,18 +55,25 @@ module AtlasRb
49
55
  # header. Falls through to {AtlasRb.config}.default_on_behalf_of when
50
56
  # omitted.
51
57
  # @return [Hash] the created `"file_set"` payload, including its `"id"`
52
- # which can then be passed to {.update} to attach a binary.
58
+ # which can then be passed to {.update} to attach a binary, and its
59
+ # `"position"` (`nil` when unordered).
53
60
  #
54
61
  # @example
55
62
  # fs = AtlasRb::FileSet.create("w-789", "primary")
56
63
  # AtlasRb::FileSet.update(fs["id"], "/tmp/article.pdf")
57
64
  #
65
+ # @example Multipage ingest — one ordered FileSet per page
66
+ # page = AtlasRb::FileSet.create("w-789", "image", position: 1)
67
+ # AtlasRb::FileSet.update(page["id"], "/tmp/page-001.tiff")
68
+ #
58
69
  # @example Retry-safe bulk-deposit create
59
70
  # key = SecureRandom.uuid
60
71
  # AtlasRb::FileSet.create("w-789", "primary", idempotency_key: key)
61
- def self.create(id, classification, idempotency_key: nil, nuid: nil, on_behalf_of: nil)
72
+ def self.create(id, classification, position: nil, idempotency_key: nil, nuid: nil, on_behalf_of: nil)
73
+ params = { work_id: id, classification: classification }
74
+ params[:position] = position if position
62
75
  AtlasRb::Mash.new(JSON.parse(
63
- connection({ work_id: id, classification: classification }, nuid,
76
+ connection(params, nuid,
64
77
  on_behalf_of: on_behalf_of, idempotency_key: idempotency_key).post(ROUTE)&.body
65
78
  ))["file_set"]
66
79
  end
data/lib/atlas_rb/work.rb CHANGED
@@ -371,6 +371,78 @@ module AtlasRb
371
371
  ).map { |entry| AtlasRb::Mash.new(entry) }
372
372
  end
373
373
 
374
+ # List a Work's page FileSets in order, each with its assets.
375
+ #
376
+ # Wraps `GET /works/<id>/file_sets` — the ordered, grouped sibling of
377
+ # {.assets} (which flattens FileSet membership away). One entry per
378
+ # page-bearing FileSet, sorted `position` ascending with unordered
379
+ # (`null`-position) FileSets last; metadata and derivative-container
380
+ # FileSets are excluded as entries. Each entry nests its downloadable
381
+ # assets — the page's content Blobs plus any per-page IIIF Delegates —
382
+ # in the same polymorphic shape {.assets} returns.
383
+ #
384
+ # This is the read a IIIF Presentation manifest assembler needs: the
385
+ # response is **unpaginated** by design, so the whole page sequence
386
+ # arrives in one call.
387
+ #
388
+ # @param id [String] the Work ID.
389
+ # @param nuid [String, nil] optional acting user's NUID, forwarded as the
390
+ # `User:` header. Required for cerberus-token requests; legacy bearer
391
+ # tokens still resolve without it.
392
+ # @param on_behalf_of [String, nil] optional NUID for the `On-Behalf-Of`
393
+ # header. Falls through to {AtlasRb.config}.default_on_behalf_of when
394
+ # omitted.
395
+ # @return [Array<AtlasRb::Mash>] one entry per page FileSet, in page
396
+ # order: `{ "noid", "type", "position", "tombstoned", "assets" => [...] }`.
397
+ #
398
+ # @example Assemble manifest canvases in page order
399
+ # AtlasRb::Work.file_sets("w-789").each do |page|
400
+ # iiif = page.assets.find { |a| a["uri"] }
401
+ # add_canvas(order: page.position, image: iiif&.uri)
402
+ # end
403
+ def self.file_sets(id, nuid: nil, on_behalf_of: nil)
404
+ JSON.parse(
405
+ connection({}, nuid, on_behalf_of: on_behalf_of).get(ROUTE + id + '/file_sets')&.body
406
+ ).map { |entry| AtlasRb::Mash.new(entry) }
407
+ end
408
+
409
+ # Fetch the Work-level METS structural metadata (page order).
410
+ #
411
+ # Wraps `GET /works/<id>/mets` — the JSON projection of the Work's METS
412
+ # document, whose physical structMap is the preservation record of page
413
+ # order. The page sequence surfaces under `"mets" => "pages"` (one entry
414
+ # per page: `noid` / `order` / `label`). Atlas builds the document when
415
+ # the Work is completed ({.complete}) and rebuilds it on page changes
416
+ # thereafter, so a Work that has never been completed has no METS yet —
417
+ # Atlas answers `404` and this binding returns `nil` (matching
418
+ # {User.find_by_nuid}'s missing-resource convention).
419
+ #
420
+ # For runtime page listing (e.g. manifest assembly) prefer {.file_sets},
421
+ # which needs no completion and carries each page's assets; this read is
422
+ # the preservation-record view.
423
+ #
424
+ # @param id [String] the Work ID.
425
+ # @param nuid [String, nil] optional acting user's NUID, forwarded as the
426
+ # `User:` header. Required for cerberus-token requests; legacy bearer
427
+ # tokens still resolve without it.
428
+ # @param on_behalf_of [String, nil] optional NUID for the `On-Behalf-Of`
429
+ # header. Falls through to {AtlasRb.config}.default_on_behalf_of when
430
+ # omitted.
431
+ # @return [Hash, nil] the `"work"` object, already unwrapped: `{ "id",
432
+ # "mets" => { "created_at_iso", "agent", "files", "structure_label",
433
+ # "pages" => [...] } }` — or `nil` when the Work has no METS yet
434
+ # (never completed) or does not exist.
435
+ #
436
+ # @example
437
+ # AtlasRb::Work.mets("w-789").mets.pages.map(&:order)
438
+ # # => [1, 2, 3]
439
+ def self.mets(id, nuid: nil, on_behalf_of: nil)
440
+ response = connection({}, nuid, on_behalf_of: on_behalf_of).get(ROUTE + id + '/mets')
441
+ return nil if response.status == 404
442
+
443
+ AtlasRb::Mash.new(JSON.parse(response.body))["work"]
444
+ end
445
+
374
446
  # Fetch the Work's MODS representation in the requested format.
375
447
  #
376
448
  # @param id [String] the Work ID.
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.3.2
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cliff