parliament-opensearch 0.4.1 → 0.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
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