archivesspace-client 0.1.3 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1723d47efa6b10e5106ca28bfa6f247bf79603d2
4
- data.tar.gz: f6b404154c5c87ee9a74036d6501cc3304df01ea
2
+ SHA256:
3
+ metadata.gz: 6ea50bb167b4debf8781434efa1ff7b06d077a8ab869f02c30ea8d1cd66de3c9
4
+ data.tar.gz: 83f63ad1f11fc35ca89cdabe871a1e1fa91f935e2e6e284f038b6db2c0257065
5
5
  SHA512:
6
- metadata.gz: 7de5e06e6900dda657cfae615058c10859ba565aa27f16184ec7d44f23c7c2513a52c9717186f8ce04361adabc3097b562db785694bb38556a003177e92b4718
7
- data.tar.gz: 17a2e5174475986516c757f7b4f875352546555f0f3aee8539c7f3d2f090789dd1f7087614ca38ea3d0b554c50a351d7307ec8d29706bc816b4fcb328b2e60d9
6
+ metadata.gz: faa0086ae6ecd33700e3cf16c41b7457ebf094eb4a5e79109c3999ce0e916f8924450cb6ef8bcb4a761f0d6ed3a1c12a457dec4cd5738429a8f80fb249303fbe
7
+ data.tar.gz: '09a6fca39d7846875715216e8b10d5d29b776b433c37abef3490b5964e62deca9de5f01e69f868a476cceb11c7ceaa43032cfb906f9fff35da10b43e0b3582e7'
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in archivesspace-client.gemspec
data/README.md CHANGED
@@ -1,10 +1,8 @@
1
- Archivesspace Client
2
- ===
1
+ # Archivesspace Client
3
2
 
4
- Interact with ArchivesSpace via its API.
3
+ Interact with ArchivesSpace via the API.
5
4
 
6
- Installation
7
- ---
5
+ ## Installation
8
6
 
9
7
  Add this line to your application's Gemfile:
10
8
 
@@ -20,10 +18,11 @@ bundle install
20
18
 
21
19
  Or install it yourself as:
22
20
 
23
- $ gem install archivesspace-client
21
+ ```bash
22
+ gem install archivesspace-client
23
+ ```
24
24
 
25
- Usage
26
- ---
25
+ ## Usage
27
26
 
28
27
  See the examples directory for a range of use cases.
29
28
 
@@ -37,8 +36,6 @@ client = ArchivesSpace::Client.new.login
37
36
 
38
37
  **Custom configuration**
39
38
 
40
- To supply custom configuration to client:
41
-
42
39
  ```ruby
43
40
  config = ArchivesSpace::Configuration.new({
44
41
  base_uri: "https://archives.university.edu/api",
@@ -90,8 +87,36 @@ client.get('digital_objects') # instead of "repositories/2/digital_objects" etc.
90
87
  client.config.base_repo = ""
91
88
  ```
92
89
 
93
- Development
94
- ---
90
+ ## Templates
91
+
92
+ Templates are an optional feature that can help simplify the effort of creating
93
+ json payloads for ArchivesSpace. Rather than construct the json programatically
94
+ according to the schemas a `.erb` template can be used to generate payloads
95
+ instead which are transformed to json automatically. There are a small number of
96
+ templates provided with the client, but you can create your own and access them
97
+ by setting the `ARCHIVESSPACE_CLIENT_TEMPLATES_PATH` envvar. A particularly simple
98
+ template might look like:
99
+
100
+ ```erb
101
+ {
102
+ "digital_object_id": "<%= data[:digital_object_id] %>",
103
+ "title": "<%= data[:title] %>"
104
+ }
105
+ ```
106
+
107
+ Practically speaking there isn't much benefit to this example, but in the case of
108
+ a more complex record structure where you want to populate deeply nested elements
109
+ using a flat file structure (like csv) this can be a very convenient way of
110
+ assembling the payload. To process a template:
111
+
112
+ ```ruby
113
+ data = { repo_code: 'ABC', name: 'ABC Archive', agent_contact_name: 'ABC Admin' }
114
+ json = ArchivesSpace::Template.process(:repository_with_agent, data)
115
+ response = client.post('/repositories/with_agent', json)
116
+ puts response.result.success? ? '=)' : '=('
117
+ ```
118
+
119
+ ## Development
95
120
 
96
121
  To run the examples start a local instance of ArchivesSpace then:
97
122
 
@@ -99,7 +124,9 @@ To run the examples start a local instance of ArchivesSpace then:
99
124
  bundle exec ruby examples/repo_and_user.rb
100
125
  ```
101
126
 
102
- Any script placed in the examples directory with a `my_` prefix are ignored by git. Follow the convention used by the existing scripts to bootstrap and experiment away.
127
+ Any script placed in the examples directory with a `my_` prefix are ignored by
128
+ git. Follow the convention used by the existing scripts to bootstrap and
129
+ experiment away.
103
130
 
104
131
  To run the tests:
105
132
 
@@ -107,13 +134,25 @@ To run the tests:
107
134
  bundle exec rake
108
135
  ```
109
136
 
