endeca_xml 0.5.1 → 0.5.3
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/README.rdoc +9 -7
- data/lib/endeca_xml/version.rb +1 -1
- data/lib/endeca_xml.rb +63 -76
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= endeca_xml
|
2
2
|
|
3
|
-
endeca_xml provides an interface between your web application and the Endeca
|
3
|
+
endeca_xml provides an interface between your web application and the thanxmedia Endeca XML API
|
4
4
|
|
5
5
|
== Features
|
6
6
|
|
@@ -30,22 +30,24 @@ Then bundle install:
|
|
30
30
|
|
31
31
|
A lot more work has been done since the previous version. endeca_xml now constructs an XML query to send to thanxmedia via a form submission. An example of how the form is formatted is below:
|
32
32
|
|
33
|
-
<form
|
33
|
+
<form method="post" action="/endeca">
|
34
34
|
<input type="hidden" name="endeca[base]" value="{'RecordsSet' => true, 'Dimensions' => true, 'BusinessRulesResult' => true, 'AppliedFilters' => true}" />
|
35
|
-
<input type="hidden" name="endeca[nav]" value="{'type' => '', 'ids' => [1, 2, 3, 4]}" />
|
35
|
+
<input type="hidden" name="endeca[nav]" value="{'type' => 'category [or] dimension', 'ids' => [1, 2, 3, 4]}" />
|
36
36
|
<input type="hidden" name="endeca[search]" value="{'search-key' => 'key', 'search-term' => 'term'}" />
|
37
37
|
<input type="hidden" name="endeca[sort]" value="{'sort-key' => 'key', 'direction' => 'direction'}" />
|
38
38
|
<input type="hidden" name="endeca[paging]" value="{'RecordsOffset' => 0, 'RecordsPerPage' => 10}" />
|
39
39
|
<input type="hidden" name="endeca[parameters]" value="{'AggregationKey' => 'key'}" />
|
40
40
|
<input type="hidden" name="endeca[profiles]" value="{'profiles' => [1, 2, 3, 4]}" />
|
41
|
-
<input type="hidden" name="endeca[filters]" value="{'
|
41
|
+
<input type="hidden" name="endeca[filters]" value="{'Between' => {'lower-bound' => 1, 'upper-bound' => 2, 'attribute-name' => 'test', 'lat-long' => 123.4, 'distance' => '100'}, 'LessThan' => {}, 'LessThanOrEqual' => {}, 'GreaterThan' => {}, 'GreaterThanOrEqual' => {}, 'GeocodeLessThan' => {}, 'GeocodeGreaterThan' => {}, 'GeocodeBetween' => {}}" />
|
42
42
|
<input type="submit" />
|
43
43
|
</form>
|
44
|
-
|
44
|
+
|
45
|
+
This example is a complete example. It is not necessary to include anything that you don't intend to use (ie. blank or empty hash's/values). If you don't need an option, don't include the input field, and if you don't need a value within an option don't include it.
|
46
|
+
|
45
47
|
== TODO
|
46
48
|
|
47
|
-
*
|
48
|
-
*
|
49
|
+
* (complete) Pass all parameters into the initializer and have EndecaXml deconstruct the url and reconstruct it as XML rather than having the developer use each method individually.
|
50
|
+
* (complete) Have EndecaXml make the request after its all done constructing the query rather than requiring that the developer use the request method.
|
49
51
|
* Review the code and clean things up, making it nice and sugary sweet.
|
50
52
|
* The add_filters method needs some documentation, an example, and to be tested in a query.
|
51
53
|
* It occurred to me that the name is a little too ambiguous as this gem deals more specifically with thanxmedia's XML API and not Endeca directly, so a change of name is in order
|
data/lib/endeca_xml/version.rb
CHANGED
data/lib/endeca_xml.rb
CHANGED
@@ -7,41 +7,49 @@ require 'uri'
|
|
7
7
|
# each input name corresponds to a function that is called when building the XML. It is important that the names stay the same (for now)!
|
8
8
|
#
|
9
9
|
# <form action="/endeca" method="post">
|
10
|
+
# <input type="hidden" name="endeca[host]" value="{'host' => 'http://eodhc.endecaondemand.net:35828/ws/main'}">
|
10
11
|
# <input type="hidden" name="endeca[base]" value="{'RecordsSet' => true, 'Dimensions' => true, 'BusinessRulesResult' => true, 'AppliedFilters' => true}" />
|
11
|
-
# <input type="hidden" name="endeca[nav]" value="{'type' => '', 'ids' => [1, 2, 3, 4]}" />
|
12
|
+
# <input type="hidden" name="endeca[nav]" value="{'type' => 'category [or] dimension', 'ids' => [1, 2, 3, 4]}" />
|
12
13
|
# <input type="hidden" name="endeca[search]" value="{'search-key' => 'key', 'search-term' => 'term'}" />
|
13
14
|
# <input type="hidden" name="endeca[sort]" value="{'sort-key' => 'key', 'direction' => 'direction'}" />
|
14
15
|
# <input type="hidden" name="endeca[paging]" value="{'RecordsOffset' => 0, 'RecordsPerPage' => 10}" />
|
15
16
|
# <input type="hidden" name="endeca[parameters]" value="{'AggregationKey' => 'key'}" />
|
16
17
|
# <input type="hidden" name="endeca[profiles]" value="{'profiles' => [1, 2, 3, 4]}" />
|
17
|
-
# <input type="hidden" name="endeca[filters]" value="{'
|
18
|
+
# <input type="hidden" name="endeca[filters]" value="{'Between' => {'lower-bound' => 1, 'upper-bound' => 2, 'attribute-name' => 'test', 'lat-long' => 123.4, 'distance' => 100}, 'LessThan' => {}, 'LessThanOrEqual' => {}, 'GreaterThan' => {}, 'GreaterThanOrEqual' => {}, 'GeocodeLessThan' => {}, 'GeocodeGreaterThan' => {}, 'GeocodeBetween' => {}}" />
|
18
19
|
# <input type="submit" />
|
19
20
|
# </form>
|
20
21
|
|
21
22
|
class EndecaXml
|
22
|
-
|
23
|
+
|
23
24
|
def initialize(params)
|
24
25
|
@body = Builder::XmlMarkup.new(:indent => 2)
|
25
|
-
|
26
|
+
|
26
27
|
# puts "PARAMS: #{params}"
|
27
|
-
|
28
|
+
|
28
29
|
# take the parameters past in a form post and creates the options hash out of each key|value pair, using the key as root key in a new hash, and the value as that hash's value
|
29
30
|
options = {}
|
30
31
|
params.each do |key, value|
|
31
32
|
options.update(Hash[key, eval(value)])
|
32
33
|
end
|
33
|
-
|
34
|
+
|
34
35
|
# puts "OPTIONS: #{options}"
|
35
|
-
|
36
|
+
|
36
37
|
# call a corresponding function based off the root key created for each hash in the options hash to build the endeca query
|
37
38
|
options.each do |key, value|
|
38
39
|
self.send(key.to_sym, value)
|
39
40
|
end
|
40
|
-
|
41
|
+
|
41
42
|
# once the XML request is built send it off
|
42
43
|
send_request
|
43
44
|
end
|
44
|
-
|
45
|
+
|
46
|
+
def host(options)
|
47
|
+
options.each do |key, value|
|
48
|
+
@uri = URI.parse(value)
|
49
|
+
end
|
50
|
+
@http = Net::HTTP.new(uri.host, uri.port)
|
51
|
+
end
|
52
|
+
|
45
53
|
def base(options)
|
46
54
|
# puts "BASE: #{options}"
|
47
55
|
options.each do |key, value|
|
@@ -49,7 +57,7 @@ class EndecaXml
|
|
49
57
|
end
|
50
58
|
# print @body.target!
|
51
59
|
end
|
52
|
-
|
60
|
+
|
53
61
|
def nav(options)
|
54
62
|
# puts "NAV: #{options}"
|
55
63
|
case options['type']
|
@@ -70,7 +78,7 @@ class EndecaXml
|
|
70
78
|
end
|
71
79
|
# puts @body.target!
|
72
80
|
end
|
73
|
-
|
81
|
+
|
74
82
|
def search(options)
|
75
83
|
# puts "SEARCH: #{options}"
|
76
84
|
@body.Searches do
|
@@ -82,11 +90,11 @@ class EndecaXml
|
|
82
90
|
end
|
83
91
|
# puts @body.target!
|
84
92
|
end
|
85
|
-
|
93
|
+
|
86
94
|
def sort(options)
|
87
95
|
# puts "SORT: #{options}"
|
88
96
|
@body.Sorts do
|
89
|
-
@body.Sort do
|
97
|
+
@body.Sort do
|
90
98
|
options.each do |key, value|
|
91
99
|
@body.tag!(key, value)
|
92
100
|
end
|
@@ -94,7 +102,7 @@ class EndecaXml
|
|
94
102
|
end
|
95
103
|
# puts @body.target!
|
96
104
|
end
|
97
|
-
|
105
|
+
|
98
106
|
def paging(options)
|
99
107
|
# puts "PAGING: #{options}"
|
100
108
|
options.each do |key, value|
|
@@ -102,17 +110,17 @@ class EndecaXml
|
|
102
110
|
end
|
103
111
|
# puts @body.target!
|
104
112
|
end
|
105
|
-
|
113
|
+
|
106
114
|
def parameters(options)
|
107
|
-
# puts "PARAMETERS: #{
|
115
|
+
# puts "PARAMETERS: #{options}"
|
108
116
|
options.each do |key, value|
|
109
117
|
@body.tag!(key, value)
|
110
118
|
end
|
111
119
|
# puts @body.target!
|
112
120
|
end
|
113
|
-
|
121
|
+
|
114
122
|
def profiles(options)
|
115
|
-
# puts "PROFILES: #{
|
123
|
+
# puts "PROFILES: #{options}"
|
116
124
|
@body.UserProfiles do
|
117
125
|
options.each do |key, value|
|
118
126
|
# puts "#{key}: #{value}"
|
@@ -123,56 +131,40 @@ class EndecaXml
|
|
123
131
|
end
|
124
132
|
# puts @body.target!
|
125
133
|
end
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
# attribute-name
|
141
|
-
# lower-bound
|
142
|
-
# upper-bound
|
143
|
-
# lat-long
|
144
|
-
# distance
|
145
|
-
def filters(filters)
|
146
|
-
puts "FILTERS: #{filters}"
|
147
|
-
# filters.each do |filter|
|
148
|
-
# @body.RangeFilters do
|
149
|
-
# @body.tag!(filter[0], filter[1]) do
|
150
|
-
# filters[2].each do |option|
|
151
|
-
# @body.tag!(option[0], option[1])
|
152
|
-
# end
|
153
|
-
# end
|
154
|
-
# end
|
155
|
-
# end
|
134
|
+
|
135
|
+
def filters(options)
|
136
|
+
# puts "FILTERS: #{options}"
|
137
|
+
@body.RangeFilters do
|
138
|
+
options.each do |key, value|
|
139
|
+
# puts "#{key}: #{value}"
|
140
|
+
@body.tag!(key, value) do
|
141
|
+
value.each do |key, value|
|
142
|
+
@body.tag!(key, value)
|
143
|
+
end
|
144
|
+
end unless value.empty?
|
145
|
+
end
|
146
|
+
end
|
147
|
+
# puts @body.target!
|
156
148
|
end
|
157
|
-
|
149
|
+
|
158
150
|
def get_records
|
159
|
-
@
|
151
|
+
@response['RecordsSet']['Record'].each do |record|
|
160
152
|
record.each do |key, value|
|
161
153
|
puts "#{key}: #{value}"
|
162
154
|
end
|
163
155
|
end unless response['RecordsSet'].nil?
|
164
156
|
end
|
165
|
-
|
157
|
+
|
166
158
|
def get_breadcrumbs
|
167
|
-
@
|
159
|
+
@response['Breadcrumbs']['Breads'].each do |crumb|
|
168
160
|
crumb.each do |key, value|
|
169
161
|
puts "#{key}: #{value}"
|
170
162
|
end
|
171
163
|
end unless response['Breadcrumbs'].nil?
|
172
164
|
end
|
173
|
-
|
165
|
+
|
174
166
|
def get_dimensions
|
175
|
-
@
|
167
|
+
@response['Dimensions']['Dimension'].each do |dimension|
|
176
168
|
dimension.each do |key, value|
|
177
169
|
puts "#{key}: #{value}"
|
178
170
|
if key == 'DimensionValues'
|
@@ -187,19 +179,19 @@ class EndecaXml
|
|
187
179
|
puts " #{key}: #{value}"
|
188
180
|
end
|
189
181
|
end
|
190
|
-
end
|
182
|
+
end
|
191
183
|
end
|
192
184
|
end unless response['Dimensions'].nil?
|
193
185
|
end
|
194
|
-
|
186
|
+
|
195
187
|
def get_business_rules
|
196
|
-
@
|
188
|
+
@response['BusinessRulesResult']['BusinessRules']['BusinessRule'].each do |rule|
|
197
189
|
rule.each do |key, value|
|
198
190
|
puts "#{key}: #{value}"
|
199
191
|
value.each do |key, value|
|
200
192
|
puts " #{key}: #{value}"
|
201
193
|
end if key == 'properties'
|
202
|
-
|
194
|
+
|
203
195
|
if key == 'RecordSet'
|
204
196
|
if value.instance_of?(Array)
|
205
197
|
value['Record'].each do |record|
|
@@ -216,15 +208,15 @@ class EndecaXml
|
|
216
208
|
end
|
217
209
|
end unless response['BusinessRulesResult'].nil?
|
218
210
|
end
|
219
|
-
|
211
|
+
|
220
212
|
def get_applied_filters
|
221
|
-
@
|
213
|
+
@response['AppliedFilters'].each do |filter|
|
222
214
|
puts "FILTER: #{filter}"
|
223
215
|
end unless response['AppliedFilters'].nil?
|
224
216
|
end
|
225
|
-
|
217
|
+
|
226
218
|
private
|
227
|
-
|
219
|
+
|
228
220
|
# complete the endeca XML reqeust and send the request to the endeca API
|
229
221
|
def send_request
|
230
222
|
# insert all of the XML blocks that have been included in the request into the endeca Query XML tag
|
@@ -232,26 +224,21 @@ class EndecaXml
|
|
232
224
|
query.Query do
|
233
225
|
query << @body.target!
|
234
226
|
end
|
235
|
-
|
227
|
+
|
236
228
|
# puts "QUERY: #{query.target!}"
|
237
|
-
|
238
|
-
uri = URI.parse('http://workbench.deliverframework.net:4000/ws/main')
|
239
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
240
|
-
|
229
|
+
|
241
230
|
begin
|
242
|
-
request,
|
231
|
+
request, response = @http.post(@uri.path, query.target!, 'Content-type' => 'application/xml')
|
232
|
+
handle_response(Crack::XML.parse(response))
|
243
233
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, Errno::ECONNREFUSED, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => error
|
244
234
|
puts "ERROR: #{error.message}"
|
245
235
|
end
|
246
236
|
end
|
247
|
-
|
248
|
-
# get the request response
|
249
|
-
def response
|
250
|
-
# parse XML response into an hash
|
251
|
-
response = Crack::XML.parse(@response)
|
237
|
+
|
238
|
+
# get the request response and parse it into an hash
|
239
|
+
def handle_response(response)
|
252
240
|
# puts "RESPONSE: #{response}"
|
253
|
-
|
254
|
-
@blarg = response['Final']
|
241
|
+
@response = response['Final']
|
255
242
|
end
|
256
|
-
|
243
|
+
|
257
244
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: endeca_xml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.5.
|
5
|
+
version: 0.5.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- sdomino
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-07-01 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: crack
|