qa 3.1.0 → 4.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +16 -548
- data/app/controllers/qa/linked_data_terms_controller.rb +64 -42
- data/app/controllers/qa/terms_controller.rb +14 -6
- data/app/models/qa/iri_template/url_config.rb +47 -0
- data/app/models/qa/iri_template/variable_map.rb +62 -0
- data/app/models/qa/linked_data/config/context_map.rb +77 -0
- data/app/models/qa/linked_data/config/context_property_map.rb +144 -0
- data/app/models/qa/linked_data/config/helper.rb +34 -0
- data/app/services/qa/iri_template_service.rb +31 -0
- data/{lib/qa/authorities → app/services/qa}/linked_data/authority_service.rb +3 -4
- data/app/services/qa/linked_data/authority_url_service.rb +48 -0
- data/app/services/qa/linked_data/deep_sort_service.rb +238 -0
- data/app/services/qa/linked_data/graph_service.rb +106 -0
- data/app/services/qa/linked_data/language_service.rb +30 -0
- data/app/services/qa/linked_data/language_sort_service.rb +81 -0
- data/app/services/qa/linked_data/mapper/context_mapper_service.rb +59 -0
- data/app/services/qa/linked_data/mapper/graph_mapper_service.rb +40 -0
- data/app/services/qa/linked_data/mapper/search_results_mapper_service.rb +70 -0
- data/config/authorities/linked_data/loc.json +5 -2
- data/config/authorities/linked_data/oclc_fast.json +3 -2
- data/config/initializers/linked_data_authorities.rb +1 -1
- data/config/locales/qa.en.yml +9 -0
- data/lib/generators/qa/install/templates/config/initializers/qa.rb +4 -0
- data/lib/qa.rb +8 -0
- data/lib/qa/authorities/assign_fast/generic_authority.rb +1 -1
- data/lib/qa/authorities/base.rb +0 -11
- data/lib/qa/authorities/crossref/generic_authority.rb +1 -1
- data/lib/qa/authorities/geonames.rb +1 -1
- data/lib/qa/authorities/getty/aat.rb +7 -2
- data/lib/qa/authorities/getty/tgn.rb +7 -2
- data/lib/qa/authorities/getty/ulan.rb +7 -2
- data/lib/qa/authorities/linked_data.rb +0 -1
- data/lib/qa/authorities/linked_data/config.rb +29 -28
- data/lib/qa/authorities/linked_data/config/search_config.rb +21 -79
- data/lib/qa/authorities/linked_data/config/term_config.rb +7 -77
- data/lib/qa/authorities/linked_data/find_term.rb +25 -17
- data/lib/qa/authorities/linked_data/generic_authority.rb +6 -5
- data/lib/qa/authorities/linked_data/rdf_helper.rb +6 -73
- data/lib/qa/authorities/linked_data/search_query.rb +54 -101
- data/lib/qa/authorities/loc/generic_authority.rb +4 -4
- data/lib/qa/authorities/web_service_base.rb +1 -8
- data/lib/qa/configuration.rb +7 -0
- data/lib/qa/version.rb +1 -1
- data/lib/tasks/mesh.rake +19 -18
- data/spec/controllers/linked_data_terms_controller_spec.rb +51 -1
- data/spec/controllers/terms_controller_spec.rb +15 -15
- data/spec/fixtures/authorities/linked_data/lod_encoding_config.json +2 -1
- data/spec/fixtures/authorities/linked_data/lod_full_config.json +56 -2
- data/spec/fixtures/authorities/linked_data/lod_full_config_1_0.json +164 -0
- data/spec/fixtures/authorities/linked_data/lod_lang_defaults.json +5 -4
- data/spec/fixtures/authorities/linked_data/lod_lang_multi_defaults.json +3 -2
- data/spec/fixtures/authorities/linked_data/lod_lang_no_defaults.json +3 -2
- data/spec/fixtures/authorities/linked_data/lod_lang_param.json +3 -2
- data/spec/fixtures/authorities/linked_data/lod_min_config.json +3 -2
- data/spec/fixtures/authorities/linked_data/lod_search_only_config.json +2 -1
- data/spec/fixtures/authorities/linked_data/lod_sort.json +2 -1
- data/spec/fixtures/authorities/linked_data/lod_term_id_param_config.json +2 -1
- data/spec/fixtures/authorities/linked_data/lod_term_only_config.json +2 -1
- data/spec/fixtures/authorities/linked_data/lod_term_uri_param_config.json +2 -1
- data/spec/fixtures/getty-error-response.txt +10 -0
- data/spec/fixtures/lod_2_ranked_2_unranked.nt +17 -0
- data/spec/fixtures/lod_3_ranked_varying_preds.nt +16 -0
- data/spec/fixtures/lod_lang_search_filtering.nt +11 -0
- data/spec/fixtures/lod_search_with_blanknode_subjects.nt +18 -0
- data/spec/fixtures/lod_term_with_blanknode_objects.nt +8 -0
- data/spec/lib/authorities/assign_fast_spec.rb +1 -0
- data/spec/lib/authorities/getty/aat_spec.rb +14 -2
- data/spec/lib/authorities/getty/tgn_spec.rb +14 -2
- data/spec/lib/authorities/getty/ulan_spec.rb +14 -2
- data/spec/lib/authorities/linked_data/authority_service_spec.rb +2 -1
- data/spec/lib/authorities/linked_data/config_spec.rb +284 -5
- data/spec/lib/authorities/linked_data/find_term_spec.rb +3 -1
- data/spec/lib/authorities/linked_data/generic_authority_spec.rb +92 -42
- data/spec/lib/authorities/linked_data/search_config_spec.rb +67 -160
- data/spec/lib/authorities/linked_data/search_query_spec.rb +3 -127
- data/spec/lib/authorities/linked_data/term_config_spec.rb +6 -134
- data/spec/lib/authorities/loc_spec.rb +9 -9
- data/spec/lib/configuration_spec.rb +20 -7
- data/spec/lib/tasks/mesh.rake_spec.rb +2 -2
- data/spec/models/iri_template/url_config_spec.rb +102 -0
- data/spec/models/iri_template/variable_map_spec.rb +105 -0
- data/spec/models/linked_data/config/context_map_spec.rb +148 -0
- data/spec/models/linked_data/config/context_property_map_spec.rb +286 -0
- data/spec/services/iri_template_service_spec.rb +69 -0
- data/spec/services/linked_data/authority_url_service_spec.rb +107 -0
- data/spec/services/linked_data/deep_sort_service_spec.rb +260 -0
- data/spec/services/linked_data/graph_service_spec.rb +232 -0
- data/spec/services/linked_data/language_service_spec.rb +66 -0
- data/spec/services/linked_data/language_sort_service_spec.rb +58 -0
- data/spec/services/linked_data/mapper/context_mapper_service_spec.rb +137 -0
- data/spec/services/linked_data/mapper/graph_mapper_service_spec.rb +110 -0
- data/spec/services/linked_data/mapper/search_results_mapper_service_spec.rb +109 -0
- data/spec/spec_helper.rb +10 -2
- metadata +81 -11
|
@@ -10,7 +10,8 @@ module Qa::Authorities
|
|
|
10
10
|
# @see Qa::LinkedDataTermsController#show
|
|
11
11
|
# @see Qa::Authorities::LinkedData::Config
|
|
12
12
|
class GenericAuthority < Base
|
|
13
|
-
attr_reader :
|
|
13
|
+
attr_reader :authority_config
|
|
14
|
+
private :authority_config
|
|
14
15
|
|
|
15
16
|
delegate :supports_term?, :term_subauthorities?, :term_subauthority?,
|
|
16
17
|
:term_id_expects_uri?, :term_id_expects_id?, to: :term_config
|
|
@@ -19,7 +20,7 @@ module Qa::Authorities
|
|
|
19
20
|
delegate :subauthority?, :subauthorities?, to: :search_config, prefix: 'search'
|
|
20
21
|
|
|
21
22
|
def initialize(auth_name)
|
|
22
|
-
@
|
|
23
|
+
@authority_config = Qa::Authorities::LinkedData::Config.new(auth_name)
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def reload_authorities
|
|
@@ -27,7 +28,7 @@ module Qa::Authorities
|
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
def authorities_service
|
|
30
|
-
@authorities_service ||= Qa::
|
|
31
|
+
@authorities_service ||= Qa::LinkedData::AuthorityService
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def search_service
|
|
@@ -45,11 +46,11 @@ module Qa::Authorities
|
|
|
45
46
|
private
|
|
46
47
|
|
|
47
48
|
def search_config
|
|
48
|
-
|
|
49
|
+
authority_config.search
|
|
49
50
|
end
|
|
50
51
|
|
|
51
52
|
def term_config
|
|
52
|
-
|
|
53
|
+
authority_config.term
|
|
53
54
|
end
|
|
54
55
|
end
|
|
55
56
|
end
|
|
@@ -7,6 +7,9 @@ module Qa::Authorities
|
|
|
7
7
|
module RdfHelper
|
|
8
8
|
private
|
|
9
9
|
|
|
10
|
+
# TODO: elr - The bulk of the methods in this class moved to app/services/linked_data/rdf_service.rb. The remaining
|
|
11
|
+
# methods are expected to move in a later refactor.
|
|
12
|
+
|
|
10
13
|
def object_value(stmt_hash, consolidated_hash, name, as_string = true)
|
|
11
14
|
new_object_value = stmt_hash[name]
|
|
12
15
|
new_object_value = new_object_value.to_s if as_string
|
|
@@ -24,70 +27,6 @@ module Qa::Authorities
|
|
|
24
27
|
consolidated_hash
|
|
25
28
|
end
|
|
26
29
|
|
|
27
|
-
def get_linked_data(url)
|
|
28
|
-
begin
|
|
29
|
-
graph = RDF::Graph.load(url)
|
|
30
|
-
rescue IOError => e
|
|
31
|
-
process_error(e, url)
|
|
32
|
-
end
|
|
33
|
-
graph
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def process_error(e, url)
|
|
37
|
-
uri = URI(url)
|
|
38
|
-
raise RDF::FormatError, "Unknown RDF format of results returned by #{uri}. (RDF::FormatError) You may need to include gem 'linkeddata'." if e.is_a? RDF::FormatError
|
|
39
|
-
response_code = ioerror_code(e)
|
|
40
|
-
case response_code
|
|
41
|
-
when '404'
|
|
42
|
-
raise Qa::TermNotFound, "#{uri} Not Found - Term may not exist at LOD Authority. (HTTPNotFound - 404)"
|
|
43
|
-
when '500'
|
|
44
|
-
raise Qa::ServiceError, "#{uri.hostname} on port #{uri.port} is not responding. Try again later. (HTTPServerError - 500)"
|
|
45
|
-
when '503'
|
|
46
|
-
raise Qa::ServiceUnavailable, "#{uri.hostname} on port #{uri.port} is not responding. Try again later. (HTTPServiceUnavailable - 503)"
|
|
47
|
-
else
|
|
48
|
-
raise Qa::ServiceError, "Unknown error for #{uri.hostname} on port #{uri.port}. Try again later. (Cause - #{e.message})"
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def ioerror_code(e)
|
|
53
|
-
msg = e.message
|
|
54
|
-
return 'format' if msg.start_with? "Unknown RDF format"
|
|
55
|
-
a = msg.size - 4
|
|
56
|
-
z = msg.size - 2
|
|
57
|
-
msg[a..z]
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# Filter a graph to the specified languages
|
|
61
|
-
# @param [RDF::Graph] the graph to be filtered.
|
|
62
|
-
# @param [String | Symbol | Array<String|Symbol>] language for filtering graph (e.g. "en" or :en or ["en", "fr"] or [:en, :fr])
|
|
63
|
-
# @returns [RDF::Graph] graph of linked data filtered on the specified languages
|
|
64
|
-
def filter_language(graph, language)
|
|
65
|
-
language = normalize_language(language)
|
|
66
|
-
return graph if language.nil?
|
|
67
|
-
graph.each do |st|
|
|
68
|
-
graph.delete(st) unless !st.object.respond_to?(:language) || st.object.language.nil? || language.include?(st.object.language)
|
|
69
|
-
end
|
|
70
|
-
graph
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# Filter a graph to remove any statement with a blanknode for the subject
|
|
74
|
-
# @param [RDF::Graph] the graph to be filtered.
|
|
75
|
-
# @returns [RDF::Graph] graph of linked data with blanknodes removed
|
|
76
|
-
def filter_out_blanknodes(graph)
|
|
77
|
-
return graph if graph.subjects.blank?
|
|
78
|
-
graph.each do |st|
|
|
79
|
-
graph.delete(st) if st.subject.anonymous?
|
|
80
|
-
end
|
|
81
|
-
graph
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def normalize_language(language)
|
|
85
|
-
language = [language.to_sym] if language.is_a? String
|
|
86
|
-
language = [language] if language.is_a? Symbol
|
|
87
|
-
return nil unless language.is_a? Array
|
|
88
|
-
language
|
|
89
|
-
end
|
|
90
|
-
|
|
91
30
|
def extract_preds(graph, preds)
|
|
92
31
|
RDF::Query.execute(graph) do
|
|
93
32
|
preds[:required].each do |key, pred|
|
|
@@ -100,17 +39,11 @@ module Qa::Authorities
|
|
|
100
39
|
end
|
|
101
40
|
|
|
102
41
|
def sort_string_by_language(str_literals)
|
|
103
|
-
return str_literals if str_literals.
|
|
104
|
-
str_literals
|
|
105
|
-
str_literals.
|
|
106
|
-
str_literals.uniq!
|
|
42
|
+
return str_literals if str_literals.blank?
|
|
43
|
+
str_literals = Qa::LinkedData::LanguageSortService.new(str_literals).sort
|
|
44
|
+
str_literals.map!(&:to_s).uniq!
|
|
107
45
|
str_literals.delete_if { |s| s.nil? || s.length <= 0 }
|
|
108
46
|
end
|
|
109
|
-
|
|
110
|
-
def blank_node?(obj)
|
|
111
|
-
return true if obj.to_s.starts_with? "_:g"
|
|
112
|
-
false
|
|
113
|
-
end
|
|
114
47
|
end
|
|
115
48
|
end
|
|
116
49
|
end
|
|
@@ -3,98 +3,100 @@
|
|
|
3
3
|
module Qa::Authorities
|
|
4
4
|
module LinkedData
|
|
5
5
|
class SearchQuery
|
|
6
|
-
|
|
6
|
+
class_attribute :authority_service, :graph_service, :language_service, :language_sort_service, :results_mapper_service
|
|
7
|
+
self.authority_service = Qa::LinkedData::AuthorityUrlService
|
|
8
|
+
self.graph_service = Qa::LinkedData::GraphService
|
|
9
|
+
self.language_service = Qa::LinkedData::LanguageService
|
|
10
|
+
self.language_sort_service = Qa::LinkedData::LanguageSortService
|
|
11
|
+
self.results_mapper_service = Qa::LinkedData::Mapper::SearchResultsMapperService
|
|
7
12
|
|
|
8
13
|
# @param [SearchConfig] search_config The search portion of the config
|
|
9
14
|
def initialize(search_config)
|
|
10
15
|
@search_config = search_config
|
|
11
16
|
end
|
|
12
17
|
|
|
13
|
-
attr_reader :search_config
|
|
18
|
+
attr_reader :search_config, :graph, :language
|
|
19
|
+
private :graph, :language
|
|
14
20
|
|
|
15
21
|
delegate :subauthority?, :supports_sort?, to: :search_config
|
|
16
22
|
|
|
17
23
|
# Search a linked data authority
|
|
18
|
-
# @
|
|
19
|
-
# @param [Symbol] (optional) language
|
|
20
|
-
# @param [Hash] (optional)
|
|
21
|
-
# @param [String]
|
|
24
|
+
# @praram [String] the query
|
|
25
|
+
# @param language [Symbol] (optional) language used to select literals when multi-language is supported (e.g. :en, :fr, etc.)
|
|
26
|
+
# @param replacements [Hash] (optional) replacement values with { pattern_name (defined in YAML config) => value }
|
|
27
|
+
# @param subauth [String] (optional) the subauthority to query
|
|
28
|
+
# @param context [Boolean] (optional) true if context should be returned with the results; otherwise, false (default: false)
|
|
22
29
|
# @return [String] json results
|
|
23
30
|
# @example Json Results for Linked Data Search
|
|
24
31
|
# [ {"uri":"http://id.worldcat.org/fast/5140","id":"5140","label":"Cornell, Joseph"},
|
|
25
32
|
# {"uri":"http://id.worldcat.org/fast/72456","id":"72456","label":"Cornell, Sarah Maria, 1802-1832"},
|
|
26
33
|
# {"uri":"http://id.worldcat.org/fast/409667","id":"409667","label":"Cornell, Ezra, 1807-1874"} ]
|
|
27
|
-
def search(query, language: nil, replacements: {}, subauth: nil)
|
|
34
|
+
def search(query, language: nil, replacements: {}, subauth: nil, context: false)
|
|
28
35
|
raise Qa::InvalidLinkedDataAuthority, "Unable to initialize linked data search sub-authority #{subauth}" unless subauth.nil? || subauthority?(subauth)
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
@context = context
|
|
37
|
+
@language = language_service.preferred_language(user_language: language, authority_language: search_config.language)
|
|
38
|
+
url = authority_service.build_url(action_config: search_config, action: :search, action_request: query, substitutions: replacements, subauthority: subauth)
|
|
31
39
|
Rails.logger.info "QA Linked Data search url: #{url}"
|
|
32
|
-
|
|
33
|
-
parse_search_authority_response
|
|
40
|
+
load_graph(url: url)
|
|
41
|
+
parse_search_authority_response
|
|
34
42
|
end
|
|
35
43
|
|
|
36
44
|
private
|
|
37
45
|
|
|
38
|
-
def
|
|
39
|
-
graph =
|
|
40
|
-
graph =
|
|
41
|
-
results = extract_preds(graph, preds_for_search)
|
|
42
|
-
consolidated_results = consolidate_search_results(results)
|
|
43
|
-
json_results = convert_search_to_json(consolidated_results)
|
|
44
|
-
sort_search_results(json_results)
|
|
46
|
+
def load_graph(url:)
|
|
47
|
+
@graph = graph_service.load_graph(url: url)
|
|
48
|
+
@graph = graph_service.filter(graph: @graph, language: language, remove_blanknode_subjects: true)
|
|
45
49
|
end
|
|
46
50
|
|
|
47
|
-
def
|
|
48
|
-
|
|
51
|
+
def parse_search_authority_response
|
|
52
|
+
results = results_mapper_service.map_values(graph: @graph, predicate_map: preds_for_search, sort_key: :sort,
|
|
53
|
+
preferred_language: @language, context_map: context_map)
|
|
54
|
+
convert_results_to_json(results)
|
|
49
55
|
end
|
|
50
56
|
|
|
51
|
-
def
|
|
52
|
-
|
|
53
|
-
raise Qa::InvalidConfiguration, "required label_predicate is missing in search configuration for LOD authority #{auth_name}" if label_pred_uri.nil?
|
|
54
|
-
{ label: label_pred_uri }
|
|
57
|
+
def context_map
|
|
58
|
+
context? ? search_config.context_map : nil
|
|
55
59
|
end
|
|
56
60
|
|
|
57
|
-
def
|
|
58
|
-
|
|
61
|
+
def context?
|
|
62
|
+
@context == true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def preds_for_search
|
|
66
|
+
label_pred_uri = search_config.results_label_predicate
|
|
67
|
+
raise Qa::InvalidConfiguration, "required label_predicate is missing in search configuration for LOD authority #{auth_name}" if label_pred_uri.nil?
|
|
68
|
+
preds = { label: label_pred_uri }
|
|
69
|
+
preds[:uri] = :subject_uri
|
|
59
70
|
preds[:altlabel] = search_config.results_altlabel_predicate unless search_config.results_altlabel_predicate.nil?
|
|
60
71
|
preds[:id] = search_config.results_id_predicate unless search_config.results_id_predicate.nil?
|
|
61
|
-
preds[:sort] =
|
|
72
|
+
preds[:sort] = sort_predicate.present? ? sort_predicate : preds[:label]
|
|
62
73
|
preds
|
|
63
74
|
end
|
|
64
75
|
|
|
65
|
-
def
|
|
66
|
-
|
|
67
|
-
return consolidated_results if results.nil? || !results.count.positive?
|
|
68
|
-
results.each do |statement|
|
|
69
|
-
stmt_hash = statement.to_h
|
|
70
|
-
uri = stmt_hash[:uri].to_s
|
|
71
|
-
consolidated_hash = init_consolidated_hash(consolidated_results, uri, stmt_hash[:id].to_s)
|
|
72
|
-
|
|
73
|
-
consolidated_hash[:label] = object_value(stmt_hash, consolidated_hash, :label, false)
|
|
74
|
-
consolidated_hash[:altlabel] = object_value(stmt_hash, consolidated_hash, :altlabel, false)
|
|
75
|
-
consolidated_hash[:sort] = object_value(stmt_hash, consolidated_hash, :sort, false)
|
|
76
|
-
consolidated_results[uri] = consolidated_hash
|
|
77
|
-
end
|
|
78
|
-
consolidated_results.each do |res|
|
|
79
|
-
consolidated_hash = res[1]
|
|
80
|
-
consolidated_hash[:label] = sort_string_by_language consolidated_hash[:label]
|
|
81
|
-
consolidated_hash[:altlabel] = sort_string_by_language consolidated_hash[:altlabel]
|
|
82
|
-
consolidated_hash[:sort] = sort_string_by_language consolidated_hash[:sort]
|
|
83
|
-
end
|
|
84
|
-
consolidated_results
|
|
76
|
+
def sort_predicate
|
|
77
|
+
@sort_predicate ||= search_config.results_sort_predicate
|
|
85
78
|
end
|
|
86
79
|
|
|
87
|
-
def
|
|
80
|
+
def convert_results_to_json(results)
|
|
88
81
|
json_results = []
|
|
89
|
-
|
|
90
|
-
json_results << { uri: uri, id: h[:id], label: full_label(h[:label], h[:altlabel]), sort: h[:sort] }
|
|
91
|
-
end
|
|
82
|
+
results.each { |result| json_results << convert_result_to_json(result) }
|
|
92
83
|
json_results
|
|
93
84
|
end
|
|
94
85
|
|
|
86
|
+
def convert_result_to_json(result)
|
|
87
|
+
json_result = {}
|
|
88
|
+
json_result[:uri] = result[:uri].first.to_s
|
|
89
|
+
json_result[:id] = result[:id].first.to_s
|
|
90
|
+
json_result[:label] = full_label(result[:label], result[:altlabel])
|
|
91
|
+
json_result[:context] = result[:context] if context?
|
|
92
|
+
json_result
|
|
93
|
+
end
|
|
94
|
+
|
|
95
95
|
def full_label(label = [], altlabel = [])
|
|
96
|
+
label = language_sort_service.new(label, language).sort
|
|
97
|
+
altlabel = language_sort_service.new(altlabel, language).sort
|
|
96
98
|
lbl = wrap_labels(label)
|
|
97
|
-
lbl += " (#{altlabel.join(', ')})"
|
|
99
|
+
lbl += " (#{altlabel.join(', ')})" if altlabel.present?
|
|
98
100
|
lbl = lbl.slice(0..95) + '...' if lbl.length > 98
|
|
99
101
|
lbl.strip
|
|
100
102
|
end
|
|
@@ -105,55 +107,6 @@ module Qa::Authorities
|
|
|
105
107
|
lbl = '[' + lbl + ']' if labels.size > 1
|
|
106
108
|
lbl
|
|
107
109
|
end
|
|
108
|
-
|
|
109
|
-
def sort_search_results(json_results) # rubocop:disable Metrics/MethodLength
|
|
110
|
-
return json_results unless supports_sort?
|
|
111
|
-
json_results.sort! do |a, b|
|
|
112
|
-
cmp = sort_when_missing_sort_predicate(a, b)
|
|
113
|
-
next cmp unless cmp.nil?
|
|
114
|
-
|
|
115
|
-
cmp = numeric_sort(a, b)
|
|
116
|
-
next cmp unless cmp.nil?
|
|
117
|
-
|
|
118
|
-
as = a[:sort].collect(&:downcase)
|
|
119
|
-
bs = b[:sort].collect(&:downcase)
|
|
120
|
-
cmp = 0
|
|
121
|
-
0.upto([as.size, bs.size].max - 1) do |i|
|
|
122
|
-
cmp = sort_when_same_but_one_has_more_values(as, bs, i)
|
|
123
|
-
break unless cmp.nil?
|
|
124
|
-
|
|
125
|
-
cmp = (as[i] <=> bs[i])
|
|
126
|
-
break if cmp.nonzero? # stop checking as soon as a value in the two lists are different
|
|
127
|
-
end
|
|
128
|
-
cmp
|
|
129
|
-
end
|
|
130
|
-
json_results.each { |h| h.delete(:sort) }
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def sort_when_missing_sort_predicate(a, b)
|
|
134
|
-
return 0 unless a.key?(:sort) || b.key?(:sort) # leave unchanged if both are missing
|
|
135
|
-
return -1 unless a.key? :sort # consider missing a value lower than existing b value
|
|
136
|
-
return 1 unless b.key? :sort # consider missing b value lower than existing a value
|
|
137
|
-
nil
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def sort_when_same_but_one_has_more_values(as, bs, current_list_size)
|
|
141
|
-
return -1 if as.size <= current_list_size # consider shorter a list of values lower then longer b list
|
|
142
|
-
return 1 if bs.size <= current_list_size # consider shorter b list of values lower then longer a list
|
|
143
|
-
nil
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def numeric_sort(a, b)
|
|
147
|
-
return nil if a[:sort].size > 1
|
|
148
|
-
return nil if b[:sort].size > 1
|
|
149
|
-
return nil unless s_is_i? a[:sort][0]
|
|
150
|
-
return nil unless s_is_i? b[:sort][0]
|
|
151
|
-
Integer(a[:sort][0]) <=> Integer(b[:sort][0])
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def s_is_i?(s)
|
|
155
|
-
/\A[-+]?\d+\z/ === s # rubocop:disable Style/CaseEquality
|
|
156
|
-
end
|
|
157
110
|
end
|
|
158
111
|
end
|
|
159
112
|
end
|
|
@@ -24,9 +24,9 @@ module Qa::Authorities
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def build_query_url(q)
|
|
27
|
-
escaped_query =
|
|
28
|
-
authority_fragment = Loc.get_url_for_authority(subauthority) +
|
|
29
|
-
"
|
|
27
|
+
escaped_query = ERB::Util.url_encode(q)
|
|
28
|
+
authority_fragment = Loc.get_url_for_authority(subauthority) + ERB::Util.url_encode(subauthority)
|
|
29
|
+
"http://id.loc.gov/search/?q=#{escaped_query}&q=#{authority_fragment}&format=json"
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def find(id)
|
|
@@ -34,7 +34,7 @@ module Qa::Authorities
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def find_url(id)
|
|
37
|
-
"
|
|
37
|
+
"http://id.loc.gov/authorities/#{@subauthority}/#{id}.json"
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
private
|
|
@@ -14,18 +14,11 @@ module Qa::Authorities
|
|
|
14
14
|
# @param url [String]
|
|
15
15
|
# @return [Hash] a parsed JSON response
|
|
16
16
|
def json(url)
|
|
17
|
+
Rails.logger.info "Retrieving json for url: #{url}"
|
|
17
18
|
r = response(url).body
|
|
18
19
|
JSON.parse(r)
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
##
|
|
22
|
-
# @deprecated Use #json instead
|
|
23
|
-
def get_json(url)
|
|
24
|
-
warn '[DEPRECATED] #get_json is deprecated; use #json instead.' \
|
|
25
|
-
"Called from #{Gem.location_of_caller.join(':')}."
|
|
26
|
-
json(url)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
22
|
##
|
|
30
23
|
# Make a web request and retrieve the response.
|
|
31
24
|
#
|
data/lib/qa/configuration.rb
CHANGED
|
@@ -30,5 +30,12 @@ module Qa
|
|
|
30
30
|
|
|
31
31
|
# Hold linked data authority configs
|
|
32
32
|
attr_accessor :linked_data_authority_configs
|
|
33
|
+
|
|
34
|
+
# For linked data access, specify default language for sorting and selection. The default is only used if a language is not
|
|
35
|
+
# specified in the authority's configuration file and not passed in as a parameter. (e.g. :en, [:en], or [:en, :fr])
|
|
36
|
+
attr_writer :default_language
|
|
37
|
+
def default_language
|
|
38
|
+
@default_language ||= :en
|
|
39
|
+
end
|
|
33
40
|
end
|
|
34
41
|
end
|
data/lib/qa/version.rb
CHANGED
data/lib/tasks/mesh.rake
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
require 'benchmark'
|
|
2
2
|
|
|
3
|
-
namespace :
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
namespace :qa do
|
|
4
|
+
namespace :mesh do
|
|
5
|
+
desc "Import MeSH terms from the file $MESH_FILE, it will update any terms which are already in the database"
|
|
6
|
+
task import: :environment do
|
|
7
|
+
fname = ENV['MESH_FILE']
|
|
8
|
+
if fname.nil?
|
|
9
|
+
puts "Need to set $MESH_FILE with path to file to ingest"
|
|
10
|
+
next # transfers control out of this block
|
|
11
|
+
end
|
|
12
|
+
Benchmark.bm(30) do |bm|
|
|
13
|
+
bm.report("Importing #{fname}") do
|
|
14
|
+
m = Qa::Authorities::MeshTools::MeshImporter.new
|
|
15
|
+
File.open(fname) do |f|
|
|
16
|
+
m.import_from_file(f)
|
|
17
|
+
end
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
|
-
end
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
desc "Delete all mesh terms from the database---not implemented"
|
|
23
|
+
task :clear do
|
|
24
|
+
puts "Not implemented"
|
|
25
|
+
end
|
|
25
26
|
end
|
|
26
27
|
end
|