110
- Contributing
111
- ---
137
+ ## Publishing
138
+
139
+ Bump version in `lib/archivesspace/client/version.rb` then:
140
+
141
+ ```bash
142
+ VERSION=0.1.8
143
+ gem build archivesspace-client
144
+ git add . && git commit -m "Bump to $VERSION"
145
+ git tag v$VERSION
146
+ git push origin master
147
+ git push --tags
148
+ gem push archivesspace-client-$VERSION.gem
149
+ ```
150
+
151
+ ## Contributing
112
152
 
113
153
  Bug reports and pull requests are welcome on GitHub at https://github.com/lyrasis/archivesspace-client.
114
154
 
115
- License
116
- ---
155
+ ## License
117
156
 
118
157
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
119
158
 
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
@@ -1,31 +1,32 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'archivesspace/client/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "archivesspace-client"
8
+ spec.name = 'archivesspace-client'
8
9
  spec.version = ArchivesSpace::Client::VERSION
9
- spec.authors = ["Mark Cooper"]
10
- spec.email = ["mark.c.cooper@outlook.com"]
11
- spec.summary = %q{Interact with ArchivesSpace via its RESTful API.}
12
- spec.description = %q{Interact with ArchivesSpace via its RESTful API.}
13
- spec.homepage = ""
14
- spec.license = "MIT"
10
+ spec.authors = ['Mark Cooper']
11
+ spec.email = ['mark.c.cooper@outlook.com']
12
+ spec.summary = 'Interact with ArchivesSpace via the API.'
13
+ spec.description = 'Interact with ArchivesSpace via the API.'
14
+ spec.homepage = ''
15
+ spec.license = 'MIT'
15
16
 
16
17
  spec.files = `git ls-files -z`.split("\x0")
17
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
+ spec.require_paths = ['lib']
20
21
 
21
- spec.add_development_dependency "bundler", "~> 1.10"
22
- spec.add_development_dependency "rake", "~> 10.0"
23
- spec.add_development_dependency "rspec", "3.6.0"
24
- spec.add_development_dependency "vcr", "3.0.3"
25
- spec.add_development_dependency "webmock", "3.0.1"
26
- spec.add_development_dependency "awesome_print", "~> 1.8.0"
22
+ spec.add_development_dependency 'awesome_print', '~> 1.8.0'
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec', '3.6.0'
26
+ spec.add_development_dependency 'vcr', '3.0.3'
27
+ spec.add_development_dependency 'webmock', '3.0.1'
27
28
 
28
- spec.add_dependency "httparty", "0.14.0"
29
- spec.add_dependency "json", "2.0.3"
30
- spec.add_dependency "nokogiri", "1.6.8.1"
29
+ spec.add_dependency 'httparty', '~> 0.14'
30
+ spec.add_dependency 'json', '~> 2.0'
31
+ spec.add_dependency 'nokogiri', '~> 1.10'
31
32
  end
data/examples/export.rb CHANGED
@@ -1,29 +1,36 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
2
4
  require 'awesome_print'
3
5
  require 'archivesspace/client'
4
6
 
5
7
  # official sandbox
6
- config = ArchivesSpace::Configuration.new({
7
- base_uri: "http://sandbox.archivesspace.org/api",
8
- base_repo: "",
9
- username: "admin",
10
- password: "admin",
11
- page_size: 50,
12
- throttle: 0,
13
- verify_ssl: false,
14
- })
8
+ config = ArchivesSpace::Configuration.new(
9
+ {
10
+ base_uri: 'http://test.archivesspace.org/staff/api',
11
+ base_repo: '',
12
+ username: 'admin',
13
+ password: 'admin',
14
+ page_size: 50,
15
+ throttle: 0,
16
+ verify_ssl: false
17
+ }
18
+ )
15
19
 
16
20
  client = ArchivesSpace::Client.new(config).login
17
21
  client.config.throttle = 0.5
18
- client.config.base_repo = "repositories/2"
22
+ client.config.base_repo = 'repositories/2'
19
23
 
20
24
  begin
21
- # date -d '2015-07-01 00:00:00' +'%s' # 1435734000
22
- client.resources("ead", { query: { modified_since: "1435734000" } }) do |ead|
25
+ # date -d '2021-02-01 00:00:00' +'%s' # 1612166400
26
+ client.resources(query: { modified_since: '1612166400' }).each do |resource|
23
27
  # for now we are just printing ...
24
28
  # but you would actually write to a zip file or whatever
25
- ap ead
29
+ id = resource['uri'].split('/')[-1]
30
+ opts = { include_unpublished: false }
31
+ response = client.get("resource_descriptions/#{id}.xml", opts)
32
+ puts Nokogiri::XML(response.body).to_xml
26
33
  end
27
- rescue ArchivesSpace::RequestError => ex
28
- puts ex.message
29
- end
34
+ rescue ArchivesSpace::RequestError => e
35
+ puts e.message
36
+ end
@@ -1,15 +1,16 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
2
4
  require 'awesome_print'
3
5
  require 'archivesspace/client'
4
6
 
