parliament-opensearch 0.4.1 → 0.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
2
  SHA1:
3
- metadata.gz: 9cc1f42826fd6847a609290b7dcde216463f4a29
4
- data.tar.gz: 9ca3acfff1f103c9f622b018d3e7be5fc6e1b217
3
+ metadata.gz: 112097c40a5e35ada1bb98ad15fdfc7c3fadbb5c
4
+ data.tar.gz: 4926ff9614056c0541fc9bb937576abe2e9966d2
5
5
  SHA512:
6
- metadata.gz: abb4f499efbe83adaa61df55ed69178c40b0edb4f1b75980234da290ca2c8112628ede01a7f70b6b41e062af8b01c2df731c1f88433f0897a6ca5f2e9d055898
7
- data.tar.gz: a2aa4643437795e51d03f095f739ea28c55cbdd6a4ce87081540d58af4972266413655aa7fb4d8ccfc729a32cc70b2a0927206042010927d2c14a415df43eb68
6
+ metadata.gz: c3dc002e7c6c966cd48f8901db83e6a2aec9b2f7b475c9043c77f07d1fa401ee51784d2e38c5a9698e915622fb3843dc0dfb087296b678c31a1bf030117edab9
7
+ data.tar.gz: bf2700d0847e84b52c24caa645b2bb2d30fd51c7f880de7e22b261123e1ab4e34a923e08c558d9955e62c1135969c5eddcddd301515751e4eff9f7fee3e405be
@@ -4,7 +4,7 @@ module Parliament
4
4
  #
5
5
  # @since 0.1.0
6
6
  class OpenSearchResponseBuilder < Parliament::Builder::BaseResponseBuilder
7
- OPEN_SEARCH_ELEMENTS = %w(totalResults Query startIndex itemsPerPage).freeze
7
+ OPEN_SEARCH_ELEMENTS = %w[totalResults Query startIndex itemsPerPage].freeze
8
8
 
9
9
  # Builds a Feedjira::Feed response. It adds the extra OpenSearch feed elements, then parses the HTTP Response.
10
10
  def build
@@ -60,6 +60,7 @@ module Parliament
60
60
  def register_opensearch
61
61
  require 'parliament/open_search/version'
62
62
  require 'parliament/open_search/description_error'
63
+ require 'parliament/open_search/description_cache'
63
64
  end
64
65
 
65
66
  def register_opensearch_request
@@ -0,0 +1,98 @@
1
+ module Parliament
2
+ module OpenSearch
3
+ # A module used to download, cache and serve description files for our OpenSearch requests.
4
+ # @since 0.1
5
+ module DescriptionCache
6
+ DESCRIPTION_CACHE_TIME = 600 # 10 minutes
7
+
8
+ class << self
9
+ # Given a description uri, either download the file or serve it from our cache
10
+ #
11
+ # @param [String] uri the uri of our description file
12
+ # @return [String] our description file
13
+ def fetch(uri)
14
+ store
15
+
16
+ if cache_valid?(store[uri])
17
+ templates = @store[uri][:templates]
18
+ else
19
+ templates = download_description_templates(uri)
20
+
21
+ @store[uri] = { timestamp: Time.now, templates: templates }
22
+ end
23
+
24
+ templates
25
+ end
26
+
27
+ # Given a uri, remove the description from our store.
28
+ #
29
+ # @param [String] uri the uri of our description
30
+ # @return [nil|Hash] returns nil if the description was not in the store,
31
+ # or a Hash representing the deleted description's entry
32
+ def delete(uri)
33
+ store
34
+
35
+ @store.delete(uri)
36
+ end
37
+
38
+ # Returns a copy of our description store
39
+ #
40
+ # @return [Hash] returns our description store
41
+ def store
42
+ @store ||= {}
43
+ end
44
+
45
+ private
46
+
47
+ # Given a description entry from our store, tell us if the cache is still valid
48
+ #
49
+ # @param [Hash] description_entry the entry we are checking
50
+ # @return [Boolean] is the description cache valid?
51
+ def cache_valid?(description_entry)
52
+ return false if description_entry.nil?
53
+
54
+ (Time.now <= (description_entry[:timestamp] + DESCRIPTION_CACHE_TIME))
55
+ end
56
+
57
+ # Given a description uri, download it and return the certificate data
58
+ #
59
+ # @param [String] uri the uri of our certificates
60
+ # @return [String] certificate data
61
+ def download_description_templates(uri)
62
+ return if uri.nil?
63
+
64
+ begin
65
+ url = URI.parse(uri)
66
+ rescue URI::InvalidURIError => e
67
+ raise Parliament::OpenSearch::DescriptionError.new(uri), "Invalid description URI passed '#{uri}': #{e.message}"
68
+ end
69
+
70
+ headers = {
71
+ 'Accept' => 'application/opensearchdescription+xml',
72
+ 'Ocp-Apim-Subscription-Key' => ENV['OPENSEARCH_AUTH_TOKEN']
73
+ }
74
+ headers['Request-Id'] = "#{ENV['ApplicationInsights.request.id']}description-#{store.keys.length + 1}" if ENV['ApplicationInsights.request.id']
75
+ request = Parliament::Request::BaseRequest.new(base_url: uri,
76
+ headers: headers)
77
+ xml_response = request.get
78
+
79
+ begin
80
+ xml_root = REXML::Document.new(xml_response.response.body).root
81
+ templates = []
82
+ xml_root.elements.each('Url') do |url|
83
+ type = url.attributes['type']
84
+ template = url.attributes['template']
85
+ templates << { type: type, template: template }
86
+ end
87
+
88
+ raise Parliament::OpenSearch::DescriptionError.new(url), "The document found does not contain the required node. Attempted to get a 'Url' element with the attribute 'template'. Please check the description document at '#{url}' and try again." if templates.empty?
89
+ rescue NoMethodError
90
+ raise Parliament::OpenSearch::DescriptionError.new(url), "The document found does not appear to be XML. Please check the description document at '#{url}' and try again."
91
+ end
92
+
93
+ templates
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -1,5 +1,5 @@
1
1
  module Parliament
2
2
  module OpenSearch
3
- VERSION = '0.4.1'.freeze
3
+ VERSION = '0.5.0'.freeze
4
4
  end
5
5
  end
@@ -5,7 +5,7 @@ module Parliament
5
5
  # @since 0.1.0
6
6
  # attr [Hash] templates the different types and template urls set from the OpenSearch API description document.
7
7
  class OpenSearchRequest < Parliament::Request::BaseRequest
8
- attr_reader :templates
8
+ attr_reader :templates, :description_url
9
9
 
