atlas_rb 0.0.83 → 0.0.85

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: 0a7a8531fb28a840a529a888d8d5b789ea9ba69aed95fa59d5899f4aea42afd8
4
- data.tar.gz: 2f545fdddc0d22cdb3def311ed73abcb946524bffb0a3d55952e1cee9226eb10
3
+ metadata.gz: a85ca8a2fc7cb44ff2d348c03e2a1d8a0b5c01a35ddeccd823445071290d4ea0
4
+ data.tar.gz: 1dbf5a8aeb3052c5841003951710320d23559133f00a2a24ed57bc7631472c79
5
5
  SHA512:
6
- metadata.gz: 5fbc732c7f405ffe14c22169a38e8037eec302a4572f691ca41e2ebd8f5450aad5c33eab8d0b712dacf9295b62d364178ace4caa9af5d932c65f6f2ca04e9044
7
- data.tar.gz: 4454c5562263f3401d9cf10764594b7acaf8d978f6264d6738d8f9324abe8b1e9542ce009559c59e3ee31ac36e2fee4a32222912efd43c6fdc06c798d8105a0e
6
+ metadata.gz: 86d853b18df5e0f278de6e4c58bf8df6705fc88d495c72ebd44c7e2075357e486e3c7c5702bb40ae7cdd211576a374f2bda920fc2aba3f1f0be3a7f8999388f0
7
+ data.tar.gz: 255bfa1ce0f3edf9268dd58b86093d429e2fac74d118a72a68e02106d9bc5779978c874b6d6ded9ffe68798949c2ffef90bd845aa66d34a93c23fab48962b16f
data/.version CHANGED
@@ -1 +1 @@
1
- 0.0.83
1
+ 0.0.85
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- atlas_rb (0.0.83)
4
+ atlas_rb (0.0.85)
5
5
  faraday (~> 2.7)
6
6
  faraday-follow_redirects (~> 0.3.0)
7
7
  faraday-multipart (~> 1)
8
+ hashie (~> 5.0)
8
9
 
9
10
  GEM
10
11
  remote: https://rubygems.org/
@@ -20,6 +21,8 @@ GEM
20
21
  multipart-post (~> 2.0)
21
22
  faraday-net_http (3.4.2)
22
23
  net-http (~> 0.5)
24
+ hashie (5.1.0)
25
+ logger
23
26
  json (2.19.4)
24
27
  logger (1.7.0)
25
28
  multipart-post (2.4.1)
data/README.md CHANGED
@@ -75,6 +75,11 @@ AtlasRb::Blob.create("w-789", path, name) # blob under work w-789 with original
75
75
 
76
76
  ## End-to-end example
77
77
 