5
- username = "mrx"
6
- password = "123456"
7
+ username = 'admin'
8
+ password = 'admin'
7
9
 
8
10
  # default client connection: localhost:8089, admin, admin
9
11
  client = ArchivesSpace::Client.new.login
10
12
  begin
11
- client.password_reset username, password
12
- puts "Successfully updated password for #{username}."
13
- rescue Exception => ex
14
- puts "Failed to update password for #{username},\n#{ex.message}"
13
+ puts client.password_reset(username, password).parsed
14
+ rescue StandardError => e
15
+ puts "Failed to update password for #{username},\n#{e.message}"
15
16
  end
@@ -1,46 +1,60 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
2
4
  require 'awesome_print'
3
5
  require 'archivesspace/client'
4
6
 
5
- # default client connection: localhost:8089, admin, admin
6
- client = ArchivesSpace::Client.new.login
7
+ # official sandbox
8
+ config = ArchivesSpace::Configuration.new(
9
+ {
10
+ base_uri: 'http://sandbox.archivesspace.org/api',
11
+ base_repo: '',
12
+ username: 'admin',
13
+ password: 'admin',
14
+ page_size: 50,
15
+ throttle: 0,
16
+ verify_ssl: false
17
+ }
18
+ )
19
+
20
+ client = ArchivesSpace::Client.new(config).login
7
21
 
8
22
  ap ArchivesSpace::Template.list # view available templates
9
23
 
10
24
  repo_data = {
11
- repo_code: "XYZ",
12
- name: "XYZ Archive",
13
- agent_contact_name: "John Doe",
25
+ repo_code: 'XYZ',
26
+ name: 'XYZ Archive',
27
+ agent_contact_name: 'XYZ Admin'
14
28
  }
15
29
 
16
30
  user_data = {
17
- username: "lmessi",
18
- name: "Lionel Messi",
19
- is_admin: true,
31
+ username: 'lmessi',
32
+ name: 'Lionel Messi',
33
+ is_admin: true
20
34
  }
21
- user_password = "123456"
35
+ user_password = '123456'
22
36
 
23
- repository = ArchivesSpace::Template.process_template(:repository_with_agent, repo_data)
37
+ repository = ArchivesSpace::Template.process(:repository_with_agent, repo_data)
24
38
 
25
39
  begin
26
40
  response = client.post('/repositories/with_agent', repository)
27
- if response.status_code == 201
28
- repository = client.repositories.find { |r| r["repo_code"] == "XYZ" }
41
+ if response.result.success?
42
+ repository = client.repositories.find { |r| r['repo_code'] == 'XYZ' }
29
43
  ap repository
30
- ap client.delete(repository["uri"])
44
+ ap client.delete(repository['uri'])
31
45
  else
32
46
  ap response.parsed
33
47
  end
34
48
 
35
- user = ArchivesSpace::Template.process_template(:user, user_data)
49
+ user = ArchivesSpace::Template.process(:user, user_data)
36
50
  response = client.post('users', user, { password: user_password })
37
- if response.status_code == 201
38
- user = client.users.find { |r| r["username"] == "lmessi" }
51
+ if response.result.success?
52
+ user = client.users.find { |r| r['username'] == 'lmessi' }
39
53
  ap user
40
- ap client.delete user["uri"]
54
+ ap client.delete user['uri']
41
55
  else
42
56
  ap response.parsed
43
57
  end
44
- rescue ArchivesSpace::RequestError => ex
45
- puts ex.message
58
+ rescue ArchivesSpace::RequestError => e
59
+ puts e.message
46
60
  end
@@ -1,17 +1,21 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
2
4
  require 'awesome_print'
3
5
  require 'archivesspace/client'
4
6
 
5
7
  # official sandbox
6
- config = ArchivesSpace::Configuration.new({
7
- base_uri: "http://sandbox.archivesspace.org/api",
8
- base_repo: "",
9
- username: "admin",
10
- password: "admin",
11
- page_size: 50,
12
- throttle: 0,
13
- verify_ssl: false,
14
- })
8
+ config = ArchivesSpace::Configuration.new(
9
+ {
10
+ base_uri: 'http://sandbox.archivesspace.org/api',
11
+ base_repo: '',
12
+ username: 'admin',
13
+ password: 'admin',
14
+ page_size: 50,
15
+ throttle: 0,
16
+ verify_ssl: false
17
+ }
18
+ )
15
19
 
16
20
  client = ArchivesSpace::Client.new(config).login
