puree 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 589862f38fbdf73c8255cfd00e51191fbbdde42a
4
+ data.tar.gz: 146680ea5def8f36b7a4bc377413949e2c244de4
5
+ SHA512:
6
+ metadata.gz: 9728d190508de23b7b08e3fb0094700f9ec190b40573d32dd8740fad263fca7447b3ff169b89eff6831dc2cf933a3cc2224e6947601610d31c203ffff615018e
7
+ data.tar.gz: 470051d32055bbd820d7e44a3d931a48419a087cad860a8522c890c8e58a16321fbe60167609f25d528c38b7c8813ae764df6f037c5b4315d61c48c2abeac85f
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea
@@ -0,0 +1,34 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+ This project adheres to [Semantic Versioning](http://semver.org/).
4
+
5
+ ## 0.6.0 - 2016-05-06
6
+ ### Added
7
+ - API map factored out of Resource.
8
+ - Collections (journal, organisation, person, project, publication, publisher).
9
+ - Resource classes with HTTParty metadata (journal, organisation, person, project, publication, publisher).
10
+
11
+ ## 0.5.0 - 2016-04-29
12
+ ### Added
13
+ - Refactoring ctor.
14
+ - Populate resource metadata from get and assignment.
15
+ - Dataset collection.
16
+ - RSpec tests for dataset collection.
17
+
18
+ ## 0.4.0 - 2016-04-27
19
+ ### Added
20
+ - Date normalisation and conversion to ISO8601.
21
+
22
+ ## 0.3.0 - 2016-04-26
23
+ ### Added
24
+ - Yard documentation.
25
+ - Simplification of public interface method names.
26
+
27
+ ## 0.2.0 - 2016-04-25
28
+ ### Added
29
+ - RSpec tests for datasets.
30
+
31
+ ## 0.1.0 - 2016-04-21
32
+ ### Added
33
+ - Working product supports datasets.
34
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in puree.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Adrian Albin-Clark
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,232 @@
1
+ # Purée
2
+
3
+ A Ruby client for the Pure Research Information System API.
4
+
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'puree'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install puree
19
+
20
+ ## Usage
21
+ ```ruby
22
+ endpoint = 'http://example.com/ws/rest'
23
+ ```
24
+
25
+ Dataset.
26
+
27
+ ```ruby
28
+ d = Puree::Dataset.new
29
+
30
+ # Get metadata using ID
31
+ d.get id: 12345678,
32
+ endpoint: endpoint,
33
+ username: username,
34
+ password: password
35
+
36
+ # Get metadata using UUID
37
+ d.get uuid: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',
38
+ endpoint: endpoint,
39
+ username: username,
40
+ password: password
41
+
42
+ # Filter metadata into simple data structures
43
+ d.title
44
+ d.description
45
+ d.keyword
46
+ d.person
47
+ d.temporal
48
+ d.geographical
49
+ d.file
50
+ d.publication
51
+ d.available
52
+ d.access
53
+ d.doi
54
+
55
+ # Combine metadata into one simple data structure
56
+ d.metadata
57
+
58
+ # Access HTTParty functionality
59
+ d.response # HTTParty object
60
+ d.response.body # XML
61
+ d.response.code
62
+ d.response.message
63
+ d.response.headers # hash
64
+ ```
65
+
66
+ Collection.
67
+
68
+ ```ruby
69
+ c = Puree::Collection.new(resource_type: :dataset)
70
+
71
+ # Get minimal datasets, optionally specifying a quantity (default is 20)
72
+ c.get endpoint: endpoint,
73
+ username: username,
74
+ password: password,
75
+ qty: 100000
76
+
77
+ # Get UUIDs for datasets
78
+ uuids = c.uuid
79
+
80
+ # Get metadata using UUID
81
+ datasets = []
82
+ uuids.each do |uuid|
83
+ d = Puree::Dataset.new
84
+ d.get endpoint: endpoint,
85
+ username: username,
86
+ password: password,
87
+ uuid: uuid
88
+ datasets << d.metadata
89
+ end
90
+ ```
91
+
92
+
93
+ ## Dataset data structures
94
+
95
+ ### available
96
+ Date made available. If year is present, month and day will have data or an empty string.
97
+
98
+ ```ruby
99
+ {
100
+ "year"=>"2016",
101
+ "month"=>"2",
102
+ "day"=>"4"
103
+ }
104
+ ```
105
+
106
+ ### file
107
+ An array of files.
108
+
109
+ ```ruby
110
+ [
111
+ {
112
+ "name"=>"foo.csv",
113
+ "mime"=>"application/octet-stream",
114
+ "size"=>"1616665158",
115
+ "url"=>"http://example.com/ws/rest/files/12345678/foo.csv",
116
+ "title"=>"foo.csv",
117
+ "license"=>{
118
+ "name"=>"CC BY-NC",
119
+ "url"=>"http://creativecommons.org/licenses/by-nc/4.0/"
120
+ }
121
+ },
122
+ ]
123
+ ```
124
+
125
+ ### person
126
+ Contains an array of internal persons and an array of external persons.
127
+
128
+ ```ruby
129
+ {
130
+ "internal"=>[
131
+ {
132
+ "name"=>{
133
+ "first"=>"Stan",
134
+ "last"=>"Laurel"
135
+ },
136
+ "role"=>"Creator",
137
+ "uuid"=>"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
138
+ },
139
+ ],
140
+ "external"=>[
141
+ ]
142
+ }
143
+ ```
144
+
145
+ ### publication
146
+ An array of related publications.
147
+
148
+ ```ruby
149
+ [
150
+ {
151
+ "type"=>"Journal article",
152
+ "title"=>"An interesting title",
153
+ "uuid"=>"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
154
+ },
155
+ ]
156
+ ```
157
+
158
+ ### temporal
159
+ Date range. If year is present, month and day will have data or an empty string.
160
+
161
+ ```ruby
162
+ {
163
+ "start"=>{
164
+ "year"=>"2005",
165
+ "month"=>"5",
166
+ "day"=>"10"
167
+ },
168
+ "end"=>{
169
+ "year"=>"2011",
170
+ "month"=>"9",
171
+ "day"=>"18"
172
+ }
173
+ }
174
+ ```
175
+
176
+
177
+ ## Utilities
178
+
179
+ ### Convert date to ISO 8601 format.
180
+
181
+ ```ruby
182
+ Puree::Date.iso d.available
183
+ ```
184
+ ```ruby
185
+ {
186
+ "year"=>"2016",
187
+ "month"=>"4",
188
+ "day"=>"18"
189
+ }
190
+ ```
191
+ becomes
192
+
193
+ ```ruby
194
+ "2016-04-18"
195
+ ```
196
+
197
+
198
+ ## API coverage
199
+ Version
200
+
201
+ ```ruby
202
+ 5.5.1
203
+ ```
204
+
205
+ Resource metadata
206
+
207
+ ```ruby
208
+ :dataset
209
+ ```
210
+
211
+ Resource metadata (single hash only)
212
+
213
+ ```ruby
214
+ :journal
215
+ :organisation
216
+ :person
217
+ :project
218
+ :publication
219
+ :publisher
220
+ ```
221
+
222
+ Collections (for obtaining identifiers)
223
+
224
+ ```ruby
225
+ :dataset
226
+ :journal
227
+ :organisation
228
+ :person
229
+ :project
230
+ :publication
231
+ :publisher
232
+ ```
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,12 @@
1
+ require 'httparty'
2
+ require 'puree/date'
3
+ require 'puree/map'
4
+ require 'puree/resource'
5
+ require 'puree/dataset'
6
+ require 'puree/journal'
7
+ require 'puree/organisation'
8
+ require 'puree/person'
9
+ require 'puree/project'
10
+ require 'puree/publication'
11
+ require 'puree/publisher'
12
+ require 'puree/collection'
@@ -0,0 +1,80 @@
1
+ module Puree
2
+
3
+ # Collection resource
4
+ #
5
+ class Collection < Resource
6
+
7
+ def initialize(resource_type: nil)
8
+ super(resource_type)
9
+ @uuids = []
10
+ end
11
+
12
+ # Get
13
+ #
14
+ # @param endpoint [String]
15
+ # @param username [String]
16
+ # @param password [String]
17
+ # @param qty [Integer]
18
+ # @return [HTTParty::Response]
19
+ def get(endpoint:nil, username:nil, password:nil, qty:nil)
20
+ # strip any trailing slash
21
+ @endpoint = endpoint.sub(/(\/)+$/, '')
22
+ @auth = Base64::strict_encode64(username + ':' + password)
23
+
24
+ @options = {
25
+ latest_api: true,
26
+ resource_type: @resource_type.to_sym,
27
+ rendering: :system,
28
+ qty: qty
29
+ }
30
+ headers = {
31
+ 'Accept' => 'application/xml',
32
+ 'Authorization' => 'Basic ' + @auth
33
+ }
34
+ query = {}
35
+ query['rendering'] = @options[:rendering]
36
+ if @options[:qty]
37
+ query['window.size'] = @options[:qty]
38
+ end
39
+
40
+ @response = HTTParty.get(url, query: query, headers: headers)
41
+ end
42
+
43
+
44
+ # Array of UUIDs
45
+ #
46
+ # @return [Array<String>]
47
+ def uuid
48
+ collect_uuid
49
+ @uuids
50
+ end
51
+
52
+
53
+
54
+ private
55
+
56
+
57
+ def collect_uuid
58
+ response_name = service_response_name
59
+ resp = @response[response_name]['result']['renderedItem']
60
+ arr = []
61
+ if resp.is_a?(Array)
62
+ arr = resp
63
+ else
64
+ arr << resp
65
+ end
66
+ arr.each do |a|
67
+ tableRows = a['div']['table']['tbody']['tr']
68
+ tableRows.each do |row|
69
+ if row['th'] === 'UUID'
70
+ uuid = row['td']
71
+ @uuids << uuid
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,273 @@
1
+ module Puree
2
+
3
+ # Dataset resource
4
+ #
5
+ class Dataset < Resource
6
+
7
+ def initialize
8
+ super(:dataset)
9
+ end
10
+
11
+ # Title
12
+ #
13
+ # @return [Array<String>]
14
+ def title
15
+ data = node 'title'
16
+ if !data.nil? && !data.empty?
17
+ data = data['localizedString']["__content__"]
18
+ data.is_a?(Array) ? data : data.split(',')
19
+ else
20
+ []
21
+ end
22
+ end
23
+
24
+ # Keyword
25
+ #
26
+ # @return [Array<String>]
27
+ def keyword
28
+ data = node 'keywordGroups'
29
+ if !data.nil? && !data.empty?
30
+ data = data['keywordGroup']['keyword']['userDefinedKeyword']['freeKeyword']
31
+ data.is_a?(Array) ? data : data.split(',')
32
+ else
33
+ []
34
+ end
35
+ end
36
+
37
+ # Description
38
+ #
39
+ # @return [Array<String>]
40
+ def description
41
+ data = node 'descriptions'
42
+ if !data.nil? && !data.empty?
43
+ data = data['classificationDefinedField']['value']['localizedString']['__content__'].tr("\n", '')
44
+ data.is_a?(Array) ? data : data.split(',')
45
+ else
46
+ []
47
+ end
48
+ end
49
+
50
+ # Person, internal and external
51
+ #
52
+ # @return [Hash<Array, Array>]
53
+ def person
54
+ data = node('persons')
55
+ persons = {}
56
+ if !data.nil? && !data.empty?
57
+ data = data['dataSetPersonAssociation']
58
+ else
59
+ return persons
60
+ end
61
+ internal_persons = []
62
+ external_persons = []
63
+ case data
64
+ when Array
65
+ data.each do |d|
66
+ person = generic_person d
67
+ if d.key? 'person'
68
+ person['uuid'] = d['person']['uuid']
69
+ internal_persons << person
70
+ end
71
+ if d.key? 'externalPerson'
72
+ person['uuid'] = d['externalPerson']['uuid']
73
+ external_persons << person
74
+ end
75
+ end
76
+ when Hash
77
+ person = generic_person data
78
+ if data.key? 'person'
79
+ person['uuid'] = data['person']['uuid']
80
+ internal_persons << person
81
+ end
82
+ if data.key? 'externalPerson'
83
+ person['uuid'] = data['externalPerson']['uuid']
84
+ external_persons << person
85
+ end
86
+ end
87
+ persons['internal'] = internal_persons
88
+ persons['external'] = external_persons
89
+ persons
90
+ end
91
+
92
+ # Publication
93
+ #
94
+ # @return [Array<Hash>]
95
+ def publication
96
+ data = node('relatedPublications')
97
+ publications = []
98
+ if !data.nil? && !data.empty?
99
+ # convert to array
100
+ data_arr = []
101
+ if data['relatedContent'].is_a?(Array)
102
+ data_arr = data['relatedContent']
103
+ else
104
+ data_arr[0] = data['relatedContent']
105
+ end
106
+ data_arr.each do |d|
107
+ o = {}
108
+ o['type'] = d['typeClassification']
109
+ o['title'] = d['title']
110
+ o['uuid'] = d['uuid']
111
+ publications << o
112
+ end
113
+ end
114
+ publications
115
+ end
116
+
117
+ # Date made available
118
+ #
119
+ # @return [Hash]
120
+ def available
121
+ data = node('dateMadeAvailable')
122
+ Puree::Date.normalise(data)
123
+ end
124
+
125
+ # Geographical coverage
126
+ #
127
+ # @return [Array<String>]
128
+ def geographical
129
+ data = node 'geographicalCoverage'
130
+ if !data.nil? && !data.empty?
131
+ data = data['localizedString']["__content__"]
132
+ data.is_a?(Array) ? data : data.split(',')
133
+ else
134
+ []
135
+ end
136
+ end
137
+
138
+ # Temporal coverage
139
+ #
140
+ # @return [Hash]
141
+ def temporal
142
+ data = {}
143
+ data['start'] = {}
144
+ data['end'] = {}
145
+ start_date = temporal_coverage_start_date
146
+ if !start_date.nil? && !start_date.empty?
147
+ data['start'] = start_date
148
+ end
149
+ end_date = temporal_coverage_end_date
150
+ if !end_date.nil? && !end_date.empty?
151
+ data['end'] = end_date
152
+ end
153
+ data
154
+ end
155
+
156
+ # Open access permission
157
+ #
158
+ # @return [String]
159
+ def access
160
+ data = node 'openAccessPermission'
161
+ !data.nil? && !data.empty? ? data['term']['localizedString']["__content__"] : ''
162
+ end
163
+
164
+
165
+ # Supporting file
166
+ #
167
+ # @return [Array<Hash>]
168
+ def file
169
+ data = node 'documents'
170
+
171
+ docs = []
172
+ if !data.nil? && !data.empty?
173
+ # convert to array
174
+ data_arr = []
175
+ if data['document'].is_a?(Array)
176
+ data_arr = data['document']
177
+ else
178
+ data_arr << data['document']
179
+ end
180
+
181
+ data_arr.each do |d|
182
+ doc = {}
183
+ # doc['id'] = d['id']
184
+ doc['name'] = d['fileName']
185
+ doc['mime'] = d['mimeType']
186
+ doc['size'] = d['size']
187
+ doc['url'] = d['url']
188
+ doc['title'] = d['title']
189
+ # doc['createdDate'] = doc['createdDate']
190
+ # doc['visibleOnPortalDate'] = doc['visibleOnPortalDate']
191
+ # doc['limitedVisibility'] = doc['limitedVisibility']
192
+
193
+ license = {}
194
+ if d['documentLicense']
195
+ license_name = d['documentLicense']['term']['localizedString']['__content__']
196
+ license['name'] = license_name
197
+ license_url = d['documentLicense']['description']['localizedString']['__content__']
198
+ license['url'] = license_url
199
+ doc['license'] = license
200
+ end
201
+ docs << doc
202
+
203
+ end
204
+ end
205
+ docs
206
+ end
207
+
208
+ # Digital Object Identifier
209
+ #
210
+ # @return [String]
211
+ def doi
212
+ data = node 'doi'
213
+ !data.nil? && !data.empty? ? data['doi'] : ''
214
+ end
215
+
216
+ # def state
217
+ # # useful?
218
+ # data = node 'startedWorkflows'
219
+ # !data.empty? ? data['startedWorkflow']['state'] : ''
220
+ # end
221
+
222
+ # All metadata
223
+ #
224
+ # @return [Hash]
225
+ def metadata
226
+ o = {}
227
+ o['title'] = title
228
+ o['description'] = description
229
+ o['keyword'] = keyword
230
+ o['person'] = person
231
+ o['temporal'] = temporal
232
+ o['geographical'] = geographical
233
+ o['file'] = file
234
+ o['publication'] = publication
235
+ o['available'] = available
236
+ o['access'] = access
237
+ o['doi'] = doi
238
+ o
239
+ end
240
+
241
+ private
242
+
243
+ # Assembles basic information about a person
244
+ #
245
+ # @param generic_data [Hash]
246
+ # @return [Hash]
247
+ def generic_person(generic_data)
248
+ person = {}
249
+ name = {}
250
+ name['first'] = generic_data['name']['firstName']
251
+ name['last'] = generic_data['name']['lastName']
252
+ person['name'] = name
253
+ person['role'] = generic_data['personRole']['term']['localizedString']["__content__"]
254
+ person
255
+ end
256
+
257
+ # Temporal coverage start date
258
+ #
259
+ # @return [Hash]
260
+ def temporal_coverage_start_date
261
+ data = node('temporalCoverageStartDate')
262
+ !data.nil? && !data.empty? ? Puree::Date.normalise(data) : {}
263
+ end
264
+
265
+ # Temporal coverage end date
266
+ #
267
+ # @return [Hash]
268
+ def temporal_coverage_end_date
269
+ data = node('temporalCoverageEndDate')
270
+ !data.nil? && !data.empty? ? Puree::Date.normalise(data) : {}
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,61 @@
1
+ module Puree
2
+
3
+ module Date
4
+
5
+ # Converts a date with three components (year, month, day) to ISO8601 format
6
+ #
7
+ # @param data [Hash]
8
+ # @return [String]
9
+ def self.iso(data)
10
+ iso_date = ''
11
+ year = data['year']
12
+ month = data['month']
13
+ day = data['day']
14
+ if !year.empty?
15
+ iso_date << year
16
+ else
17
+ iso_date
18
+ end
19
+ if !month.empty?
20
+ # Add leading zero to convert to ISO 8601
21
+ if month.length < 2
22
+ month.insert(0, '0')
23
+ end
24
+ iso_date << '-' + month
25
+ else
26
+ iso_date
27
+ end
28
+ if !day.empty?
29
+ # Add leading zero to convert to ISO 8601
30
+ if day.length < 2
31
+ day.insert(0, '0')
32
+ end
33
+ iso_date << '-' + day
34
+ end
35
+ iso_date
36
+ end
37
+
38
+ private
39
+
40
+ # Forces a date to have three components (year, month, day)
41
+ #
42
+ # @param data [Hash]
43
+ # @return [Hash]
44
+ def self.normalise(data)
45
+ if !data.nil? && !data.empty?
46
+ date = {}
47
+ year = data['year']
48
+ month = data['month']
49
+ day = data['day']
50
+ date['year'] = year ? year : ''
51
+ date['month'] = month ? month : ''
52
+ date['day'] = day ? day : ''
53
+ date
54
+ else
55
+ {}
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -0,0 +1,13 @@
1
+ module Puree
2
+
3
+ # Journal resource
4
+ #
5
+ class Journal < Resource
6
+
7
+ def initialize
8
+ super(:journal)
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,48 @@
1
+ module Puree
2
+
3
+ class Map
4
+
5
+ def initialize
6
+ @convention = %w(
7
+ journal
8
+ organisation
9
+ person
10
+ project
11
+ publication
12
+ publisher
13
+ )
14
+
15
+ @api_map = {
16
+ resource_type: {
17
+ dataset: {
18
+ service: 'datasets',
19
+ response: 'GetDataSetsResponse'
20
+ }
21
+ }
22
+ }
23
+
24
+ add_convention
25
+ end
26
+
27
+ # Pure API map
28
+ #
29
+ # @return [Hash]
30
+ def get
31
+ @api_map
32
+ end
33
+
34
+
35
+ private
36
+
37
+ def add_convention
38
+ @convention.each do |c|
39
+ resource_type = {}
40
+ resource_type[:service] = c
41
+ resource_type[:response] = 'Get' + c.capitalize + 'Response'
42
+ @api_map[:resource_type][c.to_sym] = resource_type
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,13 @@
1
+ module Puree
2
+
3
+ # Organisation resource
4
+ #
5
+ class Organisation < Resource
6
+
7
+ def initialize
8
+ super(:organisation)
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ module Puree
2
+
3
+ # Person resource
4
+ #
5
+ class Person < Resource
6
+
7
+ def initialize
8
+ super(:person)
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ module Puree
2
+
3
+ # Project resource
4
+ #
5
+ class Project < Resource
6
+
7
+ def initialize
8
+ super(:project)
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ module Puree
2
+
3
+ # Publication resource
4
+ #
5
+ class Publication < Resource
6
+
7
+ def initialize
8
+ super(:publication)
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ module Puree
2
+
3
+ # Publisher resource
4
+ #
5
+ class Publisher < Resource
6
+
7
+ def initialize
8
+ super(:publisher)
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,124 @@
1
+ module Puree
2
+
3
+ # Abstract base class for resources.
4
+ #
5
+ class Resource
6
+
7
+ def initialize(resource_type)
8
+ @resource_type = resource_type
9
+ @api_map = Puree::Map.new.get
10
+ end
11
+
12
+ # Get
13
+ #
14
+ # @param endpoint [String]
15
+ # @param username [String]
16
+ # @param password [String]
17
+ # @param uuid [String]
18
+ # @param id [String]
19
+ # @return [HTTParty::Response]
20
+ def get(endpoint:nil, username:nil, password:nil, uuid:nil, id:nil)
21
+ # strip any trailing slash
22
+ @endpoint = endpoint.sub(/(\/)+$/, '')
23
+ @auth = Base64::strict_encode64(username + ':' + password)
24
+
25
+ @options = {
26
+ latest_api: true,
27
+ resource_type: @resource_type.to_sym,
28
+ rendering: :xml_long,
29
+ uuid: uuid,
30
+ id: id,
31
+ }
32
+ headers = {
33
+ 'Accept' => 'application/xml',
34
+ 'Authorization' => 'Basic ' + @auth
35
+ }
36
+ query = {}
37
+ query['rendering'] = @options[:rendering]
38
+ if @options[:uuid]
39
+ query['uuids.uuid'] = @options[:uuid]
40
+ else
41
+ if @options[:id]
42
+ query['pureInternalIds.id'] = @options[:id]
43
+ end
44
+ end
45
+
46
+ @response = HTTParty.get(url, query: query, headers: headers)
47
+
48
+ if get_data?
49
+ response_name = service_response_name
50
+ content = @response.parsed_response[response_name]['result']['content']
51
+ set_content(content)
52
+ end
53
+ @response
54
+ end
55
+
56
+ # Response, if get method has been called
57
+ #
58
+ # @return [HTTParty::Response]
59
+ # @return [Nil]
60
+ def response
61
+ @response ? @response : nil
62
+ end
63
+
64
+ # Set content
65
+ #
66
+ # @param content [Hash]
67
+ def set_content(content)
68
+ if !content.nil? && !content.empty?
69
+ @content = content
70
+ else
71
+ @content = {}
72
+ end
73
+ end
74
+
75
+ # Content
76
+ #
77
+ # @return [Hash]
78
+ def content
79
+ @content ? @content : {}
80
+ end
81
+
82
+
83
+
84
+ private
85
+
86
+
87
+
88
+ # Node
89
+ #
90
+ # @return [Hash]
91
+ def node(name)
92
+ @content ? @content[name] : {}
93
+ end
94
+
95
+ # Is there any data after get?
96
+ #
97
+ # @return [Boolean]
98
+ def get_data?
99
+ response_name = service_response_name
100
+ @response.parsed_response[response_name]['count'] != '0' ? true : false
101
+ end
102
+
103
+ def service_name
104
+ resource_type = @options[:resource_type]
105
+ @api_map[:resource_type][resource_type][:service]
106
+ end
107
+
108
+ def service_response_name
109
+ resource_type = @options[:resource_type]
110
+ @api_map[:resource_type][resource_type][:response]
111
+ end
112
+
113
+ def url
114
+ service = service_name
115
+ if @options[:latest_api] === false
116
+ service_api_mode = service
117
+ else
118
+ service_api_mode = service + '.current'
119
+ end
120
+ @endpoint + '/' + service_api_mode
121
+ end
122
+
123
+ end
124
+ end
@@ -0,0 +1,3 @@
1
+ module Puree
2
+ VERSION = "0.6.0"
3
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'puree/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "puree"
8
+ spec.version = Puree::VERSION
9
+ spec.authors = ["Adrian Albin-Clark"]
10
+ spec.email = ["a.albin-clark@lancaster.ac.uk"]
11
+ spec.summary = %q{A client for the Pure Research Information System API.}
12
+ spec.description = %q{Consumes the Pure Research Information System API and facilitates post-processing of metadata into simple data structures.}
13
+ spec.homepage = "https://github.com/lulibrary/puree.git"
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_runtime_dependency 'httparty', '~> 0'
22
+ spec.add_development_dependency "bundler", "~> 1.5"
23
+ spec.add_development_dependency 'rake', '~> 0'
24
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Collection' do
4
+
5
+ it '#new' do
6
+ p = Puree::Collection.new(resource_type: :dataset)
7
+ expect(p).to be_an_instance_of Puree::Collection
8
+ end
9
+
10
+ describe 'data retrieval' do
11
+ before(:all) do
12
+ endpoint = ENV['PURE_ENDPOINT']
13
+ username = ENV['PURE_USERNAME']
14
+ password = ENV['PURE_PASSWORD']
15
+ @p = Puree::Collection.new(resource_type: :dataset)
16
+ @p.get endpoint: endpoint,
17
+ username: username,
18
+ password: password
19
+ end
20
+
21
+ it '#UUID' do
22
+ expect(@p.uuid).to be_an_instance_of(Array)
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Dataset' do
4
+
5
+ it '#new' do
6
+ p = Puree::Dataset.new
7
+ expect(p).to be_an_instance_of Puree::Dataset
8
+ end
9
+
10
+ describe 'data retrieval' do
11
+ before(:all) do
12
+ endpoint = ENV['PURE_ENDPOINT']
13
+ username = ENV['PURE_USERNAME']
14
+ password = ENV['PURE_PASSWORD']
15
+ uuid = ENV['PURE_DATASET_UUID']
16
+ @p = Puree::Dataset.new
17
+ @p.get endpoint: endpoint,
18
+ username: username,
19
+ password: password,
20
+ uuid: uuid
21
+ end
22
+
23
+ it '#title' do
24
+ expect(@p.title).to be_an_instance_of(Array)
25
+ end
26
+
27
+ it '#keyword' do
28
+ expect(@p.keyword).to be_an_instance_of(Array)
29
+ end
30
+
31
+ it '#description' do
32
+ expect(@p.description).to be_an_instance_of(Array)
33
+ end
34
+
35
+ it '#person' do
36
+ expect(@p.person).to be_an_instance_of(Hash)
37
+ end
38
+
39
+ it '#publication' do
40
+ expect(@p.publication).to be_an_instance_of(Array)
41
+ end
42
+
43
+ it '#available' do
44
+ expect(@p.available).to be_an_instance_of(Hash)
45
+ end
46
+
47
+ it '#geographical' do
48
+ expect(@p.geographical).to be_an_instance_of(Array)
49
+ end
50
+
51
+ it '#temporal' do
52
+ expect(@p.temporal).to be_an_instance_of(Hash)
53
+ end
54
+
55
+ it '#access' do
56
+ expect(@p.access).to be_an_instance_of(String)
57
+ end
58
+
59
+ it '#file' do
60
+ expect(@p.file).to be_an_instance_of(Array)
61
+ end
62
+
63
+ it '#doi' do
64
+ expect(@p.doi).to be_an_instance_of(String)
65
+ end
66
+
67
+ it '#metadata' do
68
+ expect(@p.metadata).to be_an_instance_of(Hash)
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,12 @@
1
+ require 'httparty'
2
+ require 'puree/date'
3
+ require 'puree/map'
4
+ require 'puree/resource'
5
+ require 'puree/dataset'
6
+ require 'puree/journal'
7
+ require 'puree/organisation'
8
+ require 'puree/person'
9
+ require 'puree/project'
10
+ require 'puree/publication'
11
+ require 'puree/publisher'
12
+ require 'puree/collection'
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puree
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
5
+ platform: ruby
6
+ authors:
7
+ - Adrian Albin-Clark
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
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
+ description: Consumes the Pure Research Information System API and facilitates post-processing
56
+ of metadata into simple data structures.
57
+ email:
58
+ - a.albin-clark@lancaster.ac.uk
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - CHANGELOG.md
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - lib/puree.rb
70
+ - lib/puree/collection.rb
71
+ - lib/puree/dataset.rb
72
+ - lib/puree/date.rb
73
+ - lib/puree/journal.rb
74
+ - lib/puree/map.rb
75
+ - lib/puree/organisation.rb
76
+ - lib/puree/person.rb
77
+ - lib/puree/project.rb
78
+ - lib/puree/publication.rb
79
+ - lib/puree/publisher.rb
80
+ - lib/puree/resource.rb
81
+ - lib/puree/version.rb
82
+ - puree.gemspec
83
+ - spec/collection.rb
84
+ - spec/dataset.rb
85
+ - spec/spec_helper.rb
86
+ homepage: https://github.com/lulibrary/puree.git
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.2.2
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: A client for the Pure Research Information System API.
110
+ test_files:
111
+ - spec/collection.rb
112
+ - spec/dataset.rb
113
+ - spec/spec_helper.rb
114
+ has_rdoc: