qa 5.1.0 → 5.5.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8158fccc9df38a91d74c1dbda277ce9308cf08c3
4
- data.tar.gz: 28be737c24fc1cdd77fed1fc5da6216c68b675fd
2
+ SHA256:
3
+ metadata.gz: 73811a2b2371ead4042bab0a11e4b4b0f496e94eb6e92a2f6ddb550ac90f9d41
4
+ data.tar.gz: a8888e0db1aa46b562eaab6d45be5fd0de8df52ac9753189416a3ca0fc0d44a3
5
5
  SHA512:
6
- metadata.gz: d8e1fdedaa020bf6ffcac6bf1248729439d758be0966bb397aeaf05c54c681fd0f4f5e5c061e9b5ece5f8b8c9dc0494c6d1c9091c2f691e185256cb1cc42ec18
7
- data.tar.gz: 49e4402ab1422fee3e78cc7fdf485175144642b26fc6697a64873877fbbdc6095ad011881e8c42a35c9fb21c5704a056443f0ce6bc7e26c14494c958007d6434
6
+ metadata.gz: e4aaecb73516d38ddca2ed4dc61571aa1c70fc4fdedee75d4aa1a7763193147303b97124d4e858471508f09ba6adb6158fb63111c5f2ca817d4cf4ec7164690f
7
+ data.tar.gz: 9446f03eeaad6aa21890f97d4def246a6915f932f83b764a1bea2b6c9a818c8eb43c45f5d3b8b8235cd57d1efc59c4c08caab93fe1ed1ab5bea65d5a690f23cf
data/README.md CHANGED
@@ -1,77 +1,83 @@
1
1
  # Questioning Authority
2
2
 
