puree 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 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: