qa 5.1.0 → 5.5.0

Sign up to get free protection for your applications and to get access to all the features.
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