qa 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +24 -21
- data/Rakefile +1 -1
- data/app/controllers/qa/terms_controller.rb +22 -53
- data/config/routes.rb +4 -7
- data/lib/qa/authorities.rb +3 -1
- data/lib/qa/authorities/base.rb +27 -8
- data/lib/qa/authorities/getty.rb +56 -0
- data/lib/qa/authorities/loc.rb +27 -131
- data/lib/qa/authorities/loc_subauthority.rb +90 -0
- data/lib/qa/authorities/local.rb +38 -21
- data/lib/qa/authorities/local_subauthority.rb +18 -0
- data/lib/qa/authorities/mesh.rb +16 -23
- data/lib/qa/authorities/mesh_tools/mesh_data_parser.rb +0 -25
- data/lib/qa/authorities/mesh_tools/mesh_importer.rb +0 -2
- data/lib/qa/authorities/oclcts.rb +17 -24
- data/lib/qa/authorities/tgnlang.rb +4 -18
- data/lib/qa/authorities/web_service_base.rb +3 -10
- data/lib/qa/version.rb +1 -1
- data/spec/controllers/terms_controller_spec.rb +93 -44
- data/spec/fixtures/aat-response.txt +108 -0
- data/spec/fixtures/getty-aat-find-response.json +2494 -0
- data/spec/fixtures/loc-response.txt +1521 -17
- data/spec/fixtures/loc-subject-find-response.txt +24 -0
- data/spec/internal/Gemfile +16 -13
- data/spec/internal/Gemfile.lock +121 -86
- data/spec/internal/app/assets/javascripts/application.js +1 -1
- data/spec/internal/app/assets/stylesheets/application.css +1 -1
- data/spec/internal/bin/rails +1 -5
- data/spec/internal/bin/rake +0 -4
- data/spec/internal/bin/setup +29 -0
- data/spec/internal/config.ru +1 -1
- data/spec/internal/config/application.rb +3 -0
- data/spec/internal/config/boot.rb +1 -2
- data/spec/internal/config/environments/development.rb +4 -0
- data/spec/internal/config/environments/production.rb +14 -18
- data/spec/internal/config/environments/test.rb +5 -2
- data/spec/internal/config/initializers/assets.rb +11 -0
- data/spec/internal/config/initializers/cookies_serializer.rb +1 -1
- data/spec/internal/config/secrets.yml +2 -2
- data/spec/internal/db/development.sqlite3 +0 -0
- data/spec/internal/db/migrate/{20140620210534_create_qa_subject_mesh_terms.qa.rb → 20150311214117_create_qa_subject_mesh_terms.qa.rb} +0 -0
- data/spec/internal/db/migrate/{20140620210535_create_qa_mesh_tree.qa.rb → 20150311214118_create_qa_mesh_tree.qa.rb} +0 -0
- data/spec/internal/db/migrate/{20140620210536_add_term_lower_to_qa_subject_mesh_terms.qa.rb → 20150311214119_add_term_lower_to_qa_subject_mesh_terms.qa.rb} +0 -0
- data/spec/internal/db/schema.rb +3 -3
- data/spec/internal/db/test.sqlite3 +0 -0
- data/spec/internal/lib/generators/test_app_generator.rb +0 -1
- data/spec/internal/log/development.log +498 -207
- data/spec/internal/test/test_helper.rb +0 -3
- data/spec/lib/authorities_getty_spec.rb +71 -0
- data/spec/lib/authorities_loc_spec.rb +98 -65
- data/spec/lib/authorities_loc_subauthorities.rb +81 -0
- data/spec/lib/authorities_local_spec.rb +53 -79
- data/spec/lib/authorities_local_subauthorities_spec.rb +43 -0
- data/spec/lib/authorities_mesh_spec.rb +16 -12
- data/spec/lib/authorities_oclcts_spec.rb +17 -17
- data/spec/lib/authorities_tgnlang_spec.rb +4 -7
- data/spec/lib/mesh_data_parser_spec.rb +13 -13
- data/spec/lib/tasks/mesh.rake_spec.rb +4 -4
- data/spec/models/subject_mesh_term_spec.rb +5 -5
- data/spec/routing/route_spec.rb +34 -0
- data/spec/spec_helper.rb +5 -22
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +0 -1
- metadata +44 -12
- data/lib/qa/authorities/local/subauthority.rb +0 -65
- data/spec/internal/bin/spring +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e22891ac5c80978a68ef9606122e197fb348c47
|
4
|
+
data.tar.gz: dc3f442fa9a2f974100fea8e6ca7f42ae3f0c953
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 972243b9cd33d2267e14cb341765f87e7c0ac83cc3f8252f1b9f18e6a4e0078452e85ee9d58d62b0d31173ae317a054fd7499fdda883b6e5116a51095c5b9d85
|
7
|
+
data.tar.gz: ad6c420a0e4507ff26b191f1c3b455f5eb900d06ca60638f84abf6ecc4f66c681feae69fe210e24c46f7357262554bc899740abd8bcf1de3d92f4efc66c98502
|
data/README.md
CHANGED
@@ -162,25 +162,34 @@ using the file's name as the sub-authority. For example, if I create `foo.yml`,
|
|
162
162
|
:term: Term 2
|
163
163
|
:active: false
|
164
164
|
|
165
|
-
|
166
|
-
|
167
|
-
## Medical Subject Headings (MeSH)
|
165
|
+
### Medical Subject Headings (MeSH)
|
168
166
|
|
169
167
|
Provides autocompletion of [MeSH terms](http://www.nlm.nih.gov/mesh/introduction.html). This
|
170
168
|
implementation is simple, and only provides *descriptors* and does not implement *qualifiers* (in
|
171
169
|
the technical MeSH sense of these terms). The terms are stored in a local database, which is then
|
172
170
|
queried to provide the suggestions.
|
173
171
|
|
174
|
-
|
172
|
+
To use, run the included rake task to copy over the relevant database migrations into your application:
|
173
|
+
|
174
|
+
rake qa:install:migrations
|
175
|
+
|
176
|
+
Then, create the tables in your database
|
177
|
+
|
178
|
+
rake db:migrate
|
179
|
+
|
180
|
+
Now that you've setup your application to use MeSH terms, you'll now need to load the tems into your
|
181
|
+
database so you can query them locally.
|
175
182
|
|
176
183
|
To import the mesh terms into the local database, first download the MeSH descriptor dump in ASCII
|
177
|
-
format
|
178
|
-
|
184
|
+
format. You can read about doing this [here](http://www.nlm.nih.gov/mesh/filelist.html). Once you have this file, use the
|
185
|
+
following rake task to load the terms into your database:
|
179
186
|
|
180
187
|
MESH_FILE=path/to/mesh.txt rake mesh:import
|
181
188
|
|
182
189
|
This may take a few minutes to finish.
|
183
190
|
|
191
|
+
**Note:** Updating the tables with new terms is currently not supported.
|
192
|
+
|
184
193
|
# Developer Notes
|
185
194
|
|
186
195
|
[How to Contribute](./CONTRIBUTING.md)
|
@@ -188,12 +197,17 @@ This may take a few minutes to finish.
|
|
188
197
|
To develop this gem, clone the repository, then run:
|
189
198
|
|
190
199
|
bundle install
|
191
|
-
rake
|
200
|
+
rake ci
|
201
|
+
|
202
|
+
This will install the gems, create a dummy application under spec/internal and run the tests. After you've made changes,
|
203
|
+
make sure you've included tests and run the test suite with a new sample application:
|
204
|
+
|
205
|
+
rake engine_cart:clean
|
206
|
+
rake ci
|
192
207
|
|
193
|
-
|
194
|
-
directory so that further tests and run against a new dummy application.
|
208
|
+
Commit your features into a new branch and submit a pull request.
|
195
209
|
|
196
|
-
##
|
210
|
+
## Compatibility
|
197
211
|
|
198
212
|
Currently, it is compatible with Rails 4.0 and 4.1 under both Ruby 2.0 and 2.1.
|
199
213
|
|
@@ -201,17 +215,6 @@ Currently, it is compatible with Rails 4.0 and 4.1 under both Ruby 2.0 and 2.1.
|
|
201
215
|
|
202
216
|
For help with Questioning Authority, contact <hydra-tech@googlegroups.com>.
|
203
217
|
|
204
|
-
# Original Authors
|
205
|
-
|
206
|
-
* [Stephen Anderson](https://github.com/scande3)
|
207
|
-
* [Don Brower](https://github.com/dbrower)
|
208
|
-
* [Jim Coble](https://github.com/coblej)
|
209
|
-
* [Mike Durbin](https://github.com/mikedurbin)
|
210
|
-
* [Randall Floyd](https://github.com/stormfin)
|
211
|
-
* [Eric James](https://github.com/yulgit1)
|
212
|
-
* [Mike Stroming](https://github.com/mstroming)
|
213
|
-
* [Adam Wead](https://github.com/awead)
|
214
|
-
|
215
218
|
### Special thanks to...
|
216
219
|
|
217
220
|
[Jeremy Friesen](https://github.com/jeremyf) who gave us the name for our gem.
|
data/Rakefile
CHANGED
@@ -4,74 +4,38 @@
|
|
4
4
|
|
5
5
|
class Qa::TermsController < ApplicationController
|
6
6
|
|
7
|
-
before_action :
|
8
|
-
before_action :
|
7
|
+
before_action :check_vocab_param, :init_authority
|
8
|
+
before_action :check_query_param, only: :search
|
9
9
|
|
10
|
-
#
|
10
|
+
# If the subauthority supports it, return a list of all terms in the authority
|
11
11
|
def index
|
12
|
-
|
13
|
-
@authority = authority_class.constantize.new
|
14
|
-
@authority.search(params[:q], params[:sub_authority])
|
15
|
-
|
16
|
-
respond_to do |format|
|
17
|
-
format.html { render :layout => false, json: @authority.results }
|
18
|
-
format.json { render :layout => false, json: @authority.results }
|
19
|
-
format.js { render :layout => false, :text => @authority.results }
|
20
|
-
end
|
12
|
+
render json: @authority.all
|
21
13
|
end
|
22
14
|
|
15
|
+
# Return a list of terms based on a query
|
23
16
|
def search
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
#initialize the authority and run the search. if there's a sub-authority and it's valid, include that param
|
28
|
-
@authority = authority_class.constantize.new
|
29
|
-
@authority.search(params[:q], params[:sub_authority])
|
30
|
-
|
31
|
-
respond_to do |format|
|
32
|
-
format.html { render :layout => false, :text => @authority.results.to_json }
|
33
|
-
format.json { render :layout => false, :text => @authority.results.to_json }
|
34
|
-
format.js { render :layout => false, :text => @authority.results }
|
35
|
-
end
|
36
|
-
|
17
|
+
terms = @authority.search(url_search)
|
18
|
+
render json: terms
|
37
19
|
end
|
38
20
|
|
21
|
+
# If the subauthority supports it, return all the information for a given term
|
39
22
|
def show
|
40
|
-
|
41
|
-
|
42
|
-
result = authority.full_record(params[:id], params[:sub_authority])
|
43
|
-
|
44
|
-
respond_to do |format|
|
45
|
-
format.html { render :layout => false, :text => result.to_json }
|
46
|
-
format.json { render :layout => false, :text => result.to_json }
|
47
|
-
format.js { render :layout => false, :text => result }
|
48
|
-
end
|
23
|
+
term = @authority.find(params[:id])
|
24
|
+
render json: term
|
49
25
|
end
|
50
26
|
|
51
27
|
def check_vocab_param
|
52
|
-
unless params[:vocab].present?
|
53
|
-
head :bad_request
|
54
|
-
end
|
28
|
+
head :not_found unless params[:vocab].present?
|
55
29
|
end
|
56
30
|
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
|
31
|
+
def init_authority
|
32
|
+
@authority = authority_class.constantize.new(params[:sub_authority])
|
33
|
+
rescue
|
34
|
+
head :not_found
|
61
35
|
end
|
62
36
|
|
63
|
-
def
|
64
|
-
|
65
|
-
authority_class.constantize
|
66
|
-
rescue
|
67
|
-
head :bad_request
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def check_sub_authority
|
72
|
-
unless params[:sub_authority].nil?
|
73
|
-
head :bad_request unless authority_class.constantize.authority_valid?(params[:sub_authority])
|
74
|
-
end
|
37
|
+
def check_query_param
|
38
|
+
head :not_found unless params[:q].present?
|
75
39
|
end
|
76
40
|
|
77
41
|
private
|
@@ -80,4 +44,9 @@ class Qa::TermsController < ApplicationController
|
|
80
44
|
"Qa::Authorities::"+params[:vocab].capitalize
|
81
45
|
end
|
82
46
|
|
47
|
+
# converts wildcards into URL-encoded characters
|
48
|
+
def url_search
|
49
|
+
params[:q].gsub("*", "%2A")
|
50
|
+
end
|
51
|
+
|
83
52
|
end
|
data/config/routes.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
Qa::Engine.routes.draw do
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
match "/terms" => "terms#index", :via=>:get
|
7
|
-
match "/show/:vocab/:id" => "terms#show", :via=>:get
|
8
|
-
match "/show/:vocab/:sub_authority/:id" => "terms#show", :via=>:get
|
2
|
+
get "/terms/:vocab(/:sub_authority)", controller: :terms, action: :index
|
3
|
+
get "/search/:vocab(/:sub_authority)", controller: :terms, action: :search
|
4
|
+
get "/show/:vocab/:id", controller: :terms, action: :show
|
5
|
+
get "/show/:vocab/:sub_authority/:id", controller: :terms, action: :show
|
9
6
|
end
|
data/lib/qa/authorities.rb
CHANGED
@@ -2,9 +2,11 @@ module Qa::Authorities
|
|
2
2
|
extend ActiveSupport::Autoload
|
3
3
|
|
4
4
|
autoload :Base
|
5
|
+
autoload :Getty
|
5
6
|
autoload :Loc
|
7
|
+
autoload :LocSubauthority
|
6
8
|
autoload :Local
|
7
|
-
autoload :
|
9
|
+
autoload :LocalSubauthority
|
8
10
|
autoload :Mesh
|
9
11
|
autoload :MeshTools
|
10
12
|
autoload :Oclcts
|
data/lib/qa/authorities/base.rb
CHANGED
@@ -2,21 +2,40 @@ require 'deprecation'
|
|
2
2
|
|
3
3
|
module Qa::Authorities
|
4
4
|
class Base
|
5
|
+
extend Deprecation
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
attr_accessor :sub_authority
|
8
|
+
|
9
|
+
# Registers the authority and its sub-authority if it has one
|
10
|
+
def initialize *args
|
11
|
+
if args.first
|
12
|
+
raise "Invalid sub-authority" unless sub_authorities.include?(args.first)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# By default, an authority has no subauthorities unless they
|
17
|
+
# are defined by the subclassed authority.
|
18
|
+
def sub_authorities
|
19
|
+
[]
|
8
20
|
end
|
9
21
|
|
10
|
-
#
|
11
|
-
|
22
|
+
# By default, #all is not implemented.
|
23
|
+
# If the subclassed authority does have this feature
|
24
|
+
# then you will overide the #all method in the subclassed authority.
|
25
|
+
# TODO: need to set some kind of error here
|
26
|
+
def all
|
12
27
|
end
|
13
28
|
|
14
|
-
|
15
|
-
|
29
|
+
# By default, #find is not implemented.
|
30
|
+
# If the subclassed authority does have this feature
|
31
|
+
# then you will overide the #find method in the subclassed authority.
|
32
|
+
# TODO: need to set some kind of error here
|
33
|
+
def find id
|
16
34
|
end
|
17
35
|
|
18
|
-
def
|
19
|
-
|
36
|
+
def full_record id, sub_authority=nil
|
37
|
+
Deprecation.warn(".full_record is deprecated. Use .find instead")
|
38
|
+
find(id)
|
20
39
|
end
|
21
40
|
|
22
41
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Qa::Authorities
|
4
|
+
class Getty < WebServiceBase
|
5
|
+
|
6
|
+
def initialize *args
|
7
|
+
super
|
8
|
+
@sub_authority ||= args.first
|
9
|
+
raise "No sub-authority provided" if sub_authority.nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def sub_authorities
|
13
|
+
[ "aat" ]
|
14
|
+
end
|
15
|
+
|
16
|
+
def search q
|
17
|
+
parse_authority_response(json(build_query_url(q)))
|
18
|
+
end
|
19
|
+
|
20
|
+
# get_json is not ideomatic, so we'll make an alias
|
21
|
+
def json(*args)
|
22
|
+
get_json(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_query_url q
|
26
|
+
untainted = q.gsub(/[\w\s-]/, '')
|
27
|
+
sparql = "PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
|
28
|
+
SELECT * WHERE { ?s skos:prefLabel ?name .
|
29
|
+
?s skos:inScheme <http://vocab.getty.edu/#{@sub_authority}/> .
|
30
|
+
?s rdf:type <http://vocab.getty.edu/ontology#Concept> .
|
31
|
+
FILTER regex(?name, \"#{untainted}\", \"i\") .
|
32
|
+
FILTER langMatches( lang(?name), \"EN\" ) .
|
33
|
+
} LIMIT 10"
|
34
|
+
"http://vocab.getty.edu/sparql.json?query=#{URI.escape(sparql)}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
|
35
|
+
end
|
36
|
+
|
37
|
+
def find id
|
38
|
+
json(find_url(id))
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_url id
|
42
|
+
"http://vocab.getty.edu/#{@sub_authority}/#{id}.json"
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# Reformats the data received from the LOC service
|
48
|
+
def parse_authority_response(response)
|
49
|
+
response['results']['bindings'].map do |result|
|
50
|
+
{ 'id' => result['s']['value'], 'label' => result['name']['value'] }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
data/lib/qa/authorities/loc.rb
CHANGED
@@ -1,97 +1,44 @@
|
|
1
1
|
require 'uri'
|
2
2
|
|
3
3
|
module Qa::Authorities
|
4
|
-
class Loc <
|
5
|
-
extend Deprecation
|
4
|
+
class Loc < WebServiceBase
|
6
5
|
|
7
|
-
|
8
|
-
# This is set to a JSON object
|
9
|
-
def initialize
|
10
|
-
end
|
11
|
-
|
12
|
-
def search(q, sub_authority=nil)
|
13
|
-
if ! (sub_authority.nil? || Loc.sub_authorities.include?(sub_authority))
|
14
|
-
@raw_response = nil
|
15
|
-
@response = nil
|
16
|
-
return
|
17
|
-
end
|
6
|
+
include Qa::Authorities::LocSubauthority
|
18
7
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
@response = parse_authority_response(@raw_response)
|
8
|
+
def initialize *args
|
9
|
+
super
|
10
|
+
@sub_authority ||= args.first
|
11
|
+
raise "No sub-authority provided" if sub_authority.nil?
|
24
12
|
end
|
25
13
|
|
26
|
-
def
|
27
|
-
|
28
|
-
begin
|
29
|
-
vocab_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2F'
|
30
|
-
authority_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fauthorities%2F'
|
31
|
-
datatype_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fdatatypes%2F'
|
32
|
-
vocab_preservation_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2Fpreservation%2F'
|
33
|
-
{
|
34
|
-
'subjects' => authority_base_url,
|
35
|
-
'names' => authority_base_url,
|
36
|
-
'classification' => authority_base_url,
|
37
|
-
'childrensSubjects' => authority_base_url,
|
38
|
-
'genreForms' => authority_base_url,
|
39
|
-
'graphicMaterials' => vocab_base_url,
|
40
|
-
'organizations' => vocab_base_url,
|
41
|
-
'relators' => vocab_base_url,
|
42
|
-
'countries' => vocab_base_url,
|
43
|
-
'geographicAreas' => vocab_base_url,
|
44
|
-
'languages' => vocab_base_url,
|
45
|
-
'iso639-1' => vocab_base_url,
|
46
|
-
'iso639-2' => vocab_base_url,
|
47
|
-
'iso639-5' => vocab_base_url,
|
48
|
-
'edtf' => datatype_base_url,
|
49
|
-
'preservation' => vocab_base_url,
|
50
|
-
'actionsGranted' => vocab_base_url,
|
51
|
-
'agentType' => vocab_base_url,
|
52
|
-
'contentLocationType' => vocab_preservation_base_url,
|
53
|
-
'copyrightStatus' => vocab_preservation_base_url,
|
54
|
-
'cryptographicHashFunctions' => vocab_preservation_base_url,
|
55
|
-
'environmentCharacteristic' => vocab_preservation_base_url,
|
56
|
-
'environmentPurpose' => vocab_preservation_base_url,
|
57
|
-
'eventRelatedAgentRole' => vocab_preservation_base_url,
|
58
|
-
'eventRelatedObjectRole' => vocab_preservation_base_url,
|
59
|
-
'eventType' => vocab_preservation_base_url,
|
60
|
-
'formatRegistryRole' => vocab_preservation_base_url,
|
61
|
-
'hardwareType' => vocab_preservation_base_url,
|
62
|
-
'inhibitorTarget' => vocab_preservation_base_url,
|
63
|
-
'inhibitorType' => vocab_preservation_base_url,
|
64
|
-
'objectCategory' => vocab_preservation_base_url,
|
65
|
-
'preservationLevelRole' => vocab_preservation_base_url,
|
66
|
-
'relationshipSubType' => vocab_preservation_base_url,
|
67
|
-
'relationshipType' => vocab_preservation_base_url,
|
68
|
-
'rightsBasis' => vocab_preservation_base_url,
|
69
|
-
'rightsRelatedAgentRole' => vocab_preservation_base_url,
|
70
|
-
'signatureEncoding' => vocab_preservation_base_url,
|
71
|
-
'signatureMethod' => vocab_preservation_base_url,
|
72
|
-
'softwareType' => vocab_preservation_base_url,
|
73
|
-
'storageMedium' => vocab_preservation_base_url
|
74
|
-
}
|
75
|
-
end
|
14
|
+
def sub_authorities
|
15
|
+
authorities + vocabularies + datatypes + preservation
|
76
16
|
end
|
77
17
|
|
18
|
+
def search q
|
19
|
+
@raw_response = get_json(build_query_url(q))
|
20
|
+
parse_authority_response
|
21
|
+
end
|
78
22
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
23
|
+
def build_query_url q
|
24
|
+
escaped_query = URI.escape(q)
|
25
|
+
authority_fragment = get_url_for_authority(sub_authority) + URI.escape(sub_authority)
|
26
|
+
return "http://id.loc.gov/search/?q=#{escaped_query}&q=#{authority_fragment}&format=json"
|
83
27
|
end
|
84
28
|
|
85
|
-
def
|
86
|
-
|
29
|
+
def find id
|
30
|
+
get_json(find_url(id))
|
87
31
|
end
|
88
32
|
|
89
|
-
def
|
90
|
-
@
|
33
|
+
def find_url id
|
34
|
+
"http://id.loc.gov/authorities/#{@sub_authority}/#{id}.json"
|
91
35
|
end
|
92
36
|
|
93
|
-
|
94
|
-
|
37
|
+
private
|
38
|
+
|
39
|
+
# Reformats the data received from the LOC service
|
40
|
+
def parse_authority_response
|
41
|
+
@raw_response.select {|response| response[0] == "atom:entry"}.map do |response|
|
95
42
|
loc_response_to_qa(response_to_struct(response))
|
96
43
|
end
|
97
44
|
end
|
@@ -101,7 +48,7 @@ module Qa::Authorities
|
|
101
48
|
# Note that this is a pretty naive conversion. There should probably just
|
102
49
|
# be a class that properly translates and stores the various pieces of
|
103
50
|
# data, especially if this logic could be useful in other auth lookups.
|
104
|
-
def response_to_struct
|
51
|
+
def response_to_struct response
|
105
52
|
result = response.each_with_object({}) do |result_parts, result|
|
106
53
|
next unless result_parts[0]
|
107
54
|
key = result_parts[0].sub('atom:', '').sub('dcterms:', '')
|
@@ -121,63 +68,12 @@ module Qa::Authorities
|
|
121
68
|
end
|
122
69
|
|
123
70
|
# Simple conversion from LoC-based struct to QA hash
|
124
|
-
def loc_response_to_qa
|
71
|
+
def loc_response_to_qa data
|
125
72
|
{
|
126
73
|
"id" => data.id || data.title,
|
127
74
|
"label" => data.title
|
128
75
|
}
|
129
76
|
end
|
130
77
|
|
131
|
-
def find_record_in_response(raw_response, id)
|
132
|
-
raw_response.each do |single_response|
|
133
|
-
next if single_response[0] != "atom:entry"
|
134
|
-
single_response.each do |result_part|
|
135
|
-
if (result_part[0] == 'atom:title' ||
|
136
|
-
result_part[0] == 'atom:id') && id == result_part[2]
|
137
|
-
return single_response
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
return nil
|
142
|
-
end
|
143
|
-
|
144
|
-
def get_full_record(id, sub_authority)
|
145
|
-
Deprecation.warn(Loc, "get_full_record is deprecated and will be removed in 0.1.0. Use full_record instead", caller)
|
146
|
-
full_record(id, sub_authority)
|
147
|
-
end
|
148
|
-
|
149
|
-
def full_record(id, sub_authority)
|
150
|
-
search(id, sub_authority)
|
151
|
-
full_record = find_record_in_response(@raw_response, id)
|
152
|
-
|
153
|
-
if full_record.nil?
|
154
|
-
# record not found
|
155
|
-
return {}
|
156
|
-
end
|
157
|
-
|
158
|
-
parsed_result = {}
|
159
|
-
full_record.each do |section|
|
160
|
-
if section.class == Array
|
161
|
-
label = section[0].split(':').last.to_s
|
162
|
-
case label
|
163
|
-
when 'title', 'id', 'updated', 'created'
|
164
|
-
parsed_result[label] = section[2]
|
165
|
-
when 'link'
|
166
|
-
if section[1]['type'] != nil
|
167
|
-
parsed_result[label + "||#{section[1]['type']}"] = section[1]["href"]
|
168
|
-
else
|
169
|
-
parsed_result[label] = section[1]["href"]
|
170
|
-
end
|
171
|
-
when 'author'
|
172
|
-
author_list = []
|
173
|
-
#FIXME: Find example with two authors to better understand this data.
|
174
|
-
author_list << section[2][2]
|
175
|
-
parsed_result[label] = author_list
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
parsed_result
|
180
|
-
end
|
181
|
-
|
182
78
|
end
|
183
79
|
end
|