archivesspace-client 0.1.12 → 0.3.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.
@@ -4,23 +4,24 @@ module ArchivesSpace
4
4
  class Configuration
5
5
  def defaults
6
6
  {
7
- base_uri: 'http://localhost:8089',
8
- base_repo: '',
7
+ base_uri: "http://localhost:8089",
8
+ base_repo: "",
9
9
  debug: false,
10
- username: 'admin',
11
- password: 'admin',
10
+ username: "admin",
11
+ password: "admin",
12
12
  page_size: 50,
13
13
  throttle: 0,
14
- verify_ssl: true
14
+ verify_ssl: true,
15
+ timeout: 60
15
16
  }
16
17
  end
17
18
 
18
19
  def initialize(settings = {})
19
20
  settings = defaults.merge(settings)
20
21
  settings.each do |property, value|
21
- next unless defaults.keys.include? property
22
+ next unless defaults.key?(property)
22
23
 
23
- instance_variable_set("@#{property}", value)
24
+ instance_variable_set(:"@#{property}", value)
24
25
  self.class.send(:attr_accessor, property)
25
26
  end
26
27
  end
@@ -20,7 +20,7 @@ module ArchivesSpace
20
20
  ]
21
21
 
22
22
  ENDPOINTS.each do |endpoint|
23
- method_name = endpoint.split('/').last # remove prefix
23
+ method_name = endpoint.split("/").last # remove prefix
24
24
  define_method(method_name) do |options = {}|
25
25
  all(endpoint, options)
26
26
  end
@@ -36,8 +36,8 @@ module ArchivesSpace
36
36
  result = get(path, options)
37
37
  results = []
38
38
 
39
- if result.parsed.respond_to?(:key) && result.parsed.key?('results')
40
- results = result.parsed['results']
39
+ if result.parsed.respond_to?(:key) && result.parsed.key?("results")
40
+ results = result.parsed["results"]
41
41
  else
42
42
  results = result.parsed
43
43
  unlimited_listing = true
@@ -10,26 +10,28 @@ module ArchivesSpace
10
10
  delete: {},
11
11
  get: {},
12
12
  post: {
13
- 'Content-Type' => 'application/json',
14
- 'Content-Length' => 'nnnn'
13
+ "Content-Type" => "application/json",
14
+ "Content-Length" => "nnnn"
15
15
  },
16
16
  put: {
17
- 'Content-Type' => 'application/json',
18
- 'Content-Length' => 'nnnn'
17
+ "Content-Type" => "application/json",
18
+ "Content-Length" => "nnnn"
19
19
  }
20
20
  }
21
21
  headers[method]
22
22
  end
23
23
 
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
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
29
  @options[:headers] =
30
30
  options[:headers] ? default_headers(@method).merge(options[:headers]) : default_headers(@method)
31
- @options[:verify] = config.verify_ssl
32
- @options[:query] = {} unless options.key? :query
31
+ @options[:headers]["User-Agent"] = "#{Client::NAME}/#{Client::VERSION}"
32
+ @options[:verify] = config.verify_ssl
33
+ @options[:timeout] = config.timeout
34
+ @options[:query] = {} unless options.key? :query
33
35
 
34
36
  self.class.debug_output($stdout) if @config.debug
35
37
 
@@ -5,11 +5,11 @@ module ArchivesSpace
5
5
  attr_reader :result, :parsed, :body, :headers, :status, :status_code
6
6
 
7
7
  def initialize(result)
8
- @result = result
9
- @parsed = result.parsed_response
10
- @body = result.body
11
- @headers = result.headers
12
- @status = result.response
8
+ @result = result
9
+ @parsed = result.parsed_response
10
+ @body = result.body
11
+ @headers = result.headers
12
+ @status = result.response
13
13
  @status_code = result.code.to_i
14
14
  end
15
15
  end
@@ -10,51 +10,51 @@ module ArchivesSpace
10
10
  def group_user_assignment(users_with_roles)
11
11
  updated = []
12
12
  groups.each do |group|