3
- Code:
4
- [![Gem Version](https://badge.fury.io/rb/qa.png)](http://badge.fury.io/rb/qa)
5
- [![Build Status](https://circleci.com/gh/samvera/questioning_authority.svg?style=svg)](https://circleci.com/gh/samvera/questioning_authority)
6
- [![Coverage Status](https://coveralls.io/repos/github/samvera/questioning_authority/badge.svg?branch=master)](https://coveralls.io/github/samvera/questioning_authority?branch=master)
3
+ Code: [![Gem Version](https://badge.fury.io/rb/qa.png)](http://badge.fury.io/rb/qa) [![Build Status](https://circleci.com/gh/samvera/questioning_authority.svg?style=svg)](https://circleci.com/gh/samvera/questioning_authority) [![Coverage Status](https://coveralls.io/repos/github/samvera/questioning_authority/badge.svg?branch=master)](https://coveralls.io/github/samvera/questioning_authority?branch=master)
7
4
 
8
- Docs:
9
- [![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md)
10
- [![Apache 2.0 License](http://img.shields.io/badge/APACHE2-license-blue.svg)](./LICENSE)
5
+ Docs: [![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md) [![Apache 2.0 License](http://img.shields.io/badge/APACHE2-license-blue.svg)](./LICENSE)
11
6
 
12
7
  Jump In: [![Slack Status](http://slack.samvera.org/badge.svg)](http://slack.samvera.org/)
13
8
 
14
9
  You should question your authorities.
15
10
 
16
- ----
11
+ --------------------------------------------------------------------------------
12
+
17
13
  ## Table of Contents
18
14
 
19
- * [What does this do?](#what-does-this-do)
20
- * [How does it work?](#how-does-it-work)
21
- * [Sub-Authorities](#sub-authorities)
22
- * [How do I use this?](#how-do-i-use-this)
23
- * [Basic QA Requests](#basic-qa-requests)
24
- * [Typical JSON Results](#typical-json-results)
25
- * [Authority Sources information](#authority-sources-information)
26
- * [Developer Notes](#developer-notes)
27
- * [Compatibility](#compatibility)
28
- * [Product Owner & Maintenance](#product-owner--maintenance)
29
- * [Product Owner](#product-owner)
30
- * [Help](#help)
31
- * [Acknowledgments](#acknowledgments)
32
-
33
- ## Not seeing documentation you used to find in the README?
34
-
35
- Much of the documentation has moved to the [Questioning Authority wiki](https://github.com/samvera/questioning_authority/wiki) to allow for better organization. We hope that you will find this easier to use.
36
-
37
- ----
15
+ - [What does this do?](#what-does-this-do)
16
+ - [How does it work?](#how-does-it-work)
17
+
18
+ - [Sub-Authorities](#sub-authorities)
19
+
20
+ - [How do I use this?](#how-do-i-use-this)
21
+
22
+ - [Basic QA Requests](#basic-qa-requests)
23
+ - [Typical JSON Results](#typical-json-results)
24
+
25
+ - [Authority Sources information](#authority-sources-information)
26
+
27
+ - [Developer Notes](#developer-notes)
28
+
29
+ - [Compatibility](#compatibility)
30
+ - [Product Owner & Maintenance](#product-owner--maintenance)
31
+
32
+ - [Product Owner](#product-owner)
33
+
34
+ - [Help](#help)
35
+
36
+ - [Acknowledgments](#acknowledgments)
37
+
38
+ ## Not seeing documentation you used to find in the README?
39
+
40
+ Much of the documentation has moved to the [Questioning Authority wiki](https://github.com/samvera/questioning_authority/wiki) to allow for better organization. We hope that you will find this easier to use.
41
+
42
+ --------------------------------------------------------------------------------
43
+
38
44
  ## What does this do?
39
45
 
40
- Provides a set of uniform RESTful routes to query any controlled vocabulary or set of authority terms.
41
- Results are returned in JSON and can be used within the context of a Rails application or any other
42
- Ruby environment. Primary examples would include providing auto-complete functionality via Javascript
43
- or populating a dropdown menu with a set of terms.
46
+ Provides a set of uniform RESTful routes to query any controlled vocabulary or set of authority terms. Results are returned in JSON and can be used within the context of a Rails application or any other Ruby environment. Primary examples would include providing auto-complete functionality via Javascript or populating a dropdown menu with a set of terms.
44
47
 
45
48
  ## How does it work?
46
49
 
47
- Authorities are defined as classes, each implementing a set of methods allowing a controller to return
48
- results from a given vocabulary in the JSON format. The controller does three things:
50
+ Authorities are defined as classes, each implementing a set of methods allowing a controller to return results from a given vocabulary in the JSON format. The controller does three things:
49
51
 
50
- * provide a list of all terms (if allowed by the class)
51
- * return a set of terms matching a given query
52
- * return the complete information for a specific term given its identifier
52
+ - provide a list of all terms (if allowed by the class)
53
+ - return a set of terms matching a given query
54
+ - return the complete information for a specific term given its identifier
53
55
 
54
- Depending on the kind of authority or its API, the controller may not do all of these things such
55
- as return a complete list of terms.
56
+ Depending on the kind of authority or its API, the controller may not do all of these things such as return a complete list of terms.
56
57
 
57
58
  ### Sub-Authorities
58
59
 
59
- Some authorities, such as Library of Congress, allow sub-authorities which is an additional parameter that
60
- further defines the kind of authority to use with the context of a larger one.
60
+ Some authorities, such as Library of Congress, allow sub-authorities which is an additional parameter that further defines the kind of authority to use with the context of a larger one.
61
61
 
62
62
  ## How do I use this?
63
63
 
64
64
  Add the gem to your Gemfile
65
65
 
66
- gem 'qa'
66
+ ```
67
+ gem 'qa'
68
+ ```
67
69
 
68
70
  Run bundler
69
71
 
70
- bundle install
72
+ ```
73
+ bundle install
74
+ ```
71
75
 
72
76
  Install the gem to your application
73
77
 
74
- rails generate qa:install
78
+ ```
79
+ rails generate qa:install
80
+ ```
75
81
 
76
82
  This will copy over some additional config files and add the engine's routes to your `config/route.rb`.
77
83
 
@@ -79,84 +85,104 @@ Start questioning your authorities!
79
85
 
80
86
  ### Basic QA Requests
81
87
 
82
- These show the basic routing patterns for connecting to authorities. See the [Questioning Authority wiki](https://github.com/samvera/questioning_authority/wiki) documentation for detailed documentation and examples for each authority and local authorities.
88
+ These show the basic routing patterns for connecting to authorities. See the [Questioning Authority wiki](https://github.com/samvera/questioning_authority/wiki) documentation for detailed documentation and examples for each authority and local authorities.
83
89
 
84
90
  Return a complete list of terms:
85
91
 
86
- /qa/terms/:vocab
87
- /qa/terms/:vocab/:subauthority
92
+ ```
93
+ /qa/terms/:vocab
94
+ /qa/terms/:vocab/:subauthority
95
+ ```
88
96
 
89
97
  Return a set of terms matching a given query
90
98
 
91
- /qa/search/:vocab?q=search_term
92
- /qa/search/:vocab/:subauthority?q=search_term
99
+ ```
100
+ /qa/search/:vocab?q=search_term
101
+ /qa/search/:vocab/:subauthority?q=search_term
102
+ ```
93
103
 
94
104
  Return the complete information for a specific term given its identifier
95
105
 
96
- /qa/show/:vocab/:id
97
- /qa/show/:vocab/:subauthority/:id
98
-
99
-
106
+ ```
107
+ /qa/show/:vocab/:id
108
+ /qa/show/:vocab/:subauthority/:id
109
+ ```
100
110
 
101
111
  ### Typical JSON Results
102
112
 
103
113
  Results are returned in JSON in this format:
104
114
 
105
- [
106
- {"id" : "subject_id_1", "label" : "First labels"},
107
- {"id" : "subject_id_2", "label" : "Printing labels"},
108
- {"id" : "", "label" : "This term has no id number"},
109
- {"id" : "", "label" : "Neither does this"}
110
- ]
111
-
115
+ ```
116
+ [
117
+ {"id" : "subject_id_1", "label" : "First labels"},
118
+ {"id" : "subject_id_2", "label" : "Printing labels"},
119
+ {"id" : "", "label" : "This term has no id number"},
120
+ {"id" : "", "label" : "Neither does this"}
121
+ ]
122
+ ```
112
123
 
113
124
  # Authority Sources information
114
125
 
115
126
  See the [Questioning Authority wiki](https://github.com/samvera/questioning_authority/wiki) for documentation on how to connect to the supported authorities, documentation on how to create new authorities, and other useful tips.
116
127
 
117
-
118
128
  # Developer Notes
119
129
 
120
130
  [How to Contribute](./CONTRIBUTING.md)
121
131
 
122
132
  To develop this gem, clone the repository, then run:
123
133
 
124
- bundle install
125
- rake ci
134
+ ```
135
+ bundle install
136
+ rake ci
137
+ ```
126
138
 
127
- This will install the gems, create a dummy application under spec/internal and run the tests. After you've made changes,
128
- make sure you've included tests and run the test suite with a new sample application:
139
+ This will install the gems, create a dummy application under spec/internal and run the tests. After you've made changes, make sure you've included tests and run the test suite with a new sample application:
129
140
 
130
- rake engine_cart:clean
131
- rake ci
141
+ ```
142
+ rake engine_cart:clean
143
+ rake ci
144
+ ```
132
145
 
133
146
  Commit your features into a new branch and submit a pull request.
134
147
 
135
148
  ## Compatibility
136
149
 
137
- * Ruby 2.5 or the latest 2.4 version is recommended. Later versions may also work.
138
- * Rails 5 is required. We recommend the latest Rails 5.2 release.
150
+ - Ruby 2.5 or the latest 2.4 version is recommended. Later versions may also work.
151
+ - Rails 5 is required. We recommend the latest Rails 5.2 release.
139
152
 
140
153
  ## Product Owner & Maintenance
141
154
 
142
- Questioning Authority is a Core Component of the Samvera community. The documentation for
143
- what this means can be found [here](http://samvera.github.io/core_components.html#requirements-for-a-core-component).
155
+ Questioning Authority is a Core Component of the Samvera community. The documentation for what this means can be found [here](http://samvera.github.io/core_components.html#requirements-for-a-core-component).
144
156
 
145
157
  ### Product Owner
146
158
 
147
159
  [elrayle](https://github.com/elrayle)
148
160
 
161
+ ## Releasing
162
+
163
+ 1. `bundle install`
164
+ 2. Increase the version number in `lib/qa/version.rb`
165
+ 3. Increase the same version number in `.github_changelog_generator`
166
+ 4. Update `CHANGELOG.md` by running this command:
167
+
168
+ ```
169
+ github_changelog_generator --user samvera --project questioning_authority --token YOUR_GITHUB_TOKEN_HERE
170
+ ```
171
+
172
+ 5. Commit these changes to the master branch
173
+
174
+ 6. Run `rake release`
175
+
149
176
  # Help
150
177
 
151
178
  The Samvera community is here to help. Please see our [support guide](./SUPPORT.md).
152
179
 
153
180
  # Acknowledgments
154
181
 
155
- This software has been developed by and is brought to you by the Samvera community. Learn more at the
156
- [Samvera website](http://samvera.org/).
182
+ This software has been developed by and is brought to you by the Samvera community. Learn more at the [Samvera website](http://samvera.org/).
157
183
 
158
184
  ![Samvera Logo](https://wiki.duraspace.org/download/thumbnails/87459292/samvera-fall-font2-200w.png?version=1&modificationDate=1498550535816&api=v2)
159
185
 
160
- ### Special thanks to...
186
+ ## Special thanks to...
161
187
 
162
188
  [Jeremy Friesen](https://github.com/jeremyf) who gave us the name for our gem.
@@ -91,6 +91,7 @@ module Qa
91
91
  end
92
92
 
93
93
  def process_error(e, url)
94
+ Rails.logger.warn("******** RDF::Graph#load failure: exception=#{e.inspect}, url=#{url}")
94
95
  uri = URI(url)
95
96
  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
96
97
  response_code = ioerror_code(e)
@@ -1,8 +1,9 @@
1
1
  # Service to construct a request header that includes optional attributes for search and fetch requests.
2
+ require 'geocoder'
2
3
  module Qa
3
4
  module LinkedData
4
5
  class RequestHeaderService
5
- attr_reader :request, :params
6
+ attr_reader :request, :params, :request_id
6
7
 
7
8
  # @param request [HttpRequest] request from controller
8
9
  # @param params [Hash] attribute-value pairs holding the request parameters
@@ -16,6 +17,8 @@ module Qa
16
17
  def initialize(request:, params:)
17
18
  @request = request
18
19
  @params = params
20
+ @request_id = request.request_id
21
+ log_request
19
22
  end
20
23
 
21
24
  # Construct request parameters to pass to search_query (linked data module).
@@ -23,6 +26,8 @@ module Qa
23
26
  # @see Qa::Authorities::LinkedData::SearchQuery
24
27
  def search_header
25
28
  header = {}
29
+ header[:request] = request
30
+ header[:request_id] = request_id
26
31
  header[:subauthority] = params.fetch(:subauthority, nil)
27
32
  header[:user_language] = user_language
28
33
  header[:performance_data] = performance_data?
@@ -37,6 +42,8 @@ module Qa
37
42
  # @see Qa::Authorities::LinkedData::FindTerm
38
43
  def fetch_header
39
44
  header = {}
45
+ header[:request] = request
46
+ header[:request_id] = request_id
40
47
  header[:subauthority] = params.fetch(:subauthority, nil)
41
48
  header[:user_language] = user_language
42
49
  header[:performance_data] = performance_data?
@@ -62,6 +69,18 @@ module Qa
62
69
 
63
70
  private
64
71
 
72
+ def log_request
73
+ msg = "******** #{request.path_parameters[:action].upcase}"
74
+ unless Qa.config.suppress_ip_data_from_log
75
+ gc = request.respond_to?(:location) ? request.location : nil
76
+ city = gc.nil? ? "UNKNOWN" : gc.city
77
+ state = gc.nil? ? "UNKNOWN" : gc.state
78
+ country = gc.nil? ? "UNKNOWN" : gc.country
79
+ msg += " from IP #{request.ip} in {city: #{city}, state: #{state}, country: #{country}}"
80
+ end
81
+ Rails.logger.info(msg)
82
+ end
83
+
65
84
  # filter literals in results to this language
66
85
  def user_language
67
86
  request_language = request.env['HTTP_ACCEPT_LANGUAGE']
@@ -23,4 +23,9 @@ Qa.config do |config|
23
23
  # When false, properties that do not override default optional behavior will be shown whether or not the property has a value in the graph.
24
24
  # When true, properties that do not override default optional behavior will not be shown whn the property does not have a value in the graph.
25
25
  # config.property_map_default_for_optional = false
26
+
27
+ # IP data including IP address, city, state, and country will be logged with each request.
28
+ # When false, IP data is logged
29
+ # When true, IP data will not be logged (default for backward compatibility)
30
+ # config.suppress_ip_data_from_log = true
26
31
  end
@@ -55,6 +55,28 @@ module Qa::Authorities
55
55
  "http://id.loc.gov/ontologies/bibframe/Role"
56
56
  end
57
57
 
58
+ def format(tc)
59
+ return 'json' unless tc.params.key?('format')
60
+ return 'json' if tc.params['format'].blank?
61
+ tc.params['format']
62
+ end
63
+
64
+ def jsonld?(tc)
65
+ format(tc).casecmp?('jsonld')
66
+ end
67
+
68
+ def n3?(tc)
69
+ format(tc).casecmp?('n3')
70
+ end
71
+
72
+ def ntriples?(tc)
73
+ format(tc).casecmp?('ntriples')
74
+ end
75
+
76
+ def graph_format?(tc)
77
+ jsonld?(tc) || n3?(tc) || ntriples?(tc)
78
+ end
79
+
58
80
  def discogs_genres
59
81
  DISCOGS_GENRE_MAPPING
60
82
  end
@@ -63,6 +85,19 @@ module Qa::Authorities
63
85
  DISCOGS_FORMATS_MAPPING
64
86
  end
65
87
 
88
+ # @param json results
89
+ # @param json results
90
+ # @return [String] status information
91
+ def check_for_msg_response(release_resp, master_resp)
92
+ if release_resp.key?("message") && master_resp.key?("message")
93
+ "no responses"
94
+ elsif !release_resp.key?("message") && !master_resp.key?("message")
95
+ "two responses"
96
+ else
97
+ "mixed"
98
+ end
99
+ end
100
+
66
101
  # both the work and the instance require a statement for the release year
67
102
  # @param [Hash] the http response from discogs
68
103
  # @return [Array] rdf statements
@@ -4,6 +4,7 @@ module Qa::Authorities
4
4
  class Discogs::GenericAuthority < Base
5
5
  include WebServiceBase
6
6
  include Discogs::DiscogsTranslation
7
+ include Discogs::DiscogsUtils
7
8
 
8
9
  class_attribute :discogs_secret, :discogs_key
9
10
  attr_accessor :primary_artists, :selected_format, :work_uri, :instance_uri
@@ -28,7 +29,14 @@ module Qa::Authorities
28
29
  Rails.logger.error "Questioning Authority tried to call Discogs, but no secret and/or key were set."
29
30
  return []
30
31
  end
31
- parse_authority_response(json(build_query_url(q, tc.params["subauthority"])))
32
+ response = json(build_query_url(q, tc))
33
+ if tc.params["response_header"] == "true"
34
+ response_hash = {}
35
+ response_hash["results"] = parse_authority_response(response)
36
+ response_hash["response_header"] = build_response_header(response)
37
+ return response_hash
38
+ end
39
+ parse_authority_response(response)
32
40
  end
33
41
 
34
42
  # If the subauthority = "all" (though it shouldn't), call the fetch_discogs_results method to determine
@@ -52,9 +60,18 @@ module Qa::Authorities
52
60
  # @param [String] the query
53
61
  # @param [String] the subauthority
54
62
  # @return [String] the url
55
- def build_query_url(q, subauthority)
63
+ def build_query_url(q, tc)
64
+ page = nil
65
+ per_page = nil
66
+ if tc.params["startRecord"].present?
67
+ page = (tc.params["startRecord"].to_i - 1) / tc.params["maxRecords"].to_i + 1
68
+ per_page = tc.params["maxRecords"]
69
+ else
70
+ page = tc.params["page"]
71
+ per_page = tc.params["per_page"]
72
+ end
56
73
  escaped_q = ERB::Util.url_encode(q)
57
- "https://api.discogs.com/database/search?q=#{escaped_q}&type=#{subauthority}&key=#{discogs_key}&secret=#{discogs_secret}"
74
+ "https://api.discogs.com/database/search?q=#{escaped_q}&type=#{tc.params['subauthority']}&page=#{page}&per_page=#{per_page}&key=#{discogs_key}&secret=#{discogs_secret}"
58
75
  end
59
76
 
60
77
  # @param [String] the id of the selected item
@@ -86,19 +103,6 @@ module Qa::Authorities
86
103
  release_resp
87
104
  end
88
105
 
89
- # @param json results
90
- # @param json results
91
- # @return [String] status information
92
- def check_for_msg_response(release_resp, master_resp)
93
- if release_resp.key?("message") && master_resp.key?("message")
94
- "no responses"
95
- elsif !release_resp.key?("message") && !master_resp.key?("message")
96
- "two responses"
97
- else
98
- "mixed"
99
- end
100
- end
101
-
102
106
  # @param [Hash] the http response from discogs
103
107
  # @example returns parsed discogs data with context
104
108
  # [{
@@ -131,6 +135,19 @@ module Qa::Authorities
131
135
  end
132
136
  end
133
137
 
138
+ # @param [Hash] the http response from discogs
139
+ # @param [Class] QA::TermsController
140
+ # @example returns parsed discogs pagination data
141
+ def build_response_header(response)
142
+ start_record = (response['pagination']['page'] - 1) * response['pagination']['per_page'] + 1
143
+ rh_hash = {}
144
+ rh_hash['start_record'] = start_record
145
+ rh_hash['requested_records'] = response['pagination']['per_page']
146
+ rh_hash['retrieved_records'] = response['results'].length
147
+ rh_hash['total_records'] = response['pagination']['items']
148
+ rh_hash
149
+ end
150
+
134
151
  # @param [Hash] the results hash from the JSON returned by Discogs
135
152
  def build_uri(result)
136
153
  result['uri'].present? ? "https://www.discogs.com" + result['uri'].to_s : result['resource_url'].to_s
@@ -156,27 +173,5 @@ module Qa::Authorities
156
173
  def get_context_for_array(item)
157
174
  item.present? ? item : [""]
158
175
  end
159
-
160
- def format(tc)
161
- return 'json' unless tc.params.key?('format')
162
- return 'json' if tc.params['format'].blank?
163
- tc.params['format']
164
- end
165
-
166
- def jsonld?(tc)
167
- format(tc).casecmp?('jsonld')
168
- end
169
-
170
- def n3?(tc)
171
- format(tc).casecmp?('n3')
172
- end
173
-
174
- def ntriples?(tc)
175
- format(tc).casecmp?('ntriples')
176
- end
177
-
178
- def graph_format?(tc)
179
- jsonld?(tc) || n3?(tc) || ntriples?(tc)
180
- end
181
176
  end
182
177
  end