10
10
  OPEN_SEARCH_PARAMETERS = {
11
11
  count: 10,
@@ -27,11 +27,11 @@ module Parliament
27
27
  # @param [Hash] headers the headers being sent in the request.
28
28
  # @param [Parliament::OpenSearch::Builder] builder the builder required to create the response.
29
29
  def initialize(description_url: nil, headers: nil, builder: nil)
30
- @description_url = description_url
30
+ @description_url = description_url ||= self.class.description_url
31
31
 
32
32
  raise Parliament::OpenSearch::DescriptionError.new(@description_url), 'No description URL passed to Parliament::OpenSearchRequest#new and, no Parliament::OpenSearchRequest#base_url value set. Without a description URL, we are unable to make any search requests.' if @description_url.nil? && self.class.templates.nil?
33
33
 
34
- @templates = Parliament::Request::OpenSearchRequest.get_description(@description_url) || self.class.templates
34
+ @templates = Parliament::OpenSearch::DescriptionCache.fetch(@description_url)
35
35
  @open_search_parameters = self.class.open_search_parameters
36
36
 
37
37
  super(base_url: nil, headers: headers, builder: builder)
@@ -49,8 +49,6 @@ module Parliament
49
49
  super(params: params)
50
50
  end
51
51
 
52
- private
53
-
54
52
  # @attr [String] templates the different types and template urls set from the OpenSearch API description document.
55
53
  # @attr [Hash] open_search_parameters the possible parameters to use in the query url.
56
54
  class << self
@@ -58,56 +56,23 @@ module Parliament
58
56
 
59
57
  def description_url=(description_url)
60
58
  @description_url = description_url
61
- @templates = Parliament::Request::OpenSearchRequest.get_description(@description_url)
59
+ @templates = Parliament::OpenSearch::DescriptionCache.fetch(@description_url)
62
60
  end
63
61
 
64
62
  def open_search_parameters
65
63
  OPEN_SEARCH_PARAMETERS.dup
66
64
  end
67
-
68
- def get_description(url)
69
- return if url.nil?
70
-
71
- begin
72
- URI.parse(url)
73
- rescue URI::InvalidURIError => e
74
- raise Parliament::OpenSearch::DescriptionError.new(url), "Invalid description URI passed '#{url}': #{e.message}"
75
- end
76
-
77
- request = Parliament::Request::BaseRequest.new(base_url: url,
78
- headers: {
79
- 'Accept' => 'application/opensearchdescription+xml',
80
- 'Ocp-Apim-Subscription-Key' => ENV['OPENSEARCH_AUTH_TOKEN']
81
- })
82
- xml_response = request.get
83
-
84
- begin
85
- xml_root = REXML::Document.new(xml_response.response.body).root
86
- templates = { url: [] }
87
- xml_root.elements.each('Url') do |url|
88
- type = url.attributes['type']
89
- template = url.attributes['template']
90
- templates[:url] << { type: type, template: template }
91
- end
92
-
93
- raise Parliament::OpenSearch::DescriptionError.new(url), "The document found does not contain the required node. Attempted to get a 'Url' element with the attribute 'template'. Please check the description document at '#{url}' and try again." if templates[:url].empty?
94
- rescue NoMethodError
95
- raise Parliament::OpenSearch::DescriptionError.new(url), "The document found does not appear to be XML. Please check the description document at '#{url}' and try again."
96
- end
97
-
98
- templates
99
- end
100
65
  end
101
66
 
102
- def query_url
103
- @query_url
104
- end
67
+ private
68
+
69
+ attr_reader :query_url
105
70
 
106
71
  def setup_query_url(search_params, type = nil)
107
72
  search_terms = search_params[:query]
108
73
  type ||= 'application/atom+xml'
109
74
 
110
- url_hash = @templates[:url].select { |url| url[:type] == type }.first
75
+ url_hash = @templates.select { |url| url[:type] == type }.first
111
76
 
112
77
  raise Parliament::OpenSearch::DescriptionError.new(type), "There is no url for the requested type '#{type}'." if url_hash.nil?
113
78
 
@@ -31,4 +31,5 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency 'vcr', '~> 3.0'
32
32
  spec.add_development_dependency 'webmock', '~> 2.3'
33
33
  spec.add_development_dependency 'parliament-ruby', '~> 0.7.4'
34
+ spec.add_development_dependency 'timecop'
34
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parliament-opensearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rebecca Appleyard
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-12-14 00:00:00.000000000 Z
12
+ date: 2018-05-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: feedjira
@@ -157,6 +157,20 @@ dependencies:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
159
  version: 0.7.4
160
+ - !ruby/object:Gem::Dependency
161
+ name: timecop
162
+ requirement: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ type: :development
168
+ prerelease: false
169
+ version_requirements: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
160
174
  description: 'Parliamentary OpenSearch response builder '
161
175
  email:
162
176
  - rklappleyard@gmail.com
@@ -180,6 +194,7 @@ files:
180
194
  - gocd/web1live.yaml
181
195
  - lib/parliament/builder/open_search_response_builder.rb
182
196
  - lib/parliament/open_search.rb
197
+ - lib/parliament/open_search/description_cache.rb
183
198
  - lib/parliament/open_search/description_error.rb
184
199
  - lib/parliament/open_search/version.rb
185
200
  - lib/parliament/request/open_search_request.rb