13
- group = get("groups/#{uri_to_id(group['uri'])}").parsed
13
+ group = get("groups/#{uri_to_id(group["uri"])}").parsed
14
14
  update = false
15
15
 
16
16
  users_with_roles.each do |user, roles|
17
17
  # should the user still belong to this group?
18
- if group['member_usernames'].include?(user)
19
- unless roles.include? group['group_code']
20
- group['member_usernames'].delete user
18
+ if group["member_usernames"].include?(user)
19
+ unless roles.include? group["group_code"]
20
+ group["member_usernames"].delete user
21
21
  update = true
22
22
  end
23
23
  # should the user be added to this group?
24
- elsif roles.include? group['group_code']
25
- group['member_usernames'] << user
24
+ elsif roles.include? group["group_code"]
25
+ group["member_usernames"] << user
26
26
  update = true
27
27
  end
28
28
  end
29
29
 
30
30
  next unless update
31
31
 
32
- response = post("/groups/#{uri_to_id(group['uri'])}", group.to_json)
32
+ response = post("/groups/#{uri_to_id(group["uri"])}", group.to_json)
33
33
  updated << response
34
34
  end
35
35
  updated
36
36
  end
37
37
 
38
38
  def login
39
- username = config.username
40
- password = config.password
39
+ username = config.username
40
+ password = config.password
41
41
  base_repo = config.base_repo
42
42
  use_global_repository # ensure we're in the global scope to login
43
- result = request('POST', "/users/#{username}/login", { query: { password: password } })
44
- unless result.parsed['session']
43
+ result = request("POST", "/users/#{username}/login", {query: {password: password}})
44
+ unless result.parsed["session"]
45
45
  raise ConnectionError, "API client login failed as user [#{username}], check username and password are correct"
46
46
  end
47
47
 
48
48
  config.base_repo = base_repo # reset repo as set by the cfg
49
- @token = result.parsed['session']
49
+ @token = result.parsed["session"]
50
50
  self
51
51
  end
52
52
 
53
53
  def password_reset(username, password)
54
- user = all('users').find { |u| u['username'] == username }
54
+ user = all("users").find { |u| u["username"] == username }
55
55
  raise RequestError, user.status unless user
56
56
 
57
- post(user['uri'], user.to_json, { password: password })
57
+ post(user["uri"], user.to_json, {password: password})
58
58
  end
59
59
 
60
60
  # def search(params)
@@ -64,7 +64,7 @@ module ArchivesSpace
64
64
  private
65
65
 
66
66
  def uri_to_id(uri)
67
- uri.split('/').last
67
+ uri.split("/").last
68
68
  end
69
69
  end
70
70
  end
@@ -3,24 +3,67 @@
3
3
  module ArchivesSpace
4
4
  module Template
5
5
  def self.list
6
- Dir.glob File.join(templates_path, '*.erb')
6
+ Dir.glob ["*"], base: File.join(templates_path)
7
7
  end
8
8
 
9
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
- end
14
-
15
- def self.read(file)
16
- File.read("#{templates_path}/#{file}.json.erb")
10
+ processor = File.extname(template).delete(".").camelize
11
+ processor = Object.const_get("ArchivesSpace::Template::#{processor}")
12
+ processor.new(template, data).process
17
13
  end
18
14
 
19
15
  def self.templates_path
20
16
  ENV.fetch(
21
- 'ARCHIVESSPACE_CLIENT_TEMPLATES_PATH',
22
- File.join(File.dirname(File.expand_path(__FILE__)), 'templates')
17
+ "ARCHIVESSPACE_CLIENT_TEMPLATES_PATH",
18
+ File.join(File.dirname(File.expand_path(__FILE__)), "templates")
23
19
  )
24
20
  end