17
- puts client.get("version").body
21
+ puts client.get('version').body
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
4
+ require 'awesome_print'
5
+ require 'archivesspace/client'
6
+
7
+ # official sandbox
8
+ config = ArchivesSpace::Configuration.new(
9
+ {
10
+ base_uri: 'http://sandbox.archivesspace.org/api',
11
+ base_repo: '',
12
+ username: 'admin',
13
+ password: 'admin',
14
+ page_size: 50,
15
+ throttle: 0,
16
+ verify_ssl: false
17
+ }
18
+ )
19
+
20
+ client = ArchivesSpace::Client.new(config).login
21
+
22
+ user_data = {
23
+ username: 'bde',
24
+ name: 'BDE',
25
+ is_admin: false
26
+ }
27
+
28
+ client.post(
29
+ 'users',
30
+ ArchivesSpace::Template.process(:user, user_data),
31
+ { password: '123456' }
32
+ )
33
+
34
+ users_with_roles = {
35
+ 'bde' => ['repository-basic-data-entry']
36
+ }
37
+
38
+ begin
39
+ client.config.base_repo = "repositories/2"
40
+ results = client.group_user_assignment users_with_roles
41
+ ap results.map(&:parsed)
42
+ rescue ArchivesSpace::RequestError => e
43
+ puts e.message
44
+ end
@@ -1,22 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'httparty'
2
4
  require 'json'
3
5
  require 'nokogiri'
4
6
 
5
7
  # mixins required first
6
- require "archivesspace/client/helpers"
8
+ require 'archivesspace/client/helpers'
7
9
 
8
- require "archivesspace/client/client"
9
- require "archivesspace/client/configuration"
10
- require "archivesspace/client/request"
11
- require "archivesspace/client/response"
12
- require "archivesspace/client/template"
13
- require "archivesspace/client/version"
10
+ require 'archivesspace/client/client'
11
+ require 'archivesspace/client/configuration'
12
+ require 'archivesspace/client/request'
13
+ require 'archivesspace/client/response'
14
+ require 'archivesspace/client/template'
15
+ require 'archivesspace/client/version'
14
16
 
15
17
  module ArchivesSpace
16
-
17
- class ConnectionError < Exception ; end
18
- class ContextError < Exception ; end
19
- class ParamsError < Exception ; end
20
- class RequestError < Exception ; end
21
-
22
- end
18
+ class ConnectionError < RuntimeError; end
19
+ class ContextError < RuntimeError; end
20
+ class ParamsError < RuntimeError; end
21
+ class RequestError < RuntimeError; end
22
+ end
@@ -1,12 +1,14 @@
1
- module ArchivesSpace
1
+ # frozen_string_literal: true
2
2
 
3
+ module ArchivesSpace
3
4
  class Client
4
5
  include Helpers
5
6
  attr_accessor :token
6
7
  attr_reader :config
7
8
 
8
9
  def initialize(config = Configuration.new)
9
- raise "Invalid configuration object" unless config.kind_of? ArchivesSpace::Configuration
10
+ raise 'Invalid configuration object' unless config.is_a? ArchivesSpace::Configuration
11
+
10
12
  @config = config
11
13
  @token = nil
12
14
  end
@@ -16,11 +18,11 @@ module ArchivesSpace
16
18
  end
17
19
 
18
20
  def post(path, payload, params = {})
19
- request 'POST', path, { body: payload.to_json, query: params }
21
+ request 'POST', path, { body: payload, query: params }
20
22
  end
21
23
 
22
24
  def put(path, payload, params = {})
23
- request 'PUT', path, { body: payload.to_json, query: params }
25
+ request 'PUT', path, { body: payload, query: params }
24
26
  end
25
27
 
26
28
  def delete(path)
@@ -31,11 +33,9 @@ module ArchivesSpace
31
33
 
32
34
  def request(method, path, options = {})
33
35
  sleep config.throttle
34
- options[:headers] = { "X-ArchivesSpace-Session" => token } if token
36
+ options[:headers] = { 'X-ArchivesSpace-Session' => token } if token
35
37
  result = Request.new(config, method, path, options).execute
36
38
  Response.new result
37
39
  end
38
-
39
40
  end
40
-
41
41
  end
@@ -1,16 +1,16 @@
1
- module ArchivesSpace
1
+ # frozen_string_literal: true
2
2
 
3
+ module ArchivesSpace
3
4
  class Configuration
4
-
5
5
  def defaults
6
6
  {
7
- base_uri: "http://localhost:8089",
8
- base_repo: "",
9
- username: "admin",
10
- password: "admin",
7
+ base_uri: 'http://localhost:8089',
8
+ base_repo: '',
9
+ username: 'admin',
10
+ password: 'admin',
11
11
  page_size: 50,
12
12
  throttle: 0,
13
- verify_ssl: true,
13
+ verify_ssl: true
14
14
  }
15
15
  end
16
16
 
@@ -18,11 +18,10 @@ module ArchivesSpace
18
18
  settings = defaults.merge(settings)
19
19
  settings.each do |property, value|
20
20
  next unless defaults.keys.include? property
21
+
21
22
  instance_variable_set("@#{property}", value)
22
23
  self.class.send(:attr_accessor, property)
23
24
  end
24
25
  end
25
-
26
26
  end
27
-
28
- end
27
+ end
@@ -1,168 +1,133 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # needed for roundtrip hash merging
2
4
  class ::Hash
3
5
  def deep_merge(second)
4
- merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
5
- self.merge(second, &merger)
6
+ merger = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
7
+ merge(second, &merger)
6
8
  end
7
9
  end
8
10
 
9
11
  module ArchivesSpace
10
-
11
12
  module Helpers
