archivesspace-client 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 166c7dc29eb3bba590d2480d4b0a4d67392d7066
4
+ data.tar.gz: 63c5bd51a5f5f093a1afb247da0942bba3bd68d2
5
+ SHA512:
6
+ metadata.gz: 774fcbf7d02bbb34cdc549ee8dbda2f6fb7181eaecb188f70879a7f975a7e93ca2792d2748ade0fc46afda945a57ecaadd5c0f7cd5cd9198621d459c11813667
7
+ data.tar.gz: d6996636d70071997bd14f185acf17e3e3cd7b3338be987a39514af25ce46516b2cc456aae9e64ed1d2b3b4caa9e66c81648424fe34d8e4031839674a0e469e7
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ *.lock
4
+ *.xml
5
+ *.zip
6
+ .bundle
7
+ .config
8
+ .yardoc
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ examples/my_*.rb
15
+ lib/bundler/man
16
+ pkg
17
+ rdoc
18
+ spec/reports
19
+ test/tmp
20
+ test/version_tmp
21
+ tmp
22
+ /archivesspace/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.3
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in archivesspace-client.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Mark Cooper
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,120 @@
1
+ Archivesspace Client
2
+ ===
3
+
4
+ Interact with ArchivesSpace via its API.
5
+
6
+ Installation
7
+ ---
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'archivesspace-client'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```bash
18
+ bundle install
19
+ ```
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install archivesspace-client
24
+
25
+ Usage
26
+ ---
27
+
28
+ See the examples directory for a range of use cases.
29
+
30
+ **Default configuration**
31
+
32
+ Create client with default settings (`localhost:8089`, `admin`, `admin`):
33
+
34
+ ```ruby
35
+ client = ArchivesSpace::Client.new.login
36
+ ```
37
+
38
+ **Custom configuration**
39
+
40
+ To supply custom configuration to client:
41
+
42
+ ```ruby
43
+ config = ArchivesSpace::Configuration.new({
44
+ base_uri: "https://archives.university.edu/api",
45
+ base_repo: "",
46
+ username: "admin",
47
+ password: "123456",
48
+ page_size: 50,
49
+ throttle: 0,
50
+ verify_ssl: false,
51
+ })
52
+
53
+ client = ArchivesSpace::Client.new(config).login
54
+ ```
55
+
56
+ **Making basic requests**
57
+
58
+ The client responds to the standard request methods:
59
+
60
+ ```ruby
61
+ client.post('users', payload, { password: "abc123" }) # CREATE
62
+ client.get('users/5') # READ
63
+ client.post('users/5', payload) # UPDATE
64
+ client.delete('users/5') # DELETE
65
+
66
+ # these all defer to `request`
67
+ client.request('GET', 'users/5')
68
+
69
+ # to add params
70
+ client.get('users', { query: { all_ids: true } }).parsed
71
+
72
+ # using convenience methods
73
+ user = client.all('users').find { |user| user["username"] == "jdoe" }
74
+
75
+ # or even ...
76
+ user = client.users.find { |user| user["username"] == "jdoe" }
77
+ ```
78
+
79
+ See `helpers.rb` for more convenience methods such as `client.digital_objects` etc.
80
+
81
+ **Setting a repository context**
82
+
83
+ Update the `base_repo` configuration value to add a repository scope to requests (this is optional).
84
+
85
+ ```ruby
86
+ client.config.base_repo = "repositories/2"
87
+ client.get('digital_objects') # instead of "repositories/2/digital_objects" etc.
88
+
89
+ # to reset
90
+ client.config.base_repo = ""
91
+ ```
92
+
93
+ Development
94
+ ---
95
+
96
+ To run the examples start a local instance of ArchivesSpace then:
97
+
98
+ ```bash
99
+ bundle exec ruby examples/repo_and_user.rb
100
+ ```
101
+
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.
103
+
104
+ To run the tests:
105
+
106
+ ```bash
107
+ bundle exec rake
108
+ ```
109
+
110
+ Contributing
111
+ ---
112
+
113
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lyrasis/archivesspace-client.
114
+
115
+ License
116
+ ---
117
+
118
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
119
+
120
+ ---
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'archivesspace/client/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "archivesspace-client"
8
+ 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"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.10"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "vcr"
25
+ spec.add_development_dependency "webmock"
26
+ spec.add_development_dependency "awesome_print"
27
+
28
+ spec.add_dependency "httparty"
29
+ spec.add_dependency "json"
30
+ spec.add_dependency "nokogiri"
31
+ end
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'awesome_print'
3
+ require 'archivesspace/client'
4
+
5
+ # default client connection: localhost:8089, admin, admin
6
+ client = ArchivesSpace::Client.new.login
7
+ client.config.throttle 0.5
8
+
9
+ client.config.base_repo = "repositories/2"
10
+ # date -d '2015-07-01 00:00:00' +'%s' # 1435734000
11
+ client.resources("ead", { query: { modified_since: "1435734000" } }) do |ead|
12
+ # for now we are just printing ...
13
+ # but you would actually write to a zip file or whatever
14
+ ap ead
15
+ end
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'awesome_print'
3
+ require 'archivesspace/client'
4
+
5
+ username = "mrx"
6
+ password = "123456"
7
+
8
+ # default client connection: localhost:8089, admin, admin
9
+ client = ArchivesSpace::Client.new.login
10
+ begin
11
+ client.password_reset username, password
12
+ puts "Successfully updated password for #{username}."
13
+ rescue Exception => e
14
+ puts "Failed to update password for #{username},\n#{e.message}"
15
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'awesome_print'
3
+ require 'archivesspace/client'
4
+
5
+ # default client connection: localhost:8089, admin, admin
6
+ client = ArchivesSpace::Client.new.login
7
+
8
+ # todo ... example of assignment using CSV
@@ -0,0 +1,40 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'awesome_print'
3
+ require 'archivesspace/client'
4
+
5
+ # default client connection: localhost:8089, admin, admin
6
+ client = ArchivesSpace::Client.new.login
7
+
8
+ ap ArchivesSpace::Template.list # view available templates
9
+
10
+ repo_data = {
11
+ repo_code: "XYZ",
12
+ name: "XYZ Archive",
13
+ agent_contact_name: "John Doe",
14
+ }
15
+
16
+ repository = ArchivesSpace::Template.process_template(:repository_with_agent, repo_data)
17
+ response = client.post('/repositories/with_agent', repository)
18
+ if response.status_code == 201
19
+ repository = client.repositories.find { |r| r["repo_code"] == "XYZ" }
20
+ ap repository
21
+ ap client.delete(repository["uri"])
22
+ else
23
+ ap response.parsed
24
+ end
25
+
26
+ user_data = {
27
+ username: "lmessi",
28
+ name: "Lionel Messi",
29
+ is_admin: true,
30
+ }
31
+
32
+ user = ArchivesSpace::Template.process_template(:user, user_data)
33
+ response = client.post('users', user, { password: "123456" })
34
+ if response.status_code == 201
35
+ user = client.users.find { |r| r["username"] == "lmessi" }
36
+ ap user
37
+ ap client.delete user["uri"]
38
+ else
39
+ ap response.parsed
40
+ end
@@ -0,0 +1,22 @@
1
+ require 'httparty'
2
+ require 'json'
3
+ require 'nokogiri'
4
+
5
+ # mixins required first
6
+ require "archivesspace/client/helpers"
7
+
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"
14
+
15
+ 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
@@ -0,0 +1,41 @@
1
+ module ArchivesSpace
2
+
3
+ class Client
4
+ include Helpers
5
+ attr_accessor :token
6
+ attr_reader :config
7
+
8
+ def initialize(config = Configuration.new)
9
+ raise "Invalid configuration object" unless config.kind_of? ArchivesSpace::Configuration
10
+ @config = config
11
+ @token = nil
12
+ end
13
+
14
+ def get(path, options = {})
15
+ request 'GET', path, options
16
+ end
17
+
18
+ def post(path, payload, params = {})
19
+ request 'POST', path, { body: payload.to_json, query: params }
20
+ end
21
+
22
+ def put(path, payload)
23
+ request 'PUT', path, { body: payload.to_json }
24
+ end
25
+
26
+ def delete(path)
27
+ request 'DELETE', path
28
+ end
29
+
30
+ private
31
+
32
+ def request(method, path, options = {})
33
+ sleep config.throttle
34
+ options[:headers] = { "X-ArchivesSpace-Session" => token } if token
35
+ result = Request.new(config, method, path, options).execute
36
+ Response.new result
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,28 @@
1
+ module ArchivesSpace
2
+
3
+ class Configuration
4
+
5
+ def defaults
6
+ {
7
+ base_uri: "http://localhost:8089",
8
+ base_repo: "",
9
+ username: "admin",
10
+ password: "admin",
11
+ page_size: 50,
12
+ throttle: 0,
13
+ verify_ssl: true,
14
+ }
15
+ end
16
+
17
+ def initialize(settings = {})
18
+ settings = defaults.merge(settings)
19
+ settings.each do |property, value|
20
+ next unless defaults.keys.include? property
21
+ instance_variable_set("@#{property}", value)
22
+ self.class.send(:attr_accessor, property)
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,163 @@
1
+ # needed for roundtrip hash merging
2
+ class ::Hash
3
+ 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
+ end
7
+ end
8
+
9
+ module ArchivesSpace
10
+
11
+ module Helpers
12
+
13
+ def accessions(options = {}, &block)
14
+ records = all('accessions', options) do |record|
15
+ yield record if block_given?
16
+ end
17
+ records
18
+ end
19
+
20
+ def all(path, options = {}, &block)
21
+ all = []
22
+ format = options.delete(:format)
23
+ # options[:headers] -- add xml headers if format
24
+
25
+ result = get(path, options.merge({ query: { all_ids: true } } ))
26
+ ap result
27
+ raise RequestError.new result.status if result.status_code != 200
28
+ result.parsed.each do |id|
29
+ path_with_id = format ? "#{format}/#{id}.xml" : "#{path}/#{id}"
30
+ result = get(path_with_id, options)
31
+ raise RequestError.new result.status if result.status_code != 200
32
+ record = format ? Nokogiri::XML(result.body).to_xml : result.parsed
33
+ yield record if block_given?
34
+ all << record
35
+ end
36
+ all
37
+ end
38
+
39
+ def backend_version
40
+ get "version"
41
+ end
42
+
43
+ def batch_import(payload, params = {})
44
+ # create "batch_import", payload, params
45
+ end
46
+
47
+ def digital_object_to_xml(digital_object, format = "dublin_core")
48
+ id = digital_object["uri"].split("/")[-1]
49
+ path = "digital_objects/#{format}/#{id}.xml"
50
+ get_xml path
51
+ end
52
+
53
+ def digital_objects(format = nil, options = {}, &block)
54
+ path = "digital_objects"
55
+ format = format ? "#{path}/#{format}" : nil
56
+ records = all(path, options.merge({ format: format })) do |record|
57
+ yield record if block_given?
58
+ end
59
+ records
60
+ end
61
+
62
+ def groups
63
+ #
64
+ end
65
+
66
+ def group_user_assignment(users_with_roles, params = { with_members: true })
67
+ # updated = []
68
+ # groups.each do |group|
69
+ # changed = false
70
+
71
+ # users_with_roles.each do |user, roles|
72
+ # if roles.include? group["group_code"]
73
+ # unless group["member_usernames"].include? user
74
+ # group["member_usernames"] << user
75
+ # changed = true
76
+ # end
77
+ # else
78
+ # if group["member_usernames"].include? user
79
+ # group["member_usernames"].delete user
80
+ # changed = true
81
+ # end
82
+ # end
83
+ # end
84
+
85
+ # if changed
86
+ # updated << update( group, params )
87
+ # end
88
+
89
+ # sleep 1 # moderate requests
90
+ # end
91
+ # updated
92
+ end
93
+
94
+ def login
95
+ username, password = config.username, config.password
96
+ result = request('POST', "/users/#{username}/login", { query: { password: password } })
97
+ raise ConnectionError.new "Failed to connect to ArchivesSpace backend as #{username} #{password}" unless result.parsed["session"]
98
+ @token = result.parsed["session"]
99
+ self
100
+ end
101
+
102
+ def password_reset(username, password)
103
+ user = all('users').find { |u| u["username"] == username }
104
+ raise RequestError.new user.status unless user
105
+ post(user["uri"], user, { password: password })
106
+ end
107
+
108
+ def repositories
109
+ records = get('repositories').parsed.each do |record|
110
+ yield record if block_given?
111
+ end
112
+ records
113
+ end
114
+
115
+ def repositories_with_agent
116
+ #
117
+ end
118
+
119
+ def resource_to_xml(resource, format = "ead")
120
+ id = resource["uri"].split("/")[-1]
121
+ path = format == "ead" ? "resource_descriptions/#{id}.xml" : "resources/#{format}/#{id}.xml"
122
+ get_xml path
123
+ end
124
+
125
+ def resources(format = nil, options = {}, &block)
126
+ path = 'resources'
127
+ # the api is inconsistent with the path structure for resource ead (and pdf)
128
+ if format
129
+ if format =~ /(ead|pdf)/
130
+ format = "resource_descriptions"
131
+ else
132
+ format = "#{path}/#{format}"
133
+ end
134
+ end
135
+ records = all(path, options.merge({ format: format })) do |record|
136
+ yield record if block_given?
137
+ end
138
+ records
139
+ end
140
+
141
+ def search(params)
142
+ # get "search", params
143
+ end
144
+
145
+ def users
146
+ records = all('users') do |record|
147
+ yield record if block_given?
148
+ end
149
+ records
150
+ end
151
+
152
+ private
153
+
154
+ def get_xml(path)
155
+ # add xml headers
156
+ response = get(path)
157
+ raise RequestError.new path unless response.status_code == 200
158
+ Nokogiri::XML(response.body).to_xml
159
+ end
160
+
161
+ end
162
+
163
+ end
@@ -0,0 +1,44 @@
1
+ module ArchivesSpace
2
+
3
+ class Request
4
+ include HTTParty
5
+ attr_reader :config, :headers, :method, :path, :options
6
+
7
+ def default_headers(method = :get)
8
+ headers = {
9
+ delete: {},
10
+ get: {},
11
+ post: {
12
+ "Content-Type" => "application/json",
13
+ "Content-Length" => "nnnn",
14
+ },
15
+ put: {
16
+ "Content-Type" => "application/json",
17
+ "Content-Length" => "nnnn",
18
+ }
19
+ }
20
+ headers[method]
21
+ end
22
+
23
+ def initialize(config, method = "GET", path = "", options = {})
24
+ @config = config
25
+ @method = method.downcase.to_sym
26
+ @path = path
27
+
28
+ @options = options
29
+ @options[:headers] = options[:headers] ? default_headers(@method).merge(options[:headers]) : default_headers
30
+ @options[:verify] = config.verify_ssl
31
+ @options[:query] = {} unless options.has_key? :query
32
+
33
+ base_uri = (config.base_repo.nil? or config.base_repo.empty?) ? config.base_uri : "#{config.base_uri}/#{config.base_repo}"
34
+ self.class.base_uri base_uri
35
+ # self.class.default_params abc: 123
36
+ end
37
+
38
+ def execute
39
+ self.class.send method, "/#{path}", options
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,18 @@
1
+ module ArchivesSpace
2
+
3
+ class Response
4
+ attr_reader :result, :parsed, :body, :headers, :status, :status_code, :xml
5
+
6
+ def initialize(result)
7
+ # throw error
8
+ @result = result
9
+ @parsed = result.parsed_response
10
+ @body = result.body
11
+ @headers = result.headers
12
+ @status = result.response
13
+ @status_code = result.code.to_i
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,25 @@
1
+ module ArchivesSpace
2
+
3
+ module Template
4
+
5
+ def self.list
6
+ []
7
+ end
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)
13
+ end
14
+
15
+ def self.read_template(file)
16
+ File.read("#{self.templates_path}/#{file.to_s}.json.erb")
17
+ end
18
+
19
+ def self.templates_path
20
+ File.join(File.dirname(File.expand_path(__FILE__)), 'templates')
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,4 @@
1
+ {
2
+ "digital_object_id": "<%= data[:digital_object_id] %>",
3
+ "title": "<%= data[:title] %>"
4
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "repo_code": "<%= data[:repo_code] %>",
3
+ "name": "<%= data[:name] %>",
4
+ "org_code": "<%= data[:org_code] %>",
5
+ "country": "<%= data[:country] %>",
6
+ "parent_institution_name": "<%= data[:parent_institution_name] %>",
7
+ "url": "<%= data[:url] %>"
8
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "repository": {
3
+ "repo_code": "<%= data[:repo_code] %>",
4
+ "name": "<%= data[:name] %>",
5
+ "org_code": "<%= data[:org_code] %>",
6
+ "country": "<%= data[:country] %>",
7
+ "parent_institution_name": "<%= data[:parent_institution_name] %>",
8
+ "url": "<%= data[:url] %>"
9
+ },
10
+ "agent_representation": {
11
+ "names": [
12
+ {
13
+ "primary_name": "<%= data[:name] %>",
14
+ "source": "local",
15
+ "sort_name": "<%= data[:name] %>"
16
+ }
17
+ ],
18
+ "agent_contacts": [
19
+ {
20
+ "name": "<%= data[:agent_contact_name] %>",
21
+ "address_1": "<%= data[:agent_contact_address_1] %>",
22
+ "address_2": "<%= data[:agent_contact_address_2] %>",
23
+ "address_3": "<%= data[:agent_contact_address_3] %>",
24
+ "city": "<%= data[:agent_contact_city] %>",
25
+ "region": "",
26
+ "country": "<%= data[:agent_contact_country] %>",
27
+ "post_code": "<%= data[:agent_contact_post_code] %>",
28
+ "telephone": "<%= data[:agent_contact_telephone] %>",
29
+ "telephone_ext": "",
30
+ "fax": "",
31
+ "email": "<%= data[:agent_contact_email] %>",
32
+ "note": ""
33
+ }
34
+ ]
35
+ }
36
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "username": "<%= data[:username] %>",
3
+ "name": "<%= data[:name] %>",
4
+ "email": "<%= data[:email] %>",
5
+ "first_name": "<%= data[:first_name] %>",
6
+ "last_name": "<%= data[:last_name] %>",
7
+ "telephone": "<%= data[:telephone] %>",
8
+ "title": "<%= data[:title] %>",
9
+ "department": "<%= data[:department] %>",
10
+ "additional_contact": "<%= data[:additional_contact] %>",
11
+ "is_admin": <%= data[:is_admin] || "false" %>
12
+ }
@@ -0,0 +1,5 @@
1
+ module ArchivesSpace
2
+ class Client
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArchivesSpace::Client do
4
+
5
+ let(:client) { ArchivesSpace::Client.new }
6
+ let(:login) { -> { client.login } }
7
+
8
+ describe "Configuration" do
9
+
10
+ it 'will use the default configuration if none is provided' do
11
+ client = ArchivesSpace::Client.new
12
+ expect(client.config.base_uri).to eq DEFAULT_BASE_URI
13
+ end
14
+
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)
17
+ end
18
+
19
+ it 'will allow a configuration object to be provided' do
20
+ client = ArchivesSpace::Client.new(ArchivesSpace::Configuration.new({ base_uri: CUSTOM_BASE_URI }))
21
+ expect(client.config.base_uri).to eq CUSTOM_BASE_URI
22
+ end
23
+
24
+ end
25
+
26
+ describe "Version information" do
27
+
28
+ it 'has a version number' do
29
+ expect(ArchivesSpace::Client::VERSION).not_to be nil
30
+ end
31
+
32
+ it "can retrieve the backend version info" do
33
+ VCR.use_cassette('backend_version') do
34
+ login.call
35
+ response = client.get "version"
36
+ expect(response.status_code).to eq(200)
37
+ expect(response.body).to match(/ArchivesSpace \(.*\)/)
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArchivesSpace::Configuration do
4
+
5
+ it 'uses the default profile for configuration settings' do
6
+ config = ArchivesSpace::Configuration.new
7
+ expect(config.base_uri).to eq DEFAULT_BASE_URI
8
+ end
9
+
10
+ it 'allows configuration settings to be provided' do
11
+ config = ArchivesSpace::Configuration.new({
12
+ base_uri: CUSTOM_BASE_URI,
13
+ })
14
+ expect(config.base_uri).to eq CUSTOM_BASE_URI
15
+ end
16
+
17
+ it 'allows the configuration properties to be updated' do
18
+ config = ArchivesSpace::Configuration.new
19
+ config.base_uri = CUSTOM_BASE_URI
20
+ expect(config.base_uri).to eq CUSTOM_BASE_URI
21
+ end
22
+
23
+ it 'ignores unrecognized configuration properties' do
24
+ config = ArchivesSpace::Configuration.new({ xyz: 123 })
25
+ expect{ config.xyz }.to raise_error(NoMethodError)
26
+ end
27
+
28
+ end
@@ -0,0 +1,68 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://localhost:8089//users/admin/login?password=admin
6
+ body:
7
+ encoding: UTF-8
8
+ string: ''
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 200
13
+ message: OK
14
+ headers:
15
+ Date:
16
+ - Sat, 26 Dec 2015 05:05:14 GMT
17
+ Content-Type:
18
+ - application/json
19
+ Cache-Control:
20
+ - private, must-revalidate, max-age=0
21
+ Content-Length:
22
+ - '2491'
23
+ X-Content-Type-Options:
24
+ - nosniff
25
+ Server:
26
+ - Jetty(8.1.5.v20120716)
27
+ body:
28
+ encoding: UTF-8
29
+ string: |
30
+ {"session":"a1b9e7cac8fb01d2502678702c1eaa71b1fa6375a1de8b1f965095e71f4fd6f8","user":{"lock_version":84,"username":"admin","name":"Administrator","is_system_user":true,"create_time":"2015-12-24T05:51:42Z","system_mtime":"2015-12-26T05:05:14Z","user_mtime":"2015-12-26T05:05:14Z","jsonmodel_type":"user","groups":[],"is_admin":true,"uri":"/users/1","agent_record":{"ref":"/agents/people/1"},"permissions":{"/repositories/1":["update_location_record","delete_vocabulary_record","update_subject_record","delete_subject_record","update_agent_record","delete_agent_record","update_vocabulary_record","merge_subject_record","merge_agent_record","update_container_profile_record","administer_system","become_user","cancel_importer_job","create_repository","delete_archival_record","delete_classification_record","delete_event_record","delete_repository","import_records","index_system","manage_agent_record","manage_container_profile_record","manage_container_record","manage_rde_templates","manage_repository","manage_subject_record","manage_users","manage_vocabulary_record","mediate_edits","merge_agents_and_subjects","merge_archival_record","suppress_archival_record","system_config","transfer_archival_record","transfer_repository","update_accession_record","update_classification_record","update_container_record","update_digital_object_record","update_event_record","update_resource_record","view_all_records","view_repository","view_suppressed"],"_archivesspace":["administer_system","become_user","cancel_importer_job","create_repository","delete_archival_record","delete_classification_record","delete_event_record","delete_repository","import_records","index_system","manage_agent_record","manage_container_profile_record","manage_container_record","manage_rde_templates","manage_repository","manage_subject_record","manage_users","manage_vocabulary_record","mediate_edits","merge_agents_and_subjects","merge_archival_record","suppress_archival_record","system_config","transfer_archival_record","transfer_repository","update_accession_record","update_classification_record","update_container_record","update_digital_object_record","update_event_record","update_resource_record","view_all_records","view_repository","view_suppressed","update_location_record","delete_vocabulary_record","update_subject_record","delete_subject_record","update_agent_record","delete_agent_record","update_vocabulary_record","merge_subject_record","merge_agent_record","update_container_profile_record"]}}}
31
+ http_version:
32
+ recorded_at: Sat, 26 Dec 2015 05:05:14 GMT
33
+ - request:
34
+ method: get
35
+ uri: http://localhost:8089/version
36
+ body:
37
+ encoding: US-ASCII
38
+ string: ''
39
+ headers:
40
+ X-Archivesspace-Session:
41
+ - a1b9e7cac8fb01d2502678702c1eaa71b1fa6375a1de8b1f965095e71f4fd6f8
42
+ response:
43
+ status:
44
+ code: 200
45
+ message: OK
46
+ headers:
47
+ Date:
48
+ - Sat, 26 Dec 2015 05:05:14 GMT
49
+ Content-Type:
50
+ - text/html;charset=UTF-8
51
+ Cache-Control:
52
+ - private, must-revalidate, max-age=0
53
+ Content-Length:
54
+ - '29'
55
+ X-Xss-Protection:
56
+ - 1; mode=block
57
+ X-Content-Type-Options:
58
+ - nosniff
59
+ X-Frame-Options:
60
+ - SAMEORIGIN
61
+ Server:
62
+ - Jetty(8.1.5.v20120716)
63
+ body:
64
+ encoding: UTF-8
65
+ string: ArchivesSpace (20151120-0315)
66
+ http_version:
67
+ recorded_at: Sat, 26 Dec 2015 05:05:14 GMT
68
+ recorded_with: VCR 3.0.1
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'archivesspace/client'
3
+ require 'vcr'
4
+ require 'webmock/rspec'
5
+
6
+ # GLOBAL VALUES FOR SPECS
7
+ DEFAULT_BASE_URI = "http://localhost:8089"
8
+ CUSTOM_BASE_URI = "https://archives.university.edu/api"
9
+
10
+ VCR.configure do |c|
11
+ c.cassette_library_dir = "spec/fixtures/cassettes"
12
+ c.hook_into :webmock
13
+ c.default_cassette_options = { :record => :once }
14
+ end
metadata ADDED
@@ -0,0 +1,202 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: archivesspace-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mark Cooper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: vcr
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
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: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: httparty
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: json
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: nokogiri
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Interact with ArchivesSpace via its RESTful API.
140
+ email:
141
+ - mark.c.cooper@outlook.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".gitignore"
147
+ - ".rspec"
148
+ - ".travis.yml"
149
+ - Gemfile
150
+ - LICENSE.txt
151
+ - README.md
152
+ - Rakefile
153
+ - archivesspace-client.gemspec
154
+ - examples/export.rb
155
+ - examples/password_reset.rb
156
+ - examples/perms_and_groups.rb
157
+ - examples/repo_and_user.rb
158
+ - lib/archivesspace/client.rb
159
+ - lib/archivesspace/client/client.rb
160
+ - lib/archivesspace/client/configuration.rb
161
+ - lib/archivesspace/client/helpers.rb
162
+ - lib/archivesspace/client/request.rb
163
+ - lib/archivesspace/client/response.rb
164
+ - lib/archivesspace/client/template.rb
165
+ - lib/archivesspace/client/templates/digital_object.json.erb
166
+ - lib/archivesspace/client/templates/repository.json.erb
167
+ - lib/archivesspace/client/templates/repository_with_agent.json.erb
168
+ - lib/archivesspace/client/templates/user.json.erb
169
+ - lib/archivesspace/client/version.rb
170
+ - spec/archivesspace/client_spec.rb
171
+ - spec/archivesspace/configuration_spec.rb
172
+ - spec/fixtures/cassettes/backend_version.yml
173
+ - spec/spec_helper.rb
174
+ homepage: ''
175
+ licenses:
176
+ - MIT
177
+ metadata: {}
178
+ post_install_message:
179
+ rdoc_options: []
180
+ require_paths:
181
+ - lib
182
+ required_ruby_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ requirements: []
193
+ rubyforge_project:
194
+ rubygems_version: 2.2.2
195
+ signing_key:
196
+ specification_version: 4
197
+ summary: Interact with ArchivesSpace via its RESTful API.
198
+ test_files:
199
+ - spec/archivesspace/client_spec.rb
200
+ - spec/archivesspace/configuration_spec.rb
201
+ - spec/fixtures/cassettes/backend_version.yml
202
+ - spec/spec_helper.rb