endeca_on_demand 0.0.1
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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +144 -0
- data/Rakefile +2 -0
- data/endeca_on_demand.gemspec +25 -0
- data/lib/endeca_on_demand/crumb.rb +16 -0
- data/lib/endeca_on_demand/dimension.rb +18 -0
- data/lib/endeca_on_demand/dimension_value_id.rb +16 -0
- data/lib/endeca_on_demand/record.rb +16 -0
- data/lib/endeca_on_demand/rule.rb +17 -0
- data/lib/endeca_on_demand/search_report.rb +16 -0
- data/lib/endeca_on_demand/version.rb +3 -0
- data/lib/endeca_on_demand.rb +430 -0
- metadata +89 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 sdomino
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
= EndecaOnDemand
|
2
|
+
|
3
|
+
The official unofficial Endeca On-Demand Web API gem, EndecaOnDemand will take a query-string and construct an XML query that it then sends to a hosted Endeca On-Demand Cluster. It will then parse the response and expose an API for using the response data.
|
4
|
+
|
5
|
+
== Features
|
6
|
+
|
7
|
+
* Provides an easy way for you to use the Thanx Media, Endeca On-Demand Web API
|
8
|
+
* Builds an XML query from a query-string, formatted for the Endeca On-Demand Service
|
9
|
+
* Handles the Endeca On-Demand response XML and exposes methods to use response data
|
10
|
+
|
11
|
+
== Install
|
12
|
+
|
13
|
+
=== Rails
|
14
|
+
|
15
|
+
Add this line to your Gemfile:
|
16
|
+
|
17
|
+
gem 'EndecaOnDemand'
|
18
|
+
|
19
|
+
Then bundle install:
|
20
|
+
|
21
|
+
bundle install
|
22
|
+
|
23
|
+
---
|
24
|
+
|
25
|
+
=== Non Rails
|
26
|
+
|
27
|
+
gem install EndecaOnDemand
|
28
|
+
|
29
|
+
== Usage
|
30
|
+
|
31
|
+
EndecaOnDemand constructs an XML query to send to a hosted Endeca On-Demand Cluster, via a query string:
|
32
|
+
NOTE: This is a complete example. Any unneeded option should not be included in the query-string
|
33
|
+
|
34
|
+
<a href='www.example.com/example/catalog?search-key=primary&search-term=name&DimensionValueIds=1,2,3,4&sort-key=name&sort-direction=descending&RecordOffset=0&RecordsPerPage=9&AggregationKey=name&UserProfiles=1,2,3,4&filter=between'>FULL ENDECA REQUEST</a>
|
35
|
+
|
36
|
+
The following is an example of an empty 'options' hash that would then need to be constructed from a query-string:
|
37
|
+
NOTE: The base options and current category are set manually and not via a query-string
|
38
|
+
|
39
|
+
options = {
|
40
|
+
'add_base' => {'RecordsSet' => true, 'Dimensions' => true, 'BusinessRulesResult' => true, 'AppliedFilters' => true},
|
41
|
+
'add_keyword_search' => {},
|
42
|
+
'add_dimension_value_id_navigation' => {},
|
43
|
+
'add_category_navigation_query' => "current_category_id",
|
44
|
+
'add_sorting' => {},
|
45
|
+
'add_paging' => {},
|
46
|
+
'add_advanced_parameters' => {},
|
47
|
+
'add_profiles' => {},
|
48
|
+
'add_filters' => {}
|
49
|
+
}
|
50
|
+
|
51
|
+
The following is what a prepared 'options' hash would look like (using the above example query-string):
|
52
|
+
NOTE: This is a complete example. It is not necessary to include anything that you don't need, or you may choose to include it and just leave it blank.
|
53
|
+
|
54
|
+
options = {
|
55
|
+
'add_base' => {'RecordsSet' => true, 'Dimensions' => true, 'BusinessRulesResult' => true, 'AppliedFilters' => true},
|
56
|
+
'add_keyword_search' => {'searh-key => 'key', search-term => 'term'},
|
57
|
+
'add_dimension_value_id_navigation' => {[1, 2, 3, 4]},
|
58
|
+
'add_category_navigation_query' => 1,
|
59
|
+
'add_sorting' => {'sort-key' => 'key', 'sort-direction' => 'Descending'},
|
60
|
+
'add_paging' => {'RecordOffset' => 0, 'RecordsPerPage' => 9},
|
61
|
+
'add_advanced_parameters' => {'AggregationKey' => 'key'},
|
62
|
+
'add_profiles' => {[1, 2, 3, 4]},
|
63
|
+
'add_filters' => {}
|
64
|
+
}
|
65
|
+
|
66
|
+
Provide the location of your hosted Endeca On-Demand Cluster (this can be set as a variable or passed directly as a parameter)
|
67
|
+
|
68
|
+
host = 'your/EndecaOnDemand/hosted/cluster'
|
69
|
+
|
70
|
+
Pass your 'host' and 'options' hash to new EndecaOnDemand
|
71
|
+
|
72
|
+
@endeca = EndecaOnDemand.new(host, options)
|
73
|
+
|
74
|
+
Below are (ruby) examples of how you could access the response data:
|
75
|
+
|
76
|
+
Records:
|
77
|
+
|
78
|
+
@endeca.records.each do |record|
|
79
|
+
puts "---------- BEGIN RECORD"
|
80
|
+
puts "RECORD: #{record.inspect}"
|
81
|
+
puts "---------- END"
|
82
|
+
end
|
83
|
+
|
84
|
+
Breadcrumbs:
|
85
|
+
|
86
|
+
@endeca.breadcrumbs.each do |crumb|
|
87
|
+
puts "---------- BEGIN CRUMB"
|
88
|
+
puts "CRUMB: #{crumb.inspect}"
|
89
|
+
puts "---------- END"
|
90
|
+
end
|
91
|
+
|
92
|
+
Dimensions:
|
93
|
+
|
94
|
+
@endeca.dimensions.each do |dimension|
|
95
|
+
puts "---------- BEGIN DIMENSION"
|
96
|
+
puts "DIMENSION: #{dimension.inspect}"
|
97
|
+
puts "DIMENSION VALUES: #{dimension.dimensionvalues}"
|
98
|
+
puts "DIMENSION VALUES ARRAY: #{dimension.dimension_values}"
|
99
|
+
puts "---------- END"
|
100
|
+
end
|
101
|
+
|
102
|
+
Rules:
|
103
|
+
|
104
|
+
@endeca.rules.each do |rule|
|
105
|
+
puts "---------- BEGIN RULE"
|
106
|
+
puts "RULE: #{rule.inspect}"
|
107
|
+
puts "RULE PROPERTIES: #{rule.properties}"
|
108
|
+
puts "RULE PROPERTIES_ARRAY: #{rule.properties_array}"
|
109
|
+
puts "RULE RECORDS: #{rule.records}"
|
110
|
+
puts "---------- END"
|
111
|
+
end
|
112
|
+
|
113
|
+
Filters:
|
114
|
+
|
115
|
+
@endeca.filters.each do |filter|
|
116
|
+
puts "---------- BEGIN FILTER"
|
117
|
+
puts "FILTER: #{filter.inspect}"
|
118
|
+
puts "---------- END"
|
119
|
+
end
|
120
|
+
|
121
|
+
Each object will have associated instance variables that will allow you directly call any value on that object:
|
122
|
+
|
123
|
+
@endeca.records.each do |record|
|
124
|
+
record.p_name
|
125
|
+
etc...
|
126
|
+
end
|
127
|
+
|
128
|
+
== F.A.Q
|
129
|
+
|
130
|
+
* Q: I'm getting a response error saying something about multiple values for model Category
|
131
|
+
A: You are most likely trying to pass a CategoryId (CID) with DimensionValueId(s) (DVID) that don't match. The DVIDs must belong to the category passed as the CID.
|
132
|
+
|
133
|
+
== TODO
|
134
|
+
|
135
|
+
* More detail on breadcrumbs (and their suggested use as left nav filters)
|
136
|
+
* More on filters
|
137
|
+
|
138
|
+
== CONTACT
|
139
|
+
|
140
|
+
Please contact me with any question, bugs, suggestions, or... donations? :)
|
141
|
+
|
142
|
+
== Copyright
|
143
|
+
|
144
|
+
Copyright (c) 2011 Steve Domino. See LICENSE.txt for further details
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "endeca_on_demand/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "endeca_on_demand"
|
7
|
+
s.version = EndecaOnDemand::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ['sdomino']
|
10
|
+
s.email = ['sdomino@pagodabox.com']
|
11
|
+
s.homepage = 'http://github.com/sdomino/endeca_on_demand'
|
12
|
+
s.summary = 'Formerly EndecaXml (endeca_xml), This gem provides an easy way for you to use the Thanx Media, Endeca On-Demand Web API'
|
13
|
+
s.description = 'EndecaOnDemand will take a query-string and construct an XML query that it then sends to a hosted Endeca On-Demand Cluster. It will then parse the response and expose an API for using the response data.'
|
14
|
+
|
15
|
+
s.rubyforge_project = "endeca_on_demand"
|
16
|
+
|
17
|
+
s.add_dependency 'crackoid'
|
18
|
+
|
19
|
+
s.add_development_dependency 'rspec'
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class EndecaOnDemand
|
2
|
+
class Crumb
|
3
|
+
|
4
|
+
def initialize(crumb)
|
5
|
+
# puts "CRUMB: #{crumb}"
|
6
|
+
crumb.each do |key, value|
|
7
|
+
# puts "#{key} | #{value}"
|
8
|
+
self.instance_variable_set(:"@#{key.downcase}", value)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# is there anyway to do this dynamically?
|
13
|
+
attr_reader :name, :original_id, :id
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class EndecaOnDemand
|
2
|
+
class Dimension
|
3
|
+
|
4
|
+
def initialize(dimension)
|
5
|
+
# puts "DIMENSION: #{dimension}"
|
6
|
+
dimension.each do |key, value|
|
7
|
+
# puts "#{key} | #{value}"
|
8
|
+
self.instance_variable_set(:"@#{key.downcase}", value)
|
9
|
+
end
|
10
|
+
|
11
|
+
@dimension_values = []
|
12
|
+
end
|
13
|
+
|
14
|
+
# is there anyway to do this dynamically?
|
15
|
+
attr_reader :name, :id, :group_name, :hasmore, :count, :dimensionvalues, :dimension_values
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class EndecaOnDemand
|
2
|
+
class DimensionValueId
|
3
|
+
|
4
|
+
def initialize(id)
|
5
|
+
# puts "ID: #{id}"
|
6
|
+
id.each do |key, value|
|
7
|
+
# puts "#{key} | #{value}"
|
8
|
+
self.instance_variable_set(:"@#{key.downcase}", value)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# is there anyway to do this dynamically?
|
13
|
+
attr_reader :dimensionvalueid
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class EndecaOnDemand
|
2
|
+
class Record
|
3
|
+
|
4
|
+
def initialize(record)
|
5
|
+
# puts "RECORD: #{record}"
|
6
|
+
record.each do |key, value|
|
7
|
+
# puts "#{key} | #{value}"
|
8
|
+
self.instance_variable_set(:"@#{key.downcase}", value)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# is there anyway to do this dynamically?
|
13
|
+
attr_reader :p_name, :p_category_id, :p_dax_item_number, :p_image, :p_price_retail, :p_price_sale, :p_price_sort, :p_url_detail
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class EndecaOnDemand
|
2
|
+
class Rule
|
3
|
+
|
4
|
+
def initialize(rule)
|
5
|
+
rule.each do |key, value|
|
6
|
+
self.instance_variable_set(:"@#{key.downcase}", value)
|
7
|
+
end
|
8
|
+
|
9
|
+
@properties_array = []
|
10
|
+
@records = []
|
11
|
+
end
|
12
|
+
|
13
|
+
# is there anyway to do this dynamically?
|
14
|
+
attr_reader :title, :id, :style, :zone, :recordcount, :recordset, :properties, :properties_array, :records
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class EndecaOnDemand
|
2
|
+
class SearchReport
|
3
|
+
|
4
|
+
def initialize(report)
|
5
|
+
# puts "REPORT: #{report}"
|
6
|
+
report.each do |key, value|
|
7
|
+
# puts "#{key} | #{value}"
|
8
|
+
self.instance_variable_set(:"@#{key.downcase}", value)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# is there anyway to do this dynamically?
|
13
|
+
attr_reader :none
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,430 @@
|
|
1
|
+
Dir["#{File.dirname(__FILE__)}/endeca_on_demand/*"].each { |file| require(file)}
|
2
|
+
|
3
|
+
require 'builder'
|
4
|
+
require 'crackoid'
|
5
|
+
require 'net/http'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
class EndecaOnDemand
|
9
|
+
|
10
|
+
def initialize(host, options)
|
11
|
+
@body = Builder::XmlMarkup.new(:indent => 2)
|
12
|
+
|
13
|
+
#
|
14
|
+
# puts "HOST: #{host}"
|
15
|
+
set_host(host)
|
16
|
+
|
17
|
+
#
|
18
|
+
# puts "OPTIONS: #{options}"
|
19
|
+
options.each do |key, value|
|
20
|
+
self.send(key.to_sym, value) unless value.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
send_request
|
25
|
+
end
|
26
|
+
|
27
|
+
### API
|
28
|
+
|
29
|
+
def records
|
30
|
+
@records
|
31
|
+
end
|
32
|
+
|
33
|
+
def breadcrumbs
|
34
|
+
@breadcrumbs
|
35
|
+
end
|
36
|
+
|
37
|
+
def filtercrumbs
|
38
|
+
@filtercrumbs
|
39
|
+
end
|
40
|
+
|
41
|
+
def dimensions
|
42
|
+
@dimensions
|
43
|
+
end
|
44
|
+
|
45
|
+
def rules
|
46
|
+
@business_rules
|
47
|
+
end
|
48
|
+
|
49
|
+
def search_reports
|
50
|
+
@search_reports
|
51
|
+
end
|
52
|
+
|
53
|
+
def selected_dimension_value_ids
|
54
|
+
@selected_dimension_value_ids
|
55
|
+
end
|
56
|
+
|
57
|
+
### /API
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
### XML REQUEST ###
|
62
|
+
|
63
|
+
## SET REQUEST HOST
|
64
|
+
def set_host(host)
|
65
|
+
@uri = URI.parse(host)
|
66
|
+
@http = Net::HTTP.new(@uri.host, @uri.port)
|
67
|
+
end
|
68
|
+
|
69
|
+
## ADD BASE OPTIONS TO REQUEST
|
70
|
+
def add_base(options)
|
71
|
+
options.each do |key, value|
|
72
|
+
@body.tag!(key, value)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
## BUILD REQUEST BODY
|
77
|
+
|
78
|
+
# Adds dimension_value_id_navigation to the request via one or more DimensionValueIds (DVID).
|
79
|
+
# NOTE: If the optional CategoryId (CID) is passed, all DVIDs must belong to the category.
|
80
|
+
def add_dimension_value_id_navigation(options)
|
81
|
+
@body.SelectedDimensionValueIds do
|
82
|
+
options.each do |dimension|
|
83
|
+
@body.tag!('DimensionValueId', dimension)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# (OPTIONAL) Adds category_navigation_query to the request via a CID.
|
89
|
+
# 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.
|
90
|
+
def add_category_navigation_query(options)
|
91
|
+
@body.Category do
|
92
|
+
@body.tag!('CategoryId', options)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Adds search-key and search-term to the request.
|
97
|
+
def add_keyword_search(options)
|
98
|
+
@body.Searches do
|
99
|
+
@body.Search do
|
100
|
+
options.each do |key, value|
|
101
|
+
@body.tag!(key, value)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Adds sort-key and sort-direction to the request.
|
108
|
+
def add_sorting(options)
|
109
|
+
@body.Sorts do
|
110
|
+
@body.Sort do
|
111
|
+
options.each do |key, value|
|
112
|
+
@body.tag!(key, value)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Adds RecordOffset and RecordsPerPage to the request.
|
119
|
+
def add_paging(options)
|
120
|
+
options.each do |key, value|
|
121
|
+
@body.tag!(key, value)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
def add_advanced_parameters(options)
|
127
|
+
# puts "PARAMETERS: #{options}"
|
128
|
+
options.each do |key, value|
|
129
|
+
@body.tag!(key, value)
|
130
|
+
end
|
131
|
+
# puts @body.target!
|
132
|
+
end
|
133
|
+
|
134
|
+
# Adds UserProfile(s) to the request.
|
135
|
+
#TODO: test and see what happens if profiles are passed and don't exist
|
136
|
+
def add_profiles(options)
|
137
|
+
@body.UserProfiles do
|
138
|
+
options.each do |profile|
|
139
|
+
@body.tag!('UserProfile', profile)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
#
|
145
|
+
def add_filters(options)
|
146
|
+
# puts "FILTERS: #{options}"
|
147
|
+
@body.RangeFilters do
|
148
|
+
options.each do |key, value|
|
149
|
+
# puts "#{key}: #{value}"
|
150
|
+
@body.tag!(key, value) do
|
151
|
+
value.each do |key, value|
|
152
|
+
@body.tag!(key, value)
|
153
|
+
end
|
154
|
+
end unless value.empty?
|
155
|
+
end
|
156
|
+
end
|
157
|
+
# puts @body.target!
|
158
|
+
end
|
159
|
+
|
160
|
+
## SEND REQUEST
|
161
|
+
|
162
|
+
# 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
|
163
|
+
def send_request
|
164
|
+
# insert all of the XML blocks that have been included in the request into the endeca Query XML tag
|
165
|
+
query = Builder::XmlMarkup.new(:indent => 2)
|
166
|
+
query.Query do
|
167
|
+
query << @body.target!
|
168
|
+
end
|
169
|
+
|
170
|
+
# puts "QUERY: #{query.target!}"
|
171
|
+
|
172
|
+
begin
|
173
|
+
request, response = @http.post(@uri.path, query.target!, 'Content-type' => 'application/xml')
|
174
|
+
handle_response(Crackoid::XML.parse(response))
|
175
|
+
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, Errno::ECONNREFUSED, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => error
|
176
|
+
puts "ERROR: #{error.message}"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
## HANDLE RESPONSE
|
181
|
+
|
182
|
+
# get the request response and parse it into an hash
|
183
|
+
def handle_response(response)
|
184
|
+
# puts "RESPONSE: #{response}"
|
185
|
+
@response = response['Final']
|
186
|
+
|
187
|
+
build_data
|
188
|
+
end
|
189
|
+
|
190
|
+
def build_data
|
191
|
+
build_records
|
192
|
+
build_breadcrumbs
|
193
|
+
build_dimensions
|
194
|
+
build_business_rules
|
195
|
+
build_search_reports
|
196
|
+
build_selected_dimension_value_ids
|
197
|
+
end
|
198
|
+
|
199
|
+
# builds the RECORDS hash
|
200
|
+
def build_records
|
201
|
+
puts "RECORDS SET: #{@response['RecordsSet']}"
|
202
|
+
|
203
|
+
# NOTE: this may need to be reworked a little. look in recordset for nodes that our outside of records...
|
204
|
+
@records = []
|
205
|
+
unless @response['RecordsSet'].nil?
|
206
|
+
if @response['RecordsSet']['Record'].instance_of?(Hash)
|
207
|
+
@records.push(EndecaXml::Record.new(@response['RecordsSet']))
|
208
|
+
elsif @response['RecordsSet']['Record'].instance_of?(Array)
|
209
|
+
@response['RecordsSet']['Record'].each do |record|
|
210
|
+
@records.push(EndecaXml::Record.new(record))
|
211
|
+
end
|
212
|
+
else
|
213
|
+
puts "This record is a(n): #{@response['RecordsSet'].class}"
|
214
|
+
end
|
215
|
+
else
|
216
|
+
puts 'There are no records with this response!'
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# builds the BREADCRUMBS hash
|
221
|
+
# TODO: one final pass on this to make sure its awesome (do i need the has for each key/values?) readdress how the filtercrumbs are handles and see if it is the best way
|
222
|
+
def build_breadcrumbs
|
223
|
+
@breadcrumbs = []
|
224
|
+
@filtercrumbs = []
|
225
|
+
|
226
|
+
# puts "BREADCRUMBS: #{@response['Breadcrumbs'}"
|
227
|
+
breadcrumbs = @response['Breadcrumbs']
|
228
|
+
unless breadcrumbs.nil?
|
229
|
+
|
230
|
+
# puts "BREADS: #{@response['Breadcrumbs']['Breads']}"
|
231
|
+
breads = @response['Breadcrumbs']['Breads']
|
232
|
+
|
233
|
+
breads.each do |bread|
|
234
|
+
bread.each do |key, value|
|
235
|
+
@filtercrumbs.push(value)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
if breads.instance_of?(Hash)
|
240
|
+
# puts "HASH 1: #{breads}"
|
241
|
+
if breads.instance_of?(Hash)
|
242
|
+
# puts "HASH 2: #{breads}"
|
243
|
+
if breads['Bread'].instance_of?(Hash)
|
244
|
+
# puts "HASH 2: #{breads['Bread']}"
|
245
|
+
breads['Bread'].each do |key, value|
|
246
|
+
# puts "#{key} :: #{value}"
|
247
|
+
@breadcrumbs.push(EndecaXml::Crumb.new(breads['Bread']))
|
248
|
+
end
|
249
|
+
elsif breads['Bread'].instance_of?(Array)
|
250
|
+
# puts "ARRAY 2: #{breads['Bread']}"
|
251
|
+
breads['Bread'].each do |crumb|
|
252
|
+
# puts "CRUMB 2: #{crumb}"
|
253
|
+
@breadcrumbs.push(EndecaXml::Crumb.new(crumb))
|
254
|
+
end
|
255
|
+
end
|
256
|
+
@filtercrumbs.push(breads['Bread'])
|
257
|
+
elsif bread.instance_of?(Array)
|
258
|
+
# puts "ARRAY 1: #{breads}"
|
259
|
+
breads.each do |crumb|
|
260
|
+
# puts "CRUMB: #{crumb}"
|
261
|
+
@breadcrumbs.push(EndecaXml::Crumb.new(crumb))
|
262
|
+
end
|
263
|
+
end
|
264
|
+
elsif breads.instance_of?(Array)
|
265
|
+
# puts "ARRAY 1: #{breads}"
|
266
|
+
breads.each do |bread|
|
267
|
+
# puts "BREAD: #{bread}"
|
268
|
+
if bread.instance_of?(Hash)
|
269
|
+
# puts "HASH 1: #{bread}"
|
270
|
+
if bread['Bread'].instance_of?(Hash)
|
271
|
+
# puts "HASH 2: #{bread}"
|
272
|
+
bread['Bread'].each do |key, value|
|
273
|
+
# puts "#{key} :: #{value}"
|
274
|
+
@breadcrumbs.push(EndecaXml::Crumb.new(bread['Bread']))
|
275
|
+
end
|
276
|
+
elsif bread['Bread'].instance_of?(Array)
|
277
|
+
# puts "ARRAY 2: #{bread}"
|
278
|
+
bread['Bread'].each do |crumb|
|
279
|
+
# puts "CRUMB 2: #{crumb}"
|
280
|
+
@breadcrumbs.push(EndecaXml::Crumb.new(crumb))
|
281
|
+
end
|
282
|
+
end
|
283
|
+
elsif bread.instance_of?(Array)
|
284
|
+
# puts "ARRAY 3: #{bread}"
|
285
|
+
bread['Bread'].each do |crumb|
|
286
|
+
# puts "CRUMB 3: #{crumb}"
|
287
|
+
@breadcrumbs.push(EndecaXml::Crumb.new(crumb))
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
else
|
293
|
+
puts 'There are no breadcrumbs with this response!'
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# builds the DIMENSIONS hash
|
298
|
+
# NOTE: do what breadcrumbs is doing in terms of vars
|
299
|
+
def build_dimensions
|
300
|
+
@dimensions = []
|
301
|
+
|
302
|
+
puts "DIMENSIONS: #{@response['Dimensions']}"
|
303
|
+
dimensions = @response['Dimensions']
|
304
|
+
|
305
|
+
unless @response['Dimensions'].nil?
|
306
|
+
|
307
|
+
# puts "DIMENSION: #{@response['Dimensions']['Dimension']}"
|
308
|
+
dimension = @response['Dimensions']['Dimension']
|
309
|
+
|
310
|
+
if dimension.instance_of?(Hash)
|
311
|
+
@dimension = EndecaXml::Dimension.new(dimensions)
|
312
|
+
unless dimension['DimensionValues'].nil?
|
313
|
+
if dimension['DimensionValues']['DimensionValue'].instance_of?(Hash)
|
314
|
+
@dimension.dimension_values.push(EndecaXml::Dimension.new(dimension['DimensionValues']))
|
315
|
+
elsif dimension['DimensionValues']['DimensionValue'].instance_of?(Array)
|
316
|
+
dimension['DimensionValues']['DimensionValue'].each do |dimension_value|
|
317
|
+
@dimension.dimension_values.push(EndecaXml::Dimension.new(dimension_value))
|
318
|
+
end
|
319
|
+
else
|
320
|
+
puts "This dimension value is a(n): #{dimension['DimensionValues']['DimensionValue'].class}"
|
321
|
+
end
|
322
|
+
@dimensions.push(@dimension)
|
323
|
+
else
|
324
|
+
puts "There are no dimension values on this dimension!"
|
325
|
+
end
|
326
|
+
elsif dimension.instance_of?(Array)
|
327
|
+
dimension.each do |dimension|
|
328
|
+
@dimension = EndecaXml::Dimension.new(dimension)
|
329
|
+
unless dimension['DimensionValues'].nil?
|
330
|
+
if dimension['DimensionValues']['DimensionValue'].instance_of?(Hash)
|
331
|
+
@dimension.dimension_values.push(EndecaXml::Dimension.new(dimension['DimensionValues']))
|
332
|
+
elsif dimension['DimensionValues']['DimensionValue'].instance_of?(Array)
|
333
|
+
dimension['DimensionValues']['DimensionValue'].each do |dimension_value|
|
334
|
+
@dimension.dimension_values.push(EndecaXml::Dimension.new(dimension_value))
|
335
|
+
end
|
336
|
+
else
|
337
|
+
puts "This dimension value is a(n): #{dimension['DimensionValues']['DimensionValue'].class}"
|
338
|
+
end
|
339
|
+
@dimensions.push(@dimension)
|
340
|
+
else
|
341
|
+
puts 'There are no dimension values on this dimension!'
|
342
|
+
end
|
343
|
+
end
|
344
|
+
else
|
345
|
+
puts "This dimension is a(n): #{dimensions.class}"
|
346
|
+
end
|
347
|
+
else
|
348
|
+
puts 'There are no dimensions with this response!'
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
# builds the BUSINESS RULES hash
|
353
|
+
def build_business_rules
|
354
|
+
puts "BUSINESS RULES: #{@response['BusinessRulesResult']}"
|
355
|
+
|
356
|
+
# NOTE: needs to be looked at again. look at where the array is being pushed
|
357
|
+
@business_rules = []
|
358
|
+
unless @response['BusinessRulesResult'].nil?
|
359
|
+
if @response['BusinessRulesResult']['BusinessRules'].instance_of?(Hash)
|
360
|
+
@business_rule = EndecaXml::Rule.new(@response['BusinessRulesResult']['BusinessRules'])
|
361
|
+
@response['BusinessRulesResult']['BusinessRules'].each do |key, value|
|
362
|
+
@business_rule.properties_array.push(EndecaXml::Rule.new(value)) if key == 'properties'
|
363
|
+
if key == 'RecordSet'
|
364
|
+
@business_rule.records.push(EndecaXml::Record.new(value['Record'])) unless value.nil?
|
365
|
+
end
|
366
|
+
end
|
367
|
+
elsif @response['BusinessRulesResult']['BusinessRules'].instance_of?(Array)
|
368
|
+
@response['BusinessRulesResult']['BusinessRules']['BusinessRule'].each do |rule|
|
369
|
+
@business_rule = EndecaXml::Rule.new(rule)
|
370
|
+
rule.each do |key, value|
|
371
|
+
@business_rule.properties_array.push(EndecaXml::Rule.new(value)) if key == 'properties'
|
372
|
+
if key == 'RecordSet'
|
373
|
+
@business_rule.records.push(EndecaXml::Record.new(value['Record'])) unless value.nil?
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
else
|
378
|
+
puts "This busniess rule is a(n): #{@response['RecordsSet'].class}"
|
379
|
+
end
|
380
|
+
@business_rules.push(@business_rule)
|
381
|
+
else
|
382
|
+
puts 'There are no business rules with this response!'
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
# builds the SEARCH REPORTS hash
|
387
|
+
def build_search_reports
|
388
|
+
@search_reports = []
|
389
|
+
|
390
|
+
# puts "APPLIED FILTERS: #{@response['AppliedFilters']}"
|
391
|
+
applied_filters = @response['AppliedFilters']
|
392
|
+
unless applied_filters.nil?
|
393
|
+
|
394
|
+
# puts "SEARCH REPORTS: #{@response['AppliedFilters']['SearchReports']}"
|
395
|
+
search_reports = @response['AppliedFilters']['SearchReports']
|
396
|
+
unless search_reports.nil?
|
397
|
+
#do stuff
|
398
|
+
else
|
399
|
+
puts 'There are no search reports with this response!'
|
400
|
+
end
|
401
|
+
|
402
|
+
else
|
403
|
+
puts 'There were not applied filters with this response!'
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
# builds the SELECTED DIMENSION VALUE IDS hash
|
408
|
+
def build_selected_dimension_value_ids
|
409
|
+
@selected_dimension_value_ids = []
|
410
|
+
|
411
|
+
# puts "SELECTED DIMENSION VALUE IDS: #{@response['AppliedFilters']['SelectedDimensionValueIds']}"
|
412
|
+
selected_dimension_value_ids = @response['AppliedFilters']['SelectedDimensionValueIds']
|
413
|
+
unless selected_dimension_value_ids.nil?
|
414
|
+
|
415
|
+
if selected_dimension_value_ids.instance_of?(Hash)
|
416
|
+
selected_dimension_value_id = EndecaXml::DimensionValueId.new(selected_dimension_value_ids)
|
417
|
+
elsif selected_dimension_value_ids.instance_of?(Array)
|
418
|
+
selected_dimension_value_ids.each do |key, value|
|
419
|
+
selected_dimension_value_id = EndecaXml::DimensionValueId.new(value)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
@selected_dimension_value_ids.push(selected_dimension_value_id)
|
424
|
+
|
425
|
+
else
|
426
|
+
puts "There are no selected dimension value ids with this response!"
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: endeca_on_demand
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- sdomino
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-07-22 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: crackoid
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rspec
|
28
|
+
prerelease: false
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: "0"
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id002
|
37
|
+
description: EndecaOnDemand will take a query-string and construct an XML query that it then sends to a hosted Endeca On-Demand Cluster. It will then parse the response and expose an API for using the response data.
|
38
|
+
email:
|
39
|
+
- sdomino@pagodabox.com
|
40
|
+
executables: []
|
41
|
+
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files: []
|
45
|
+
|
46
|
+
files:
|
47
|
+
- .gitignore
|
48
|
+
- Gemfile
|
49
|
+
- LICENSE.txt
|
50
|
+
- README.rdoc
|
51
|
+
- Rakefile
|
52
|
+
- endeca_on_demand.gemspec
|
53
|
+
- lib/endeca_on_demand.rb
|
54
|
+
- lib/endeca_on_demand/crumb.rb
|
55
|
+
- lib/endeca_on_demand/dimension.rb
|
56
|
+
- lib/endeca_on_demand/dimension_value_id.rb
|
57
|
+
- lib/endeca_on_demand/record.rb
|
58
|
+
- lib/endeca_on_demand/rule.rb
|
59
|
+
- lib/endeca_on_demand/search_report.rb
|
60
|
+
- lib/endeca_on_demand/version.rb
|
61
|
+
homepage: http://github.com/sdomino/endeca_on_demand
|
62
|
+
licenses: []
|
63
|
+
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project: endeca_on_demand
|
84
|
+
rubygems_version: 1.7.2
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Formerly EndecaXml (endeca_xml), This gem provides an easy way for you to use the Thanx Media, Endeca On-Demand Web API
|
88
|
+
test_files: []
|
89
|
+
|