21
+
22
+ class Processor
23
+ attr_reader :template, :data
24
+
25
+ def initialize(template, data)
26
+ @template = template
27
+ @data = data
28
+
29
+ validate_template
30
+ end
31
+
32
+ def extension
33
+ raise "Not implemented"
34
+ end
35
+
36
+ def read_template
37
+ File.read(File.join(ArchivesSpace::Template.templates_path, template))
38
+ end
39
+
40
+ def validate_template
41
+ raise "Invalid template" unless File.extname(template).end_with? extension
42
+ end
43
+ end
44
+
45
+ class Erb < Processor
46
+ def extension
47
+ ".erb"
48
+ end
49
+
50
+ def process
51
+ t = ERB.new(read_template)
52
+ r = t.result(binding).squeeze("\n")
53
+ JSON.parse(r).to_json
54
+ end
55
+ end
56
+
57
+ class Jbuilder < Processor
58
+ def extension
59
+ ".jbuilder"
60
+ end
61
+
62
+ def process
63
+ ::Jbuilder.encode do |json|
64
+ eval(read_template, binding) # standard:disable Security/Eval
65
+ end
66
+ end
67
+ end
25
68
  end
26
69
  end
@@ -0,0 +1,7 @@
1
+ json.id_0 data["object_number"]
2
+ json.title data["title"]
3
+ json.level data["description_level"]
4
+
5
+ # json.id_0 "001.001"
6
+ # json.title "Title"
7
+ # json.level "collection"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ArchivesSpace
4
4
  class Client
5
- VERSION = '0.1.12'
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
@@ -1,34 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/cli'
4
- require 'httparty'
5
- require 'json'
6
- require 'nokogiri'
3
+ require "dry/cli"
4
+ require "httparty"
5
+ require "json"
6
+ require "nokogiri"
7
+ require "jbuilder"
7
8
 
8
9
  # mixins required first
9
- require 'archivesspace/client/pagination'
10
- require 'archivesspace/client/task'
10
+ require "archivesspace/client/pagination"
11
+ require "archivesspace/client/task"
11
12
 
12
- require 'archivesspace/client/client'
13
- require 'archivesspace/client/configuration'
14
- require 'archivesspace/client/request'
15
- require 'archivesspace/client/response'
16
- require 'archivesspace/client/template'
17
- require 'archivesspace/client/version'
13
+ require "archivesspace/client/client"
14
+ require "archivesspace/client/configuration"
15
+ require "archivesspace/client/request"
16
+ require "archivesspace/client/response"
17
+ require "archivesspace/client/template"
18
+ require "archivesspace/client/version"
18
19
 
19
20
  # cli
20
- require 'archivesspace/client/cli/exec'
21
- require 'archivesspace/client/cli/version'
22
- require 'archivesspace/client/cli' # load the registry last
21
+ require "archivesspace/client/cli/exec"
22
+ require "archivesspace/client/cli/version"
23
+ require "archivesspace/client/cli" # load the registry last
23
24
 
24
25
  module ArchivesSpace
25
26
  class ConnectionError < RuntimeError; end
26
27
 
27
- class ContextError < RuntimeError; end
28
+ class ContextError < RuntimeError; end
28
29
 
29
30
  class RepositoryIdError < RuntimeError; end
30
31
 
31
- class ParamsError < RuntimeError; end
32
+ class ParamsError < RuntimeError; end
32
33
 
33
- class RequestError < RuntimeError; end
34
+ class RequestError < RuntimeError; end
34
35
  end
@@ -1,87 +1,85 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe ArchivesSpace::Client do
6
6
  let(:client) { ArchivesSpace::Client.new }
7
- let(:login) { -> { client.login } }
8
7
 
9
- describe 'Configuration' do
10
- it 'will use the default configuration if none is provided' do
11
- client = ArchivesSpace::Client.new
8
+ describe "Configuration" do
9
+ it "will use the default configuration if none is provided" do
12
10
  expect(client.config.base_uri).to eq DEFAULT_BASE_URI
13
11
  end
14
12
 
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)
13
+ it "will raise an error if supplied configuration is of invalid type" do
14
+ expect { ArchivesSpace::Client.new({base_uri: CUSTOM_BASE_URI}) }.to raise_error(RuntimeError)
17
15
  end
