qa 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/controllers/qa/linked_data_terms_controller.rb +30 -9
- data/app/controllers/qa/terms_controller.rb +3 -2
- data/app/models/qa/linked_data/config/context_property_map.rb +6 -25
- data/app/services/qa/iri_template_service.rb +32 -24
- data/app/services/qa/linked_data/authority_service.rb +8 -0
- data/app/services/qa/linked_data/authority_url_service.rb +27 -8
- data/app/services/qa/linked_data/deep_sort_service.rb +3 -2
- data/app/services/qa/linked_data/graph_service.rb +13 -0
- data/app/services/qa/linked_data/language_service.rb +12 -0
- data/app/services/qa/linked_data/language_sort_service.rb +7 -2
- data/app/services/qa/linked_data/ldpath_service.rb +40 -0
- data/app/services/qa/linked_data/mapper/graph_ldpath_mapper_service.rb +49 -0
- data/app/services/qa/linked_data/mapper/graph_mapper_service.rb +3 -11
- data/app/services/qa/linked_data/mapper/graph_predicate_mapper_service.rb +40 -0
- data/app/services/qa/linked_data/mapper/search_results_mapper_service.rb +58 -11
- data/app/services/qa/linked_data/mapper/term_results_mapper_service.rb +80 -0
- data/config/authorities/linked_data/loc.json +13 -7
- data/config/authorities/linked_data/oclc_fast.json +13 -8
- data/lib/generators/qa/discogs/USAGE +10 -0
- data/lib/generators/qa/discogs/discogs_generator.rb +12 -0
- data/lib/generators/qa/discogs/templates/config/discogs-formats.yml +346 -0
- data/lib/generators/qa/discogs/templates/config/discogs-genres.yml +627 -0
- data/lib/generators/qa/install/templates/config/initializers/qa.rb +4 -0
- data/lib/qa.rb +6 -0
- data/lib/qa/authorities.rb +2 -0
- data/lib/qa/authorities/discogs.rb +28 -0
- data/lib/qa/authorities/discogs/discogs_instance_builder.rb +145 -0
- data/lib/qa/authorities/discogs/discogs_translation.rb +126 -0
- data/lib/qa/authorities/discogs/discogs_utils.rb +89 -0
- data/lib/qa/authorities/discogs/discogs_works_builder.rb +153 -0
- data/lib/qa/authorities/discogs/generic_authority.rb +151 -0
- data/lib/qa/authorities/discogs_subauthority.rb +9 -0
- data/lib/qa/authorities/linked_data/config.rb +7 -3
- data/lib/qa/authorities/linked_data/config/search_config.rb +99 -11
- data/lib/qa/authorities/linked_data/config/term_config.rb +112 -8
- data/lib/qa/authorities/linked_data/find_term.rb +154 -84
- data/lib/qa/authorities/linked_data/search_query.rb +76 -13
- data/lib/qa/configuration.rb +8 -0
- data/lib/qa/version.rb +1 -1
- data/spec/controllers/linked_data_terms_controller_spec.rb +151 -30
- data/spec/controllers/terms_controller_spec.rb +4 -0
- data/spec/features/linked_data/language_spec.rb +298 -0
- data/spec/fixtures/authorities/linked_data/lod_full_config.json +21 -5
- data/spec/fixtures/authorities/linked_data/lod_lang_defaults.json +4 -4
- data/spec/fixtures/authorities/linked_data/lod_lang_multi_defaults.json +4 -4
- data/spec/fixtures/authorities/linked_data/lod_lang_no_defaults.json +4 -5
- data/spec/fixtures/authorities/linked_data/lod_lang_param.json +4 -4
- data/spec/fixtures/authorities/linked_data/lod_term_uri_param_config.json +1 -1
- data/spec/fixtures/discogs-find-response-json.json +1 -0
- data/spec/fixtures/discogs-find-response-jsonld-master.json +1 -0
- data/spec/fixtures/discogs-find-response-jsonld-release.json +1 -0
- data/spec/fixtures/discogs-id-matches-master.json +1 -0
- data/spec/fixtures/discogs-id-matches-release.json +1 -0
- data/spec/fixtures/discogs-id-not-found-master.json +1 -0
- data/spec/fixtures/discogs-id-not-found-release.json +1 -0
- data/spec/fixtures/discogs-search-response-no-auth.json +1 -0
- data/spec/fixtures/discogs-search-response-no-subauth.json +1 -0
- data/spec/fixtures/discogs-search-response-subauth.json +1 -0
- data/spec/fixtures/lod_lang_search_enesfrde.rdf.xml +60 -0
- data/spec/fixtures/lod_lang_search_sv.rdf.xml +42 -0
- data/spec/fixtures/lod_loc_term_found.rdf.xml +5 -0
- data/spec/lib/authorities/discogs/generic_authority_spec.rb +235 -0
- data/spec/lib/authorities/discogs_spec.rb +17 -0
- data/spec/lib/authorities/linked_data/config_spec.rb +68 -5
- data/spec/lib/authorities/linked_data/find_term_spec.rb +298 -3
- data/spec/lib/authorities/linked_data/generic_authority_spec.rb +46 -485
- data/spec/lib/authorities/linked_data/search_config_spec.rb +154 -3
- data/spec/lib/authorities/linked_data/search_query_spec.rb +240 -3
- data/spec/lib/authorities/linked_data/term_config_spec.rb +193 -5
- data/spec/lib/configuration_spec.rb +18 -0
- data/spec/models/linked_data/config/context_property_map_spec.rb +3 -31
- data/spec/services/iri_template_service_spec.rb +54 -12
- data/spec/{lib/authorities → services}/linked_data/authority_service_spec.rb +47 -0
- data/spec/services/linked_data/language_service_spec.rb +52 -11
- data/spec/services/linked_data/ldpath_service_spec.rb +61 -0
- data/spec/services/linked_data/mapper/graph_ldpath_mapper_service_spec.rb +118 -0
- data/spec/services/linked_data/mapper/graph_predicate_mapper_service_spec.rb +110 -0
- data/spec/services/linked_data/mapper/term_results_mapper_service_spec.rb +94 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/matchers/include_hash.rb +5 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +4 -0
- metadata +73 -5
- data/lib/qa/authorities/linked_data/rdf_helper.rb +0 -49
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'rdf'
|
2
|
+
module Qa::Authorities
|
3
|
+
class Discogs::GenericAuthority < Base
|
4
|
+
include WebServiceBase
|
5
|
+
include Discogs::DiscogsTranslation
|
6
|
+
|
7
|
+
class_attribute :discogs_secret, :discogs_key
|
8
|
+
attr_accessor :primary_artists
|
9
|
+
|
10
|
+
# @param [String] subauthority to use
|
11
|
+
def initialize(subauthority)
|
12
|
+
@subauthority = subauthority
|
13
|
+
self.primary_artists = []
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param [String] the query
|
17
|
+
# @param [Class] QA::TermsController
|
18
|
+
# @return json results
|
19
|
+
def search(q, tc)
|
20
|
+
# Discogs distinguishes between masters and releases, where a release represents a specific
|
21
|
+
# physical or digital object and a master represents a set of similar releases. Use of a
|
22
|
+
# subauthority (e.g., /qa/search/discogs/master) will target a specific type. Using the "all"
|
23
|
+
# subauthority will search for both types.
|
24
|
+
unless discogs_key && discogs_secret
|
25
|
+
Rails.logger.error "Questioning Authority tried to call Discogs, but no secret and/or key were set."
|
26
|
+
return []
|
27
|
+
end
|
28
|
+
parse_authority_response(json(build_query_url(q, tc.params["subauthority"])))
|
29
|
+
end
|
30
|
+
|
31
|
+
# If the subauthority = "all" (though it shouldn't), call the fetch_discogs_results method to determine
|
32
|
+
# whether the id matches a release or master. And if the requested format is json-ld, call the build_graph
|
33
|
+
# method in the translation module; otherwise, just return the Discogs json. check the response to
|
34
|
+
# determine if it should go to the translation module.
|
35
|
+
#
|
36
|
+
# @param [String] the Discogs id of the selected item
|
37
|
+
# @param [Class] QA::TermsController
|
38
|
+
# @return either json results or jsonld
|
39
|
+
def find(id, tc)
|
40
|
+
response = tc.params["subauthority"].include?("all") ? fetch_discogs_results(id) : json(find_url(id, tc.params["subauthority"]))
|
41
|
+
return build_graph(response) unless tc.params["format"] != "jsonld" || response["message"].present?
|
42
|
+
response
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param [String] the query
|
46
|
+
# @param [String] the subauthority
|
47
|
+
# @return [String] the url
|
48
|
+
def build_query_url(q, subauthority)
|
49
|
+
escaped_q = ERB::Util.url_encode(q)
|
50
|
+
"https://api.discogs.com/database/search?q=#{escaped_q}&type=#{subauthority}&key=#{discogs_key}&secret=#{discogs_secret}"
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param [String] the id of the selected item
|
54
|
+
# @param [String] the subauthority
|
55
|
+
# @return [String] the url
|
56
|
+
def find_url(id, subauthority)
|
57
|
+
"https://api.discogs.com/#{subauthority}s/#{id}"
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# In the unusual case that we have an id and the subauthority is "all", we don't know which Discogs url to
|
63
|
+
# use. If the id is a match for both a release and a master (or neither), return that info as the
|
64
|
+
# message. Otherwise, return the data for the release or master.
|
65
|
+
# @param [String] the id of the selected item
|
66
|
+
# @return json results
|
67
|
+
def fetch_discogs_results(id)
|
68
|
+
release_resp = json(find_url(id, "release"))
|
69
|
+
master_resp = json(find_url(id, "master"))
|
70
|
+
message_status = check_for_msg_response(release_resp, master_resp)
|
71
|
+
|
72
|
+
return { "message" => "Neither a master nor a release matches the requested ID." } if message_status == "no responses"
|
73
|
+
if message_status == "two responses"
|
74
|
+
return { "message" => "Both a master and a release match the requested ID.",
|
75
|
+
"resource_url" => ["https://api.discogs.com/masters/#{id}", "https://api.discogs.com/releases/#{id}"] }
|
76
|
+
end
|
77
|
+
return master_resp unless master_resp.key?("message")
|
78
|
+
# return release_resp unless release_resp.key?("message")
|
79
|
+
release_resp
|
80
|
+
end
|
81
|
+
|
82
|
+
# @param json results
|
83
|
+
# @param json results
|
84
|
+
# @return [String] status information
|
85
|
+
def check_for_msg_response(release_resp, master_resp)
|
86
|
+
if release_resp.key?("message") && master_resp.key?("message")
|
87
|
+
"no responses"
|
88
|
+
elsif !release_resp.key?("message") && !master_resp.key?("message")
|
89
|
+
"two responses"
|
90
|
+
else
|
91
|
+
"mixed"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# @param [Hash] the http response from discogs
|
96
|
+
# @example returns parsed discogs data with context
|
97
|
+
# {
|
98
|
+
# "uri": "https://api.discogs.com/releases/4212473",
|
99
|
+
# "id": "4212473",
|
100
|
+
# "label": "Frank Sinatra And The Modernaires - Sorry / Why Remind Me",
|
101
|
+
# }
|
102
|
+
# "context": {
|
103
|
+
# "Image URL": [
|
104
|
+
# "https://img.discogs.com/2e-YoNr0dvmMgbzEN0hjHD6X0sU=/fit-in/600x580/filters:strip_icc():format(jpeg):mode_rgb():quality(90)/discogs-images/R-4212473-1358693671-5430.jpeg.jpg"
|
105
|
+
# ],
|
106
|
+
# "Year": [
|
107
|
+
# "1950"
|
108
|
+
# ],
|
109
|
+
# "Record Labels": [
|
110
|
+
# "Columbia"
|
111
|
+
# ],
|
112
|
+
# "Formats": [
|
113
|
+
# "Shellac",
|
114
|
+
# "10\"",
|
115
|
+
# "78 RPM"
|
116
|
+
# ],
|
117
|
+
# "Type": [
|
118
|
+
# "release"
|
119
|
+
# ]
|
120
|
+
# }
|
121
|
+
def parse_authority_response(response)
|
122
|
+
response['results'].map do |result|
|
123
|
+
{ 'uri' => result['resource_url'].to_s,
|
124
|
+
'id' => result['id'].to_s,
|
125
|
+
'label' => result['title'].to_s,
|
126
|
+
'context' => assemble_search_context(result) }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# @param [Hash] the results hash from the JSON returned by Discogs
|
131
|
+
def assemble_search_context(result)
|
132
|
+
{ "Image URL" => get_context_for_string(result['cover_image']),
|
133
|
+
"Year" => get_context_for_string(result['year']),
|
134
|
+
"Record Labels" => get_context_for_array(result['label']),
|
135
|
+
"Formats" => get_context_for_array(result['format']),
|
136
|
+
"Type" => get_context_for_string(result['type']) }
|
137
|
+
end
|
138
|
+
|
139
|
+
# checks if the param is null, returns appropriate value
|
140
|
+
# @param [String] returns an empty string if item is not presentr
|
141
|
+
def get_context_for_string(item)
|
142
|
+
[item.present? ? item.to_s : ""]
|
143
|
+
end
|
144
|
+
|
145
|
+
# checks if the param is null, returns appropriate value
|
146
|
+
# @param [Array] returns an empty array if item is not presentr
|
147
|
+
def get_context_for_array(item)
|
148
|
+
item.present? ? item : [""]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -28,11 +28,11 @@ module Qa::Authorities
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def search
|
31
|
-
@search ||= Qa::Authorities::LinkedData::SearchConfig.new(authority_config.fetch(:search), prefixes)
|
31
|
+
@search ||= Qa::Authorities::LinkedData::SearchConfig.new(authority_config.fetch(:search), prefixes, self)
|
32
32
|
end
|
33
33
|
|
34
34
|
def term
|
35
|
-
@term ||= Qa::Authorities::LinkedData::TermConfig.new(authority_config.fetch(:term), prefixes)
|
35
|
+
@term ||= Qa::Authorities::LinkedData::TermConfig.new(authority_config.fetch(:term), prefixes, self)
|
36
36
|
end
|
37
37
|
|
38
38
|
def prefixes
|
@@ -47,6 +47,10 @@ module Qa::Authorities
|
|
47
47
|
config_version == version
|
48
48
|
end
|
49
49
|
|
50
|
+
def authority_info
|
51
|
+
search.info + term.info
|
52
|
+
end
|
53
|
+
|
50
54
|
# Return the full configuration for an authority
|
51
55
|
# @return [String] the authority configuration
|
52
56
|
def authority_config
|
@@ -79,7 +83,7 @@ module Qa::Authorities
|
|
79
83
|
def convert_1_0_url_to_2_0_url(action_key)
|
80
84
|
url_template = @authority_config.fetch(action_key, {}).fetch(:url, {}).fetch(:template, "")
|
81
85
|
return if url_template.blank?
|
82
|
-
|
86
|
+
Qa.deprecation_warning(msg: "Linked data configuration #{authority_name} has 1.0 version format which is deprecated; update to version 2.0 configuration.")
|
83
87
|
@authority_config[action_key][:url][:template] = url_template.gsub("{?", "{")
|
84
88
|
end
|
85
89
|
end
|
@@ -4,18 +4,21 @@
|
|
4
4
|
# @see Qa::Authorities::LinkedData::TermConfig
|
5
5
|
module Qa::Authorities
|
6
6
|
module LinkedData
|
7
|
-
class SearchConfig
|
8
|
-
attr_reader :prefixes
|
7
|
+
class SearchConfig # rubocop:disable Metrics/ClassLength
|
8
|
+
attr_reader :prefixes, :full_config, :search_config
|
9
|
+
private :full_config, :search_config
|
10
|
+
|
11
|
+
delegate :authority_name, to: :full_config
|
9
12
|
|
10
13
|
# @param [Hash] config the search portion of the config
|
11
|
-
|
14
|
+
# @param [Hash<Symbol><String>] prefixes URL map of prefixes to use with ldpaths
|
15
|
+
# @param [Qa::Authorities::LinkedData::Config] full_config the full linked data configuration that the passed in search config is part of
|
16
|
+
def initialize(config, prefixes = {}, full_config = nil)
|
12
17
|
@search_config = config
|
13
18
|
@prefixes = prefixes
|
19
|
+
@full_config = full_config
|
14
20
|
end
|
15
21
|
|
16
|
-
attr_reader :search_config
|
17
|
-
private :search_config
|
18
|
-
|
19
22
|
# Does this authority configuration have search defined?
|
20
23
|
# @return [Boolean] true if search is configured; otherwise, false
|
21
24
|
def supports_search?
|
@@ -29,6 +32,7 @@ module Qa::Authorities
|
|
29
32
|
end
|
30
33
|
|
31
34
|
# Return the preferred language for literal value selection for search query.
|
35
|
+
# This is the default used for this authority if the user does not pass in a language.
|
32
36
|
# Only applies if the authority provides language encoded literals.
|
33
37
|
# @return [String] the configured language for search query
|
34
38
|
def language
|
@@ -39,40 +43,80 @@ module Qa::Authorities
|
|
39
43
|
@language = lang.collect(&:to_sym)
|
40
44
|
end
|
41
45
|
|
42
|
-
# Return results predicates if specified
|
43
|
-
# @return [Hash,NilClass] all the configured predicates to pull out of the results
|
46
|
+
# Return results ldpaths or predicates if specified
|
47
|
+
# @return [Hash,NilClass] all the configured ldpaths or predicates to pull out of the results
|
44
48
|
def results
|
45
49
|
search_config[:results]
|
46
50
|
end
|
47
51
|
|
52
|
+
# Return results id_ldpath
|
53
|
+
# @return [String] the configured ldpath to use to extract the id from the results
|
54
|
+
def results_id_ldpath
|
55
|
+
Config.config_value(results, :id_ldpath)
|
56
|
+
end
|
57
|
+
|
48
58
|
# Return results id_predicate
|
49
59
|
# @return [String] the configured predicate to use to extract the id from the results
|
50
60
|
def results_id_predicate
|
61
|
+
Qa.deprecation_warning(
|
62
|
+
in_msg: 'Qa::Authorities::LinkedData::SearchConfig',
|
63
|
+
msg: "`results_id_predicate` is deprecated; use `results_id_ldpath` by updating linked data search config results to specify as `id_ldpath`"
|
64
|
+
)
|
51
65
|
Config.predicate_uri(results, :id_predicate)
|
52
66
|
end
|
53
67
|
|
68
|
+
# Return results label_ldpath
|
69
|
+
# @return [String] the configured ldpath to use to extract label values from the results
|
70
|
+
def results_label_ldpath
|
71
|
+
Config.config_value(results, :label_ldpath)
|
72
|
+
end
|
73
|
+
|
54
74
|
# Return results label_predicate
|
55
75
|
# @return [String] the configured predicate to use to extract label values from the results
|
56
76
|
def results_label_predicate
|
77
|
+
Qa.deprecation_warning(
|
78
|
+
in_msg: 'Qa::Authorities::LinkedData::SearchConfig',
|
79
|
+
msg: "`results_label_predicate` is deprecated; use `results_label_ldpath` by updating linked data search config results to specify as `label_ldpath`"
|
80
|
+
)
|
57
81
|
Config.predicate_uri(results, :label_predicate)
|
58
82
|
end
|
59
83
|
|
84
|
+
# Return results altlabel_ldpath
|
85
|
+
# @return [String] the configured ldpath to use to extract altlabel values from the results
|
86
|
+
def results_altlabel_ldpath
|
87
|
+
Config.config_value(results, :altlabel_ldpath)
|
88
|
+
end
|
89
|
+
|
60
90
|
# Return results altlabel_predicate
|
61
91
|
# @return [String] the configured predicate to use to extract altlabel values from the results
|
62
92
|
def results_altlabel_predicate
|
93
|
+
Qa.deprecation_warning(
|
94
|
+
in_msg: 'Qa::Authorities::LinkedData::SearchConfig',
|
95
|
+
msg: "`results_altlabel_predicate` is deprecated; use `results_altlabel_ldpath` by updating linked data search config results to specify as `altlabel_ldpath`"
|
96
|
+
)
|
63
97
|
Config.predicate_uri(results, :altlabel_predicate)
|
64
98
|
end
|
65
99
|
|
66
100
|
# Does this authority configuration support sorting of search results?
|
67
101
|
# @return [True|False] true if sorting of search results is supported; otherwise, false
|
68
102
|
def supports_sort?
|
69
|
-
return true unless
|
103
|
+
return true unless results_sort_ldpath.present? || !results_sort_predicate.present?
|
70
104
|
false
|
71
105
|
end
|
72
106
|
|
107
|
+
# Return results sort_ldpath
|
108
|
+
# @return [String] the configured ldpath to use for sorting results from the query search
|
109
|
+
def results_sort_ldpath
|
110
|
+
Config.config_value(results, :sort_ldpath)
|
111
|
+
end
|
112
|
+
|
73
113
|
# Return results sort_predicate
|
74
114
|
# @return [String] the configured predicate to use for sorting results from the query search
|
75
115
|
def results_sort_predicate
|
116
|
+
Qa.deprecation_warning(
|
117
|
+
in_msg: 'Qa::Authorities::LinkedData::SearchConfig',
|
118
|
+
msg: "`results_sort_predicate` is deprecated; use `results_sort_ldpath` by updating linked data search config results to specify as `sort_ldpath`"
|
119
|
+
)
|
76
120
|
Config.predicate_uri(results, :sort_predicate)
|
77
121
|
end
|
78
122
|
|
@@ -90,10 +134,20 @@ module Qa::Authorities
|
|
90
134
|
@context_map ||= Qa::LinkedData::Config::ContextMap.new(search_config.fetch(:context), prefixes)
|
91
135
|
end
|
92
136
|
|
93
|
-
# Return parameters that are
|
137
|
+
# Return parameters that are supported directly by QA api (e.g. q, subauth, lang)
|
94
138
|
# @return [Hash] the configured search url parameter mappings
|
95
139
|
def qa_replacement_patterns
|
96
|
-
search_config.fetch(:qa_replacement_patterns)
|
140
|
+
search_config.fetch(:qa_replacement_patterns, {})
|
141
|
+
end
|
142
|
+
|
143
|
+
# @return [Boolean] true if supports language parameter; otherwise, false
|
144
|
+
def supports_subauthorities?
|
145
|
+
qa_replacement_patterns.key?(:subauth) && subauthorities?
|
146
|
+
end
|
147
|
+
|
148
|
+
# @return [Boolean] true if supports language parameter; otherwise, false
|
149
|
+
def supports_language_parameter?
|
150
|
+
qa_replacement_patterns.key? :lang
|
97
151
|
end
|
98
152
|
|
99
153
|
# Are there subauthorities configured for search query?
|
@@ -121,6 +175,40 @@ module Qa::Authorities
|
|
121
175
|
@subauthorities ||= {} if search_config.nil? || !(search_config.key? :subauthorities)
|
122
176
|
@subauthorities ||= search_config.fetch(:subauthorities)
|
123
177
|
end
|
178
|
+
|
179
|
+
def info
|
180
|
+
return [] unless supports_search?
|
181
|
+
auth_name = authority_name.downcase.to_s
|
182
|
+
language = Qa::LinkedData::LanguageService.preferred_language(authority_language: language).map(&:to_s)
|
183
|
+
details = summary_without_subauthority(auth_name, language)
|
184
|
+
subauthorities.each_key { |subauth_name| details << summary_with_subauthority(auth_name, subauth_name.downcase.to_s, language) }
|
185
|
+
details
|
186
|
+
end
|
187
|
+
|
188
|
+
private
|
189
|
+
|
190
|
+
def summary_without_subauthority(auth_name, language)
|
191
|
+
[
|
192
|
+
{
|
193
|
+
"label" => "#{auth_name} search (QA)",
|
194
|
+
"uri" => "urn:qa:search:#{auth_name}",
|
195
|
+
"authority" => auth_name,
|
196
|
+
"action" => "search",
|
197
|
+
"language" => language
|
198
|
+
}
|
199
|
+
]
|
200
|
+
end
|
201
|
+
|
202
|
+
def summary_with_subauthority(auth_name, subauth_name, language)
|
203
|
+
{
|
204
|
+
"label" => "#{auth_name} search #{subauth_name} (QA)",
|
205
|
+
"uri" => "urn:qa:search:#{auth_name}:#{subauth_name}",
|
206
|
+
"authority" => auth_name,
|
207
|
+
"subauthority" => subauth_name,
|
208
|
+
"action" => "search",
|
209
|
+
"language" => language
|
210
|
+
}
|
211
|
+
end
|
124
212
|
end
|
125
213
|
end
|
126
214
|
end
|
@@ -5,15 +5,20 @@
|
|
5
5
|
module Qa::Authorities
|
6
6
|
module LinkedData
|
7
7
|
class TermConfig
|
8
|
+
attr_reader :prefixes, :full_config, :term_config
|
9
|
+
private :full_config, :term_config
|
10
|
+
|
11
|
+
delegate :authority_name, to: :full_config
|
12
|
+
|
8
13
|
# @param [Hash] config the term portion of the config
|
9
|
-
|
14
|
+
# @param [Hash<Symbol><String>] prefixes URL map of prefixes to use with ldpaths
|
15
|
+
# @param [Qa::Authorities::LinkedData::Config] full_config the full linked data configuration that the passed in search config is part of
|
16
|
+
def initialize(config, prefixes = {}, full_config = nil)
|
10
17
|
@term_config = config
|
11
18
|
@prefixes = prefixes
|
19
|
+
@full_config = full_config
|
12
20
|
end
|
13
21
|
|
14
|
-
attr_reader :term_config
|
15
|
-
private :term_config
|
16
|
-
|
17
22
|
# Does this authority configuration have term defined?
|
18
23
|
# @return [True|False] true if term fetching is configured; otherwise, false
|
19
24
|
def supports_term?
|
@@ -41,6 +46,8 @@ module Qa::Authorities
|
|
41
46
|
end
|
42
47
|
|
43
48
|
# Return the preferred language for literal value selection for term fetch. Only applies if the authority provides language encoded literals.
|
49
|
+
# This is the default used for this authority if the user does not pass in a language.
|
50
|
+
# Only applies if the authority provides language encoded literals.
|
44
51
|
# @return [Symbol] the configured language for term fetch (default - :en)
|
45
52
|
def term_language
|
46
53
|
return @term_language unless @term_language.nil?
|
@@ -49,17 +56,33 @@ module Qa::Authorities
|
|
49
56
|
lang = [lang] if lang.is_a? String
|
50
57
|
@term_language = lang.collect(&:to_sym)
|
51
58
|
end
|
59
|
+
alias language term_language
|
52
60
|
|
53
|
-
# Return results predicates
|
54
|
-
# @return [Hash] all the configured predicates to pull out of the results
|
61
|
+
# Return results ldpaths or predicates
|
62
|
+
# @return [Hash] all the configured ldpaths or predicates to pull out of the results
|
55
63
|
def term_results
|
56
64
|
Config.config_value(term_config, :results)
|
57
65
|
end
|
58
66
|
|
67
|
+
# Return results id_ldpath
|
68
|
+
# @return [String] the configured ldpath to use to extract the id from the results
|
69
|
+
def term_results_id_ldpath
|
70
|
+
Config.config_value(term_results, :id_ldpath)
|
71
|
+
end
|
72
|
+
|
59
73
|
# Return results id_predicate
|
60
74
|
# @return [String] the configured predicate to use to extract the id from the results
|
61
75
|
def term_results_id_predicate
|
62
|
-
|
76
|
+
return @pred_id unless @pred_id.blank?
|
77
|
+
@pred_id = Config.predicate_uri(term_results, :id_predicate)
|
78
|
+
return @pred_id unless @pred_id.blank?
|
79
|
+
@pred_id = pred_id_from_ldpath
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return results label_ldpath
|
83
|
+
# @return [String] the configured ldpath to use to extract label values from the results
|
84
|
+
def term_results_label_ldpath
|
85
|
+
Config.config_value(term_results, :label_ldpath)
|
63
86
|
end
|
64
87
|
|
65
88
|
# Return results label_predicate
|
@@ -68,24 +91,48 @@ module Qa::Authorities
|
|
68
91
|
Config.predicate_uri(term_results, :label_predicate)
|
69
92
|
end
|
70
93
|
|
94
|
+
# Return results altlabel_ldpath
|
95
|
+
# @return [String] the configured ldpath to use to extract altlabel values from the results
|
96
|
+
def term_results_altlabel_ldpath
|
97
|
+
Config.config_value(term_results, :altlabel_ldpath)
|
98
|
+
end
|
99
|
+
|
71
100
|
# Return results altlabel_predicate
|
72
101
|
# @return [String] the configured predicate to use to extract altlabel values from the results
|
73
102
|
def term_results_altlabel_predicate
|
74
103
|
Config.predicate_uri(term_results, :altlabel_predicate)
|
75
104
|
end
|
76
105
|
|
106
|
+
# Return results broader_ldpath
|
107
|
+
# @return [String] the configured ldpath to use to extract URIs for broader terms from the results
|
108
|
+
def term_results_broader_ldpath
|
109
|
+
Config.config_value(term_results, :broader_ldpath)
|
110
|
+
end
|
111
|
+
|
77
112
|
# Return results broader_predicate
|
78
113
|
# @return [String] the configured predicate to use to extract URIs for broader terms from the results
|
79
114
|
def term_results_broader_predicate
|
80
115
|
Config.predicate_uri(term_results, :broader_predicate)
|
81
116
|
end
|
82
117
|
|
118
|
+
# Return results narrower_ldpath
|
119
|
+
# @return [String] the configured ldpath to use to extract URIs for narrower terms from the results
|
120
|
+
def term_results_narrower_ldpath
|
121
|
+
Config.config_value(term_results, :narrower_ldpath)
|
122
|
+
end
|
123
|
+
|
83
124
|
# Return results narrower_predicate
|
84
125
|
# @return [String] the configured predicate to use to extract URIs for narrower terms from the results
|
85
126
|
def term_results_narrower_predicate
|
86
127
|
Config.predicate_uri(term_results, :narrower_predicate)
|
87
128
|
end
|
88
129
|
|
130
|
+
# Return results sameas_ldpath
|
131
|
+
# @return [String] the configured ldpath to use to extract URIs for sameas terms from the results
|
132
|
+
def term_results_sameas_ldpath
|
133
|
+
Config.config_value(term_results, :sameas_ldpath)
|
134
|
+
end
|
135
|
+
|
89
136
|
# Return results sameas_predicate
|
90
137
|
# @return [String] the configured predicate to use to extract URIs for sameas terms from the results
|
91
138
|
def term_results_sameas_predicate
|
@@ -95,15 +142,26 @@ module Qa::Authorities
|
|
95
142
|
# Return parameters that are required for QA api
|
96
143
|
# @return [Hash] the configured term url parameter mappings
|
97
144
|
def term_qa_replacement_patterns
|
98
|
-
|
145
|
+
term_config.fetch(:qa_replacement_patterns, {})
|
99
146
|
end
|
100
147
|
alias qa_replacement_patterns term_qa_replacement_patterns
|
101
148
|
|
149
|
+
# @return [Boolean] true if supports language parameter; otherwise, false
|
150
|
+
def supports_subauthorities?
|
151
|
+
qa_replacement_patterns.key?(:subauth) && subauthorities?
|
152
|
+
end
|
153
|
+
|
154
|
+
# @return [Boolean] true if supports language parameter; otherwise, false
|
155
|
+
def supports_language_parameter?
|
156
|
+
qa_replacement_patterns.key? :lang
|
157
|
+
end
|
158
|
+
|
102
159
|
# Are there subauthorities configured for term fetch?
|
103
160
|
# @return [True|False] true if there are subauthorities configured term fetch; otherwise, false
|
104
161
|
def term_subauthorities?
|
105
162
|
term_subauthority_count.positive?
|
106
163
|
end
|
164
|
+
alias subauthorities? term_subauthorities?
|
107
165
|
|
108
166
|
# Is a specific subauthority configured for term fetch?
|
109
167
|
# @return [True|False] true if the specified subauthority is configured for term fetch; otherwise, false
|
@@ -125,6 +183,52 @@ module Qa::Authorities
|
|
125
183
|
@term_subauthorities ||= term_config[:subauthorities]
|
126
184
|
end
|
127
185
|
alias subauthorities term_subauthorities
|
186
|
+
|
187
|
+
def info
|
188
|
+
return [] unless supports_term?
|
189
|
+
auth_name = authority_name.downcase.to_s
|
190
|
+
language = Qa::LinkedData::LanguageService.preferred_language(authority_language: language).map(&:to_s)
|
191
|
+
details = summary_without_subauthority(auth_name, language)
|
192
|
+
subauthorities.keys { |subauth_name| details << summary_with_subauthority(auth_name, subauth_name.downcase.to_s, language) }
|
193
|
+
details
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
def pred_id_from_ldpath
|
199
|
+
# prefix example: { skos: 'http://www.w3.org/2004/02/skos/core#' }
|
200
|
+
# ldpath example: 'skos:id :: xsd:string'
|
201
|
+
id_ldpath = term_results_id_ldpath
|
202
|
+
return nil if id_ldpath.blank?
|
203
|
+
tokens = id_ldpath.split(':')
|
204
|
+
return nil if tokens.size < 2
|
205
|
+
prefix = tokens.first.to_sym
|
206
|
+
prefix_path = prefixes[prefix]
|
207
|
+
prefix_path + tokens.second.strip
|
208
|
+
end
|
209
|
+
|
210
|
+
def summary_without_subauthority(auth_name, language)
|
211
|
+
[
|
212
|
+
{
|
213
|
+
"label" => "#{auth_name} term (QA)",
|
214
|
+
"uri" => "urn:qa:term:#{auth_name}",
|
215
|
+
"authority" => auth_name,
|
216
|
+
"action" => "term",
|
217
|
+
"language" => language
|
218
|
+
}
|
219
|
+
]
|
220
|
+
end
|
221
|
+
|
222
|
+
def summary_with_subauthority(auth_name, subauth_name, language)
|
223
|
+
{
|
224
|
+
"label" => "#{auth_name} term #{subauth_name} (QA)",
|
225
|
+
"uri" => "urn:qa:term:#{auth_name}:#{subauth_name}",
|
226
|
+
"authority" => auth_name,
|
227
|
+
"subauthority" => subauth_name,
|
228
|
+
"action" => "term",
|
229
|
+
"language" => language
|
230
|
+
}
|
231
|
+
end
|
128
232
|
end
|
129
233
|
end
|
130
234
|
end
|