13
+ def accessions(options = {})
14
+ all('accessions', options)
15
+ end
16
+
17
+ def all(path, options = {})
18
+ Enumerator.new do |yielder|
19
+ page = 1
20
+ unlimited_listing = false
21
+ loop do
22
+ options[:query] ||= {}
23
+ options[:query][:page] = page
24
+ result = get(path, options)
25
+ results = []
26
+
27
+ if result.parsed.respond_to?(:key) && result.parsed.key?('results')
28
+ results = result.parsed['results']
29
+ else
30
+ results = result.parsed
31
+ unlimited_listing = true
32
+ end
12
33
 
13
- def accessions(options = {}, &block)
14
- records = all('accessions', options) do |record|
15
- yield record if block_given?
16
- end
17
- records
18
- end
34
+ if results.any?
35
+ results.each do |i|
36
+ yielder << i
37
+ end
38
+ raise StopIteration if unlimited_listing
19
39
 
20
- def all(path, options = {}, &block)
21
- all = []
22
- format = options.delete(:format)
23
- parse_id = options.delete(:parse_id)
24
- # options[:headers] -- add xml headers if format
25
-
26
- result = get(path, options.merge({ query: { all_ids: true } } ))
27
- raise RequestError.new(result.body) if result.status_code != 200
28
- ids = result.parsed
29
- ids = ids.map{ |object| object["uri"].split("/")[-1] } if parse_id
30
- ids.each do |id|
31
- path_with_id = format ? "#{format}/#{id}.xml" : "#{path}/#{id}"
32
- result = get(path_with_id, options)
33
- raise RequestError.new(result.body) if result.status_code != 200
34
- record = format ? Nokogiri::XML(result.body).to_xml : result.parsed
35
- yield record if block_given?
36
- all << record
37
- end
38
- all
40
+ page += 1
41
+ else
42
+ raise StopIteration
43
+ end
44
+ end
45
+ end.lazy
39
46
  end
40
47
 
41
48
  def backend_version
42
- get "version"
43
- end
44
-
45
- def batch_import(payload, params = {})
46
- # create "batch_import", payload, params
49
+ get 'version'
47
50
  end
48
51
 
49
- def digital_object_to_xml(digital_object, format = "dublin_core", options = {})
50
- id = digital_object["uri"].split("/")[-1]
51
- path = "digital_objects/#{format}/#{id}.xml"
52
- get_xml path, options
53
- end
52
+ # def batch_import(payload, params = {})
53
+ # # TODO: create "batch_import", payload, params
54
+ # end
54
55
 
55
- def digital_objects(format = nil, options = {}, &block)
56
- path = "digital_objects"
57
- format = format ? "#{path}/#{format}" : nil
58
- records = all(path, options.merge({ format: format })) do |record|
59
- yield record if block_given?
60
- end
61
- records
56
+ def digital_objects(options = {})
57
+ all('digital_objects', options)
62
58
  end
63
59
 
64
- def groups
65
- records = all('groups', { parse_id: true }) do |record|
66
- yield record if block_given?
67
- end
68
- records
60
+ def groups(options = {})
61
+ all('groups', options)
69
62
  end
70
63
 
71
- def group_user_assignment(users_with_roles, params = { with_members: true })
64
+ def group_user_assignment(users_with_roles)
72
65
  updated = []
73
- groups do |group|
74
- changed = false
66
+ groups.each do |group|
67
+ group = get("groups/#{uri_to_id(group['uri'])}").parsed
68
+ update = false
75
69
 
76
70
  users_with_roles.each do |user, roles|
77
- if roles.include? group["group_code"]
78
- unless group["member_usernames"].include? user
79
- group["member_usernames"] << user
80
- changed = true
81
- end
82
- else
83
- if group["member_usernames"].include? user
84
- group["member_usernames"].delete user
85
- changed = true
71
+ # should the user still belong to this group?
72
+ if group['member_usernames'].include?(user)
73
+ unless roles.include? group['group_code']
74
+ group['member_usernames'].delete user
75
+ update = true
86
76
  end
77
+ # should the user be added to this group?
78
+ elsif roles.include? group['group_code']
79
+ group['member_usernames'] << user
80
+ update = true
87
81
  end
88
82
  end
89
83
 
90
- if changed
91
- id = group["uri"].split("/")[-1]
92
- response = post( "/groups/#{id}", group, params )
93
- updated << response.parsed
94
- end
84
+ next unless update
85
+
86
+ response = post("/groups/#{uri_to_id(group['uri'])}", group.to_json)
87
+ updated << response
95
88
  end
96
89
  updated
97
90
  end
98
91
 
99
92
  def login
100
- username, password = config.username, config.password
93
+ username = config.username
94
+ password = config.password
101
95
  result = request('POST', "/users/#{username}/login", { query: { password: password } })
102
- raise ConnectionError.new "Failed to connect to ArchivesSpace backend as #{username} #{password}" unless result.parsed["session"]
103
- @token = result.parsed["session"]
96
+ unless result.parsed['session']
97
+ raise ConnectionError, "Failed to connect to ArchivesSpace backend as #{username} #{password}"
98
+ end
99
+
100
+ @token = result.parsed['session']
104
101
  self