18
16
 
19
- it 'will allow a configuration object to be provided' do
20
- client = ArchivesSpace::Client.new(ArchivesSpace::Configuration.new({ base_uri: CUSTOM_BASE_URI }))
17
+ it "will allow a configuration object to be provided" do
18
+ client = ArchivesSpace::Client.new(ArchivesSpace::Configuration.new({base_uri: CUSTOM_BASE_URI}))
21
19
  expect(client.config.base_uri).to eq CUSTOM_BASE_URI
22
20
  end
23
21
  end
24
22
 
25
- describe 'Repository scoping' do
26
- it 'will set the repository with an integer id' do
27
- client = ArchivesSpace::Client.new
23
+ describe "Repository scoping" do
24
+ it "will set the repository with an integer id" do
28
25
  client.repository 2
29
- expect(client.config.base_repo).to eq 'repositories/2'
26
+ expect(client.config.base_repo).to eq "repositories/2"
30
27
  end
31
28
 
32
- it 'will set the repository with a string id cast to integer' do
33
- client = ArchivesSpace::Client.new
34
- client.repository '2'
35
- expect(client.config.base_repo).to eq 'repositories/2'
29
+ it "will set the repository with a string id cast to integer" do
30
+ client.repository "2"
31
+ expect(client.config.base_repo).to eq "repositories/2"
36
32
  end
37
33
 
38
- it 'will fail if the id cannot be cast to integer' do
39
- client = ArchivesSpace::Client.new
40
- expect { client.repository('xyz') }.to raise_error(
34
+ it "will fail if the id cannot be cast to integer" do
35
+ expect { client.repository("xyz") }.to raise_error(
41
36
  ArchivesSpace::RepositoryIdError
42
37
  )
43
38
  end
44
39
 
45
- it 'will use the global repo if repository is passed nil' do
46
- client = ArchivesSpace::Client.new
40
+ it "will use the global repo if repository is passed nil" do
47
41
  client.repository 2
48
42
  client.repository nil
49
- expect(client.config.base_repo).to eq ''
43
+ expect(client.config.base_repo).to eq ""
50
44
  end
51
45
 
52
- it 'will use the global repo when the method is called' do
53
- client = ArchivesSpace::Client.new
46
+ it "will use the global repo when the method is called" do
54
47
  client.repository 2
55
48
  client.use_global_repository
56
- expect(client.config.base_repo).to eq ''
49
+ expect(client.config.base_repo).to eq ""
57
50
  end
58
51
  end
59
52
 
60
- describe 'Pagination' do
61
- it 'will have a method for defined paginated record types' do
62
- client = ArchivesSpace::Client.new
53
+ describe "Requests" do
54
+ it "will have an identifiable user agent" do
55
+ request = ArchivesSpace::Request.new(client.config)
56
+ expect(request.options[:headers]["User-Agent"]).to eq "#{ArchivesSpace::Client::NAME}/#{ArchivesSpace::Client::VERSION}"
57
+ end
58
+ end
59
+
60
+ describe "Pagination" do
61
+ it "will have a method for defined paginated record types" do
63
62
  ArchivesSpace::Pagination::ENDPOINTS.each do |e|
64
- next if e.match?('/')
63
+ next if e.match?("/")
65
64
 
66
65
  expect(client.respond_to?(e.to_sym)).to be true
67
66
  end
68
67
  end
69
68
 
70
- it 'will have a method for defined paginated record types with multipart path' do
71
- client = ArchivesSpace::Client.new
69
+ it "will have a method for defined paginated record types with multipart path" do
72
70
  expect(client.respond_to?(:people)).to be true
73
71
  end
74
72
  end
75
73
 
76
- describe 'Version information' do
77
- it 'has a version number' do
74
+ describe "Version information" do
75
+ it "has a version number" do
78
76
  expect(ArchivesSpace::Client::VERSION).not_to be nil
79
77
  end
80
78
 
81
- it 'can retrieve the backend version info' do
82
- VCR.use_cassette('backend_version') do
83
- login.call
84
- response = client.get 'version'
79
+ it "can retrieve the backend version info" do
80
+ VCR.use_cassette("backend_version") do
81
+ client.login
82
+ response = client.get "version"
85
83
  expect(response.status_code).to eq(200)
86
84
  expect(response.body).to match(/ArchivesSpace \(.*\)/)
87
85
  end
@@ -1,28 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe ArchivesSpace::Configuration do
6
- it 'uses the default profile for configuration settings' do
6
+ it "uses the default profile for configuration settings" do
7
7
  config = ArchivesSpace::Configuration.new
8
8
  expect(config.base_uri).to eq DEFAULT_BASE_URI
9
9
  end
10
10
 
11
- it 'allows configuration settings to be provided' do
11
+ it "allows configuration settings to be provided" do
12
12
  config = ArchivesSpace::Configuration.new({
13
- base_uri: CUSTOM_BASE_URI
14
- })
13
+ base_uri: CUSTOM_BASE_URI
14
+ })
15
15
  expect(config.base_uri).to eq CUSTOM_BASE_URI
