qa 0.0.1
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.
- data/LICENSE +15 -0
- data/README.md +174 -0
- data/Rakefile +10 -0
- data/app/assets/javascripts/qa/application.js +13 -0
- data/app/assets/stylesheets/qa/application.css +13 -0
- data/app/controllers/qa/application_controller.rb +4 -0
- data/app/controllers/qa/terms_controller.rb +76 -0
- data/app/helpers/qa/application_helper.rb +2 -0
- data/app/models/qa/mesh_tree.rb +37 -0
- data/app/models/qa/subject_mesh_term.rb +45 -0
- data/app/views/layouts/qa/application.html.erb +14 -0
- data/config/authorities.yml +1 -0
- data/config/authorities/states.yml +101 -0
- data/config/initializers/authorities.rb +1 -0
- data/config/oclcts-authorities.yml +24 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20130917200611_create_qa_subject_mesh_terms.rb +11 -0
- data/db/migrate/20130917201026_create_qa_mesh_tree.rb +10 -0
- data/db/migrate/20130918141523_add_term_lower_to_qa_subject_mesh_terms.rb +7 -0
- data/lib/qa.rb +9 -0
- data/lib/qa/authorities.rb +12 -0
- data/lib/qa/authorities/base.rb +50 -0
- data/lib/qa/authorities/lcsh.rb +46 -0
- data/lib/qa/authorities/loc.rb +200 -0
- data/lib/qa/authorities/local.rb +69 -0
- data/lib/qa/authorities/mesh.rb +20 -0
- data/lib/qa/authorities/mesh_tools.rb +6 -0
- data/lib/qa/authorities/mesh_tools/mesh_data_parser.rb +65 -0
- data/lib/qa/authorities/mesh_tools/mesh_importer.rb +41 -0
- data/lib/qa/authorities/oclcts.rb +63 -0
- data/lib/qa/authorities/tgnlang.rb +40 -0
- data/lib/qa/data/TGN_LANGUAGES.xml +7435 -0
- data/lib/qa/engine.rb +5 -0
- data/lib/qa/version.rb +3 -0
- data/lib/tasks/qa_tasks.rake +4 -0
- data/spec/controllers/terms_controller_spec.rb +70 -0
- data/spec/fixtures/authorities/authority_A.yml +10 -0
- data/spec/fixtures/authorities/authority_B.yml +7 -0
- data/spec/fixtures/authorities/authority_C.yml +4 -0
- data/spec/fixtures/lcsh-response.txt +1 -0
- data/spec/fixtures/loc-response.txt +147 -0
- data/spec/fixtures/mesh.txt +334 -0
- data/spec/fixtures/oclcts-response-mesh-1.txt +28 -0
- data/spec/fixtures/oclcts-response-mesh-2.txt +253 -0
- data/spec/fixtures/oclcts-response-mesh-3.txt +28 -0
- data/spec/internal/Gemfile +48 -0
- data/spec/internal/Gemfile.lock +156 -0
- data/spec/internal/README.rdoc +28 -0
- data/spec/internal/Rakefile +6 -0
- data/spec/internal/app/assets/javascripts/application.js +16 -0
- data/spec/internal/app/assets/stylesheets/application.css +13 -0
- data/spec/internal/app/controllers/application_controller.rb +5 -0
- data/spec/internal/app/helpers/application_helper.rb +2 -0
- data/spec/internal/app/views/layouts/application.html.erb +14 -0
- data/spec/internal/bin/bundle +3 -0
- data/spec/internal/bin/rails +4 -0
- data/spec/internal/bin/rake +4 -0
- data/spec/internal/config.ru +4 -0
- data/spec/internal/config/application.rb +23 -0
- data/spec/internal/config/boot.rb +4 -0
- data/spec/internal/config/database.yml +25 -0
- data/spec/internal/config/environment.rb +5 -0
- data/spec/internal/config/environments/development.rb +29 -0
- data/spec/internal/config/environments/production.rb +80 -0
- data/spec/internal/config/environments/test.rb +36 -0
- data/spec/internal/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/internal/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/internal/config/initializers/inflections.rb +16 -0
- data/spec/internal/config/initializers/mime_types.rb +5 -0
- data/spec/internal/config/initializers/secret_token.rb +12 -0
- data/spec/internal/config/initializers/session_store.rb +3 -0
- data/spec/internal/config/initializers/wrap_parameters.rb +14 -0
- data/spec/internal/config/locales/en.yml +23 -0
- data/spec/internal/config/oclcts-authorities.yml +24 -0
- data/spec/internal/config/routes.rb +60 -0
- data/spec/internal/db/development.sqlite3 +0 -0
- data/spec/internal/db/migrate/20130930151844_create_qa_subject_mesh_terms.qa.rb +12 -0
- data/spec/internal/db/migrate/20130930151845_create_qa_mesh_tree.qa.rb +11 -0
- data/spec/internal/db/migrate/20130930151846_add_term_lower_to_qa_subject_mesh_terms.qa.rb +8 -0
- data/spec/internal/db/schema.rb +34 -0
- data/spec/internal/db/seeds.rb +7 -0
- data/spec/internal/db/test.sqlite3 +0 -0
- data/spec/internal/lib/generators/test_app_generator.rb +20 -0
- data/spec/internal/log/development.log +193 -0
- data/spec/internal/public/404.html +58 -0
- data/spec/internal/public/422.html +58 -0
- data/spec/internal/public/500.html +57 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/internal/public/robots.txt +5 -0
- data/spec/internal/test/test_helper.rb +15 -0
- data/spec/lib/authorities_lcsh_spec.rb +61 -0
- data/spec/lib/authorities_loc_spec.rb +35 -0
- data/spec/lib/authorities_local_spec.rb +89 -0
- data/spec/lib/authorities_mesh_spec.rb +38 -0
- data/spec/lib/authorities_oclcts_spec.rb +49 -0
- data/spec/lib/authorities_tgnlang_spec.rb +22 -0
- data/spec/lib/mesh_data_parser_spec.rb +125 -0
- data/spec/models/subject_mesh_term_spec.rb +49 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/support/lib/generators/test_app_generator.rb +20 -0
- metadata +396 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AUTHORITIES_CONFIG = YAML.load_file(File.expand_path("../../authorities.yml", __FILE__))
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
url-pattern:
|
|
2
|
+
prefix-query: http://tspilot.oclc.org/{authority-id}/?query=oclcts.rootHeading+exact+%22{query}*%22&version=1.1&operation=searchRetrieve&recordSchema=http%3A%2F%2Fzthes.z3950.org%2Fxml%2F1.0%2F&maximumRecords=10&startRecord=1&resultSetTTL=300&recordPacking=xml&recordXPath=&sortKeys=
|
|
3
|
+
id-lookup: http://tspilot.oclc.org/{authority-id}/?query=dc.identifier+exact+%22{id}%22&version=1.1&operation=searchRetrieve&recordSchema=http%3A%2F%2Fzthes.z3950.org%2Fxml%2F1.0%2F&maximumRecords=10&startRecord=1&resultSetTTL=300&recordPacking=xml&recordXPath=&sortKeys=
|
|
4
|
+
authorities:
|
|
5
|
+
lcgft:
|
|
6
|
+
name: Library of Congress Genre/Form Terms for Library and Archival Materials (LCGFT)
|
|
7
|
+
bisacsh:
|
|
8
|
+
name: Book Industry Study Group Subject Headings (BISAC®). Used with permission.
|
|
9
|
+
fast:
|
|
10
|
+
name: Faceted Application of Subject Terminology (FAST subject headings)
|
|
11
|
+
gsafd:
|
|
12
|
+
name: Form and genre headings for fiction and drama
|
|
13
|
+
lcshac:
|
|
14
|
+
name: Library of Congress AC Subject Headings
|
|
15
|
+
lcsh:
|
|
16
|
+
name: Library of Congress Subject Headings
|
|
17
|
+
mesh:
|
|
18
|
+
name: Medical Subject Headings (MeSH®)
|
|
19
|
+
lctgm:
|
|
20
|
+
name: "Thesaurus for graphic materials: TGM I, Subject terms"
|
|
21
|
+
gmgpc:
|
|
22
|
+
name: "Thesaurus for graphic materials: TGM II, Genre terms"
|
|
23
|
+
meta:
|
|
24
|
+
name: Controlled Vocabulary Metadata
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Qa::Engine.routes.draw do
|
|
2
|
+
match "/search/:vocab" => "terms#search", :via=>:get
|
|
3
|
+
match "/search/:vocab/:sub_authority" => "terms#search", :via=>:get
|
|
4
|
+
match "/terms/:vocab" => "terms#index", :via=>:get
|
|
5
|
+
match "/terms/:vocab/:sub_authority" => "terms#index", :via=>:get
|
|
6
|
+
match "/terms" => "terms#index", :via=>:get
|
|
7
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class CreateQaSubjectMeshTerms < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :qa_subject_mesh_terms do |t|
|
|
4
|
+
t.string :term_id
|
|
5
|
+
t.string :term
|
|
6
|
+
t.text :synonyms
|
|
7
|
+
end
|
|
8
|
+
add_index :qa_subject_mesh_terms, :term_id
|
|
9
|
+
add_index :qa_subject_mesh_terms, :term
|
|
10
|
+
end
|
|
11
|
+
end
|
data/lib/qa.rb
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'curl'
|
|
2
|
+
|
|
3
|
+
module Qa::Authorities
|
|
4
|
+
class Base
|
|
5
|
+
attr_accessor :response, :query_url, :raw_response
|
|
6
|
+
|
|
7
|
+
def initialize(q, sub_authority='')
|
|
8
|
+
# Implement Me and set self.query_url
|
|
9
|
+
|
|
10
|
+
if self.query_url == nil
|
|
11
|
+
raise Exception 'query url in your authorities lib is not set (implement in initialize)'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
#Default implementation assumed query_url is set
|
|
15
|
+
http = Curl.get(self.query_url) do |http|
|
|
16
|
+
http.headers['Accept'] = 'application/json'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
self.raw_response = JSON.parse(http.body_str)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.authority_valid?(sub_authority)
|
|
23
|
+
sub_authority == nil || sub_authorities.include?(sub_authority)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.sub_authorities
|
|
27
|
+
[] #Overwrite if you have sub_authorities
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def parse_authority_response
|
|
31
|
+
# Overwrite me unless your raw response needs no parsing
|
|
32
|
+
self.response = self.raw_response
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def get_full_record(id)
|
|
37
|
+
# implement me
|
|
38
|
+
{"id"=>id}.to_json
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Parse the result from LOC, and return an JSON array of terms that match the query.
|
|
42
|
+
def results
|
|
43
|
+
self.response.to_json
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# TODO: there's other info in the self.response that might be worth making access to, such as
|
|
47
|
+
# RDF links, etc.
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
|
|
3
|
+
module Qa::Authorities
|
|
4
|
+
class Lcsh < Qa::Authorities::Base
|
|
5
|
+
|
|
6
|
+
# Initialze the Lcsh class with a query and get the http response from LOC's server.
|
|
7
|
+
# This is set to a JSON object
|
|
8
|
+
def initialize(q, sub_authority='')
|
|
9
|
+
self.query_url= "http://id.loc.gov/authorities/suggest/?q=" + q
|
|
10
|
+
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Format response to the correct JSON structure
|
|
15
|
+
def parse_authority_response
|
|
16
|
+
self.response = build_response
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def query
|
|
20
|
+
self.raw_response[0]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def suggestions
|
|
24
|
+
self.raw_response[1]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def urls_for_suggestions
|
|
28
|
+
self.raw_response[3]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def build_response a = Array.new
|
|
34
|
+
self.suggestions.each_index do |i|
|
|
35
|
+
a << {"id"=>get_id_from_url(urls_for_suggestions[i]), "label"=>suggestions[i]}
|
|
36
|
+
end
|
|
37
|
+
return a
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def get_id_from_url url
|
|
41
|
+
uri = URI(url)
|
|
42
|
+
return uri.path.split(/\//).last
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
|
|
3
|
+
module Qa::Authorities
|
|
4
|
+
class Loc < Qa::Authorities::Base
|
|
5
|
+
|
|
6
|
+
# Initialze the Loc class with a query and get the http response from LOC's server.
|
|
7
|
+
# This is set to a JSON object
|
|
8
|
+
def initialize(q, sub_authority='')
|
|
9
|
+
q += '*'
|
|
10
|
+
authority_url = sub_authorityURL(sub_authority)
|
|
11
|
+
self.query_url = "http://id.loc.gov/search/?q=#{q}&q=#{authority_url}&format=json"
|
|
12
|
+
|
|
13
|
+
super
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def sub_authorityURL(sub_authority)
|
|
17
|
+
vocab_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2F'
|
|
18
|
+
authority_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fauthorities%2F'
|
|
19
|
+
datatype_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fdatatypes%2F'
|
|
20
|
+
vocab_preservation_base_url = 'cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fvocabulary%2Fpreservation%2F'
|
|
21
|
+
|
|
22
|
+
case sub_authority
|
|
23
|
+
when 'subjects'
|
|
24
|
+
return authority_base_url + URI.escape(sub_authority)
|
|
25
|
+
when 'names'
|
|
26
|
+
return authority_base_url + URI.escape(sub_authority)
|
|
27
|
+
when 'classification'
|
|
28
|
+
return authority_base_url + URI.escape(sub_authority)
|
|
29
|
+
when 'childrensSubjects'
|
|
30
|
+
return authority_base_url + URI.escape(sub_authority)
|
|
31
|
+
when 'genreForms'
|
|
32
|
+
return authority_base_url + URI.escape(sub_authority)
|
|
33
|
+
when 'graphicMaterials'
|
|
34
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
35
|
+
when 'organizations'
|
|
36
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
37
|
+
when 'relators'
|
|
38
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
39
|
+
when 'countries'
|
|
40
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
41
|
+
when 'geographicAreas'
|
|
42
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
43
|
+
when 'languages'
|
|
44
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
45
|
+
when 'iso639-1'
|
|
46
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
47
|
+
when 'iso639-2'
|
|
48
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
49
|
+
when 'iso639-5'
|
|
50
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
51
|
+
when 'edtf'
|
|
52
|
+
return datatype_base_url + URI.escape(sub_authority)
|
|
53
|
+
when 'preservation'
|
|
54
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
55
|
+
when 'actionsGranted'
|
|
56
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
57
|
+
when 'agentType'
|
|
58
|
+
return vocab_base_url + URI.escape(sub_authority)
|
|
59
|
+
when 'contentLocationType'
|
|
60
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
61
|
+
when 'copyrightStatus'
|
|
62
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
63
|
+
when 'cryptographicHashFunctions'
|
|
64
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
65
|
+
when 'environmentCharacteristic'
|
|
66
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
67
|
+
when 'environmentPurpose'
|
|
68
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
69
|
+
when 'eventRelatedAgentRole'
|
|
70
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
71
|
+
when 'eventRelatedObjectRole'
|
|
72
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
73
|
+
when 'eventType'
|
|
74
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
75
|
+
when 'formatRegistryRole'
|
|
76
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
77
|
+
when 'hardwareType'
|
|
78
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
79
|
+
when 'inhibitorTarget'
|
|
80
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
81
|
+
when 'inhibitorType'
|
|
82
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
83
|
+
when 'objectCategory'
|
|
84
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
85
|
+
when 'preservationLevelRole'
|
|
86
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
87
|
+
when 'relationshipSubType'
|
|
88
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
89
|
+
when 'relationshipType'
|
|
90
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
91
|
+
when 'rightsBasis'
|
|
92
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
93
|
+
when 'rightsRelatedAgentRole'
|
|
94
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
95
|
+
when 'signatureEncoding'
|
|
96
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
97
|
+
when 'signatureMethod'
|
|
98
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
99
|
+
when 'softwareType'
|
|
100
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
101
|
+
when 'storageMedium'
|
|
102
|
+
return vocab_preservation_base_url + URI.escape(sub_authority)
|
|
103
|
+
else
|
|
104
|
+
return ''
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def self.sub_authorities
|
|
109
|
+
['iso639-2', 'subjects', 'names', 'classification', 'childrensSubjects', 'genreForms', 'graphicMaterials', 'organizations', 'relators', 'countries', 'geographicAreas', 'languages', 'iso639-5', 'edtf', 'preservation', 'actionsGranted', 'agentType', 'contentLocationType', 'copyrightStatus', 'cryptographicHashFunctions', 'environmentCharacteristic', 'environmentPurpose', 'eventRelatedAgentRole', 'eventRelatedObjectRole', 'eventType', 'formatRegistryRole', 'hardwareType', 'inhibitorTarget', 'inhibitorType', 'objectCategory', 'preservationLevelRole', 'relationshipSubType', 'relationshipType', 'rightsBasis', 'rightsRelatedAgentRole', 'signatureEncoding', 'signatureMethod', 'softwareType', 'storageMedium']
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def parse_authority_response
|
|
114
|
+
result = []
|
|
115
|
+
self.raw_response.each do |single_response|
|
|
116
|
+
if single_response[0] == "atom:entry"
|
|
117
|
+
id = nil
|
|
118
|
+
label = ''
|
|
119
|
+
single_response.each do |result_part|
|
|
120
|
+
if(result_part[0] == 'atom:title')
|
|
121
|
+
label = result_part[2]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
if(result_part[0] == 'atom:id')
|
|
125
|
+
id = result_part[2]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
id ||= label
|
|
131
|
+
result << {"id"=>id, "label"=>label}
|
|
132
|
+
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
self.response = result
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def get_full_record(id)
|
|
139
|
+
full_record = nil
|
|
140
|
+
parsed_result = {}
|
|
141
|
+
self.raw_response.each do |single_response|
|
|
142
|
+
if single_response[0] == "atom:entry"
|
|
143
|
+
|
|
144
|
+
single_response.each do |result_part|
|
|
145
|
+
if(result_part[0] == 'atom:title')
|
|
146
|
+
if id == result_part[2]
|
|
147
|
+
full_record = single_response
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
if(result_part[0] == 'atom:id')
|
|
152
|
+
if id == result_part[2]
|
|
153
|
+
full_record = single_response
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
if full_record != nil
|
|
164
|
+
full_record.each do |section|
|
|
165
|
+
if section.class == Array
|
|
166
|
+
label = section[0].split(':').last.to_s
|
|
167
|
+
case label
|
|
168
|
+
when 'title'
|
|
169
|
+
parsed_result[label] = section[2]
|
|
170
|
+
when 'link'
|
|
171
|
+
if section[1]['type'] != nil
|
|
172
|
+
parsed_result[label + "||#{section[1]['type']}"] = section[1]["href"]
|
|
173
|
+
else
|
|
174
|
+
parsed_result[label] = section[1]["href"]
|
|
175
|
+
end
|
|
176
|
+
when 'id'
|
|
177
|
+
parsed_result[label] = section[2]
|
|
178
|
+
when 'author'
|
|
179
|
+
author_list = []
|
|
180
|
+
#FIXME: Find example with two authors to better understand this data.
|
|
181
|
+
author_list << section[2][2]
|
|
182
|
+
parsed_result[label] = author_list
|
|
183
|
+
when 'updated'
|
|
184
|
+
parsed_result[label] = section[2]
|
|
185
|
+
when 'created'
|
|
186
|
+
parsed_result[label] = section[2]
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
else
|
|
192
|
+
raise Exception 'Lookup without using a result search first not implemented yet'
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
parsed_result
|
|
196
|
+
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
end
|
|
200
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module Qa::Authorities
|
|
2
|
+
class Local < Qa::Authorities::Base
|
|
3
|
+
|
|
4
|
+
attr_accessor :response
|
|
5
|
+
|
|
6
|
+
def initialize(q, sub_authority)
|
|
7
|
+
begin
|
|
8
|
+
sub_authority_hash = YAML.load(File.read(File.join(Qa::Authorities::Local.sub_authorities_path, "#{sub_authority}.yml")))
|
|
9
|
+
rescue
|
|
10
|
+
sub_authority_hash = {}
|
|
11
|
+
end
|
|
12
|
+
@terms = normalize_terms(sub_authority_hash.fetch(:terms, []))
|
|
13
|
+
if q.blank?
|
|
14
|
+
self.response = @terms
|
|
15
|
+
else
|
|
16
|
+
sub_terms = []
|
|
17
|
+
@terms.each { |term| sub_terms << term if term[:term].downcase.start_with?(q.downcase) }
|
|
18
|
+
self.response = sub_terms
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def normalize_terms(terms)
|
|
23
|
+
normalized_terms = []
|
|
24
|
+
terms.each do |term|
|
|
25
|
+
if term.is_a? String
|
|
26
|
+
normalized_terms << { :id => term, :term => term }
|
|
27
|
+
else
|
|
28
|
+
term[:id] = term[:id] || term[:term]
|
|
29
|
+
normalized_terms << term
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
normalized_terms
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def parse_authority_response
|
|
36
|
+
parsed_response = []
|
|
37
|
+
self.response.each do |res|
|
|
38
|
+
parsed_response << { :id => res[:id], :label => res[:term] }
|
|
39
|
+
end
|
|
40
|
+
self.response = parsed_response
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def get_full_record(id)
|
|
44
|
+
target_term = {}
|
|
45
|
+
@terms.each do |term|
|
|
46
|
+
if term[:id] == id
|
|
47
|
+
target_term = term
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
target_term.to_json
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.sub_authorities_path
|
|
54
|
+
config_path = AUTHORITIES_CONFIG[:local_path]
|
|
55
|
+
if config_path.starts_with?(File::Separator)
|
|
56
|
+
config_path
|
|
57
|
+
else
|
|
58
|
+
File.join(Rails.root, config_path)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.sub_authorities
|
|
63
|
+
sub_auths = []
|
|
64
|
+
Dir.foreach(Qa::Authorities::Local.sub_authorities_path) { |file| sub_auths << File.basename(file, File.extname(file)) }
|
|
65
|
+
sub_auths
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|