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
|
@@ -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
|