endeca_on_demand 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/endeca_on_demand.gemspec +4 -0
- data/lib/endeca_on_demand/client.rb +24 -0
- data/lib/endeca_on_demand/collection.rb +41 -0
- data/lib/endeca_on_demand/pp.rb +48 -0
- data/lib/endeca_on_demand/proxy.rb +58 -8
- data/lib/endeca_on_demand/query.rb +187 -0
- data/lib/endeca_on_demand/response/applied_filters/keyword_redirect.rb +42 -0
- data/lib/endeca_on_demand/response/applied_filters/search_report/search.rb +42 -0
- data/lib/endeca_on_demand/response/applied_filters/search_report.rb +50 -0
- data/lib/endeca_on_demand/response/applied_filters/selected_dimension_value_id.rb +32 -0
- data/lib/endeca_on_demand/response/applied_filters.rb +39 -0
- data/lib/endeca_on_demand/response/breadcrumb/bread.rb +42 -0
- data/lib/endeca_on_demand/response/breadcrumb.rb +35 -0
- data/lib/endeca_on_demand/response/business_rules_result/business_rule.rb +54 -0
- data/lib/endeca_on_demand/response/business_rules_result.rb +31 -0
- data/lib/endeca_on_demand/response/dimension/dimension_value.rb +50 -0
- data/lib/endeca_on_demand/response/dimension.rb +50 -0
- data/lib/endeca_on_demand/response/property.rb +36 -0
- data/lib/endeca_on_demand/response/records_set/record.rb +53 -0
- data/lib/endeca_on_demand/response/records_set.rb +50 -0
- data/lib/endeca_on_demand/response.rb +62 -0
- data/lib/endeca_on_demand/version.rb +1 -1
- data/lib/endeca_on_demand.rb +251 -243
- metadata +69 -17
- data/lib/endeca_on_demand/bread_crumb.rb +0 -12
- data/lib/endeca_on_demand/business_rules_result/property.rb +0 -14
- data/lib/endeca_on_demand/business_rules_result.rb +0 -33
- data/lib/endeca_on_demand/dimension/dimension_value.rb +0 -14
- data/lib/endeca_on_demand/dimension.rb +0 -24
- data/lib/endeca_on_demand/keyword_redirect.rb +0 -12
- data/lib/endeca_on_demand/record_set/record.rb +0 -14
- data/lib/endeca_on_demand/record_set.rb +0 -24
- data/lib/endeca_on_demand/search_report/search.rb +0 -14
- data/lib/endeca_on_demand/search_report.rb +0 -21
- data/lib/endeca_on_demand/selected_dimension_value_id.rb +0 -12
data/lib/endeca_on_demand.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
+
require 'active_support/core_ext/hash'
|
2
|
+
|
3
|
+
require 'endeca_on_demand/pp'
|
1
4
|
require 'endeca_on_demand/proxy'
|
5
|
+
require 'endeca_on_demand/query'
|
6
|
+
require 'endeca_on_demand/response'
|
2
7
|
|
3
8
|
Dir["#{File.dirname(__FILE__)}/endeca_on_demand/**/*"].each {|file| require(file)}
|
4
9
|
|
@@ -6,293 +11,296 @@ require 'builder'
|
|
6
11
|
require 'nokogiri'
|
7
12
|
require 'net/http'
|
8
13
|
require 'uri'
|
14
|
+
require 'open-uri'
|
9
15
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
module EndecaOnDemand
|
17
|
+
|
18
|
+
##
|
19
|
+
|
20
|
+
# def initialize(host, options)
|
21
|
+
# unless host.blank?
|
22
|
+
# @body = Builder::XmlMarkup.new(:indent => 2)
|
15
23
|
|
16
|
-
|
17
|
-
|
24
|
+
# #
|
25
|
+
# set_host(host)
|
18
26
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
27
|
+
# #
|
28
|
+
# options.each do |key, value|
|
29
|
+
# self.send(key.to_sym, value) unless value.blank?
|
30
|
+
# end
|
23
31
|
|
24
|
-
|
25
|
-
|
32
|
+
# #
|
33
|
+
# send_request
|
26
34
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
+
# self.instance_variables.each do |instance_variable|
|
36
|
+
# # puts "VARS: #{instance_variable}"
|
37
|
+
# # self.class_eval("attr_reader :#{instance_variable}")
|
38
|
+
# end
|
39
|
+
# else
|
40
|
+
# puts "Unable to continue... Make sure \"#{host}\" is a valid thanxmedia host."
|
41
|
+
# end
|
42
|
+
# end
|
35
43
|
|
36
|
-
### API
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
44
|
+
# ### API
|
45
|
+
# attr_reader :records
|
46
|
+
# attr_reader :breadcrumbs, :filtercrumbs
|
47
|
+
# attr_reader :dimensions
|
48
|
+
# attr_reader :rules
|
49
|
+
# attr_reader :search_reports, :keyword_redirect
|
50
|
+
# attr_reader :selected_dimension_value_ids
|
43
51
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
### /API
|
52
|
+
# ## DEBUG
|
53
|
+
# attr_reader :uri, :http
|
54
|
+
# attr_reader :base, :query, :request, :response, :error
|
55
|
+
# ## /DEBUG
|
56
|
+
# ### /API
|
49
57
|
|
50
|
-
def success?
|
51
|
-
|
52
|
-
end
|
58
|
+
# def success?
|
59
|
+
# @error.blank?
|
60
|
+
# end
|
53
61
|
|
54
|
-
private
|
62
|
+
# private
|
55
63
|
|
56
|
-
def method_missing(method, *args, &block)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
64
|
+
# def method_missing(method, *args, &block)
|
65
|
+
# unless self.instance_variables.include?(:"@#{method}")
|
66
|
+
# puts "#{method} is unavailable."
|
67
|
+
# else
|
68
|
+
# puts "Unable to retrieve #{method} because: #{@error.message}."
|
69
|
+
# end
|
70
|
+
# end
|
63
71
|
|
64
|
-
## SEND REQUEST
|
72
|
+
# ## SEND REQUEST
|
65
73
|
|
66
|
-
# Completes the endeca XML reqeust by inserting the XML body into the requred 'Query' tags, and sends the request to your hosted Endeca On-Demand Web API
|
67
|
-
def send_request
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
74
|
+
# # Completes the endeca XML reqeust by inserting the XML body into the requred 'Query' tags, and sends the request to your hosted Endeca On-Demand Web API
|
75
|
+
# def send_request
|
76
|
+
# @query = Builder::XmlMarkup.new(:indent => 2)
|
77
|
+
# @query.Query do
|
78
|
+
# @query << @body.target!
|
79
|
+
# end
|
72
80
|
|
73
|
-
|
74
|
-
|
75
|
-
|
81
|
+
# begin
|
82
|
+
# # ask Domino what this is?
|
83
|
+
# # @request, @raw_response = @http.post(@uri.path, @query.target!, 'Content-type' => 'application/xml')
|
76
84
|
|
77
|
-
|
85
|
+
# @response = Nokogiri::XML(fetch_response.body)
|
78
86
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
87
|
+
# build_records
|
88
|
+
# build_breadcrumbs
|
89
|
+
# build_dimensions
|
90
|
+
# build_business_rules
|
91
|
+
# build_search_reports
|
92
|
+
# build_selected_dimension_value_ids
|
93
|
+
# build_keyword_redirect
|
94
|
+
# rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, Errno::ECONNREFUSED, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => error
|
95
|
+
# @error = error
|
96
|
+
# end
|
97
|
+
# end
|
90
98
|
|
91
|
-
### XML REQUEST ###
|
99
|
+
# ### XML REQUEST ###
|
92
100
|
|
93
|
-
## SET REQUEST HOST
|
94
|
-
def set_host(host)
|
95
|
-
|
96
|
-
|
97
|
-
end
|
101
|
+
# ## SET REQUEST HOST
|
102
|
+
# def set_host(host)
|
103
|
+
# @uri = URI.parse(host)
|
104
|
+
# @http = Net::HTTP.new(@uri.host, @uri.port)
|
105
|
+
# end
|
98
106
|
|
99
|
-
## ADD BASE OPTIONS TO REQUEST
|
100
|
-
def add_base(options)
|
101
|
-
|
102
|
-
|
103
|
-
|
107
|
+
# ## ADD BASE OPTIONS TO REQUEST
|
108
|
+
# def add_base(options)
|
109
|
+
# options.each do |key, value|
|
110
|
+
# @body.tag!(key, value)
|
111
|
+
# end
|
104
112
|
|
105
|
-
|
106
|
-
end
|
113
|
+
# @base = options
|
114
|
+
# end
|
107
115
|
|
108
|
-
def fetch_response
|
109
|
-
|
110
|
-
end
|
116
|
+
# def fetch_response
|
117
|
+
# @http.post(@uri.path, @query.target!, 'Content-type' => 'application/xml')
|
118
|
+
# end
|
111
119
|
|
112
|
-
## BUILD REQUEST BODY
|
120
|
+
# ## BUILD REQUEST BODY
|
113
121
|
|
114
|
-
# Adds dimension_value_id_navigation to the request via one or more DimensionValueIds (DVID).
|
115
|
-
# NOTE: If the optional CategoryId (CID) is passed, all DVIDs must belong to the category.
|
116
|
-
def add_dimension_value_id_navigation(options)
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
end
|
122
|
+
# # Adds dimension_value_id_navigation to the request via one or more DimensionValueIds (DVID).
|
123
|
+
# # NOTE: If the optional CategoryId (CID) is passed, all DVIDs must belong to the category.
|
124
|
+
# def add_dimension_value_id_navigation(options)
|
125
|
+
# @body.SelectedDimensionValueIds do
|
126
|
+
# options.each do |option|
|
127
|
+
# @body.tag!('DimensionValueId', option)
|
128
|
+
# end
|
129
|
+
# end
|
130
|
+
# end
|
123
131
|
|
124
|
-
# (OPTIONAL) Adds category_navigation_query to the request via a CID.
|
125
|
-
# NOTE: If a CID is passed, all DVIDs must belong to the category. Passing a DVID that does not belong to this category will result in an endeca response error.
|
126
|
-
def add_category_navigation_query(options)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
end
|
132
|
+
# # (OPTIONAL) Adds category_navigation_query to the request via a CID.
|
133
|
+
# # NOTE: If a CID is passed, all DVIDs must belong to the category. Passing a DVID that does not belong to this category will result in an endeca response error.
|
134
|
+
# def add_category_navigation_query(options)
|
135
|
+
# @body.Category do
|
136
|
+
# @body.tag!('CategoryId', options)
|
137
|
+
# end
|
138
|
+
# end
|
131
139
|
|
132
|
-
# Adds search-key and search-term to the request.
|
133
|
-
def add_keyword_search(options)
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
end
|
140
|
+
# # Adds search-key and search-term to the request.
|
141
|
+
# def add_keyword_search(options)
|
142
|
+
# @body.Searches do
|
143
|
+
# @body.Search do
|
144
|
+
# options.each do |key, value|
|
145
|
+
# @body.tag!(key, value)
|
146
|
+
# end
|
147
|
+
# end
|
148
|
+
# end
|
149
|
+
# end
|
142
150
|
|
143
|
-
# Adds sort-key and sort-direction to the request.
|
144
|
-
def add_sorting(options)
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
end
|
151
|
+
# # Adds sort-key and sort-direction to the request.
|
152
|
+
# def add_sorting(options)
|
153
|
+
# @body.Sorts do
|
154
|
+
# @body.Sort do
|
155
|
+
# options.each do |key, value|
|
156
|
+
# @body.tag!(key, value)
|
157
|
+
# end
|
158
|
+
# end
|
159
|
+
# end
|
160
|
+
# end
|
153
161
|
|
154
|
-
# Adds RecordOffset and RecordsPerPage to the request.
|
155
|
-
def add_paging(options)
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
end
|
162
|
+
# # Adds RecordOffset and RecordsPerPage to the request.
|
163
|
+
# def add_paging(options)
|
164
|
+
# options.each do |key, value|
|
165
|
+
# @body.tag!(key, value)
|
166
|
+
# end
|
167
|
+
# end
|
160
168
|
|
161
|
-
# Adds advanced parameters to the request.
|
162
|
-
# NOTE: For this implementation I only had the default advanced parameter (AggregationKey) to test with. This has not been tested, and most likely will not work, with any other possible advanced parameters (if any)
|
163
|
-
def add_advanced_parameters(options)
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
end
|
169
|
+
# # Adds advanced parameters to the request.
|
170
|
+
# # NOTE: For this implementation I only had the default advanced parameter (AggregationKey) to test with. This has not been tested, and most likely will not work, with any other possible advanced parameters (if any)
|
171
|
+
# def add_advanced_parameters(options)
|
172
|
+
# options.each do |key, value|
|
173
|
+
# @body.tag!(key, value)
|
174
|
+
# end
|
175
|
+
# end
|
168
176
|
|
169
|
-
# Adds UserProfile(s) to the request.
|
170
|
-
def add_profiles(options)
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
end
|
177
|
+
# # Adds UserProfile(s) to the request.
|
178
|
+
# def add_profiles(options)
|
179
|
+
# @body.UserProfiles do
|
180
|
+
# options.each do |option|
|
181
|
+
# @body.tag!('UserProfile', option)
|
182
|
+
# end
|
183
|
+
# end
|
184
|
+
# end
|
177
185
|
|
178
|
-
#
|
179
|
-
def add_filters(options)
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
end
|
186
|
+
# #
|
187
|
+
# def add_filters(options)
|
188
|
+
# # puts "FILTERS: #{options}"
|
189
|
+
# @body.RangeFilters do
|
190
|
+
# options.each do |key, value|
|
191
|
+
# # puts "#{key}: #{value}"
|
192
|
+
# @body.tag!(key, value) do
|
193
|
+
# value.each do |key, value|
|
194
|
+
# @body.tag!(key, value)
|
195
|
+
# end
|
196
|
+
# end unless value.empty?
|
197
|
+
# end
|
198
|
+
# end
|
199
|
+
# # puts @body.target!
|
200
|
+
# end
|
193
201
|
|
194
|
-
### RESPONSE XML ###
|
202
|
+
# ### RESPONSE XML ###
|
195
203
|
|
196
|
-
## BUILD RESPONSE
|
204
|
+
# ## BUILD RESPONSE
|
197
205
|
|
198
|
-
# Builds an array of RECORDS
|
199
|
-
def build_records
|
200
|
-
|
206
|
+
# # Builds an array of RECORDS
|
207
|
+
# def build_records
|
208
|
+
# @records = []
|
201
209
|
|
202
|
-
|
203
|
-
|
204
|
-
|
210
|
+
# @record_offset = @response.xpath("//RecordsSet//offset")
|
211
|
+
# @records_per_page = @response.xpath("//RecordsSet//recordsperpage")
|
212
|
+
# @total_record_count = @response.xpath("//RecordsSet//totalrecordcount")
|
205
213
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
end
|
214
|
+
# unless @response.xpath("//RecordsSet").blank?
|
215
|
+
# @response.xpath("//RecordsSet//Record").each do |record|
|
216
|
+
# @records.push(EndecaOnDemand::Record.new(record))
|
217
|
+
# end
|
218
|
+
# else
|
219
|
+
# puts 'There are no records with this response!'
|
220
|
+
# end
|
221
|
+
# end
|
214
222
|
|
215
|
-
# Builds an array of BREADCRUMBS
|
216
|
-
def build_breadcrumbs
|
217
|
-
|
218
|
-
|
223
|
+
# # Builds an array of BREADCRUMBS
|
224
|
+
# def build_breadcrumbs
|
225
|
+
# @filtercrumbs = []
|
226
|
+
# @breadcrumbs = []
|
219
227
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
end
|
228
|
+
# unless @response.xpath("//Breadcrumbs").blank?
|
229
|
+
# @response.xpath("//Breadcrumbs//Breads").each do |node|
|
230
|
+
# filtercrumbs = []
|
231
|
+
# node.xpath("./Bread").each do |node|
|
232
|
+
# breadcrumb = EndecaOnDemand::BreadCrumb.new(node)
|
233
|
+
# filtercrumbs.push(breadcrumb)
|
234
|
+
# @breadcrumbs.push(breadcrumb)
|
235
|
+
# end
|
236
|
+
# @filtercrumbs.push(filtercrumbs)
|
237
|
+
# end
|
238
|
+
# else
|
239
|
+
# puts 'There are no breadcrumbs with this response!'
|
240
|
+
# end
|
241
|
+
# end
|
234
242
|
|
235
|
-
# Builds an array of DIMENSIONS
|
236
|
-
def build_dimensions
|
237
|
-
|
243
|
+
# # Builds an array of DIMENSIONS
|
244
|
+
# def build_dimensions
|
245
|
+
# @dimensions = []
|
238
246
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
end
|
247
|
+
# unless @response.xpath("//Dimensions").blank?
|
248
|
+
# @response.xpath("//Dimensions//Dimension").each do |node|
|
249
|
+
# @dimensions.push(EndecaOnDemand::Dimension.new(node))
|
250
|
+
# end
|
251
|
+
# else
|
252
|
+
# puts 'There are no dimensions with this response!'
|
253
|
+
# end
|
254
|
+
# end
|
247
255
|
|
248
|
-
# Builds an array of BUSINESS RULES
|
249
|
-
def build_business_rules
|
250
|
-
|
256
|
+
# # Builds an array of BUSINESS RULES
|
257
|
+
# def build_business_rules
|
258
|
+
# @business_rules_results = []
|
251
259
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
end
|
260
|
+
# unless @response.xpath("//BusinessRulesResult").blank?
|
261
|
+
# @response.xpath("//BusinessRulesResult//BusinessRules//BusinessRule").each do |node|
|
262
|
+
# @business_rules_results.push(EndecaOnDemand::BusinessRulesResult.new(node))
|
263
|
+
# end
|
264
|
+
# else
|
265
|
+
# puts 'There are no business rules with this response!'
|
266
|
+
# end
|
267
|
+
# end
|
260
268
|
|
261
|
-
# Builds an array of SEARCH REPORTS includes SEARCH
|
262
|
-
def build_search_reports
|
263
|
-
|
269
|
+
# # Builds an array of SEARCH REPORTS includes SEARCH
|
270
|
+
# def build_search_reports
|
271
|
+
# @search_reports = []
|
264
272
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
end
|
273
|
+
# unless @response.xpath("//AppliedFilters").blank?
|
274
|
+
# unless @response.xpath("//AppliedFilters//SearchReports").blank?
|
275
|
+
# @search_reports.push(EndecaOnDemand::SearchReport.new(@response.xpath("//AppliedFilters//SearchReports//SearchReport")))
|
276
|
+
# else
|
277
|
+
# puts "There are no search reports with this response!"
|
278
|
+
# end
|
279
|
+
# end
|
280
|
+
# end
|
273
281
|
|
274
|
-
# Builds an array of SELECTED DIMENSION VALUE IDS
|
275
|
-
def build_selected_dimension_value_ids
|
276
|
-
|
282
|
+
# # Builds an array of SELECTED DIMENSION VALUE IDS
|
283
|
+
# def build_selected_dimension_value_ids
|
284
|
+
# @selected_dimension_value_ids = []
|
277
285
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
end
|
286
|
+
# unless @response.xpath("//AppliedFilters").blank?
|
287
|
+
# unless @response.xpath("//AppliedFilters//SelectedDimensionValueIds").blank?
|
288
|
+
# @response.xpath("//AppliedFilters//SelectedDimnesionValueIds").each do |node|
|
289
|
+
# @selected_dimension_value_ids.push(EndecaOnDemand::SelectedDimensionValueId.new(node))
|
290
|
+
# end
|
291
|
+
# else
|
292
|
+
# puts "There are no selected dimension value ids with this response!"
|
293
|
+
# end
|
294
|
+
# end
|
295
|
+
# end
|
288
296
|
|
289
|
-
# Builds a KEYWORD REDIRECT for a given search term
|
290
|
-
def build_keyword_redirect
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
end
|
297
|
+
# # Builds a KEYWORD REDIRECT for a given search term
|
298
|
+
# def build_keyword_redirect
|
299
|
+
# unless @response.xpath("//KeywordRedirects").blank?
|
300
|
+
# @keyword_redirect = EndecaOnDemand::KeywordRedirect.new(@response.xpath("//KeywordRedirects"))
|
301
|
+
# else
|
302
|
+
# puts "There is no keyword redirectd with this r!"
|
303
|
+
# end
|
304
|
+
# end
|
297
305
|
|
298
306
|
end
|