atlas_rb 1.9.4 → 1.10.1
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 +4 -4
- data/.version +1 -1
- data/CHANGELOG.md +58 -0
- data/Gemfile.lock +2 -2
- data/README.md +22 -0
- data/lib/atlas_rb/person.rb +4 -6
- data/lib/atlas_rb/work.rb +93 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d8edc13167cb16fb5482d6a5cd19760bf323f67bf1a23f00a9508f8320bf798
|
|
4
|
+
data.tar.gz: e86459ce460b8eb30cffcfaaed75b06c750649aa57559e33d5ea277ce0bd2d8c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 06a66bf273c655ae075c821d158555139094714e3b5d0f3ca15296657afe067267ef781190c4804d5a97d3576237a11d664141f28256702df4151fefde515255
|
|
7
|
+
data.tar.gz: dfd113525542142a75e0789a5e9ed34424485e1ac69359f5e4c505e24d3752e9eda54e756804f13f195588f6079d0c828426e0a5b937d8ad53c2ef8708eaff00
|
data/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.10.1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.10.1
|
|
4
|
+
|
|
5
|
+
### Added — `Work.mark_incomplete` / `Work.clear_incomplete`
|
|
6
|
+
|
|
7
|
+
A Work can now carry a second lifecycle state. `complete` says the deposit
|
|
8
|
+
finished; `incomplete` says something downstream of it gave up. Before this
|
|
9
|
+
there was no way to record that at all: every give-up handler wrote a
|
|
10
|
+
`Rails.logger.warn` and nothing else, so a deposit whose PDF rendition
|
|
11
|
+
exhausted its retries ended up with no rendition and no thumbnail, the
|
|
12
|
+
depositor was not told, and no surface listed it.
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
AtlasRb::Work.mark_incomplete(work_id, reason: "pdf_rendition_gave_up")
|
|
16
|
+
AtlasRb::Work.clear_incomplete(work_id)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`reason` is a machine token, one per give-up handler. Atlas holds it as an
|
|
20
|
+
opaque string and does **not** validate it against a list, so the vocabulary
|
|
21
|
+
belongs to the caller and a new token needs no Atlas release. Map it to display
|
|
22
|
+
text at the point of use, with a fallback for a token the view has not been
|
|
23
|
+
taught.
|
|
24
|
+
|
|
25
|
+
The flag **never hides** the Work. A record with its file, title and metadata
|
|
26
|
+
but one missing derivative is degraded, not broken, and stays readable.
|
|
27
|
+
|
|
28
|
+
Both bindings return the updated Work. `mark_incomplete` is idempotent and the
|
|
29
|
+
last reason wins; `clear_incomplete` is idempotent too, and clears the flag and
|
|
30
|
+
the reason together. Call it when a later run of the same job succeeds, which
|
|
31
|
+
makes the state self-healing.
|
|
32
|
+
|
|
33
|
+
### Added — `incomplete:` filter on `Work.list`
|
|
34
|
+
|
|
35
|
+
`AtlasRb::Work.list(incomplete: true)` is the staff list of Works whose
|
|
36
|
+
pipeline gave up, the sibling of the existing `in_progress:` "what's stuck?"
|
|
37
|
+
view. The two are independent and combine: `in_progress: false, incomplete:
|
|
38
|
+
true` reads as "finished, but degraded".
|
|
39
|
+
|
|
40
|
+
Work summaries in the response now carry `incomplete` and `incomplete_reason`
|
|
41
|
+
alongside `in_progress`.
|
|
42
|
+
|
|
43
|
+
## 1.10.0
|
|
44
|
+
|
|
45
|
+
### Removed — `title` on `Person.create` and `Person.update`
|
|
46
|
+
|
|
47
|
+
Atlas no longer holds a job title on a Person. The attribute claimed
|
|
48
|
+
Blacklight's title namespace, where display and sorting expect the Person's
|
|
49
|
+
name, so Atlas dropped it rather than renamed it: the field was display-only,
|
|
50
|
+
optional, and absent from v1.
|
|
51
|
+
|
|
52
|
+
The parameter therefore had nothing to write to. Atlas ignores an unknown key in
|
|
53
|
+
a write body, so a caller that kept passing `title:` had its value discarded
|
|
54
|
+
with no error and nothing in a log. That is the reason to remove the parameter
|
|
55
|
+
rather than leave it accepted and inert.
|
|
56
|
+
|
|
57
|
+
**Breaking.** `Person.create(…, title: "Professor")` now raises
|
|
58
|
+
`ArgumentError: unknown keyword: :title`. Drop the argument at the call site;
|
|
59
|
+
there is no replacement field.
|
|
60
|
+
|
|
3
61
|
## 1.9.4
|
|
4
62
|
|
|
5
63
|
### Fixed — write bindings parsed the response body without checking the status
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
atlas_rb (1.
|
|
4
|
+
atlas_rb (1.10.1)
|
|
5
5
|
faraday (~> 2.7)
|
|
6
6
|
faraday-follow_redirects (~> 0.3.0)
|
|
7
7
|
faraday-multipart (~> 1)
|
|
@@ -25,7 +25,7 @@ GEM
|
|
|
25
25
|
net-http (~> 0.5)
|
|
26
26
|
hashie (5.1.0)
|
|
27
27
|
logger
|
|
28
|
-
json (2.21.
|
|
28
|
+
json (2.21.2)
|
|
29
29
|
jwt (2.10.3)
|
|
30
30
|
base64
|
|
31
31
|
logger (1.7.0)
|
data/README.md
CHANGED
|
@@ -255,6 +255,28 @@ AtlasRb::Work.list(in_progress: false, page: 2) # completed deposits, page 2
|
|
|
255
255
|
AtlasRb::Work.complete("w-789") # mark w-789 done
|
|
256
256
|
```
|
|
257
257
|
|
|
258
|
+
A Work carries a second, independent lifecycle state for the other kind of
|
|
259
|
+
failure. `complete` says the deposit finished; `incomplete` says something
|
|
260
|
+
downstream of it gave up — a rendition, the derivatives, the full-text
|
|
261
|
+
extraction — after that job exhausted its retries. Call `mark_incomplete`
|
|
262
|
+
from the give-up handler, and `clear_incomplete` when a later run succeeds,
|
|
263
|
+
which makes the state self-healing.
|
|
264
|
+
|
|
265
|
+
```ruby
|
|
266
|
+
AtlasRb::Work.mark_incomplete("w-789", reason: "pdf_rendition_gave_up")
|
|
267
|
+
AtlasRb::Work.clear_incomplete("w-789")
|
|
268
|
+
AtlasRb::Work.list(incomplete: true) # the staff repair list
|
|
269
|
+
AtlasRb::Work.list(in_progress: false, incomplete: true) # finished, but degraded
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`reason` is a machine token, one per give-up handler. Atlas stores it as an
|
|
273
|
+
opaque string and does not validate it against a list, so the vocabulary is
|
|
274
|
+
yours and a new token needs no Atlas release. Map it to display text at the
|
|
275
|
+
point of use, with a fallback for a token the view has not been taught.
|
|
276
|
+
|
|
277
|
+
The flag never hides the Work. A record with its file, title and metadata but
|
|
278
|
+
one missing derivative is degraded, not broken, and stays readable.
|
|
279
|
+
|
|
258
280
|
### Audit-event history
|
|
259
281
|
|
|
260
282
|
`Resource.history` wraps Atlas's `GET /resources/<id>/history` endpoint
|
data/lib/atlas_rb/person.rb
CHANGED
|
@@ -85,7 +85,6 @@ module AtlasRb
|
|
|
85
85
|
# @param display_name [String] authoritative display name.
|
|
86
86
|
# @param bio [String, nil]
|
|
87
87
|
# @param orcid [String, nil]
|
|
88
|
-
# @param title [String, nil]
|
|
89
88
|
# @param on_behalf_of [String, nil] acting-as target (the acting principal
|
|
90
89
|
# itself comes from the ambient AtlasRb.config.default_nuid).
|
|
91
90
|
# @return [AtlasRb::Mash] the unwrapped `"person"` object.
|
|
@@ -93,8 +92,8 @@ module AtlasRb
|
|
|
93
92
|
# resource, so the write did not happen.
|
|
94
93
|
# @raise [AtlasRb::ResourceError] on any other non-2xx, carrying Atlas's status
|
|
95
94
|
# and body.
|
|
96
|
-
def self.create(nuid:, display_name:, bio: nil, orcid: nil,
|
|
97
|
-
body = { nuid: nuid, display_name: display_name, bio: bio, orcid: orcid
|
|
95
|
+
def self.create(nuid:, display_name:, bio: nil, orcid: nil, on_behalf_of: nil)
|
|
96
|
+
body = { nuid: nuid, display_name: display_name, bio: bio, orcid: orcid }.compact
|
|
98
97
|
AtlasRb::Mash.new(write_resource(
|
|
99
98
|
connection({}, nil, on_behalf_of: on_behalf_of).post(ROUTE, JSON.dump(body))
|
|
100
99
|
))["person"]
|
|
@@ -107,7 +106,6 @@ module AtlasRb
|
|
|
107
106
|
# @param display_name [String, nil]
|
|
108
107
|
# @param bio [String, nil]
|
|
109
108
|
# @param orcid [String, nil]
|
|
110
|
-
# @param title [String, nil]
|
|
111
109
|
# @param nuid [String, nil] acting principal.
|
|
112
110
|
# @param on_behalf_of [String, nil] acting-as target.
|
|
113
111
|
# @return [AtlasRb::Mash] the unwrapped, updated `"person"` object.
|
|
@@ -115,8 +113,8 @@ module AtlasRb
|
|
|
115
113
|
# resource, so the write did not happen.
|
|
116
114
|
# @raise [AtlasRb::ResourceError] on any other non-2xx, carrying Atlas's status
|
|
117
115
|
# and body.
|
|
118
|
-
def self.update(id, display_name: nil, bio: nil, orcid: nil,
|
|
119
|
-
body = { display_name: display_name, bio: bio, orcid: orcid
|
|
116
|
+
def self.update(id, display_name: nil, bio: nil, orcid: nil, nuid: nil, on_behalf_of: nil)
|
|
117
|
+
body = { display_name: display_name, bio: bio, orcid: orcid }.compact
|
|
120
118
|
AtlasRb::Mash.new(write_resource(
|
|
121
119
|
connection({}, nuid, on_behalf_of: on_behalf_of).patch(ROUTE + id, JSON.dump(body))
|
|
122
120
|
))["person"]
|
data/lib/atlas_rb/work.rb
CHANGED
|
@@ -43,6 +43,11 @@ module AtlasRb
|
|
|
43
43
|
#
|
|
44
44
|
# @param in_progress [Boolean, nil] when set, filter to Works whose
|
|
45
45
|
# `in_progress` flag matches. Omit (or pass `nil`) for "all works".
|
|
46
|
+
# @param incomplete [Boolean, nil] when set, filter to Works whose
|
|
47
|
+
# `incomplete` flag matches — the staff list of Works whose enrichment
|
|
48
|
+
# pipeline gave up (see {.mark_incomplete}). Independent of
|
|
49
|
+
# `in_progress:`, and the two combine: `in_progress: false,
|
|
50
|
+
# incomplete: true` reads as "finished, but degraded".
|
|
46
51
|
# @param page [Integer, nil] 1-indexed page number.
|
|
47
52
|
# @param per_page [Integer, nil] page size override.
|
|
48
53
|
# @param nuid [String, nil] optional acting user's NUID. On the relay-signing
|
|
@@ -53,16 +58,20 @@ module AtlasRb
|
|
|
53
58
|
# omitted.
|
|
54
59
|
# @return [AtlasRb::Mash] `{ "works" => [...], "pagination" => {...} }`.
|
|
55
60
|
# Each entry in `"works"` is a Work summary (`id`, `title`,
|
|
56
|
-
# `description`, `in_progress`).
|
|
61
|
+
# `description`, `in_progress`, `incomplete`, `incomplete_reason`).
|
|
57
62
|
#
|
|
58
63
|
# @example Find stuck deposits
|
|
59
64
|
# AtlasRb::Work.list(in_progress: true)
|
|
60
65
|
#
|
|
66
|
+
# @example Find works whose pipeline gave up
|
|
67
|
+
# AtlasRb::Work.list(incomplete: true)
|
|
68
|
+
#
|
|
61
69
|
# @example Page through all works
|
|
62
70
|
# AtlasRb::Work.list(page: 2, per_page: 50)
|
|
63
|
-
def self.list(in_progress: nil, page: nil, per_page: nil, nuid: nil, on_behalf_of: nil)
|
|
71
|
+
def self.list(in_progress: nil, incomplete: nil, page: nil, per_page: nil, nuid: nil, on_behalf_of: nil)
|
|
64
72
|
params = {}
|
|
65
73
|
params[:in_progress] = in_progress unless in_progress.nil?
|
|
74
|
+
params[:incomplete] = incomplete unless incomplete.nil?
|
|
66
75
|
params[:page] = page if page
|
|
67
76
|
params[:per_page] = per_page if per_page
|
|
68
77
|
AtlasRb::Mash.new(JSON.parse(
|
|
@@ -232,6 +241,88 @@ module AtlasRb
|
|
|
232
241
|
connection({}, nuid, on_behalf_of: on_behalf_of).post(ROUTE + id + '/complete')
|
|
233
242
|
end
|
|
234
243
|
|
|
244
|
+
# Flag a Work whose enrichment pipeline gave up.
|
|
245
|
+
#
|
|
246
|
+
# The counterpart to {.complete}, for the other half of the lifecycle:
|
|
247
|
+
# `complete` says the deposit finished, this says something downstream of
|
|
248
|
+
# it did not. Call it from a work-scoped job's give-up handler — the PDF or
|
|
249
|
+
# media rendition, the derivatives, the full-text extraction — once that
|
|
250
|
+
# job has exhausted its retries. Atlas's `GET /works?incomplete=true` then
|
|
251
|
+
# lists the Work for staff, and `incomplete_bsi` on its Solr document lets
|
|
252
|
+
# a result row render a pill without a per-row fetch.
|
|
253
|
+
#
|
|
254
|
+
# The flag **never hides** the Work. A record with its file, title and
|
|
255
|
+
# metadata but one missing derivative is degraded, not broken, and stays
|
|
256
|
+
# readable — enrichment does not fail a deposit.
|
|
257
|
+
#
|
|
258
|
+
# Idempotent on the server; the last reason wins. Clear it with
|
|
259
|
+
# {.clear_incomplete} when a later run of the same job succeeds, which
|
|
260
|
+
# makes the state self-healing.
|
|
261
|
+
#
|
|
262
|
+
# @param id [String] the Work ID.
|
|
263
|
+
# @param reason [String, nil] a machine token naming the cause — one per
|
|
264
|
+
# give-up handler, e.g. `"pdf_rendition_gave_up"`,
|
|
265
|
+
# `"media_rendition_gave_up"`, `"ingest_gave_up"`. Atlas stores it as an
|
|
266
|
+
# opaque string and does **not** validate it against a list, so the
|
|
267
|
+
# vocabulary is the caller's and a new token needs no Atlas release. Map
|
|
268
|
+
# it to display text at the point of use, with a fallback for a token the
|
|
269
|
+
# view has not been taught. A blank reason still sets the flag.
|
|
270
|
+
# @param nuid [String, nil] optional NUID of the acting user.
|
|
271
|
+
# @param on_behalf_of [String, nil] optional NUID for the `On-Behalf-Of`
|
|
272
|
+
# header. Falls through to {AtlasRb.config}.default_on_behalf_of when
|
|
273
|
+
# omitted.
|
|
274
|
+
# @return [Hash] the updated Work, the same shape {.find} returns, carrying
|
|
275
|
+
# `incomplete` and `incomplete_reason`.
|
|
276
|
+
# @raise [AtlasRb::StaleResourceError] if Atlas reports an optimistic-lock
|
|
277
|
+
# conflict that exhausted its internal retry budget (HTTP 409 with
|
|
278
|
+
# `error: "stale_resource"`).
|
|
279
|
+
# @raise [AtlasRb::NotFoundError] if Atlas answers `404` — the id names no such
|
|
280
|
+
# resource, so the write did not happen.
|
|
281
|
+
# @raise [AtlasRb::ResourceError] on any other non-2xx, carrying Atlas's status
|
|
282
|
+
# and body.
|
|
283
|
+
#
|
|
284
|
+
# @example In a give-up handler
|
|
285
|
+
# AtlasRb::Work.mark_incomplete(work_id, reason: "pdf_rendition_gave_up")
|
|
286
|
+
def self.mark_incomplete(id, reason:, nuid: nil, on_behalf_of: nil)
|
|
287
|
+
AtlasRb::Mash.new(write_resource(
|
|
288
|
+
connection({}, nuid, on_behalf_of: on_behalf_of)
|
|
289
|
+
.post(ROUTE + id + '/incomplete', JSON.dump(reason: reason))
|
|
290
|
+
))["work"]
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Clear the incomplete flag and its reason.
|
|
294
|
+
#
|
|
295
|
+
# The repair half of {.mark_incomplete}: call it from the same job when a
|
|
296
|
+
# later run succeeds, or by hand once an operator has fixed the Work. Both
|
|
297
|
+
# fields clear together — a reason without a flag would leave a stale cause
|
|
298
|
+
# on the Solr document.
|
|
299
|
+
#
|
|
300
|
+
# Idempotent: clearing a Work that was never flagged is a no-op.
|
|
301
|
+
#
|
|
302
|
+
# @param id [String] the Work ID.
|
|
303
|
+
# @param nuid [String, nil] optional NUID of the acting user.
|
|
304
|
+
# @param on_behalf_of [String, nil] optional NUID for the `On-Behalf-Of`
|
|
305
|
+
# header. Falls through to {AtlasRb.config}.default_on_behalf_of when
|
|
306
|
+
# omitted.
|
|
307
|
+
# @return [Hash] the updated Work, the same shape {.find} returns, with
|
|
308
|
+
# `incomplete` false and `incomplete_reason` null.
|
|
309
|
+
# @raise [AtlasRb::StaleResourceError] if Atlas reports an optimistic-lock
|
|
310
|
+
# conflict that exhausted its internal retry budget (HTTP 409 with
|
|
311
|
+
# `error: "stale_resource"`).
|
|
312
|
+
# @raise [AtlasRb::NotFoundError] if Atlas answers `404` — the id names no such
|
|
313
|
+
# resource, so the write did not happen.
|
|
314
|
+
# @raise [AtlasRb::ResourceError] on any other non-2xx, carrying Atlas's status
|
|
315
|
+
# and body.
|
|
316
|
+
#
|
|
317
|
+
# @example On a later successful run
|
|
318
|
+
# AtlasRb::Work.clear_incomplete(work_id)
|
|
319
|
+
def self.clear_incomplete(id, nuid: nil, on_behalf_of: nil)
|
|
320
|
+
AtlasRb::Mash.new(write_resource(
|
|
321
|
+
connection({}, nuid, on_behalf_of: on_behalf_of)
|
|
322
|
+
.delete(ROUTE + id + '/incomplete')
|
|
323
|
+
))["work"]
|
|
324
|
+
end
|
|
325
|
+
|
|
235
326
|
# Replace a Work's metadata by uploading a MODS XML document.
|
|
236
327
|
#
|
|
237
328
|
# @param id [String] the Work ID.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: atlas_rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.10.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Cliff
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|