105
102
  end
106
103
 
107
104
  def password_reset(username, password)
108
- user = all('users').find { |u| u["username"] == username }
109
- raise RequestError.new(user.status) unless user
110
- post(user["uri"], user, { password: password })
111
- end
105
+ user = all('users').find { |u| u['username'] == username }
106
+ raise RequestError, user.status unless user
112
107
 
113
- def repositories
114
- records = get('repositories').parsed.each do |record|
115
- yield record if block_given?
116
- end
117
- records
108
+ post(user['uri'], user.to_json, { password: password })
118
109
  end
119
110
 
120
- def repositories_with_agent
121
- #
111
+ def repositories(options = {})
112
+ all('repositories', options)
122
113
  end
123
114
 
124
- def resource_to_xml(resource, format = "ead", options = {})
125
- id = resource["uri"].split("/")[-1]
126
- path = format == "ead" ? "resource_descriptions/#{id}.xml" : "resources/#{format}/#{id}.xml"
127
- get_xml path, options
128
- end
115
+ def repositories_with_agent; end
129
116
 
130
- def resources(format = nil, options = {}, &block)
131
- path = 'resources'
132
- # the api is inconsistent with the path structure for resource ead (and pdf)
133
- if format
134
- if format =~ /(ead|pdf)/
135
- format = "resource_descriptions"
136
- else
137
- format = "#{path}/#{format}"
138
- end
139
- end
140
- records = all(path, options.merge({ format: format })) do |record|
141
- yield record if block_given?
142
- end
143
- records
117
+ def resources(options = {})
118
+ all('resources', options)
144
119
  end
145
120
 
146
- def search(params)
147
- # get "search", params
148
- end
121
+ # def search(params)
122
+ # # TODO: get "search", params
123
+ # end
149
124
 
150
- def users
151
- records = all('users') do |record|
152
- yield record if block_given?
153
- end
154
- records
125
+ def uri_to_id(uri)
126
+ uri.split('/').last
155
127
  end
156
128
 
157
- private
158
-
159
- def get_xml(path, options = {})
160
- # add xml headers
161
- response = get(path, options)
162
- raise RequestError.new(response.body) unless response.status_code == 200
163
- Nokogiri::XML(response.body).to_xml
129
+ def users(options = {})
130
+ all('users', options)
164
131
  end
165
-
166
132
  end
167
-
168
- end
133
+ end
@@ -1,5 +1,6 @@
1
- module ArchivesSpace
1
+ # frozen_string_literal: true
2
2
 
3
+ module ArchivesSpace
3
4
  class Request
4
5
  include HTTParty
5
6
  attr_reader :config, :headers, :method, :path, :options
@@ -9,36 +10,33 @@ module ArchivesSpace
9
10
  delete: {},
10
11
  get: {},
11
12
  post: {
12
- "Content-Type" => "application/json",
13
- "Content-Length" => "nnnn",
13
+ 'Content-Type' => 'application/json',
14
+ 'Content-Length' => 'nnnn'
14
15
  },
15
16
  put: {
16
- "Content-Type" => "application/json",
17
- "Content-Length" => "nnnn",
17
+ 'Content-Type' => 'application/json',
18
+ 'Content-Length' => 'nnnn'
18
19
  }
19
20
  }
20
21
  headers[method]
21
22
  end
22
23
 
23
- def initialize(config, method = "GET", path = "", options = {})
24
- @config = config
25
- @method = method.downcase.to_sym
26
- @path = path
24
+ def initialize(config, method = 'GET', path = '', options = {})
25
+ @config = config
26
+ @method = method.downcase.to_sym
27
+ @path = path.gsub(%r{^/+}, '')
28
+ @options = options
29
+ @options[:headers] = options[:headers] ? default_headers(@method).merge(options[:headers]) : default_headers(@method)
30
+ @options[:verify] = config.verify_ssl
31
+ @options[:query] = {} unless options.key? :query
27
32
 
28
- @options = options
29
- @options[:headers] = options[:headers] ? default_headers(@method).merge(options[:headers]) : default_headers(@method)
30
- @options[:verify] = config.verify_ssl
31
- @options[:query] = {} unless options.has_key? :query
33
+ base_uri = config.base_repo&.length&.positive? ? File.join(config.base_uri, config.base_repo) : config.base_uri
32
34
 
33
- base_uri = (config.base_repo.nil? or config.base_repo.empty?) ? config.base_uri : "#{config.base_uri}/#{config.base_repo}"
34
35
  self.class.base_uri base_uri
35
- # self.class.default_params abc: 123
36
36
  end
37
37
 
38
38
  def execute
39
39
  self.class.send method, "/#{path}", options
40
40
  end
41
-
42
41
  end
43
-
44
42
  end
@@ -1,10 +1,10 @@
1
- module ArchivesSpace
1
+ # frozen_string_literal: true
2
2
 
3
+ module ArchivesSpace
3
4
  class Response
4
- attr_reader :result, :parsed, :body, :headers, :status, :status_code, :xml
5
+ attr_reader :result, :parsed, :body, :headers, :status, :status_code
5
6
 
