qa 3.1.0 → 4.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,30 @@
|
|
1
|
+
# Service to determine which language to use for sorting and filtering.
|
2
|
+
module Qa
|
3
|
+
module LinkedData
|
4
|
+
class LanguageService
|
5
|
+
class << self
|
6
|
+
def preferred_language(user_language: nil, authority_language: nil)
|
7
|
+
return normalize_language(user_language) if user_language.present?
|
8
|
+
return normalize_language(authority_language) if authority_language.present?
|
9
|
+
normalize_language(Qa.config.default_language)
|
10
|
+
end
|
11
|
+
|
12
|
+
def literal_has_language_marker?(literal)
|
13
|
+
return false unless literal.respond_to?(:language)
|
14
|
+
literal.language.present?
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# Normalize language
|
20
|
+
# @param [String | Symbol | Array] language for filtering graph (e.g. "en" OR :en OR ["en", "fr"] OR [:en, :fr])
|
21
|
+
# @return [Array<Symbol>] an array of languages encoded as symbols (e.g. [:en] OR [:en, :fr])
|
22
|
+
def normalize_language(language)
|
23
|
+
return language if language.blank?
|
24
|
+
language = [language] unless language.is_a? Array
|
25
|
+
language.map(&:to_sym)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# Service to sort an array of literals by language and within language.
|
2
|
+
module Qa
|
3
|
+
module LinkedData
|
4
|
+
class LanguageSortService
|
5
|
+
LANGUAGE_LOCALE_KEY_FOR_NO_LANGUAGE = :NO_LANGUAGE
|
6
|
+
|
7
|
+
attr_reader :literals, :preferred_language
|
8
|
+
attr_reader :languages, :bins
|
9
|
+
private :literals, :preferred_language, :languages, :bins
|
10
|
+
# private :literals, :preferred_language, :languages, :languages=, :bins, :bins=
|
11
|
+
|
12
|
+
# @param [Array<RDF::Literals>] string literals to sort
|
13
|
+
# @param [Symbol] preferred language to appear first in the list; defaults to no preference
|
14
|
+
# @return instance of this class
|
15
|
+
def initialize(literals, preferred_language = nil)
|
16
|
+
@literals = literals
|
17
|
+
@preferred_language = preferred_language
|
18
|
+
@languages = []
|
19
|
+
@bins = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Sort the literals stored in this instance of the service
|
23
|
+
# @return sorted version of literals
|
24
|
+
def sort
|
25
|
+
return literals unless literals.present?
|
26
|
+
return @sorted_literals if @sorted_literals.present?
|
27
|
+
parse_into_language_bins
|
28
|
+
sort_languages
|
29
|
+
sort_language_bins
|
30
|
+
@sorted_literals = construct_sorted_literals
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def construct_sorted_literals
|
36
|
+
sorted_literals = []
|
37
|
+
0.upto(languages.size - 1) { |idx| sorted_literals.concat(bins[languages[idx]]) }
|
38
|
+
sorted_literals
|
39
|
+
end
|
40
|
+
|
41
|
+
def language(literal)
|
42
|
+
return LANGUAGE_LOCALE_KEY_FOR_NO_LANGUAGE unless Qa::LinkedData::LanguageService.literal_has_language_marker? literal
|
43
|
+
literal.language
|
44
|
+
end
|
45
|
+
|
46
|
+
def move_no_language_to_end
|
47
|
+
return unless languages.include?(LANGUAGE_LOCALE_KEY_FOR_NO_LANGUAGE)
|
48
|
+
languages.delete(LANGUAGE_LOCALE_KEY_FOR_NO_LANGUAGE)
|
49
|
+
languages << LANGUAGE_LOCALE_KEY_FOR_NO_LANGUAGE
|
50
|
+
end
|
51
|
+
|
52
|
+
def move_preferred_language_to_front
|
53
|
+
return unless preferred_language.present? && languages.include?(preferred_language)
|
54
|
+
languages.delete(preferred_language)
|
55
|
+
languages.insert(0, preferred_language)
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse_into_language_bins
|
59
|
+
0.upto(literals.size - 1) do |idx|
|
60
|
+
lang = language(literals[idx])
|
61
|
+
languages << lang
|
62
|
+
bin = bins.fetch(lang, [])
|
63
|
+
bin << literals[idx]
|
64
|
+
bins[lang] = bin
|
65
|
+
end
|
66
|
+
@language = languages
|
67
|
+
@bins = bins
|
68
|
+
end
|
69
|
+
|
70
|
+
def sort_languages
|
71
|
+
languages.sort!.uniq!
|
72
|
+
move_preferred_language_to_front
|
73
|
+
move_no_language_to_end
|
74
|
+
end
|
75
|
+
|
76
|
+
def sort_language_bins
|
77
|
+
bins.each_value { |bin| bin.sort_by! { |literal| literal.to_s.downcase } }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Provide service for mapping predicates to object values.
|
2
|
+
module Qa
|
3
|
+
module LinkedData
|
4
|
+
module Mapper
|
5
|
+
class ContextMapperService
|
6
|
+
class_attribute :graph_service
|
7
|
+
self.graph_service = Qa::LinkedData::GraphService
|
8
|
+
|
9
|
+
class << self
|
10
|
+
# Extract predicates specified in the predicate_map from the graph and return as a value map for a single subject URI.
|
11
|
+
# @param graph [RDF::Graph] the graph from which to extract result values
|
12
|
+
# @param context_map [Qa::LinkedData::Config::ContextMap] defines properties to extract from the graph to provide additional context
|
13
|
+
# @param subject_uri [RDF::URI] the subject within the graph for which the values are being extracted
|
14
|
+
# @return [<Hash<Symbol><Array<Object>>] mapped context values and information with hash of map key = array of object values for predicates identified in predicate_map.
|
15
|
+
# @example returned context map with one property defined
|
16
|
+
# [{"group" => "group label,
|
17
|
+
# "property" => "property label",
|
18
|
+
# "values" => ["value 1","value 2"],
|
19
|
+
# "selectable" => true,
|
20
|
+
# "drillable" => false}]
|
21
|
+
def map_context(graph:, context_map:, subject_uri:)
|
22
|
+
context = []
|
23
|
+
context_map.properties.each do |property_map|
|
24
|
+
populated_property_map = populate_property_map(context_map, property_map, graph, subject_uri)
|
25
|
+
next if populated_property_map.blank?
|
26
|
+
context << populated_property_map
|
27
|
+
end
|
28
|
+
context
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def populate_property_map(context_map, property_map, graph, subject_uri)
|
34
|
+
begin
|
35
|
+
values = property_values(property_map, graph, subject_uri)
|
36
|
+
rescue => e
|
37
|
+
values = Qa::LinkedData::Config::ContextPropertyMap::VALUE_ON_ERROR
|
38
|
+
error = e.message
|
39
|
+
end
|
40
|
+
|
41
|
+
property_info = {}
|
42
|
+
property_info["group"] = context_map.group_label(property_map.group_id) if property_map.group?
|
43
|
+
property_info["property"] = property_map.label
|
44
|
+
property_info["values"] = values
|
45
|
+
property_info["selectable"] = property_map.selectable?
|
46
|
+
property_info["drillable"] = property_map.drillable?
|
47
|
+
property_info["error"] = error if error.present?
|
48
|
+
property_info
|
49
|
+
end
|
50
|
+
|
51
|
+
def property_values(property_map, graph, subject_uri)
|
52
|
+
return property_map.expanded_values(graph, subject_uri) if property_map.expand_uri?
|
53
|
+
property_map.values(graph, subject_uri)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Provide service for mapping predicates to object values.
|
2
|
+
module Qa
|
3
|
+
module LinkedData
|
4
|
+
module Mapper
|
5
|
+
class GraphMapperService
|
6
|
+
class_attribute :graph_service
|
7
|
+
self.graph_service = Qa::LinkedData::GraphService
|
8
|
+
|
9
|
+
# Extract predicates specified in the predicate_map from the graph and return as a value map for a single subject URI.
|
10
|
+
# @param graph [RDF::Graph] the graph from which to extract result values
|
11
|
+
# @param predicate_map [Hash<Symbol><String||Symbol>] value either maps to a predicate in the graph or is :subject_uri indicating to use the subject uri as the value
|
12
|
+
# @example predicate_map
|
13
|
+
# {
|
14
|
+
# uri: :subject_uri,
|
15
|
+
# id: [#<RDF::URI URI:http://id.loc.gov/vocabulary/identifiers/lccn>],
|
16
|
+
# label: [#<RDF::URI URI:http://www.w3.org/2004/02/skos/core#prefLabel>],
|
17
|
+
# altlabel: [#<RDF::URI URI:http://www.w3.org/2004/02/skos/core#altLabel>],
|
18
|
+
# sort: [#<RDF::URI URI:http://vivoweb.org/ontology/core#rank>]'
|
19
|
+
# }
|
20
|
+
# @param subject_uri [RDF::URI] the subject within the graph for which the values are being extracted
|
21
|
+
# @return [<Hash<Symbol><Array<Object>>] mapped result values with hash of map key = array of object values for predicates identified in predicate_map.
|
22
|
+
# @example value map for a single result
|
23
|
+
# {:uri=>[#<RDF::URI:0x3fcff54a829c URI:http://id.loc.gov/authorities/names/n2010043281>],
|
24
|
+
# :id=>[#<RDF::Literal:0x3fcff4a367b4("n2010043281")>],
|
25
|
+
# :label=>[#<RDF::Literal:0x3fcff54a9a98("Valli, Sabrina"@en)>],
|
26
|
+
# :altlabel=>[],
|
27
|
+
# :sort=>[#<RDF::Literal:0x3fcff54b4c18("2")>]}
|
28
|
+
def self.map_values(graph:, predicate_map:, subject_uri:)
|
29
|
+
value_map = {}
|
30
|
+
predicate_map.each do |key, predicate|
|
31
|
+
values = predicate == :subject_uri ? [subject_uri] : graph_service.object_values(graph: graph, subject: subject_uri, predicate: predicate)
|
32
|
+
value_map[key] = values
|
33
|
+
end
|
34
|
+
value_map = yield value_map if block_given?
|
35
|
+
value_map
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Provide service for mapping graph to json limited to configured fields and context.
|
2
|
+
module Qa
|
3
|
+
module LinkedData
|
4
|
+
module Mapper
|
5
|
+
class SearchResultsMapperService
|
6
|
+
class_attribute :graph_mapper_service, :deep_sort_service, :context_mapper_service
|
7
|
+
self.graph_mapper_service = Qa::LinkedData::Mapper::GraphMapperService
|
8
|
+
self.deep_sort_service = Qa::LinkedData::DeepSortService
|
9
|
+
self.context_mapper_service = Qa::LinkedData::Mapper::ContextMapperService
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Extract predicates specified in the predicate_map from the graph and return as an array of value maps for each search result subject URI.
|
13
|
+
# If a sort key is present, a subject will only be included in the results if it has a statement with the sort predicate.
|
14
|
+
# @param graph [RDF::Graph] the graph from which to extract result values
|
15
|
+
# @param predicate_map [Hash<Symbol><String||Symbol>] value either maps to a predicate in the graph or is :subject_uri indicating to use the subject uri as the value
|
16
|
+
# @example predicate map
|
17
|
+
# {
|
18
|
+
# uri: :subject_uri,
|
19
|
+
# id: 'http://id.loc.gov/vocabulary/identifiers/lccn',
|
20
|
+
# label: 'http://www.w3.org/2004/02/skos/core#prefLabel',
|
21
|
+
# altlabel: 'http://www.w3.org/2004/02/skos/core#altLabel',
|
22
|
+
# sort: 'http://vivoweb.org/ontology/core#rank'
|
23
|
+
# }
|
24
|
+
# @param sort_key [Symbol] the key in the predicate map for the value on which to sort
|
25
|
+
# @param context_map [Qa::LinkedData::Config::ContextMap] map of additional context to include in the results
|
26
|
+
# @return [Array<Hash<Symbol><Array<Object>>>] mapped result values with each result as an element in the array
|
27
|
+
# with hash of map key = array of object values for predicates identified in map parameter.
|
28
|
+
# @example value map for a single result
|
29
|
+
# [
|
30
|
+
# {:uri=>[#<RDF::URI:0x3fcff54a829c URI:http://id.loc.gov/authorities/names/n2010043281>],
|
31
|
+
# :id=>[#<RDF::Literal:0x3fcff4a367b4("n 2010043281")>],
|
32
|
+
# :label=>[#<RDF::Literal:0x3fcff54a9a98("Valli, Sabrina"@en)>],
|
33
|
+
# :altlabel=>[],
|
34
|
+
# :sort=>[#<RDF::Literal:0x3fcff54b4c18("2")>]}
|
35
|
+
# ]
|
36
|
+
def map_values(graph:, predicate_map:, sort_key:, preferred_language: nil, context_map: nil)
|
37
|
+
search_matches = []
|
38
|
+
graph.subjects.each do |subject|
|
39
|
+
next if subject.anonymous? # skip blank nodes
|
40
|
+
values = graph_mapper_service.map_values(graph: graph, predicate_map: predicate_map, subject_uri: subject) do |value_map|
|
41
|
+
map_context(graph, sort_key, context_map, value_map, subject)
|
42
|
+
end
|
43
|
+
search_matches << values if result_subject? values, sort_key
|
44
|
+
end
|
45
|
+
search_matches = deep_sort_service.new(search_matches, sort_key, preferred_language).sort
|
46
|
+
search_matches
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# The graph mapper creates the basic value_map for all subject URIs, but we only want the ones that represent search results.
|
52
|
+
def result_subject?(value_map, sort_key)
|
53
|
+
return true unless sort_key.present? # if sort_key is not defined, then all subjects are considered matches
|
54
|
+
return false unless value_map.key? sort_key # otherwise, sort_key must be in the basic value_map
|
55
|
+
value_map[sort_key].present? # AND have a value for this to be a search result
|
56
|
+
end
|
57
|
+
|
58
|
+
def map_context(graph, sort_key, context_map, value_map, subject)
|
59
|
+
return value_map if context_map.blank?
|
60
|
+
return value_map unless result_subject? value_map, sort_key
|
61
|
+
context = {}
|
62
|
+
context = context_mapper_service.map_context(graph: graph, context_map: context_map, subject_uri: subject) if context_map.present?
|
63
|
+
value_map[:context] = context
|
64
|
+
value_map
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
{
|
2
|
+
"QA_CONFIG_VERSION": "2.0",
|
2
3
|
"term": {
|
3
4
|
"url": {
|
4
5
|
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
|
5
6
|
"@type": "IriTemplate",
|
6
|
-
"template": "http://id.loc.gov/authorities/{
|
7
|
+
"template": "http://id.loc.gov/authorities/{subauth}/{term_id}",
|
7
8
|
"variableRepresentation": "BasicRepresentation",
|
8
9
|
"mapping": [
|
9
10
|
{
|
@@ -31,7 +32,9 @@
|
|
31
32
|
"id_predicate": "http://id.loc.gov/vocabulary/identifiers/lccn",
|
32
33
|
"label_predicate": "http://www.w3.org/2004/02/skos/core#prefLabel",
|
33
34
|
"altlabel_predicate": "http://www.w3.org/2004/02/skos/core#altLabel",
|
34
|
-
"sameas_predicate": "http://www.w3.org/2004/02/skos/core#exactMatch"
|
35
|
+
"sameas_predicate": "http://www.w3.org/2004/02/skos/core#exactMatch",
|
36
|
+
"narrower_predicate": "http://www.loc.gov/mads/rdf/v1#hasNarrowerAuthority",
|
37
|
+
"broader_predicate": "http://www.loc.gov/mads/rdf/v1#hasBroaderAuthority"
|
35
38
|
},
|
36
39
|
"subauthorities": {
|
37
40
|
"subjects": "subjects",
|
@@ -1,9 +1,10 @@
|
|
1
1
|
{
|
2
|
+
"QA_CONFIG_VERSION": "2.0",
|
2
3
|
"term": {
|
3
4
|
"url": {
|
4
5
|
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
|
5
6
|
"@type": "IriTemplate",
|
6
|
-
"template": "http://id.worldcat.org/fast/{
|
7
|
+
"template": "http://id.worldcat.org/fast/{term_id}",
|
7
8
|
"variableRepresentation": "BasicRepresentation",
|
8
9
|
"mapping": [
|
9
10
|
{
|
@@ -29,7 +30,7 @@
|
|
29
30
|
"url": {
|
30
31
|
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
|
31
32
|
"@type": "IriTemplate",
|
32
|
-
"template": "http://experimental.worldcat.org/fast/search?query={
|
33
|
+
"template": "http://experimental.worldcat.org/fast/search?query={subauth}+all+%22{query}%22&sortKeys=usage&{?maximumRecords}",
|
33
34
|
"variableRepresentation": "BasicRepresentation",
|
34
35
|
"mapping": [
|
35
36
|
{
|
@@ -1 +1 @@
|
|
1
|
-
Qa::
|
1
|
+
Qa::LinkedData::AuthorityService.load_authorities
|
@@ -0,0 +1,9 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
qa:
|
4
|
+
linked_data:
|
5
|
+
ldpath:
|
6
|
+
evaluate_error: LDPATH EVALUATION ERROR (See log for more information)
|
7
|
+
evaluate_logger_error: LDPath failed to evaluate the graph with the provided ldpath.
|
8
|
+
parse_error: LDPATH PARSE ERROR (See log for more information)
|
9
|
+
parse_logger_error: LDPath failed to parse during ldpath program creation.
|
@@ -10,4 +10,8 @@ Qa.config do |config|
|
|
10
10
|
# requiring a restart of rails. By default, reloading through the browser is not allowed
|
11
11
|
# when the token is nil or blank. Change to any string to control who has access to reload.
|
12
12
|
# config.authorized_reload_token = 'YOUR_AUTH_TOKEN_DEFINED_HERE'
|
13
|
+
|
14
|
+
# For linked data access, specify default language for sorting and selection. The default is only used if a language is not
|
15
|
+
# specified in the authority's configuration file and not passed in as a parameter. (e.g. :en, [:en], or [:en, :fr])
|
16
|
+
# config.default_language = :en
|
13
17
|
end
|
data/lib/qa.rb
CHANGED
@@ -42,6 +42,9 @@ module Qa
|
|
42
42
|
# Raised when a configuration parameter is incorrect or is required and missing
|
43
43
|
class InvalidConfiguration < ArgumentError; end
|
44
44
|
|
45
|
+
# Raised when a request is made for an unsupported action (e.g. :search, :term are supported)
|
46
|
+
class UnsupportedAction < ArgumentError; end
|
47
|
+
|
45
48
|
# Raised when a linked data request to a server returns a 503 error
|
46
49
|
class ServiceUnavailable < ArgumentError; end
|
47
50
|
|
@@ -50,4 +53,9 @@ module Qa
|
|
50
53
|
|
51
54
|
# Raised when the server returns 404 for a find term request
|
52
55
|
class TermNotFound < ArgumentError; end
|
56
|
+
|
57
|
+
# Raised when a required mapping parameter is missing while building an IRI Template
|
58
|
+
module IriTemplate
|
59
|
+
class MissingParameter < StandardError; end
|
60
|
+
end
|
53
61
|
end
|
@@ -53,7 +53,7 @@ module Qa::Authorities
|
|
53
53
|
# See oclc sample code at
|
54
54
|
# http://experimental.worldcat.org/fast/assignfast/js/assignFASTComplete.js
|
55
55
|
def clean_query_string(q)
|
56
|
-
|
56
|
+
ERB::Util.url_encode(q.gsub(/-|\(|\)|:/, ""))
|
57
57
|
end
|
58
58
|
|
59
59
|
def parse_authority_response(raw_response)
|
data/lib/qa/authorities/base.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
|
-
require 'deprecation'
|
2
|
-
|
3
1
|
module Qa::Authorities
|
4
2
|
##
|
5
3
|
# @abstract The base class for all authorites. Implementing subclasses must
|
6
4
|
# provide {#all} and #{find} methods.
|
7
5
|
# @todo What about {#search}?
|
8
6
|
class Base
|
9
|
-
extend Deprecation
|
10
|
-
|
11
7
|
##
|
12
8
|
# @abstract By default, #all is not implemented. A subclass authority must
|
13
9
|
# implement this method to conform to the generic interface.
|
@@ -33,12 +29,5 @@ module Qa::Authorities
|
|
33
29
|
def find(_id)
|
34
30
|
raise NotImplementedError, "#{self.class}#find is unimplemented."
|
35
31
|
end
|
36
|
-
|
37
|
-
##
|
38
|
-
# @deprecated use {#find} instead
|
39
|
-
def full_record(id, _subauthority = nil)
|
40
|
-
Deprecation.warn('#full_record is deprecated. Use #find instead')
|
41
|
-
find(id)
|
42
|
-
end
|
43
32
|
end
|
44
33
|
end
|
@@ -7,7 +7,7 @@ module Qa::Authorities
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def build_query_url(q)
|
10
|
-
"http://vocab.getty.edu/sparql.json?query=#{
|
10
|
+
"http://vocab.getty.edu/sparql.json?query=#{ERB::Util.url_encode(sparql(q))}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
|
11
11
|
end
|
12
12
|
|
13
13
|
def sparql(q) # rubocop:disable Metrics/MethodLength
|
@@ -38,7 +38,7 @@ module Qa::Authorities
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def find_url(id)
|
41
|
-
"http://vocab.getty.edu/aat/#{id}.json"
|
41
|
+
"http://vocab.getty.edu/download/json?uri=http://vocab.getty.edu/aat/#{id}.json"
|
42
42
|
end
|
43
43
|
|
44
44
|
def request_options
|
@@ -52,6 +52,11 @@ module Qa::Authorities
|
|
52
52
|
response['results']['bindings'].map do |result|
|
53
53
|
{ 'id' => result['s']['value'], 'label' => result['name']['value'] }
|
54
54
|
end
|
55
|
+
rescue StandardError => e
|
56
|
+
cause = response.fetch('error', {}).fetch('cause', 'UNKNOWN')
|
57
|
+
cause = cause.present? ? cause : 'UNKNOWN'
|
58
|
+
Rails.logger.warn " ERROR fetching Getty response: #{e.message}; cause: #{cause}"
|
59
|
+
{}
|
55
60
|
end
|
56
61
|
end
|
57
62
|
end
|