archivesspace-client 0.4.2 → 0.5.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 +4 -4
- data/.github/workflows/ci.yml +6 -1
- data/.ruby-version +1 -1
- data/README.md +49 -22
- data/archivesspace-client.gemspec +5 -6
- data/examples/export.rb +11 -10
- data/examples/repo_and_user.rb +0 -1
- data/examples/test_connection.rb +13 -2
- data/examples/update_feed.rb +39 -0
- data/examples/user_groups.rb +4 -4
- data/lib/archivesspace/client/client.rb +22 -12
- data/lib/archivesspace/client/configuration.rb +16 -18
- data/lib/archivesspace/client/pagination.rb +1 -0
- data/lib/archivesspace/client/request.rb +10 -22
- data/lib/archivesspace/client/task.rb +14 -10
- data/lib/archivesspace/client/template.rb +1 -1
- data/lib/archivesspace/client/version.rb +1 -1
- data/lib/archivesspace/client.rb +4 -7
- data/spec/archivesspace/client_spec.rb +133 -18
- data/spec/fixtures/cassettes/login_failure.yml +37 -0
- data/spec/spec_helper.rb +1 -1
- metadata +25 -37
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 324a811c6e310286a30371cda14266b61f11570373aa20baf61b1f54b8e3c8d3
|
|
4
|
+
data.tar.gz: 319354d94ec1fb765a8a811f2ff8273c21342f40fa8e3a5e3c122b4b9af85b92
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1ecd05a580e11e19fd50db9b0f0d4ede6ff816d36d8789d50420a1d1275bf9247c5172b932f3ad9627e96655ce27f919d35e6737816650541615cf5efea22c95
|
|
7
|
+
data.tar.gz: 679be0bac6c9a81b685ed233e457d98670e00f834946f57d7ed46091bfd83040c0ee12d0e196bddd00a9bfb88fefc8b0c06170dfd294652b4322b958bfdac4df
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -3,8 +3,12 @@ on: [pull_request]
|
|
|
3
3
|
|
|
4
4
|
jobs:
|
|
5
5
|
tests:
|
|
6
|
-
name: Tests
|
|
6
|
+
name: Tests (Ruby ${{ matrix.ruby }})
|
|
7
7
|
runs-on: ubuntu-latest
|
|
8
|
+
strategy:
|
|
9
|
+
fail-fast: false
|
|
10
|
+
matrix:
|
|
11
|
+
ruby: ["3.4", "4.0"]
|
|
8
12
|
steps:
|
|
9
13
|
- name: Checkout code
|
|
10
14
|
uses: actions/checkout@v4
|
|
@@ -12,6 +16,7 @@ jobs:
|
|
|
12
16
|
- name: Setup Ruby and install gems
|
|
13
17
|
uses: ruby/setup-ruby@v1
|
|
14
18
|
with:
|
|
19
|
+
ruby-version: ${{ matrix.ruby }}
|
|
15
20
|
bundler-cache: true
|
|
16
21
|
|
|
17
22
|
- name: Lint
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
4.0.1
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ArchivesSpace Client
|
|
2
2
|
|
|
3
3
|
Interact with ArchivesSpace via the API.
|
|
4
4
|
|
|
@@ -6,17 +6,18 @@ Interact with ArchivesSpace via the API.
|
|
|
6
6
|
|
|
7
7
|
* [Installation](#installation)
|
|
8
8
|
* [Usage](#usage)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
* [Configuring a client](#configuring-a-client)
|
|
10
|
+
* [Default configuration](#default-configuration)
|
|
11
|
+
* [Custom configuration, on the fly](#custom-configuration-on-the-fly)
|
|
12
|
+
* [Custom configuration, stored for use with CLI or console](#custom-configuration-stored-for-use-with-cli-or-console)
|
|
13
|
+
* [Making basic requests](#making-basic-requests)
|
|
14
|
+
* [Setting a repository context](#setting-a-repository-context)
|
|
15
15
|
* [Templates](#templates)
|
|
16
16
|
* [CLI](#cli)
|
|
17
17
|
* [Console usage](#console-usage)
|
|
18
18
|
* [Development](#development)
|
|
19
19
|
* [Publishing](#publishing)
|
|
20
|
+
* [Changelog](#changelog)
|
|
20
21
|
* [Contributing](#contributing)
|
|
21
22
|
* [License](#license)
|
|
22
23
|
|
|
@@ -56,7 +57,7 @@ Create client with default settings (`localhost:8089`, `admin`, `admin`):
|
|
|
56
57
|
client = ArchivesSpace::Client.new.login
|
|
57
58
|
```
|
|
58
59
|
|
|
59
|
-
#### Custom configuration
|
|
60
|
+
#### Custom configuration
|
|
60
61
|
|
|
61
62
|
```ruby
|
|
62
63
|
config = ArchivesSpace::Configuration.new({
|
|
@@ -72,13 +73,11 @@ config = ArchivesSpace::Configuration.new({
|
|
|
72
73
|
client = ArchivesSpace::Client.new(config).login
|
|
73
74
|
```
|
|
74
75
|
|
|
75
|
-
**NOTE:** `ArchivesSpace::Configuration` allows you to set a `base_repo` value as well, but if this value is set in your config at the start, calls to API endpoints that do not include a repository id in the URI may not work correctly. It is recommended you set/unset the client repository as needed during use via the `#repository` method as described below. If you must set `base_repo` in the config used to create your client, note that the value should be like: "repositories/2", and not just the integer repository id.
|
|
76
|
-
|
|
77
76
|
#### Custom configuration, stored for use with CLI or console
|
|
78
77
|
|
|
79
78
|
Create a file containing JSON config data like:
|
|
80
79
|
|
|
81
|
-
```
|
|
80
|
+
```json
|
|
82
81
|
{
|
|
83
82
|
"base_uri": "http://localhost:4567",
|
|
84
83
|
"username": "admin",
|
|
@@ -95,11 +94,10 @@ The CLI and console commands will, by default, look for this stored config at `~
|
|
|
95
94
|
|
|
96
95
|
However, you may also set a custom location for the file by setting an ASCLIENT_CFG environment variable. This is handy if you prefer to use [XDG Base Directory Specification](https://xdgbasedirectoryspecification.com/), or have other opinions about where such config should live:
|
|
97
96
|
|
|
98
|
-
```
|
|
97
|
+
```bash
|
|
99
98
|
export ASCLIENT_CFG="$HOME/.config/archivesspace/client.json"
|
|
100
99
|
```
|
|
101
100
|
|
|
102
|
-
|
|
103
101
|
### Making basic requests
|
|
104
102
|
|
|
105
103
|
The client responds to the standard request methods:
|
|
@@ -139,21 +137,33 @@ client.get('repositories/2/digital_objects', query: {page: 1})
|
|
|
139
137
|
You can do:
|
|
140
138
|
|
|
141
139
|
```ruby
|
|
142
|
-
client.repository(2)
|
|
143
|
-
client.get('digital_objects', query: {page: 1})
|
|
144
|
-
|
|
140
|
+
client.repository(2) do
|
|
141
|
+
client.get('digital_objects', query: {page: 1})
|
|
142
|
+
end
|
|
145
143
|
|
|
144
|
+
# now back in the global scope
|
|
145
|
+
```
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
Scopes restore the previous context on exit (even if the block raises) and can
|
|
148
|
+
be nested:
|
|
148
149
|
|
|
149
150
|
```ruby
|
|
150
|
-
client.repository(
|
|
151
|
+
client.repository(2) do
|
|
152
|
+
client.repository(3) do
|
|
153
|
+
client.resources # scoped to repo 3
|
|
154
|
+
end
|
|
155
|
+
client.resources # back to repo 2
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# now back in the global scope
|
|
151
159
|
```
|
|
152
160
|
|
|
153
|
-
|
|
161
|
+
You can also set the scope persistently (without a block) and clear it later:
|
|
154
162
|
|
|
155
163
|
```ruby
|
|
156
|
-
client.
|
|
164
|
+
client.repository(2)
|
|
165
|
+
client.resources
|
|
166
|
+
client.use_global_repository # or: client.repository(nil)
|
|
157
167
|
```
|
|
158
168
|
|
|
159
169
|
## Templates
|
|
@@ -221,7 +231,7 @@ cd path/to/archivesspace-client
|
|
|
221
231
|
|
|
222
232
|
An IRB session opens. Entering the following should give you the backend version of the ArchivesSpace instance your stored custom config points to:
|
|
223
233
|
|
|
224
|
-
```
|
|
234
|
+
```ruby
|
|
225
235
|
@client.backend_version
|
|
226
236
|
```
|
|
227
237
|
|
|
@@ -248,9 +258,26 @@ bundle exec rake
|
|
|
248
258
|
When an updated version (`lib/archivesspace/client/version.rb`) is merged into the
|
|
249
259
|
main/master branch a new release will be built and published.
|
|
250
260
|
|
|
261
|
+
## Changelog
|
|
262
|
+
|
|
263
|
+
### 0.5.0
|
|
264
|
+
|
|
265
|
+
Breaking changes:
|
|
266
|
+
|
|
267
|
+
* Removed the `base_repo` configuration option. Use `client.repository(id)` to
|
|
268
|
+
scope requests to a repository instead, either persistently or with a
|
|
269
|
+
block that auto-restores the previous scope.
|
|
270
|
+
* `client.repository(id)` with a block now saves and restores the previous
|
|
271
|
+
context (including when nested or when the block raises), instead of always
|
|
272
|
+
resetting to the global scope.
|
|
273
|
+
* Login failure now raises `ArchivesSpace::AuthenticationError` (was
|
|
274
|
+
`ConnectionError`). `ConnectionError` has been removed.
|
|
275
|
+
* `Client.new` raises `ArchivesSpace::ConfigurationError` (was `RuntimeError`)
|
|
276
|
+
when given a non-`Configuration` argument.
|
|
277
|
+
|
|
251
278
|
## Contributing
|
|
252
279
|
|
|
253
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/lyrasis/archivesspace-client
|
|
280
|
+
Bug reports and pull requests are welcome on GitHub at <https://github.com/lyrasis/archivesspace-client>.
|
|
254
281
|
|
|
255
282
|
## License
|
|
256
283
|
|
|
@@ -23,15 +23,14 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
spec.add_development_dependency "capybara_discoball", "~> 0.1.0"
|
|
24
24
|
spec.add_development_dependency "json_spec", "~> 1.1", ">= 1.1.5"
|
|
25
25
|
spec.add_development_dependency "rake", "~> 13.0"
|
|
26
|
-
spec.add_development_dependency "rspec", "3.
|
|
27
|
-
spec.add_development_dependency "rubocop", "1.
|
|
28
|
-
spec.add_development_dependency "standard", "1.
|
|
29
|
-
spec.add_development_dependency "vcr", "6.
|
|
30
|
-
spec.add_development_dependency "webmock", "3.
|
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.13"
|
|
27
|
+
spec.add_development_dependency "rubocop", "~> 1.72"
|
|
28
|
+
spec.add_development_dependency "standard", "~> 1.44"
|
|
29
|
+
spec.add_development_dependency "vcr", "~> 6.3"
|
|
30
|
+
spec.add_development_dependency "webmock", "~> 3.24"
|
|
31
31
|
|
|
32
32
|
spec.add_dependency "dry-cli", "~> 0.7"
|
|
33
33
|
spec.add_dependency "httparty", "~> 0.14"
|
|
34
34
|
spec.add_dependency "json", "~> 2.0"
|
|
35
|
-
spec.add_dependency "nokogiri", "~> 1.10"
|
|
36
35
|
spec.add_dependency "jbuilder", "~> 2.12"
|
|
37
36
|
end
|
data/examples/export.rb
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
|
4
4
|
require "archivesspace/client"
|
|
5
|
+
require "nokogiri"
|
|
5
6
|
|
|
6
7
|
# official sandbox
|
|
7
8
|
config = ArchivesSpace::Configuration.new(
|
|
8
9
|
{
|
|
9
10
|
base_uri: "https://test.archivesspace.org/staff/api",
|
|
10
|
-
base_repo: "",
|
|
11
11
|
username: "admin",
|
|
12
12
|
password: "admin",
|
|
13
13
|
page_size: 50,
|
|
@@ -18,17 +18,18 @@ config = ArchivesSpace::Configuration.new(
|
|
|
18
18
|
|
|
19
19
|
client = ArchivesSpace::Client.new(config).login
|
|
20
20
|
client.config.throttle = 0.5
|
|
21
|
-
client.config.base_repo = "repositories/2"
|
|
22
21
|
|
|
23
22
|
begin
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
client.repository 2 do
|
|
24
|
+
# date -d '2021-02-01 00:00:00' +'%s' # 1612166400
|
|
25
|
+
client.resources(query: {modified_since: "1612166400"}).each do |resource|
|
|
26
|
+
# for now we are just printing ...
|
|
27
|
+
# but you would actually write to a zip file or whatever
|
|
28
|
+
id = resource["uri"].split("/")[-1]
|
|
29
|
+
opts = {include_unpublished: false}
|
|
30
|
+
response = client.get("resource_descriptions/#{id}.xml", opts)
|
|
31
|
+
puts Nokogiri::XML(response.body).to_xml
|
|
32
|
+
end
|
|
32
33
|
end
|
|
33
34
|
rescue ArchivesSpace::RequestError => e
|
|
34
35
|
puts e.message
|
data/examples/repo_and_user.rb
CHANGED
data/examples/test_connection.rb
CHANGED
|
@@ -6,8 +6,7 @@ require "archivesspace/client"
|
|
|
6
6
|
# official sandbox
|
|
7
7
|
config = ArchivesSpace::Configuration.new(
|
|
8
8
|
{
|
|
9
|
-
base_uri: "https://
|
|
10
|
-
base_repo: "",
|
|
9
|
+
base_uri: "https://test.archivesspace.org/staff/api",
|
|
11
10
|
username: "admin",
|
|
12
11
|
password: "admin",
|
|
13
12
|
page_size: 50,
|
|
@@ -17,4 +16,16 @@ config = ArchivesSpace::Configuration.new(
|
|
|
17
16
|
)
|
|
18
17
|
|
|
19
18
|
client = ArchivesSpace::Client.new(config).login
|
|
19
|
+
|
|
20
|
+
# globally scoped
|
|
20
21
|
puts client.get("version").body
|
|
22
|
+
puts client.get("repositories").body
|
|
23
|
+
puts client.all("users").map { |u| u["username"] }.to_a
|
|
24
|
+
|
|
25
|
+
# repo scoped
|
|
26
|
+
client.repository 2 do
|
|
27
|
+
puts client.get("accessions", query: {page: 1}).parsed["results"].map { |a| a["uri"] }.to_a
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# globally scoped, full path arg
|
|
31
|
+
puts client.get("repositories/2/resources", query: {all_ids: true}).body
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
|
4
|
+
require "archivesspace/client"
|
|
5
|
+
|
|
6
|
+
config = ArchivesSpace::Configuration.new(
|
|
7
|
+
{
|
|
8
|
+
base_uri: "https://test.archivesspace.org/staff/api",
|
|
9
|
+
username: "admin",
|
|
10
|
+
password: "admin",
|
|
11
|
+
page_size: 50,
|
|
12
|
+
throttle: 0,
|
|
13
|
+
verify_ssl: false
|
|
14
|
+
}
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
client = ArchivesSpace::Client.new(config).login
|
|
18
|
+
response = client.get("update-feed")
|
|
19
|
+
last_sequence = response.parsed[0]["sequence"] # get initial sequence value
|
|
20
|
+
|
|
21
|
+
# This is an example only, would also need to handle session/token expiration
|
|
22
|
+
loop do
|
|
23
|
+
puts "Using sequence: #{last_sequence}"
|
|
24
|
+
begin
|
|
25
|
+
response = client.get("update-feed", query: {last_sequence: last_sequence})
|
|
26
|
+
if response.result.success?
|
|
27
|
+
last_sequence = response.parsed.last["sequence"]
|
|
28
|
+
# do something with the response
|
|
29
|
+
puts response.parsed.to_json
|
|
30
|
+
end
|
|
31
|
+
rescue Net::ReadTimeout
|
|
32
|
+
# this is ok if no updates are made within the last 60 seconds
|
|
33
|
+
# (well, as defined by the timeout in client/AppConfig)
|
|
34
|
+
rescue => e
|
|
35
|
+
# some other kind of error occurred
|
|
36
|
+
puts e.message
|
|
37
|
+
break # or handle it in some other way
|
|
38
|
+
end
|
|
39
|
+
end
|
data/examples/user_groups.rb
CHANGED
|
@@ -7,7 +7,6 @@ require "archivesspace/client"
|
|
|
7
7
|
config = ArchivesSpace::Configuration.new(
|
|
8
8
|
{
|
|
9
9
|
base_uri: "https://sandbox.archivesspace.org/staff/api",
|
|
10
|
-
base_repo: "",
|
|
11
10
|
username: "admin",
|
|
12
11
|
password: "admin",
|
|
13
12
|
page_size: 50,
|
|
@@ -31,9 +30,10 @@ users_with_roles = {
|
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
begin
|
|
34
|
-
client.
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
client.repository 2 do
|
|
34
|
+
results = client.group_user_assignment users_with_roles
|
|
35
|
+
puts results.map(&:parsed)
|
|
36
|
+
end
|
|
37
37
|
rescue ArchivesSpace::RequestError => e
|
|
38
38
|
puts e.message
|
|
39
39
|
end
|
|
@@ -4,15 +4,20 @@ module ArchivesSpace
|
|
|
4
4
|
class Client
|
|
5
5
|
include Pagination
|
|
6
6
|
include Task
|
|
7
|
+
|
|
7
8
|
attr_accessor :token
|
|
8
|
-
attr_reader :config
|
|
9
|
+
attr_reader :config, :context
|
|
9
10
|
|
|
10
11
|
NAME = "ArchivesSpaceClient"
|
|
12
|
+
TOKEN = "X-ArchivesSpace-Session"
|
|
11
13
|
|
|
12
14
|
def initialize(config = Configuration.new)
|
|
13
|
-
|
|
15
|
+
unless config.is_a? ArchivesSpace::Configuration
|
|
16
|
+
raise ConfigurationError, "expected ArchivesSpace::Configuration, got #{config.class}"
|
|
17
|
+
end
|
|
14
18
|
|
|
15
19
|
@config = config
|
|
20
|
+
@context = nil
|
|
16
21
|
@token = nil
|
|
17
22
|
end
|
|
18
23
|
|
|
@@ -38,31 +43,36 @@ module ArchivesSpace
|
|
|
38
43
|
|
|
39
44
|
# Scoping requests
|
|
40
45
|
def repository(id)
|
|
41
|
-
if id.nil?
|
|
42
|
-
use_global_repository
|
|
43
|
-
return
|
|
44
|
-
end
|
|
46
|
+
return use_global_repository if id.nil?
|
|
45
47
|
|
|
46
48
|
begin
|
|
47
49
|
Integer(id)
|
|
48
|
-
rescue
|
|
50
|
+
rescue ArgumentError, TypeError
|
|
49
51
|
raise RepositoryIdError, "Invalid Repository id: #{id}"
|
|
50
52
|
end
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
new_context = "repositories/#{id}"
|
|
55
|
+
return @context = new_context unless block_given?
|
|
56
|
+
|
|
57
|
+
previous = @context
|
|
58
|
+
@context = new_context
|
|
59
|
+
begin
|
|
60
|
+
yield
|
|
61
|
+
ensure
|
|
62
|
+
@context = previous
|
|
63
|
+
end
|
|
53
64
|
end
|
|
54
65
|
|
|
55
66
|
def use_global_repository
|
|
56
|
-
@
|
|
67
|
+
@context = nil
|
|
57
68
|
end
|
|
58
69
|
|
|
59
70
|
private
|
|
60
71
|
|
|
61
72
|
def request(method, path, options = {})
|
|
62
73
|
sleep config.throttle
|
|
63
|
-
options[:headers] = {
|
|
64
|
-
|
|
65
|
-
Response.new result
|
|
74
|
+
options[:headers] = {TOKEN => token} if token
|
|
75
|
+
Request.new(context, config, method, path, options).execute
|
|
66
76
|
end
|
|
67
77
|
end
|
|
68
78
|
end
|
|
@@ -2,27 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
module ArchivesSpace
|
|
4
4
|
class Configuration
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
5
|
+
attr_accessor :base_uri, :debug, :username, :password,
|
|
6
|
+
:page_size, :throttle, :timeout, :verify_ssl
|
|
7
|
+
|
|
8
|
+
DEFAULTS = {
|
|
9
|
+
base_uri: "http://localhost:8089",
|
|
10
|
+
debug: false,
|
|
11
|
+
username: "admin",
|
|
12
|
+
password: "admin",
|
|
13
|
+
page_size: 50,
|
|
14
|
+
throttle: 0,
|
|
15
|
+
timeout: 60,
|
|
16
|
+
verify_ssl: true
|
|
17
|
+
}.freeze
|
|
18
18
|
|
|
19
19
|
def initialize(settings = {})
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
next unless defaults.key?(property)
|
|
20
|
+
DEFAULTS.merge(settings).each do |property, value|
|
|
21
|
+
next unless DEFAULTS.key?(property)
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
self.class.send(:attr_accessor, property)
|
|
23
|
+
send(:"#{property}=", value)
|
|
26
24
|
end
|
|
27
25
|
end
|
|
28
26
|
end
|
|
@@ -3,44 +3,32 @@
|
|
|
3
3
|
module ArchivesSpace
|
|
4
4
|
class Request
|
|
5
5
|
include HTTParty
|
|
6
|
+
|
|
6
7
|
attr_reader :config, :headers, :method, :path, :options
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
headers = {
|
|
10
|
-
delete: {},
|
|
11
|
-
get: {},
|
|
12
|
-
post: {
|
|
13
|
-
"Content-Type" => "application/json",
|
|
14
|
-
"Content-Length" => "nnnn"
|
|
15
|
-
},
|
|
16
|
-
put: {
|
|
17
|
-
"Content-Type" => "application/json",
|
|
18
|
-
"Content-Length" => "nnnn"
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
headers[method]
|
|
22
|
-
end
|
|
9
|
+
DEFAULT_HEADERS = {"Content-Type" => "application/json"}.freeze
|
|
23
10
|
|
|
24
|
-
def initialize(config, method = "GET", path = "", options = {})
|
|
11
|
+
def initialize(context, config, method = "GET", path = "", options = {})
|
|
25
12
|
@config = config
|
|
13
|
+
|
|
26
14
|
@method = method.downcase.to_sym
|
|
27
15
|
@path = path.gsub(%r{^/+}, "")
|
|
16
|
+
|
|
28
17
|
@options = options
|
|
29
|
-
|
|
30
|
-
|
|
18
|
+
|
|
19
|
+
@options[:headers] = DEFAULT_HEADERS.merge(@options.fetch(:headers, {}))
|
|
31
20
|
@options[:headers]["User-Agent"] = "#{Client::NAME}/#{Client::VERSION}"
|
|
21
|
+
|
|
32
22
|
@options[:verify] = config.verify_ssl
|
|
33
23
|
@options[:timeout] = config.timeout
|
|
34
24
|
@options[:query] = {} unless options.key? :query
|
|
35
25
|
|
|
36
26
|
self.class.debug_output($stdout) if @config.debug
|
|
37
|
-
|
|
38
|
-
base_uri = config.base_repo&.length&.positive? ? File.join(config.base_uri, config.base_repo) : config.base_uri
|
|
39
|
-
self.class.base_uri base_uri
|
|
27
|
+
self.class.base_uri context ? "#{config.base_uri}/#{context}" : config.base_uri
|
|
40
28
|
end
|
|
41
29
|
|
|
42
30
|
def execute
|
|
43
|
-
self.class.send
|
|
31
|
+
Response.new(self.class.send(method, "/#{path}", options))
|
|
44
32
|
end
|
|
45
33
|
end
|
|
46
34
|
end
|
|
@@ -34,21 +34,25 @@ module ArchivesSpace
|
|
|
34
34
|
def login
|
|
35
35
|
username = config.username
|
|
36
36
|
password = config.password
|
|
37
|
-
base_repo = config.base_repo
|
|
38
|
-
use_global_repository # ensure we're in the global scope to login
|
|
39
|
-
result = request("POST", "/users/#{username}/login", {query: {password: password}})
|
|
40
|
-
unless result.parsed["session"]
|
|
41
|
-
raise ConnectionError, "API client login failed as user [#{username}], check username and password are correct"
|
|
42
|
-
end
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
@
|
|
46
|
-
|
|
38
|
+
previous_context = @context
|
|
39
|
+
@context = nil
|
|
40
|
+
begin
|
|
41
|
+
result = request("POST", "/users/#{username}/login", {query: {password: password}})
|
|
42
|
+
unless result.parsed["session"]
|
|
43
|
+
raise AuthenticationError, "Login failed as user [#{username}] (status #{result.status_code}); check username and password"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
@token = result.parsed["session"]
|
|
47
|
+
self
|
|
48
|
+
ensure
|
|
49
|
+
@context = previous_context
|
|
50
|
+
end
|
|
47
51
|
end
|
|
48
52
|
|
|
49
53
|
def password_reset(username, password)
|
|
50
54
|
user = all("users").find { |u| u["username"] == username }
|
|
51
|
-
raise RequestError,
|
|
55
|
+
raise RequestError, "User not found: #{username}" unless user
|
|
52
56
|
|
|
53
57
|
post(user["uri"], user, {password: password})
|
|
54
58
|
end
|
|
@@ -7,7 +7,7 @@ module ArchivesSpace
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def self.process(template, data)
|
|
10
|
-
processor = File.extname(template).delete(".").
|
|
10
|
+
processor = File.extname(template).delete(".").capitalize
|
|
11
11
|
processor = Object.const_get("ArchivesSpace::Template::#{processor}")
|
|
12
12
|
processor.new(template, data).process
|
|
13
13
|
end
|
data/lib/archivesspace/client.rb
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
require "dry/cli"
|
|
4
4
|
require "httparty"
|
|
5
5
|
require "json"
|
|
6
|
-
require "nokogiri"
|
|
7
6
|
require "jbuilder"
|
|
8
7
|
|
|
9
8
|
# mixins required first
|
|
@@ -23,13 +22,11 @@ require "archivesspace/client/cli/version"
|
|
|
23
22
|
require "archivesspace/client/cli" # load the registry last
|
|
24
23
|
|
|
25
24
|
module ArchivesSpace
|
|
26
|
-
class
|
|
25
|
+
class AuthenticationError < StandardError; end
|
|
27
26
|
|
|
28
|
-
class
|
|
27
|
+
class ConfigurationError < StandardError; end
|
|
29
28
|
|
|
30
|
-
class RepositoryIdError <
|
|
29
|
+
class RepositoryIdError < StandardError; end
|
|
31
30
|
|
|
32
|
-
class
|
|
33
|
-
|
|
34
|
-
class RequestError < RuntimeError; end
|
|
31
|
+
class RequestError < StandardError; end
|
|
35
32
|
end
|
|
@@ -11,7 +11,7 @@ describe ArchivesSpace::Client do
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
it "will raise an error if supplied configuration is of invalid type" do
|
|
14
|
-
expect { ArchivesSpace::Client.new({base_uri: CUSTOM_BASE_URI}) }.to raise_error(
|
|
14
|
+
expect { ArchivesSpace::Client.new({base_uri: CUSTOM_BASE_URI}) }.to raise_error(ArchivesSpace::ConfigurationError)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
it "will allow a configuration object to be provided" do
|
|
@@ -20,15 +20,86 @@ describe ArchivesSpace::Client do
|
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
describe "Login" do
|
|
24
|
+
it "sends the login request at global scope even when a repo context is set" do
|
|
25
|
+
client.repository 2
|
|
26
|
+
expect(ArchivesSpace::Request).to receive(:new)
|
|
27
|
+
.with(nil, client.config, "POST", "/users/admin/login", anything)
|
|
28
|
+
.and_wrap_original do |_orig, *_args|
|
|
29
|
+
double("request", execute: double("response", parsed: {"session" => "token"}, status_code: 200))
|
|
30
|
+
end
|
|
31
|
+
client.login
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "restores the previous repo context after login" do
|
|
35
|
+
client.repository 2
|
|
36
|
+
allow(ArchivesSpace::Request).to receive(:new).and_return(
|
|
37
|
+
double("request", execute: double("response", parsed: {"session" => "token"}, status_code: 200))
|
|
38
|
+
)
|
|
39
|
+
client.login
|
|
40
|
+
expect(client.context).to eq "repositories/2"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "raises AuthenticationError and restores context when credentials are rejected" do
|
|
44
|
+
client.repository 2
|
|
45
|
+
allow(ArchivesSpace::Request).to receive(:new).and_return(
|
|
46
|
+
double("request", execute: double("response", parsed: {}, status_code: 403))
|
|
47
|
+
)
|
|
48
|
+
expect { client.login }.to raise_error(ArchivesSpace::AuthenticationError, /status 403/)
|
|
49
|
+
expect(client.context).to eq "repositories/2"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "raises AuthenticationError for a real 403 response (VCR)" do
|
|
53
|
+
bad_client = ArchivesSpace::Client.new(
|
|
54
|
+
ArchivesSpace::Configuration.new(password: "wrong")
|
|
55
|
+
)
|
|
56
|
+
VCR.use_cassette("login_failure") do
|
|
57
|
+
expect { bad_client.login }.to raise_error(
|
|
58
|
+
ArchivesSpace::AuthenticationError, /admin.*status 403/
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "Pagination" do
|
|
65
|
+
it "will have a method for defined paginated record types" do
|
|
66
|
+
ArchivesSpace::Pagination::ENDPOINTS.each do |e|
|
|
67
|
+
next if e.match?("/")
|
|
68
|
+
|
|
69
|
+
expect(client.respond_to?(e.to_sym)).to be true
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "will have a method for defined paginated record types with multipart path" do
|
|
74
|
+
expect(client.respond_to?(:people)).to be true
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "will pass page_size from configuration to the query" do
|
|
78
|
+
response = double("response", parsed: {"results" => []})
|
|
79
|
+
allow(client).to receive(:get).and_return(response)
|
|
80
|
+
client.all("resources").first
|
|
81
|
+
expect(client).to have_received(:get).with("resources", hash_including(query: hash_including(page_size: 50)))
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe "Password reset" do
|
|
86
|
+
it "will raise an error if the user is not found" do
|
|
87
|
+
allow(client).to receive(:all).with("users").and_return([].lazy)
|
|
88
|
+
expect { client.password_reset("nonexistent", "newpass") }.to raise_error(
|
|
89
|
+
ArchivesSpace::RequestError, "User not found: nonexistent"
|
|
90
|
+
)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
23
94
|
describe "Repository scoping" do
|
|
24
|
-
it "will set the
|
|
95
|
+
it "will set the context with an integer id" do
|
|
25
96
|
client.repository 2
|
|
26
|
-
expect(client.
|
|
97
|
+
expect(client.context).to eq "repositories/2"
|
|
27
98
|
end
|
|
28
99
|
|
|
29
|
-
it "will set the
|
|
100
|
+
it "will set the context with a string id cast to integer" do
|
|
30
101
|
client.repository "2"
|
|
31
|
-
expect(client.
|
|
102
|
+
expect(client.context).to eq "repositories/2"
|
|
32
103
|
end
|
|
33
104
|
|
|
34
105
|
it "will fail if the id cannot be cast to integer" do
|
|
@@ -37,37 +108,81 @@ describe ArchivesSpace::Client do
|
|
|
37
108
|
)
|
|
38
109
|
end
|
|
39
110
|
|
|
40
|
-
it "will
|
|
111
|
+
it "will fail if the id is not a valid type" do
|
|
112
|
+
expect { client.repository([]) }.to raise_error(
|
|
113
|
+
ArchivesSpace::RepositoryIdError
|
|
114
|
+
)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "will clear the context when passed nil" do
|
|
41
118
|
client.repository 2
|
|
42
119
|
client.repository nil
|
|
43
|
-
expect(client.
|
|
120
|
+
expect(client.context).to be_nil
|
|
44
121
|
end
|
|
45
122
|
|
|
46
|
-
it "will
|
|
123
|
+
it "will clear the context when use_global_repository is called" do
|
|
47
124
|
client.repository 2
|
|
48
125
|
client.use_global_repository
|
|
49
|
-
expect(client.
|
|
126
|
+
expect(client.context).to be_nil
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "scopes the context to a block and restores afterwards" do
|
|
130
|
+
client.repository(2) do
|
|
131
|
+
expect(client.context).to eq "repositories/2"
|
|
132
|
+
end
|
|
133
|
+
expect(client.context).to be_nil
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "restores the previous context when nested" do
|
|
137
|
+
client.repository 2
|
|
138
|
+
client.repository(3) do
|
|
139
|
+
expect(client.context).to eq "repositories/3"
|
|
140
|
+
end
|
|
141
|
+
expect(client.context).to eq "repositories/2"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "restores the context even if the block raises" do
|
|
145
|
+
expect { client.repository(2) { raise "boom" } }.to raise_error("boom")
|
|
146
|
+
expect(client.context).to be_nil
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "does not rebrand ArgumentError raised from within the block" do
|
|
150
|
+
expect {
|
|
151
|
+
client.repository(2) { raise ArgumentError, "from caller" }
|
|
152
|
+
}.to raise_error(ArgumentError, "from caller")
|
|
50
153
|
end
|
|
51
154
|
end
|
|
52
155
|
|
|
53
156
|
describe "Requests" do
|
|
54
157
|
it "will have an identifiable user agent" do
|
|
55
|
-
request = ArchivesSpace::Request.new(client.config)
|
|
158
|
+
request = ArchivesSpace::Request.new(nil, client.config)
|
|
56
159
|
expect(request.options[:headers]["User-Agent"]).to eq "#{ArchivesSpace::Client::NAME}/#{ArchivesSpace::Client::VERSION}"
|
|
57
160
|
end
|
|
58
161
|
end
|
|
59
162
|
|
|
60
|
-
describe "
|
|
61
|
-
|
|
62
|
-
ArchivesSpace::Pagination::ENDPOINTS.each do |e|
|
|
63
|
-
next if e.match?("/")
|
|
163
|
+
describe "URL construction" do
|
|
164
|
+
let(:config) { ArchivesSpace::Configuration.new(base_uri: "http://localhost:8089") }
|
|
64
165
|
|
|
65
|
-
|
|
66
|
-
|
|
166
|
+
it "uses the bare base_uri when context is nil" do
|
|
167
|
+
ArchivesSpace::Request.new(nil, config, "GET", "repositories")
|
|
168
|
+
expect(ArchivesSpace::Request.base_uri).to eq "http://localhost:8089"
|
|
67
169
|
end
|
|
68
170
|
|
|
69
|
-
it "
|
|
70
|
-
|
|
171
|
+
it "appends a repository context to the base_uri" do
|
|
172
|
+
ArchivesSpace::Request.new("repositories/2", config, "GET", "resources")
|
|
173
|
+
expect(ArchivesSpace::Request.base_uri).to eq "http://localhost:8089/repositories/2"
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "preserves a path prefix in base_uri when context is nil" do
|
|
177
|
+
config.base_uri = "https://example.org/staff/api"
|
|
178
|
+
ArchivesSpace::Request.new(nil, config, "GET", "repositories")
|
|
179
|
+
expect(ArchivesSpace::Request.base_uri).to eq "https://example.org/staff/api"
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "preserves a path prefix in base_uri when scoped to a repository" do
|
|
183
|
+
config.base_uri = "https://example.org/staff/api"
|
|
184
|
+
ArchivesSpace::Request.new("repositories/2", config, "GET", "resources")
|
|
185
|
+
expect(ArchivesSpace::Request.base_uri).to eq "https://example.org/staff/api/repositories/2"
|
|
71
186
|
end
|
|
72
187
|
end
|
|
73
188
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
http_interactions:
|
|
3
|
+
- request:
|
|
4
|
+
method: post
|
|
5
|
+
uri: http://localhost:8089/users/admin/login?password=wrong
|
|
6
|
+
body:
|
|
7
|
+
encoding: UTF-8
|
|
8
|
+
string: ''
|
|
9
|
+
headers:
|
|
10
|
+
Content-Type:
|
|
11
|
+
- application/json
|
|
12
|
+
User-Agent:
|
|
13
|
+
- ArchivesSpaceClient/0.3.0
|
|
14
|
+
Accept-Encoding:
|
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
|
16
|
+
Accept:
|
|
17
|
+
- "*/*"
|
|
18
|
+
response:
|
|
19
|
+
status:
|
|
20
|
+
code: 403
|
|
21
|
+
message: Forbidden
|
|
22
|
+
headers:
|
|
23
|
+
Cache-Control:
|
|
24
|
+
- private, must-revalidate, max-age=0
|
|
25
|
+
Content-Type:
|
|
26
|
+
- application/json
|
|
27
|
+
X-Content-Type-Options:
|
|
28
|
+
- nosniff
|
|
29
|
+
Content-Length:
|
|
30
|
+
- '24'
|
|
31
|
+
Server:
|
|
32
|
+
- Jetty(9.4.44.v20210927)
|
|
33
|
+
body:
|
|
34
|
+
encoding: UTF-8
|
|
35
|
+
string: '{"error":"Login failed"}'
|
|
36
|
+
recorded_at: Tue, 22 Apr 2026 12:00:00 GMT
|
|
37
|
+
recorded_with: VCR 6.3.1
|
data/spec/spec_helper.rb
CHANGED
|
@@ -6,8 +6,8 @@ require "vcr"
|
|
|
6
6
|
require "webmock/rspec"
|
|
7
7
|
|
|
8
8
|
# GLOBAL VALUES FOR SPECS
|
|
9
|
-
DEFAULT_BASE_URI = "http://localhost:8089"
|
|
10
9
|
CUSTOM_BASE_URI = "https://archives.university.edu/api"
|
|
10
|
+
DEFAULT_BASE_URI = "http://localhost:8089"
|
|
11
11
|
|
|
12
12
|
VCR.configure do |c|
|
|
13
13
|
c.cassette_library_dir = "spec/fixtures/cassettes"
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: archivesspace-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mark Cooper
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: aruba
|
|
@@ -75,72 +75,72 @@ dependencies:
|
|
|
75
75
|
name: rspec
|
|
76
76
|
requirement: !ruby/object:Gem::Requirement
|
|
77
77
|
requirements:
|
|
78
|
-
- -
|
|
78
|
+
- - "~>"
|
|
79
79
|
- !ruby/object:Gem::Version
|
|
80
|
-
version: 3.
|
|
80
|
+
version: '3.13'
|
|
81
81
|
type: :development
|
|
82
82
|
prerelease: false
|
|
83
83
|
version_requirements: !ruby/object:Gem::Requirement
|
|
84
84
|
requirements:
|
|
85
|
-
- -
|
|
85
|
+
- - "~>"
|
|
86
86
|
- !ruby/object:Gem::Version
|
|
87
|
-
version: 3.
|
|
87
|
+
version: '3.13'
|
|
88
88
|
- !ruby/object:Gem::Dependency
|
|
89
89
|
name: rubocop
|
|
90
90
|
requirement: !ruby/object:Gem::Requirement
|
|
91
91
|
requirements:
|
|
92
|
-
- -
|
|
92
|
+
- - "~>"
|
|
93
93
|
- !ruby/object:Gem::Version
|
|
94
|
-
version: '1.
|
|
94
|
+
version: '1.72'
|
|
95
95
|
type: :development
|
|
96
96
|
prerelease: false
|
|
97
97
|
version_requirements: !ruby/object:Gem::Requirement
|
|
98
98
|
requirements:
|
|
99
|
-
- -
|
|
99
|
+
- - "~>"
|
|
100
100
|
- !ruby/object:Gem::Version
|
|
101
|
-
version: '1.
|
|
101
|
+
version: '1.72'
|
|
102
102
|
- !ruby/object:Gem::Dependency
|
|
103
103
|
name: standard
|
|
104
104
|
requirement: !ruby/object:Gem::Requirement
|
|
105
105
|
requirements:
|
|
106
|
-
- -
|
|
106
|
+
- - "~>"
|
|
107
107
|
- !ruby/object:Gem::Version
|
|
108
|
-
version: 1.
|
|
108
|
+
version: '1.44'
|
|
109
109
|
type: :development
|
|
110
110
|
prerelease: false
|
|
111
111
|
version_requirements: !ruby/object:Gem::Requirement
|
|
112
112
|
requirements:
|
|
113
|
-
- -
|
|
113
|
+
- - "~>"
|
|
114
114
|
- !ruby/object:Gem::Version
|
|
115
|
-
version: 1.
|
|
115
|
+
version: '1.44'
|
|
116
116
|
- !ruby/object:Gem::Dependency
|
|
117
117
|
name: vcr
|
|
118
118
|
requirement: !ruby/object:Gem::Requirement
|
|
119
119
|
requirements:
|
|
120
|
-
- -
|
|
120
|
+
- - "~>"
|
|
121
121
|
- !ruby/object:Gem::Version
|
|
122
|
-
version: 6.
|
|
122
|
+
version: '6.3'
|
|
123
123
|
type: :development
|
|
124
124
|
prerelease: false
|
|
125
125
|
version_requirements: !ruby/object:Gem::Requirement
|
|
126
126
|
requirements:
|
|
127
|
-
- -
|
|
127
|
+
- - "~>"
|
|
128
128
|
- !ruby/object:Gem::Version
|
|
129
|
-
version: 6.
|
|
129
|
+
version: '6.3'
|
|
130
130
|
- !ruby/object:Gem::Dependency
|
|
131
131
|
name: webmock
|
|
132
132
|
requirement: !ruby/object:Gem::Requirement
|
|
133
133
|
requirements:
|
|
134
|
-
- -
|
|
134
|
+
- - "~>"
|
|
135
135
|
- !ruby/object:Gem::Version
|
|
136
|
-
version: 3.
|
|
136
|
+
version: '3.24'
|
|
137
137
|
type: :development
|
|
138
138
|
prerelease: false
|
|
139
139
|
version_requirements: !ruby/object:Gem::Requirement
|
|
140
140
|
requirements:
|
|
141
|
-
- -
|
|
141
|
+
- - "~>"
|
|
142
142
|
- !ruby/object:Gem::Version
|
|
143
|
-
version: 3.
|
|
143
|
+
version: '3.24'
|
|
144
144
|
- !ruby/object:Gem::Dependency
|
|
145
145
|
name: dry-cli
|
|
146
146
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -183,20 +183,6 @@ dependencies:
|
|
|
183
183
|
- - "~>"
|
|
184
184
|
- !ruby/object:Gem::Version
|
|
185
185
|
version: '2.0'
|
|
186
|
-
- !ruby/object:Gem::Dependency
|
|
187
|
-
name: nokogiri
|
|
188
|
-
requirement: !ruby/object:Gem::Requirement
|
|
189
|
-
requirements:
|
|
190
|
-
- - "~>"
|
|
191
|
-
- !ruby/object:Gem::Version
|
|
192
|
-
version: '1.10'
|
|
193
|
-
type: :runtime
|
|
194
|
-
prerelease: false
|
|
195
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
196
|
-
requirements:
|
|
197
|
-
- - "~>"
|
|
198
|
-
- !ruby/object:Gem::Version
|
|
199
|
-
version: '1.10'
|
|
200
186
|
- !ruby/object:Gem::Dependency
|
|
201
187
|
name: jbuilder
|
|
202
188
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -236,6 +222,7 @@ files:
|
|
|
236
222
|
- examples/repo_and_user.rb
|
|
237
223
|
- examples/templates.rb
|
|
238
224
|
- examples/test_connection.rb
|
|
225
|
+
- examples/update_feed.rb
|
|
239
226
|
- examples/user_groups.rb
|
|
240
227
|
- exe/asclient
|
|
241
228
|
- features/exec.feature
|
|
@@ -262,6 +249,7 @@ files:
|
|
|
262
249
|
- spec/archivesspace/configuration_spec.rb
|
|
263
250
|
- spec/archivesspace/templates_spec.rb
|
|
264
251
|
- spec/fixtures/cassettes/backend_version.yml
|
|
252
|
+
- spec/fixtures/cassettes/login_failure.yml
|
|
265
253
|
- spec/spec_helper.rb
|
|
266
254
|
homepage: ''
|
|
267
255
|
licenses:
|
|
@@ -281,7 +269,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
281
269
|
- !ruby/object:Gem::Version
|
|
282
270
|
version: '0'
|
|
283
271
|
requirements: []
|
|
284
|
-
rubygems_version:
|
|
272
|
+
rubygems_version: 4.0.10
|
|
285
273
|
specification_version: 4
|
|
286
274
|
summary: Interact with ArchivesSpace via the API.
|
|
287
275
|
test_files: []
|