78
+ JSON responses come back as `AtlasRb::Mash` (a `Hashie::Mash` subclass), so
79
+ you can use dot access — `community.id` — or string-keyed access —
80
+ `community["id"]` — interchangeably. Both return the same value, so existing
81
+ string-keyed callers keep working.
82
+
78
83
  ```ruby
79
84
  require "atlas_rb"
80
85
 
@@ -82,19 +87,19 @@ ENV["ATLAS_URL"] = "https://atlas.example.edu"
82
87
  ENV["ATLAS_TOKEN"] = "..."
83
88
 
84
89
  # 1. Build the org structure (each create can optionally seed MODS metadata).
85
- community = AtlasRb::Community.create(nil, "/tmp/community-mods.xml")
86
- collection = AtlasRb::Collection.create(community["id"], "/tmp/coll-mods.xml")
87
- work = AtlasRb::Work.create(collection["id"], "/tmp/work-mods.xml")
90
+ community = AtlasRb::Community.create(nil, "/tmp/community-mods.xml")
91
+ collection = AtlasRb::Collection.create(community.id, "/tmp/coll-mods.xml")
92
+ work = AtlasRb::Work.create(collection.id, "/tmp/work-mods.xml")
88
93
 
89
94
  # 2. Upload a binary attached to the work, preserving the user-facing filename.
90
- blob = AtlasRb::Blob.create(work["id"], "/tmp/upload.tmp", "thesis.pdf")
95
+ blob = AtlasRb::Blob.create(work.id, "/tmp/upload.tmp", "thesis.pdf")
91
96
 
92
97
  # 3. List everything attached to the work.
93
- AtlasRb::Work.files(work["id"])
98
+ AtlasRb::Work.files(work.id)
94
99
 
95
100
  # 4. Stream the binary back without buffering it in memory.
96
101
  File.open("out.pdf", "wb") do |f|
97
- headers = AtlasRb::Blob.content(blob["id"]) { |chunk| f.write(chunk) }
102
+ headers = AtlasRb::Blob.content(blob.id) { |chunk| f.write(chunk) }
98
103
  puts headers["content-type"]
99
104
  end
100
105
 
@@ -29,7 +29,7 @@ module AtlasRb
29
29
  def self.login(nuid)
30
30
  # JSON.parse(connection({ nuid: nuid }).post('/token')&.body)["token"]
31
31
  # need hash - id, name, token => ...
32
- JSON.parse(connection({}, nuid).get('/user')&.body)
32
+ AtlasRb::Mash.new(JSON.parse(connection({}, nuid).get('/user')&.body))
33
33
  end
34
34
 
35
35
  # Fetch only the group memberships for an NUID.
@@ -49,7 +49,7 @@ module AtlasRb
49
49
  # token = user_details[:token] ...
50
50
  # TODO - need to update atlas login to give back name, id, and token upon logging in
51
51
  # result = JSON.parse(connection({ token: token }).post('/users/2/groups')&.body)["user"]["groups"]
52
- JSON.parse(connection({}, nuid).get('/user')&.body)["groups"]
52
+ AtlasRb::Mash.new(JSON.parse(connection({}, nuid).get('/user')&.body))["groups"]
53
53
  end
54
54
  end
55
55
  end
data/lib/atlas_rb/blob.rb CHANGED
@@ -24,7 +24,7 @@ module AtlasRb
24
24
  # AtlasRb::Blob.find("b-321")
25
25
  # # => { "id" => "b-321", "original_filename" => "scan.pdf", ... }
26
26
  def self.find(id)
27
- JSON.parse(connection({}).get(ROUTE + id)&.body)['blob']
27
+ AtlasRb::Mash.new(JSON.parse(connection({}).get(ROUTE + id)&.body))['blob']
28
28
  end
29
29
 
30
30
  # Stream the Blob's binary content through a caller-supplied block.
@@ -77,7 +77,7 @@ module AtlasRb
77
77
  "application/octet-stream",
78
78
  File.basename(blob_path)) }
79
79
 
80
- JSON.parse(multipart({}).post(ROUTE, payload)&.body)['blob']
80
+ AtlasRb::Mash.new(JSON.parse(multipart({}).post(ROUTE, payload)&.body))['blob']
81
81
  end
82
82
 
83
83
  # Delete a Blob (the bytes *and* the metadata record).
@@ -107,7 +107,7 @@ module AtlasRb
107
107
  payload = { binary: Faraday::Multipart::FilePart.new(File.open(blob_path),
108
108
  "application/octet-stream",
109
109
  File.basename(blob_path)) }
110
- JSON.parse(multipart({}).patch(ROUTE + id, payload)&.body)
110
+ AtlasRb::Mash.new(JSON.parse(multipart({}).patch(ROUTE + id, payload)&.body))
111
111
  end
112
112
  end
113
113
  end
@@ -4,7 +4,7 @@ module AtlasRb
4
4
  # A grouping of {Work}s within a {Community}.
5
5
  #
6
6
  # Collections are the leaf containers in the organizational tree — they hold
7
- # Works directly and cannot contain other Collections. Every Collection has
7
+ # Works directly. Every Collection has
8
8
  # exactly one parent Community.
9
9
  #
10
10
  # See also: {Community}, {Work}.
@@ -23,7 +23,7 @@ module AtlasRb
23
23
  # AtlasRb::Collection.find("col-456")
24
24
  # # => { "id" => "col-456", "title" => "Faculty Publications", ... }
25
25
  def self.find(id)
26
- JSON.parse(connection({}).get(ROUTE + id)&.body)["collection"]
26
+ AtlasRb::Mash.new(JSON.parse(connection({}).get(ROUTE + id)&.body))["collection"]
27
27
  end
28
28
 
29
29
  # Create a new Collection under an existing Community.
@@ -42,7 +42,7 @@ module AtlasRb
42
42
  # @example
43
43
  # AtlasRb::Collection.create("c-123", "/tmp/collection-mods.xml")
44
44
  def self.create(id, xml_path = nil)
45
- result = JSON.parse(connection({ parent_id: id }).post(ROUTE)&.body)["collection"]
45
+ result = AtlasRb::Mash.new(JSON.parse(connection({ parent_id: id }).post(ROUTE)&.body))["collection"]
46
46
  return result unless xml_path.present?
47
47
 
48
48
  update(result["id"], xml_path)
@@ -68,7 +68,7 @@ module AtlasRb
68
68
  # @example
69
69
  # AtlasRb::Collection.children("col-456")
70
70
  def self.children(id)
71
- JSON.parse(connection({}).get(ROUTE + id + '/children')&.body)
71
+ AtlasRb::Mash.new(JSON.parse(connection({}).get(ROUTE + id + '/children')&.body))
72
72
  end
73
73
 
74
74
  # Replace a Collection's metadata by uploading a MODS XML document.
@@ -83,7 +83,7 @@ module AtlasRb
83
83
  payload = { binary: Faraday::Multipart::FilePart.new(File.open(xml_path),
84
84
  "application/xml",
85
85
  File.basename(xml_path)) }
86
- JSON.parse(multipart({}).patch(ROUTE + id, payload)&.body)
86
+ AtlasRb::Mash.new(JSON.parse(multipart({}).patch(ROUTE + id, payload)&.body))
87
87
  end
88
88
 
89
89
  # Patch individual metadata fields without uploading a full MODS document.
@@ -95,7 +95,7 @@ module AtlasRb
95
95
  # @example
96
96
  # AtlasRb::Collection.metadata("col-456", title: "Renamed Collection")
97
97
  def self.metadata(id, values)
98
- JSON.parse(connection({ metadata: values }).patch(ROUTE + id)&.body)
98
+ AtlasRb::Mash.new(JSON.parse(connection({ metadata: values }).patch(ROUTE + id)&.body))
99
99
  end
100
100
 
101
101
  # Fetch the Collection's MODS representation in the requested format.
@@ -24,7 +24,7 @@ module AtlasRb
24
24
  # AtlasRb::Community.find("c-123")
25
25
  # # => { "id" => "c-123", "title" => "College of Engineering", ... }
26
26
  def self.find(id)
27
- JSON.parse(connection({}).get(ROUTE + id)&.body)["community"]
27
+ AtlasRb::Mash.new(JSON.parse(connection({}).get(ROUTE + id)&.body))["community"]
28
28
  end
29
29
 
30
30
  # Create a new Community, optionally seeded with MODS metadata.
@@ -46,7 +46,7 @@ module AtlasRb
46
46
  # @example Sub-community seeded from MODS
47
47
  # AtlasRb::Community.create("c-parent", "/tmp/dept-mods.xml")
48
48
  def self.create(id = nil, xml_path = nil)
49
- result = JSON.parse(connection({ parent_id: id }).post(ROUTE)&.body)["community"]
49
+ result = AtlasRb::Mash.new(JSON.parse(connection({ parent_id: id }).post(ROUTE)&.body))["community"]
50
50
  return result unless xml_path.present?
51
51
 
52
52
  update(result["id"], xml_path)
@@ -72,7 +72,7 @@ module AtlasRb
72
72
  # @example
73
73
  # AtlasRb::Community.children("c-123")
74
74
  def self.children(id)
75
- JSON.parse(connection({}).get(ROUTE + id + '/children')&.body)
75
+ AtlasRb::Mash.new(JSON.parse(connection({}).get(ROUTE + id + '/children')&.body))
76
76
  end
77
77
 
78
78
  # Replace a Community's metadata by uploading a MODS XML document.
@@ -87,7 +87,7 @@ module AtlasRb
87
87
  payload = { binary: Faraday::Multipart::FilePart.new(File.open(xml_path),
88
88
  "application/xml",
89
89
  File.basename(xml_path)) }
90
- JSON.parse(multipart({}).patch(ROUTE + id, payload)&.body)
90
+ AtlasRb::Mash.new(JSON.parse(multipart({}).patch(ROUTE + id, payload)&.body))
91
91
  end
92
92
 
93
93
  # Patch individual metadata fields without uploading a full MODS document.
@@ -100,7 +100,7 @@ module AtlasRb
100
100
  # @example
101
101
  # AtlasRb::Community.metadata("c-123", title: "New Name")
102
102
  def self.metadata(id, values)
103
- JSON.parse(connection({ metadata: values }).patch(ROUTE + id)&.body)
103
+ AtlasRb::Mash.new(JSON.parse(connection({ metadata: values }).patch(ROUTE + id)&.body))
104
104
  end
105
105
 
106
106
  # Fetch the Community's MODS representation in the requested format.
@@ -22,7 +22,7 @@ module AtlasRb
22
22
  # @example
23
23
  # AtlasRb::FileSet.find("fs-001")
24
24
  def self.find(id)
25
- JSON.parse(connection({}).get(ROUTE + id)&.body)["file_set"]
25
+ AtlasRb::Mash.new(JSON.parse(connection({}).get(ROUTE + id)&.body))["file_set"]
26
26
  end
27
27
 
28
28
  # Create a new FileSet under a Work.
@@ -38,7 +38,7 @@ module AtlasRb
38
38
  # fs = AtlasRb::FileSet.create("w-789", "primary")
39
39
  # AtlasRb::FileSet.update(fs["id"], "/tmp/article.pdf")
40
40
  def self.create(id, classification)
41
- JSON.parse(connection({ work_id: id, classification: classification }).post(ROUTE)&.body)["file_set"]
41
+ AtlasRb::Mash.new(JSON.parse(connection({ work_id: id, classification: classification }).post(ROUTE)&.body))["file_set"]
42
42
  end
43
43
 
44
44
  # Delete a FileSet.
@@ -70,7 +70,7 @@ module AtlasRb
70
70
  payload = { binary: Faraday::Multipart::FilePart.new(File.open(blob_path),
71
71
  "application/octet-stream",
72
72
  File.basename(blob_path)) }
73
- JSON.parse(multipart({}).patch(ROUTE + id, payload)&.body)
73
+ AtlasRb::Mash.new(JSON.parse(multipart({}).patch(ROUTE + id, payload)&.body))
74
74
  end
75
75
  end
76
76
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hashie"
4
+
5
+ module AtlasRb
6
+ # Shared `Hashie::Mash` subclass used to wrap parsed JSON responses so
7
+ # callers can use dot access (`work.id`) alongside string-keyed access
8
+ # (`work["id"]`).
9
+ #
10
+ # `disable_warnings` silences Hashie's stderr noise when an Atlas
11
+ # response key collides with an existing `Hash` method (e.g. `class`,
12
+ # `type`, `id`).
13
+ class Mash < Hashie::Mash
14
+ disable_warnings
15
+ end
16
+ end
@@ -35,8 +35,8 @@ module AtlasRb
35
35
  # # => { "klass" => "Work", "resource" => { "id" => "abc123", "title" => "..." } }
36
36
  def self.find(id)
37
37
  result = JSON.parse(connection({}).get('/resources/' + id)&.body)
38
- { "klass" => result.first[0].capitalize,
39
- "resource" => result.first[1] }
38
+ AtlasRb::Mash.new("klass" => result.first[0].capitalize,
39
+ "resource" => result.first[1])
40
40
  end
41
41
 
42
42
  # Validate a MODS XML document against Atlas's schema *without* persisting it.
@@ -66,7 +66,7 @@ module AtlasRb
66
66
  # AtlasRb::Resource.permissions("abc123")
67
67
  # # => { "id" => "abc123", "read" => [...], "write" => [...] }
68
68
  def self.permissions(id)
69
- result = JSON.parse(connection({}).get('/resources/' + id + '/permissions')&.body)["resource"]
69
+ AtlasRb::Mash.new(JSON.parse(connection({}).get('/resources/' + id + '/permissions')&.body))["resource"]
70
70
  end
71
71
  end
72
72
  end
data/lib/atlas_rb/work.rb CHANGED
@@ -23,7 +23,7 @@ module AtlasRb
23
23
  # AtlasRb::Work.find("w-789")
24
24
  # # => { "id" => "w-789", "title" => "An Article", ... }
25
25
  def self.find(id)
26
- JSON.parse(connection({}).get(ROUTE + id)&.body)["work"]
26
+ AtlasRb::Mash.new(JSON.parse(connection({}).get(ROUTE + id)&.body))["work"]
27
27
  end
28
28
 
29
29
  # Create a new Work in an existing Collection.
@@ -45,7 +45,7 @@ module AtlasRb
45
45
  # @example Work seeded from MODS
46
46
  # AtlasRb::Work.create("col-456", "/tmp/work-mods.xml")
47
47
  def self.create(id, xml_path = nil)
48
- result = JSON.parse(connection({ collection_id: id }).post(ROUTE)&.body)["work"]
48
+ result = AtlasRb::Mash.new(JSON.parse(connection({ collection_id: id }).post(ROUTE)&.body))["work"]
49
49
  return result unless xml_path.present?
50
50
 
51
51
  update(result["id"], xml_path)
@@ -75,7 +75,7 @@ module AtlasRb
75
75
  payload = { binary: Faraday::Multipart::FilePart.new(File.open(xml_path),
76
76
  "application/xml",
77
77
  File.basename(xml_path)) }
78
- JSON.parse(multipart({}).patch(ROUTE + id, payload)&.body)
78
+ AtlasRb::Mash.new(JSON.parse(multipart({}).patch(ROUTE + id, payload)&.body))
79
79
  end
80
80
 
81
81
  # Patch individual metadata fields without uploading a full MODS document.
@@ -87,7 +87,7 @@ module AtlasRb
87
87
  # @example
88
88
  # AtlasRb::Work.metadata("w-789", title: "Revised Title")
89
89
  def self.metadata(id, values)
90
- JSON.parse(connection({ metadata: values }).patch(ROUTE + id)&.body)
90
+ AtlasRb::Mash.new(JSON.parse(connection({ metadata: values }).patch(ROUTE + id)&.body))
91
91
  end
92
92
 
93
93
  # List the {FileSet}s and {Blob}s attached to a Work.
@@ -101,7 +101,7 @@ module AtlasRb
101
101
  # @example
102
102
  # AtlasRb::Work.files("w-789")
103
103
  def self.files(id)
104
- JSON.parse(connection({}).get(ROUTE + id + '/files')&.body)
104
+ AtlasRb::Mash.new(JSON.parse(connection({}).get(ROUTE + id + '/files')&.body))
105
105
  end
106
106
 
107
107
  # Fetch the Work's MODS representation in the requested format.
data/lib/atlas_rb.rb CHANGED
@@ -5,6 +5,7 @@ require "faraday/multipart"
5
5
  require "faraday/follow_redirects"
6
6
  require_relative "atlas_rb/version"
7
7
  require_relative "atlas_rb/faraday_helper"
8
+ require_relative "atlas_rb/mash"
8
9
  require_relative "atlas_rb/authentication"
9
10
  require_relative "atlas_rb/resource"
10
11
  require_relative "atlas_rb/community"
@@ -14,7 +15,7 @@ require_relative "atlas_rb/file_set"
14
15
  require_relative "atlas_rb/blob"
15
16
 
16
17
  # Ruby client for the Atlas API — Northeastern University's institutional
17
- # digital repository (the successor to Cerberus).
18
+ # digital repository.
18
19
  #
19
20
  # ## Configuration
20
21
  #
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: 0.0.83
4
+ version: 0.0.85
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-04-26 00:00:00.000000000 Z
11
+ date: 2026-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: hashie
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rspec
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -106,6 +120,7 @@ files:
106
120
  - lib/atlas_rb/community.rb
107
121
  - lib/atlas_rb/faraday_helper.rb
108
122
  - lib/atlas_rb/file_set.rb
123
+ - lib/atlas_rb/mash.rb
109
124
  - lib/atlas_rb/resource.rb
110
125
  - lib/atlas_rb/version.rb
111
126
  - lib/atlas_rb/work.rb