16
16
  end
17
17
 
18
- it 'allows the configuration properties to be updated' do
18
+ it "allows the configuration properties to be updated" do
19
19
  config = ArchivesSpace::Configuration.new
20
20
  config.base_uri = CUSTOM_BASE_URI
21
21
  expect(config.base_uri).to eq CUSTOM_BASE_URI
22
22
  end
23
23
 
24
- it 'ignores unrecognized configuration properties' do
25
- config = ArchivesSpace::Configuration.new({ xyz: 123 })
24
+ it "ignores unrecognized configuration properties" do
25
+ config = ArchivesSpace::Configuration.new({xyz: 123})
26
26
  expect { config.xyz }.to raise_error(NoMethodError)
27
27
  end
28
28
  end
@@ -1,26 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe ArchivesSpace::Template do
6
- it 'can list the default templates' do
6
+ it "can list the default templates" do
7
7
  templates = ArchivesSpace::Template.list
8
8
  expect(templates).to_not be_empty
9
9
  expect(templates).to include(/repository_with_agent.*erb/)
10
+ expect(templates).to include(/resource.*jbuilder/)
10
11
  end
11
12
 
12
- it 'can change the path when template envvar is set' do
13
+ it "can change the path when template envvar is set" do
13
14
  expect(ArchivesSpace::Template.templates_path).to match(
14
- /#{File.join('lib', 'archivesspace', 'client', 'templates')}/
15
+ /#{File.join("lib", "archivesspace", "client", "templates")}/
15
16
  )
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')
17
+ ENV["ARCHIVESSPACE_CLIENT_TEMPLATES_PATH"] = "/path/to/nowhere"
18
+ expect(ArchivesSpace::Template.templates_path).to eq "/path/to/nowhere"
19
+ ENV.delete("ARCHIVESSPACE_CLIENT_TEMPLATES_PATH")
19
20
  end
20
21
 
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]
22
+ it "can process an erb template" do
23
+ data = {repo_code: "ABC", name: "ABC Archive", agent_contact_name: "ABC Admin"}
24
+ json = JSON.parse(ArchivesSpace::Template.process("repository_with_agent.json.erb", data))
25
+ expect(json["repository"]["repo_code"]).to eq data[:repo_code]
26
+ end
27
+
28
+ it "can process a jbuilder template" do
29
+ data = {"title" => "Title", "object_number" => "001.001", "description_level" => "collection"}
30
+ json = JSON.parse(ArchivesSpace::Template.process("resource.json.jbuilder", data))
31
+ expect(json["id_0"]).to eq data["object_number"]
32
+ end
33
+
34
+ it "rejects a template that does not match by extension" do
35
+ data = {"title" => "Title"}
36
+ expect {
37
+ JSON.parse(ArchivesSpace::Template::Erb.new("resource.json.jbuilder", data).process)
38
+ }.to raise_error "Invalid template"
25
39
  end
26
40
  end