archivesspace-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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