collectionspace-client 0.1.5 → 0.2.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.
- 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
|