6
7
  def initialize(result)
7
- # throw error
8
8
  @result = result
9
9
  @parsed = result.parsed_response
10
10
  @body = result.body
@@ -12,7 +12,5 @@ module ArchivesSpace
12
12
  @status = result.response
13
13
  @status_code = result.code.to_i
14
14
  end
15
-
16
15
  end
17
-
18
- end
16
+ end
@@ -1,25 +1,26 @@
1
- module ArchivesSpace
1
+ # frozen_string_literal: true
2
2
 
3
+ module ArchivesSpace
3
4
  module Template
4
-
5
5
  def self.list
6
- []
6
+ Dir.glob File.join(templates_path, '*.erb')
7
7
  end
8
8
 
9
- def self.process_template(template, data)
10
- t = ERB.new(self.read_template(template))
11
- r = t.result(binding).gsub(/\n+/,"\n")
12
- JSON.parse(r)
9
+ def self.process(template, data)
10
+ t = ERB.new(read(template))
11
+ r = t.result(binding).gsub(/\n+/, "\n")
12
+ JSON.parse(r).to_json
13
13
  end
14
14
 
15
- def self.read_template(file)
16
- File.read("#{self.templates_path}/#{file.to_s}.json.erb")
15
+ def self.read(file)
16
+ File.read("#{templates_path}/#{file}.json.erb")
17
17
  end
18
18
 
19
19
  def self.templates_path
20
- File.join(File.dirname(File.expand_path(__FILE__)), 'templates')
20
+ ENV.fetch(
21
+ 'ARCHIVESSPACE_CLIENT_TEMPLATES_PATH',
22
+ File.join(File.dirname(File.expand_path(__FILE__)), 'templates')
23
+ )
21
24
  end
22
-
23
25
  end
24
-
25
- end
26
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ArchivesSpace
2
4
  class Client
3
- VERSION = "0.1.3"
5
+ VERSION = '0.1.8'
4
6
  end
5
7
  end
@@ -1,43 +1,39 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe ArchivesSpace::Client do
4
-
5
6
  let(:client) { ArchivesSpace::Client.new }
6
7
  let(:login) { -> { client.login } }
7
8
 
8
- describe "Configuration" do
9
-
9
+ describe 'Configuration' do
10
10
  it 'will use the default configuration if none is provided' do
11
11
  client = ArchivesSpace::Client.new
12
12
  expect(client.config.base_uri).to eq DEFAULT_BASE_URI
13
13
  end
14
14
 
15
15
  it 'will raise an error if supplied configuration is of invalid type' do
16
- expect{ ArchivesSpace::Client.new({ base_uri: CUSTOM_BASE_URI }) }.to raise_error(RuntimeError)
16
+ expect { ArchivesSpace::Client.new({ base_uri: CUSTOM_BASE_URI }) }.to raise_error(RuntimeError)
17
17
  end
18
18
 
19
19
  it 'will allow a configuration object to be provided' do
20
20
  client = ArchivesSpace::Client.new(ArchivesSpace::Configuration.new({ base_uri: CUSTOM_BASE_URI }))
21
21
  expect(client.config.base_uri).to eq CUSTOM_BASE_URI
22
22
  end
23
-
24
23
  end
25
24
 
26
- describe "Version information" do
27
-
25
+ describe 'Version information' do
28
26
  it 'has a version number' do
29
27
  expect(ArchivesSpace::Client::VERSION).not_to be nil
30
28
  end
31
29
 
32
- it "can retrieve the backend version info" do
30
+ it 'can retrieve the backend version info' do
33
31
  VCR.use_cassette('backend_version') do
34
32
  login.call
35
- response = client.get "version"
33
+ response = client.get 'version'
36
34
  expect(response.status_code).to eq(200)
37
35
  expect(response.body).to match(/ArchivesSpace \(.*\)/)
38
36
  end
39
37
  end
40
-
41
38
  end
42
-
43
- end
39
+ end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe ArchivesSpace::Configuration do
4
-
5
6
  it 'uses the default profile for configuration settings' do
6
7
  config = ArchivesSpace::Configuration.new
7
8
  expect(config.base_uri).to eq DEFAULT_BASE_URI
@@ -9,8 +10,8 @@ describe ArchivesSpace::Configuration do
9
10
 
10
11
  it 'allows configuration settings to be provided' do
11
12
  config = ArchivesSpace::Configuration.new({
12
- base_uri: CUSTOM_BASE_URI,
13
- })
13
+ base_uri: CUSTOM_BASE_URI
14
+ })
14
15
  expect(config.base_uri).to eq CUSTOM_BASE_URI
15
16
  end
16
17
 
@@ -22,7 +23,6 @@ describe ArchivesSpace::Configuration do
22
23
 
23
24
  it 'ignores unrecognized configuration properties' do
24
25
  config = ArchivesSpace::Configuration.new({ xyz: 123 })
25
- expect{ config.xyz }.to raise_error(NoMethodError)
26
+ expect { config.xyz }.to raise_error(NoMethodError)
26
27
  end
