collectionspace-client 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/README.md +16 -59
- data/Rakefile +3 -3
- data/collectionspace-client.gemspec +19 -19
- data/examples/demo.rb +12 -11
- data/examples/media_with_external_file.rb +18 -18
- data/examples/purge_empty_vocabs.rb +20 -0
- data/examples/search.rb +13 -59
- data/lib/collectionspace/client/client.rb +16 -13
- data/lib/collectionspace/client/configuration.rb +8 -10
- data/lib/collectionspace/client/helpers.rb +19 -91
- data/lib/collectionspace/client/request.rb +15 -13
- data/lib/collectionspace/client/response.rb +5 -11
- data/lib/collectionspace/client/search.rb +6 -5
- data/lib/collectionspace/client/version.rb +1 -1
- data/lib/collectionspace/client.rb +11 -13
- metadata +21 -7
- data/examples/export.rb +0 -31
- data/examples/purge-empty-vocabularies.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 624c2100ab4de83a3748eea7ec37a0fd4743cdda9365e8ccd29d452b11f0b8ad
|
4
|
+
data.tar.gz: 7f25d8c31ad74c28999de4bb5c5822f655f947154828174a3351d818e036a5f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d65eaf040bb629d702085af054b47b2f39411784c0f8f7cdb032f48af79f99b846ef1f803ef357634d477f4b4d7c9f585e07c1d5b5e9476f22247b67ae0cd00c
|
7
|
+
data.tar.gz: 0661b69f11ea60a5ce5edc94f753a048a7ec6ce2585c855c69af25e4cfb1998106a13132e42fdbe8b70a5184a6032c817650253ebf215930a83ba7e1dd73a42d
|
data/.rubocop.yml
ADDED
data/README.md
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
CollectionSpace Client
|
2
|
-
===
|
1
|
+
# CollectionSpace Client
|
3
2
|
|
4
3
|
CollectionSpace API client.
|
5
4
|
|
6
|
-
Installation
|
7
|
-
---
|
5
|
+
## Installation
|
8
6
|
|
9
7
|
Add this line to your application's Gemfile:
|
10
8
|
|
@@ -12,54 +10,13 @@ Add this line to your application's Gemfile:
|
|
12
10
|
gem 'collectionspace-client'
|
13
11
|
```
|
14
12
|
|
15
|
-
And then execute:
|
16
|
-
|
17
|
-
$ bundle install
|
18
|
-
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install collectionspace-client
|
22
|
-
|
23
|
-
Usage
|
24
|
-
---
|
25
|
-
|
26
|
-
Basic usage:
|
27
|
-
|
28
|
-
```ruby
|
29
|
-
require 'collectionspace/client'
|
30
|
-
|
31
|
-
config = CollectionSpace::Configuration.new({
|
32
|
-
base_uri: "https://cspace.muesum.org/cspace-services",
|
33
|
-
username: "admin@cspace.muesum.org",
|
34
|
-
password: "Administrator",
|
35
|
-
})
|
36
|
-
|
37
|
-
client = CollectionSpace::Client.new(config)
|
38
|
-
|
39
|
-
result = client.post_blob_uri "http://cspace.muesum.org/assets/mueseum.png"
|
40
|
-
|
41
|
-
raise "=(" if result.status_code != 201
|
13
|
+
And then execute `bundle install`, or install it yourself as: `gem install collectionspace-client`.
|
42
14
|
|
43
|
-
|
44
|
-
path: "blobs",
|
45
|
-
type: "blobs_common",
|
46
|
-
field: "name",
|
47
|
-
expression: "ILIKE '%museum.png%'",
|
48
|
-
}
|
15
|
+
## Usage
|
49
16
|
|
50
|
-
|
17
|
+
See the sample scripts within the [examples](examples/) directory.
|
51
18
|
|
52
|
-
|
53
|
-
|
54
|
-
if result.status_code == 200
|
55
|
-
ap result.parsed['abstract_common_list']
|
56
|
-
end
|
57
|
-
```
|
58
|
-
|
59
|
-
See the sample scripts within the `examples` directory for more.
|
60
|
-
|
61
|
-
Development
|
62
|
-
---
|
19
|
+
## Development
|
63
20
|
|
64
21
|
To run the examples:
|
65
22
|
|
@@ -75,26 +32,26 @@ To run the tests:
|
|
75
32
|
bundle exec rake
|
76
33
|
```
|
77
34
|
|
78
|
-
Publishing
|
79
|
-
---
|
35
|
+
## Publishing
|
80
36
|
|
81
37
|
Bump version in `lib/collectionspace/client/version.rb` then:
|
82
38
|
|
83
39
|
```bash
|
84
|
-
VERSION=0.
|
85
|
-
|
86
|
-
|
40
|
+
VERSION=0.2.0
|
41
|
+
git add .
|
42
|
+
git commit -m "Bump version: v${VERSION}"
|
43
|
+
git push origin master
|
87
44
|
git tag v$VERSION
|
88
45
|
git push --tags
|
46
|
+
gem build collectionspace-client
|
47
|
+
gem push collectionspace-client-$VERSION.gem
|
89
48
|
```
|
90
49
|
|
91
|
-
Contributing
|
92
|
-
---
|
50
|
+
## Contributing
|
93
51
|
|
94
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
52
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/collectionspace/collectionspace-client.
|
95
53
|
|
96
|
-
License
|
97
|
-
---
|
54
|
+
## License
|
98
55
|
|
99
56
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
100
57
|
|
data/Rakefile
CHANGED
@@ -1,31 +1,31 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'collectionspace/client/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'collectionspace-client'
|
8
7
|
spec.version = CollectionSpace::Client::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
8
|
+
spec.authors = ['Mark Cooper']
|
9
|
+
spec.email = ['mark.cooper@lyrasis.org']
|
11
10
|
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
11
|
+
spec.summary = 'CollectionSpace API client.'
|
12
|
+
spec.homepage = 'https://github.com/lyrasis/collectionspace-client.git'
|
13
|
+
spec.license = 'MIT'
|
15
14
|
|
16
15
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
-
spec.bindir =
|
16
|
+
spec.bindir = 'exe'
|
18
17
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
-
spec.require_paths = [
|
18
|
+
spec.require_paths = ['lib']
|
20
19
|
|
21
|
-
spec.add_dependency
|
22
|
-
spec.add_dependency
|
23
|
-
spec.add_dependency
|
20
|
+
spec.add_dependency 'httparty'
|
21
|
+
spec.add_dependency 'json'
|
22
|
+
spec.add_dependency 'nokogiri'
|
24
23
|
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
24
|
+
spec.add_development_dependency 'awesome_print'
|
25
|
+
spec.add_development_dependency 'bundler'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rspec'
|
28
|
+
spec.add_development_dependency 'rubocop'
|
29
|
+
spec.add_development_dependency 'vcr'
|
30
|
+
spec.add_development_dependency 'webmock'
|
31
31
|
end
|
data/examples/demo.rb
CHANGED
@@ -1,21 +1,22 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
2
2
|
require 'awesome_print'
|
3
3
|
require 'collectionspace/client'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
client = CollectionSpace::Client.new(
|
6
|
+
CollectionSpace::Configuration.new(
|
7
|
+
base_uri: 'https://core.dev.collectionspace.org/cspace-services',
|
8
|
+
username: 'admin@core.collectionspace.org',
|
9
|
+
password: 'Administrator'
|
10
|
+
)
|
11
|
+
)
|
7
12
|
client.config.throttle = 1
|
8
13
|
|
9
14
|
# GET REQUEST FOR CONDITIONCHECK RECORDS AND PRINT THE PARSED RESPONSE AND XML
|
10
15
|
response = client.get('conditionchecks')
|
11
|
-
|
12
|
-
ap response.parsed
|
13
|
-
ap response.xml
|
14
|
-
end
|
16
|
+
ap response.parsed if response.result.success?
|
15
17
|
|
16
18
|
# GET ALL INTAKE RECORDS AND PROCESS PER PAGE (INSTEAD OF WAITING FOR ALL)
|
17
|
-
client.all('
|
18
|
-
|
19
|
-
|
20
|
-
ap intake.parsed
|
19
|
+
client.all('personauthorities').each do |item|
|
20
|
+
i = client.get item['uri']
|
21
|
+
ap i.parsed
|
21
22
|
end
|
@@ -1,26 +1,26 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
2
2
|
require 'awesome_print'
|
3
3
|
require 'collectionspace/client'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
client = CollectionSpace::Client.new(
|
6
|
+
CollectionSpace::Configuration.new(
|
7
|
+
base_uri: 'https://core.dev.collectionspace.org/cspace-services',
|
8
|
+
username: 'admin@core.collectionspace.org',
|
9
|
+
password: 'Administrator'
|
10
|
+
)
|
11
|
+
)
|
7
12
|
client.config.throttle = 1
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
media_url = "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
|
14
|
+
media_url = 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png'
|
12
15
|
media = <<-XML
|
13
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
14
|
-
<document name="media">
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
</document>
|
16
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
17
|
+
<document name="media">
|
18
|
+
<ns2:media_common xmlns:ns2="http://collectionspace.org/services/media" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
19
|
+
<title>GOOGLE</title>
|
20
|
+
<identificationNumber>GOOGLE-1</identificationNumber>
|
21
|
+
</ns2:media_common>
|
22
|
+
</document>
|
20
23
|
XML
|
21
24
|
|
22
|
-
response = client.post('media', media,
|
23
|
-
puts response.
|
24
|
-
if response.status_code == 201
|
25
|
-
puts response.headers['location']
|
26
|
-
end
|
25
|
+
response = client.post('media', media, query: { 'blobUri' => media_url })
|
26
|
+
puts response.result.headers['location'] if response.result.success?
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
2
|
+
require 'collectionspace/client'
|
3
|
+
|
4
|
+
client = CollectionSpace::Client.new(
|
5
|
+
CollectionSpace::Configuration.new(
|
6
|
+
base_uri: 'https://core.dev.collectionspace.org/cspace-services',
|
7
|
+
username: 'admin@core.collectionspace.org',
|
8
|
+
password: 'Administrator'
|
9
|
+
)
|
10
|
+
)
|
11
|
+
client.config.throttle = 1
|
12
|
+
|
13
|
+
client.all('vocabularies').each do |item|
|
14
|
+
uri = item['uri']
|
15
|
+
puts "Checking vocabulary: #{uri}"
|
16
|
+
next unless client.count("#{uri}/items").zero?
|
17
|
+
|
18
|
+
puts "Purging empty vocabulary:\t#{item['displayName']} (#{item['csid']})"
|
19
|
+
client.delete uri
|
20
|
+
end
|
data/examples/search.rb
CHANGED
@@ -1,67 +1,21 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
2
2
|
require 'awesome_print'
|
3
3
|
require 'collectionspace/client'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
config = CollectionSpace::Configuration.new(
|
6
|
+
base_uri: 'https://core.dev.collectionspace.org/cspace-services',
|
7
|
+
username: 'admin@core.collectionspace.org',
|
8
|
+
password: 'Administrator'
|
9
|
+
)
|
7
10
|
|
8
|
-
|
9
|
-
search_args = {
|
10
|
-
path: "collectionobjects",
|
11
|
-
type: "collectionobjects_common",
|
12
|
-
field: 'titleGroupList/*1/title',
|
13
|
-
expression: "ILIKE '%blue%'",
|
14
|
-
}
|
15
|
-
|
16
|
-
query = CollectionSpace::Search.new.from_hash search_args
|
17
|
-
ap client.search(query).parsed
|
18
|
-
|
19
|
-
# SEARCH AND REFORMAT RESULTS
|
20
|
-
|
21
|
-
# assume retrieved for collectionobject i.e.: AttributeMap.where(type: 'collectionobject')
|
22
|
-
attribute_map = [
|
23
|
-
{ field: 'title', key: 'collectionobjects_common', nested_key: 'title', with: nil },
|
24
|
-
{ field: 'title_type', key: 'collectionobjects_common', nested_key: 'titleType', with: nil },
|
25
|
-
{ field: 'display_date', key: 'collectionobjects_common', nested_key: 'dateDisplayDate', with: nil },
|
26
|
-
{ field: 'object_production_person_group', key: 'collectionobjects_common', nested_key: 'objectProductionPersonGroup', with: 'objectProductionPerson' },
|
27
|
-
{ field: 'content_persons', key: 'collectionobjects_common', nested_key: 'contentPersons', with: 'contentPerson' },
|
28
|
-
{ field: 'responsible_department', key: 'collectionobjects_common', nested_key: 'responsibleDepartment', with: nil },
|
29
|
-
{ field: 'created_by', key: 'collectionspace_core', nested_key: 'createdBy', with: nil },
|
30
|
-
{ field: 'created_at', key: 'collectionspace_core', nested_key: 'createdAt', with: nil },
|
31
|
-
{ field: 'updated_at', key: 'collectionspace_core', nested_key: 'updatedAt', with: nil },
|
32
|
-
]
|
11
|
+
client = CollectionSpace::Client.new(config)
|
33
12
|
|
34
13
|
search_args = {
|
35
|
-
path:
|
36
|
-
type:
|
37
|
-
field: '
|
38
|
-
expression: "
|
14
|
+
path: 'groups',
|
15
|
+
type: 'groups_common',
|
16
|
+
field: 'title',
|
17
|
+
expression: "ILIKE '%DTS 001%'"
|
39
18
|
}
|
40
19
|
|
41
|
-
|
42
|
-
|
43
|
-
result = client.search(query)
|
44
|
-
if result.status_code == 200
|
45
|
-
data = result.parsed["abstract_common_list"]["list_item"]
|
46
|
-
data.each do |item|
|
47
|
-
record = client.get(item["uri"]).parsed
|
48
|
-
|
49
|
-
attributes = {}
|
50
|
-
attribute_map.each do |map|
|
51
|
-
if map[:with]
|
52
|
-
as = client.deep_find(record, map[:key], map[:nested_key])
|
53
|
-
values = []
|
54
|
-
if as.is_a? Array
|
55
|
-
values = as.map { |a| client.strip_refname( client.deep_find(a, map[:with]) ) }
|
56
|
-
elsif as.is_a? Hash and as[ map[:with] ]
|
57
|
-
values = as[ map[:with] ].is_a?(Array) ? as[ map[:with] ].map { |a| client.strip_refname(a) } : [ client.strip_refname(as[ map[:with] ]) ]
|
58
|
-
end
|
59
|
-
attributes[map[:field]] = values
|
60
|
-
else
|
61
|
-
attributes[map[:field]] = client.deep_find(record, map[:key], map[:nested_key])
|
62
|
-
end
|
63
|
-
end
|
64
|
-
# PRINT REFORMATTED RESULTS
|
65
|
-
ap attributes
|
66
|
-
end
|
67
|
-
end
|
20
|
+
response = client.search(CollectionSpace::Search.new.from_hash(search_args))
|
21
|
+
ap response.parsed['abstract_common_list'] if response.result.success?
|
@@ -1,12 +1,14 @@
|
|
1
1
|
module CollectionSpace
|
2
|
-
|
2
|
+
# CollectionSpace client
|
3
3
|
class Client
|
4
|
-
include DeepFind
|
5
4
|
include Helpers
|
6
5
|
attr_reader :config
|
7
6
|
|
8
7
|
def initialize(config = Configuration.new)
|
9
|
-
|
8
|
+
unless config.is_a? CollectionSpace::Configuration
|
9
|
+
raise CollectionSpace::ArgumentError, 'Invalid configuration object'
|
10
|
+
end
|
11
|
+
|
10
12
|
@config = config
|
11
13
|
end
|
12
14
|
|
@@ -14,15 +16,14 @@ module CollectionSpace
|
|
14
16
|
request 'GET', path, options
|
15
17
|
end
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
request 'POST', path, { body: payload }.merge(additional_options)
|
19
|
+
def post(path, payload, options = {})
|
20
|
+
check_payload(payload)
|
21
|
+
request 'POST', path, { body: payload }.merge(options)
|
21
22
|
end
|
22
23
|
|
23
24
|
def put(path, payload)
|
24
|
-
|
25
|
-
request 'PUT', path,
|
25
|
+
check_payload(payload)
|
26
|
+
request 'PUT', path, body: payload
|
26
27
|
end
|
27
28
|
|
28
29
|
def delete(path)
|
@@ -31,12 +32,14 @@ module CollectionSpace
|
|
31
32
|
|
32
33
|
private
|
33
34
|
|
35
|
+
def check_payload(payload)
|
36
|
+
errors = Nokogiri::XML(payload).errors
|
37
|
+
raise CollectionSpace::PayloadError, errors if errors.any?
|
38
|
+
end
|
39
|
+
|
34
40
|
def request(method, path, options = {})
|
35
41
|
sleep config.throttle
|
36
|
-
|
37
|
-
Response.new result
|
42
|
+
Response.new(Request.new(config, method, path, options).execute)
|
38
43
|
end
|
39
|
-
|
40
44
|
end
|
41
|
-
|
42
45
|
end
|
@@ -1,28 +1,26 @@
|
|
1
1
|
module CollectionSpace
|
2
|
-
|
2
|
+
# CollectionSpace configuration
|
3
3
|
class Configuration
|
4
|
-
|
5
4
|
def defaults
|
6
5
|
{
|
7
|
-
base_uri:
|
8
|
-
username:
|
9
|
-
password:
|
10
|
-
page_size:
|
6
|
+
base_uri: nil,
|
7
|
+
username: nil,
|
8
|
+
password: nil,
|
9
|
+
page_size: 25,
|
11
10
|
include_deleted: false,
|
12
11
|
throttle: 0,
|
13
|
-
verify_ssl: true
|
12
|
+
verify_ssl: true
|
14
13
|
}
|
15
14
|
end
|
16
15
|
|
17
16
|
def initialize(settings = {})
|
18
17
|
settings = defaults.merge(settings)
|
19
18
|
settings.each do |property, value|
|
20
|
-
next unless defaults.
|
19
|
+
next unless defaults.key? property
|
20
|
+
|
21
21
|
instance_variable_set("@#{property}", value)
|
22
22
|
self.class.send(:attr_accessor, property)
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
26
25
|
end
|
27
|
-
|
28
26
|
end
|
@@ -1,36 +1,21 @@
|
|
1
1
|
module CollectionSpace
|
2
|
-
|
3
|
-
# http://www.garrettqmartin.com/2015/02/03/finding-deeply-nested-hash-keys/
|
4
|
-
module DeepFind
|
5
|
-
def deep_find(obj, key, nested_key = nil)
|
6
|
-
return obj[key] if obj.respond_to?(:key?) && obj.key?(key)
|
7
|
-
if obj.is_a? Enumerable
|
8
|
-
found = nil
|
9
|
-
obj.find { |*a| found = deep_find(a.last, key) }
|
10
|
-
if nested_key
|
11
|
-
deep_find(found, nested_key)
|
12
|
-
else
|
13
|
-
found
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
2
|
+
# Helper methods for client requests
|
19
3
|
module Helpers
|
20
|
-
|
21
4
|
# get ALL records at path by paging through record set
|
22
5
|
def all(path, options = {})
|
23
6
|
list_type, list_item = get_list_types(path)
|
24
7
|
Enumerator.new do |yielder|
|
25
8
|
page = 0
|
26
9
|
loop do
|
27
|
-
|
28
|
-
|
10
|
+
response = request('GET', path, options.merge(query: { pgNum: page }))
|
11
|
+
unless response.result.success?
|
12
|
+
raise CollectionSpace::RequestError, response.result.body
|
13
|
+
end
|
29
14
|
|
30
|
-
items =
|
31
|
-
raise StopIteration if items
|
15
|
+
items = response.parsed[list_type].fetch('itemsInPage', 0).to_i
|
16
|
+
raise StopIteration if items.zero?
|
32
17
|
|
33
|
-
list_items =
|
18
|
+
list_items = response.parsed[list_type][list_item]
|
34
19
|
list_items = [list_items] if items == 1
|
35
20
|
list_items.each { |item| yielder << item }
|
36
21
|
page += 1
|
@@ -39,84 +24,27 @@ module CollectionSpace
|
|
39
24
|
end
|
40
25
|
|
41
26
|
def count(path)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
count = result.parsed['abstract_common_list']['totalItems'].to_i if result.status_code == 200
|
46
|
-
count
|
47
|
-
end
|
48
|
-
|
49
|
-
# create blob record by external url
|
50
|
-
def post_blob_url(url)
|
51
|
-
raise ArgumentError.new("Invalid blob URL #{url}") unless URI.parse(url).scheme =~ /^https?/
|
52
|
-
request 'POST', "blobs", {
|
53
|
-
query: { "blobUri" => url },
|
54
|
-
}
|
55
|
-
end
|
56
|
-
|
57
|
-
def post_relationship(type_a, csid_a, type_b, csid_b)
|
58
|
-
# requires an erb template
|
59
|
-
# request 'POST', "relations", { body: payload }
|
60
|
-
# flip for reciprocal relationship
|
61
|
-
# request 'POST', "relations", { body: payload }
|
62
|
-
end
|
63
|
-
|
64
|
-
def search(query, options = {})
|
65
|
-
options = prepare_query(query, options)
|
66
|
-
request "GET", query.path, options
|
27
|
+
list_type, = get_list_types(path)
|
28
|
+
response = request('GET', path, query: { pgSz: 1 })
|
29
|
+
response.parsed[list_type]['totalItems'].to_i if response.result.success?
|
67
30
|
end
|
68
31
|
|
69
|
-
def search_all(query, options = {}, &block)
|
70
|
-
options = prepare_query(query, options)
|
71
|
-
all query.path, options, &block
|
72
|
-
end
|
73
|
-
|
74
|
-
def strip_refname(refname)
|
75
|
-
stripped = refname.match(/('.*')/)[0].delete("'") rescue ''
|
76
|
-
stripped
|
77
|
-
end
|
78
|
-
|
79
|
-
# parsed record and map to get restructured object
|
80
|
-
def to_object(record, attribute_map, stringify_keys = false)
|
81
|
-
attributes = {}
|
82
|
-
attribute_map.each do |map|
|
83
|
-
map = map.inject({}) { |memo,(k,v)| memo[k.to_s] = v; memo} if stringify_keys
|
84
|
-
if map["with"]
|
85
|
-
as = deep_find(record, map["key"], map["nested_key"])
|
86
|
-
values = []
|
87
|
-
if as.is_a? Array
|
88
|
-
values = as.map { |a| strip_refname( deep_find(a, map["with"]) ) }
|
89
|
-
elsif as.is_a? Hash and as[ map["with"] ]
|
90
|
-
values = as[ map["with"] ].is_a?(Array) ? as[ map["with"] ].map { |a| strip_refname(a) } : [ strip_refname(as[ map["with"] ]) ]
|
91
|
-
end
|
92
|
-
attributes[map["field"]] = values
|
93
|
-
else
|
94
|
-
attributes[map["field"]] = deep_find(record, map["key"], map["nested_key"])
|
95
|
-
end
|
96
|
-
end
|
97
|
-
attributes
|
98
|
-
end
|
99
|
-
|
100
|
-
private
|
101
|
-
|
102
32
|
def get_list_types(path)
|
103
|
-
list_type, list_item = nil
|
104
33
|
if path == 'relations'
|
105
|
-
|
106
|
-
list_item = 'relation_list_item'
|
34
|
+
%w[relations_common_list relation_list_item]
|
107
35
|
else
|
108
|
-
|
109
|
-
list_item = 'list_item'
|
36
|
+
%w[abstract_common_list list_item]
|
110
37
|
end
|
111
|
-
return list_type, list_item
|
112
38
|
end
|
113
39
|
|
114
40
|
def prepare_query(query, options = {})
|
115
41
|
query_string = "#{query.type}:#{query.field} #{query.expression}"
|
116
|
-
options
|
117
|
-
options
|
42
|
+
options.merge(query: { as: query_string })
|
118
43
|
end
|
119
44
|
|
45
|
+
def search(query, options = {})
|
46
|
+
options = prepare_query(query, options)
|
47
|
+
request 'GET', query.path, options
|
48
|
+
end
|
120
49
|
end
|
121
|
-
|
122
|
-
end
|
50
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module CollectionSpace
|
2
|
-
|
2
|
+
# CollectionSpace request
|
3
3
|
class Request
|
4
4
|
include HTTParty
|
5
5
|
attr_reader :config, :headers, :method, :path, :options
|
@@ -9,41 +9,43 @@ module CollectionSpace
|
|
9
9
|
delete: {},
|
10
10
|
get: {},
|
11
11
|
post: {
|
12
|
-
|
13
|
-
|
12
|
+
'Content-Type' => 'application/xml',
|
13
|
+
'Content-Length' => 'nnnn'
|
14
14
|
},
|
15
15
|
put: {
|
16
|
-
|
17
|
-
|
16
|
+
'Content-Type' => 'application/xml',
|
17
|
+
'Content-Length' => 'nnnn'
|
18
18
|
}
|
19
19
|
}
|
20
20
|
headers[method]
|
21
21
|
end
|
22
22
|
|
23
|
-
def initialize(config, method =
|
23
|
+
def initialize(config, method = 'GET', path = '', options = {})
|
24
24
|
@config = config
|
25
25
|
@method = method.downcase.to_sym
|
26
|
-
@path = path.gsub(
|
26
|
+
@path = path.gsub(%r{^/}, '')
|
27
27
|
|
28
28
|
@auth = {
|
29
29
|
username: config.username,
|
30
|
-
password: config.password
|
30
|
+
password: config.password
|
31
31
|
}
|
32
32
|
|
33
|
+
headers = default_headers(@method).merge(options.fetch(:headers, {}))
|
33
34
|
@options = options
|
34
35
|
@options[:basic_auth] = @auth
|
35
|
-
@options[:headers] =
|
36
|
+
@options[:headers] = headers
|
36
37
|
@options[:verify] = config.verify_ssl
|
37
|
-
@options[:query] =
|
38
|
+
@options[:query] = options.fetch(:query, {})
|
38
39
|
|
39
40
|
self.class.base_uri config.base_uri
|
40
|
-
self.class.default_params
|
41
|
+
self.class.default_params(
|
42
|
+
wf_deleted: config.include_deleted,
|
43
|
+
pgSz: config.page_size
|
44
|
+
)
|
41
45
|
end
|
42
46
|
|
43
47
|
def execute
|
44
48
|
self.class.send method, "/#{path}", options
|
45
49
|
end
|
46
|
-
|
47
50
|
end
|
48
|
-
|
49
51
|
end
|
@@ -1,20 +1,14 @@
|
|
1
1
|
module CollectionSpace
|
2
|
-
|
2
|
+
# CollectionSpace response
|
3
3
|
class Response
|
4
|
-
attr_reader :result, :parsed, :
|
4
|
+
attr_reader :result, :parsed, :status_code, :xml
|
5
5
|
|
6
6
|
def initialize(result)
|
7
|
-
# throw error
|
8
7
|
@result = result
|
9
8
|
@parsed = result.parsed_response
|
10
|
-
@body = result.body
|
11
|
-
@headers = result.headers
|
12
|
-
@status = result.response
|
13
9
|
@status_code = result.code.to_i
|
14
|
-
|
15
|
-
@xml =
|
10
|
+
body = result.body
|
11
|
+
@xml = @result.success? && body =~ /<?xml/ ? Nokogiri::XML(body) : nil
|
16
12
|
end
|
17
|
-
|
18
13
|
end
|
19
|
-
|
20
|
-
end
|
14
|
+
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
module CollectionSpace
|
2
|
-
|
2
|
+
# CollectionSpace search
|
3
3
|
class Search
|
4
4
|
attr_accessor :path, :type, :field, :expression
|
5
5
|
|
6
6
|
def initialize(path: nil, type: nil, field: nil, expression: nil)
|
7
|
-
@path
|
7
|
+
@path = path
|
8
|
+
@type = type
|
9
|
+
@field = field
|
10
|
+
@expression = expression
|
8
11
|
end
|
9
12
|
|
10
13
|
def from_hash(query)
|
@@ -13,7 +16,5 @@ module CollectionSpace
|
|
13
16
|
end
|
14
17
|
self
|
15
18
|
end
|
16
|
-
|
17
19
|
end
|
18
|
-
|
19
|
-
end
|
20
|
+
end
|
@@ -3,19 +3,17 @@ require 'nokogiri'
|
|
3
3
|
require 'uri'
|
4
4
|
|
5
5
|
# mixins required first
|
6
|
-
require
|
6
|
+
require 'collectionspace/client/helpers'
|
7
7
|
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
8
|
+
require 'collectionspace/client/client'
|
9
|
+
require 'collectionspace/client/configuration'
|
10
|
+
require 'collectionspace/client/request'
|
11
|
+
require 'collectionspace/client/response'
|
12
|
+
require 'collectionspace/client/search'
|
13
|
+
require 'collectionspace/client/version'
|
14
14
|
|
15
15
|
module CollectionSpace
|
16
|
-
|
17
|
-
class
|
18
|
-
class
|
19
|
-
|
20
|
-
|
21
|
-
end
|
16
|
+
class ArgumentError < StandardError; end
|
17
|
+
class PayloadError < StandardError; end
|
18
|
+
class RequestError < StandardError; end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: collectionspace-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Cooper
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: awesome_print
|
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'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: bundler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,7 +109,7 @@ dependencies:
|
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
112
|
+
name: rubocop
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
115
|
- - ">="
|
@@ -109,7 +123,7 @@ dependencies:
|
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: vcr
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - ">="
|
@@ -123,7 +137,7 @@ dependencies:
|
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
140
|
+
name: webmock
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
143
|
- - ">="
|
@@ -145,6 +159,7 @@ extra_rdoc_files: []
|
|
145
159
|
files:
|
146
160
|
- ".gitignore"
|
147
161
|
- ".rspec"
|
162
|
+
- ".rubocop.yml"
|
148
163
|
- ".travis.yml"
|
149
164
|
- Gemfile
|
150
165
|
- LICENSE.txt
|
@@ -152,9 +167,8 @@ files:
|
|
152
167
|
- Rakefile
|
153
168
|
- collectionspace-client.gemspec
|
154
169
|
- examples/demo.rb
|
155
|
-
- examples/export.rb
|
156
170
|
- examples/media_with_external_file.rb
|
157
|
-
- examples/
|
171
|
+
- examples/purge_empty_vocabs.rb
|
158
172
|
- examples/search.rb
|
159
173
|
- lib/collectionspace/client.rb
|
160
174
|
- lib/collectionspace/client/client.rb
|
data/examples/export.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
-
require 'awesome_print'
|
3
|
-
require 'collectionspace/client'
|
4
|
-
require 'date'
|
5
|
-
|
6
|
-
# MONKEY PATCHING FOR RAILS LIKE 3.days.ago
|
7
|
-
class Fixnum
|
8
|
-
SECONDS_IN_DAY = 24 * 60 * 60
|
9
|
-
|
10
|
-
def days
|
11
|
-
self * SECONDS_IN_DAY
|
12
|
-
end
|
13
|
-
|
14
|
-
def ago
|
15
|
-
Time.now - self
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# CREATE CLIENT WITH DEFAULT (DEMO) CONFIGURATION -- BE NICE!!!
|
20
|
-
client = CollectionSpace::Client.new
|
21
|
-
client.config.throttle = 1
|
22
|
-
|
23
|
-
# GET ALL CATALOGING RECORDS AND DUMP THE XML IF UPDATED SINCE 3 DAYS AGO
|
24
|
-
client.all('collectionobjects').each do |item|
|
25
|
-
updated = Date.parse item["updatedAt"]
|
26
|
-
if updated > Date.parse(14.days.ago.to_s)
|
27
|
-
collectionobject = client.get item["uri"]
|
28
|
-
# TO EXPORT WRITE THE BODY TO FILE, HERE WE JUST PRINT IT
|
29
|
-
ap collectionobject.body # OR .xml.to_s
|
30
|
-
end
|
31
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
-
require 'awesome_print'
|
3
|
-
require 'collectionspace/client'
|
4
|
-
|
5
|
-
# CREATE CLIENT WITH DEFAULT (DEMO) CONFIGURATION -- BE NICE!!!
|
6
|
-
client = CollectionSpace::Client.new
|
7
|
-
client.config.throttle = 1
|
8
|
-
|
9
|
-
client.all('vocabularies').each do |item|
|
10
|
-
uri = item["uri"]
|
11
|
-
puts "Checking vocabulary: #{uri}"
|
12
|
-
if client.count("#{uri}/items") == 0
|
13
|
-
puts "Purging empty vocabulary:\t#{item['displayName']} (#{item['csid']})"
|
14
|
-
# YOU WOULD UNCOMMENT THIS TO ACTUALLY PERFORM THE PURGE ...
|
15
|
-
# client.delete uri
|
16
|
-
end
|
17
|
-
end
|