endeca_on_demand 1.0.1 → 1.1.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.
- 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
|