27
-
28
- end
28
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ArchivesSpace::Template do
6
+ it 'can list the default templates' do
7
+ templates = ArchivesSpace::Template.list
8
+ expect(templates).to_not be_empty
9
+ expect(templates).to include(/repository_with_agent.*erb/)
10
+ end
11
+
12
+ it 'can change the path when template envvar is set' do
13
+ expect(ArchivesSpace::Template.templates_path).to match(
14
+ /#{File.join('lib', 'archivesspace', 'client', 'templates')}/
15
+ )
16
+ ENV['ARCHIVESSPACE_CLIENT_TEMPLATES_PATH'] = '/path/to/nowhere'
17
+ expect(ArchivesSpace::Template.templates_path).to eq '/path/to/nowhere'
18
+ ENV.delete('ARCHIVESSPACE_CLIENT_TEMPLATES_PATH')
19
+ end
20
+
21
+ it 'can process a template' do
22
+ data = { repo_code: 'ABC', name: 'ABC Archive', agent_contact_name: 'ABC Admin' }
23
+ json = JSON.parse(ArchivesSpace::Template.process(:repository_with_agent, data))
24
+ expect(json['repository']['repo_code']).to eq data[:repo_code]
25
+ end
26
+ end
@@ -2,7 +2,7 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: post
5
- uri: http://localhost:8089//users/admin/login?password=admin
5
+ uri: http://localhost:8089/users/admin/login?password=admin
6
6
  body:
7
7
  encoding: UTF-8
8
8
  string: ''
data/spec/spec_helper.rb CHANGED
@@ -1,14 +1,16 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
2
4
  require 'archivesspace/client'
3
5
  require 'vcr'
4
6
  require 'webmock/rspec'
5
7
 
6
8
  # GLOBAL VALUES FOR SPECS
7
- DEFAULT_BASE_URI = "http://localhost:8089"
8
- CUSTOM_BASE_URI = "https://archives.university.edu/api"
9
+ DEFAULT_BASE_URI = 'http://localhost:8089'
10
+ CUSTOM_BASE_URI = 'https://archives.university.edu/api'
9
11
 
10
12
  VCR.configure do |c|
11
- c.cassette_library_dir = "spec/fixtures/cassettes"
13
+ c.cassette_library_dir = 'spec/fixtures/cassettes'
12
14
  c.hook_into :webmock
13
- c.default_cassette_options = { :record => :once }
14
- end
15
+ c.default_cassette_options = { record: :once }
16
+ end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: archivesspace-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Cooper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-01 00:00:00.000000000 Z
11
+ date: 2021-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: awesome_print
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.10'
19
+ version: 1.8.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.10'
26
+ version: 1.8.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,63 +94,49 @@ dependencies:
80
94
  - - '='
81
95
  - !ruby/object:Gem::Version
82
96
  version: 3.0.1
83
- - !ruby/object:Gem::Dependency
84
- name: awesome_print
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 1.8.0
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 1.8.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: httparty
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '='
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.14.0
103
+ version: '0.14'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '='
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.14.0
110
+ version: '0.14'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: json
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '='
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 2.0.3
117
+ version: '2.0'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '='
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 2.0.3
124
+ version: '2.0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: nokogiri
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - '='
129
+ - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 1.6.8.1
131
+ version: '1.10'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - '='
136
+ - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 1.6.8.1
139
- description: Interact with ArchivesSpace via its RESTful API.
138
+ version: '1.10'
139
+ description: Interact with ArchivesSpace via the API.
140
140
  email:
141
141
  - mark.c.cooper@outlook.com
142
142
  executables: []
@@ -155,6 +155,7 @@ files:
155
155
  - examples/password_reset.rb
156
156
  - examples/repo_and_user.rb
157
157
  - examples/test_connection.rb
158
+ - examples/user_groups.rb
158
159
  - lib/archivesspace/client.rb
159
160
  - lib/archivesspace/client/client.rb
160
161
  - lib/archivesspace/client/configuration.rb
@@ -169,6 +170,7 @@ files:
169
170
  - lib/archivesspace/client/version.rb
170
171
  - spec/archivesspace/client_spec.rb
171
172
  - spec/archivesspace/configuration_spec.rb
173
+ - spec/archivesspace/templates_spec.rb
172
174
  - spec/fixtures/cassettes/backend_version.yml
173
175
  - spec/spec_helper.rb
174
176
  homepage: ''
@@ -190,13 +192,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
192
  - !ruby/object:Gem::Version
191
193
  version: '0'
192
194
  requirements: []
193
- rubyforge_project:
194
- rubygems_version: 2.6.10
195
+ rubygems_version: 3.1.6
195
196
  signing_key:
196
197
  specification_version: 4
197
- summary: Interact with ArchivesSpace via its RESTful API.
198
+ summary: Interact with ArchivesSpace via the API.
198
199
  test_files:
199
200
  - spec/archivesspace/client_spec.rb
200
201
  - spec/archivesspace/configuration_spec.rb
202
+ - spec/archivesspace/templates_spec.rb
201
203
  - spec/fixtures/cassettes/backend_version.yml
202
204
  - spec/spec_helper.rb