idol-search 0.5.0 → 0.6.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/VERSION +1 -1
- data/idol-search.gemspec +3 -1
- data/lib/abridged_results_parser.rb +76 -0
- data/lib/filters.rb +88 -0
- data/lib/idol-search.rb +9 -167
- data/test/test_idol-search.rb +12 -0
- metadata +4 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/idol-search.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "idol-search"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Shane Sherman"]
|
@@ -26,6 +26,8 @@ Gem::Specification.new do |s|
|
|
26
26
|
"VERSION",
|
27
27
|
"examples.rb",
|
28
28
|
"idol-search.gemspec",
|
29
|
+
"lib/abridged_results_parser.rb",
|
30
|
+
"lib/filters.rb",
|
29
31
|
"lib/hash_from_xml.rb",
|
30
32
|
"lib/idol-search.rb",
|
31
33
|
"test/helper.rb",
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Idol
|
2
|
+
|
3
|
+
class AbridgedResultsParser
|
4
|
+
attr_accessor :result, :parsed_result
|
5
|
+
def initialize(result)
|
6
|
+
@result = result
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse
|
10
|
+
fields = []
|
11
|
+
autoparsed_result = Hash.from_xml(@result)
|
12
|
+
xml = Nokogiri::XML(@result)
|
13
|
+
|
14
|
+
autn_ids = xml.xpath('//autn:abrid').first.content.split(",")
|
15
|
+
weights = xml.xpath('//autn:abrweight')[0].content.split(',').map{|w|w.to_i}
|
16
|
+
|
17
|
+
# parse out the field meta data
|
18
|
+
xml.xpath('//autn:abrfield').each do |field_data|
|
19
|
+
name = field_data.xpath('autn:abrname')[0].content
|
20
|
+
lengths = field_data.xpath('autn:abrlength')[0].content.split(',').map{|l| l.to_i }
|
21
|
+
values = field_data.xpath('autn:abrvalue')[0].content.strip
|
22
|
+
array_size_of_values = field_data.xpath('autn:abrnumber')[0].content.split(',').map{|n| n.to_i }
|
23
|
+
|
24
|
+
current_values_position = 0
|
25
|
+
parsed_values = []
|
26
|
+
|
27
|
+
# the abridged results store everything in a big long string with the lengths to
|
28
|
+
# split on in a different comma seperated string. so it's parse out the values based
|
29
|
+
# on the value length
|
30
|
+
lengths.each do |length|
|
31
|
+
parsed_values << values[current_values_position, length]
|
32
|
+
current_values_position += length
|
33
|
+
end
|
34
|
+
|
35
|
+
# if the value is an array there's some additional magic that needs to be done to get the right array value
|
36
|
+
final_values = []
|
37
|
+
index = 0
|
38
|
+
array_size_of_values.each do |array_size|
|
39
|
+
if array_size == 1
|
40
|
+
final_values << parsed_values[index]
|
41
|
+
elsif array_size > 1
|
42
|
+
final_values << parsed_values[index, array_size]
|
43
|
+
end
|
44
|
+
index += 1
|
45
|
+
end
|
46
|
+
|
47
|
+
fields << {:name => name, :values => final_values}
|
48
|
+
end
|
49
|
+
|
50
|
+
normalized_results = []
|
51
|
+
index = 0
|
52
|
+
|
53
|
+
# build a hash that mimics the hash from the unabridged normal results
|
54
|
+
autn_ids.each do |id|
|
55
|
+
result = {:id => id, :weight => weights[index], :content => {}}
|
56
|
+
fields.each do |field|
|
57
|
+
section, name = field[:name].split("/")
|
58
|
+
unless result[:content].has_key?(section)
|
59
|
+
result[:content][section] = {}
|
60
|
+
end
|
61
|
+
result[:content][section][name] = field[:values][index]
|
62
|
+
end
|
63
|
+
normalized_results << result
|
64
|
+
index += 1
|
65
|
+
end
|
66
|
+
|
67
|
+
response_data = autoparsed_result[:autnresponse][:responsedata]
|
68
|
+
response_data[:hit] = normalized_results
|
69
|
+
response_data.delete(:abrid)
|
70
|
+
response_data.delete(:abrweight)
|
71
|
+
response_data.delete(:abrfield)
|
72
|
+
@parsed_result = autoparsed_result
|
73
|
+
@parsed_result
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/filters.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
module Idol
|
2
|
+
module Conjunctions
|
3
|
+
AND = "AND"
|
4
|
+
OR = "OR"
|
5
|
+
NOT = "NOT"
|
6
|
+
BEFORE = "BEFORE"
|
7
|
+
AFTER = "AFTER"
|
8
|
+
end
|
9
|
+
|
10
|
+
module Filters
|
11
|
+
MATCH = "MATCH"
|
12
|
+
EQUAL = "EQUAL"
|
13
|
+
GREATER = "GREATER"
|
14
|
+
LESS = "LESS"
|
15
|
+
NRANGE = "NRANGE"
|
16
|
+
NOT_EQUAL = "NOTEQUAL"
|
17
|
+
WILD = "WILD"
|
18
|
+
|
19
|
+
MATCH_ALL = "MATCHALL"
|
20
|
+
EQUAL_ALL = "EQUALALL"
|
21
|
+
|
22
|
+
NOT_MATCH = "NOTMATCH"
|
23
|
+
NOT_STRING = "NOTSTRING"
|
24
|
+
NOT_WILD = "NOTWILD"
|
25
|
+
|
26
|
+
STRING = "STRING"
|
27
|
+
STRING_ALL = "STRINGALL"
|
28
|
+
SUBSTRING = "SUBSTRING"
|
29
|
+
|
30
|
+
TERM = "TERM"
|
31
|
+
TERM_ALL = "TERMALL"
|
32
|
+
TERM_EXACT = "TERMEXACT"
|
33
|
+
TERM_EXACT_ALL = "TERMEXACTALL"
|
34
|
+
TERM_EXACT_PHRASE = "TERMEXACTPHRASE"
|
35
|
+
TERM_PHRASE = "TERMPHRASE"
|
36
|
+
end
|
37
|
+
|
38
|
+
class FieldTextFilter
|
39
|
+
attr_accessor :fields, :specifier, :values
|
40
|
+
def initialize(fields, specifier, values)
|
41
|
+
@fields = fields.is_a?(Array) ? fields : [fields]
|
42
|
+
@specifier = specifier
|
43
|
+
@values = values.is_a?(Array) ? values : [values]
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_idol_syntax
|
47
|
+
values_string = @values.map{|v| escape(v) }.join(",")
|
48
|
+
"#{specifier}{#{values_string}}:#{fields.join(':')}"
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def escape(value)
|
53
|
+
value.gsub("&", "%26").gsub("\\", "%5C").gsub("%", "%25").gsub("{", "%257B").gsub("{", "%257D")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class FieldTextFilterCollection
|
58
|
+
include Enumerable
|
59
|
+
def initialize
|
60
|
+
@filters = []
|
61
|
+
@conjunctions = []
|
62
|
+
end
|
63
|
+
|
64
|
+
def <<(filter)
|
65
|
+
@filters << filter
|
66
|
+
end
|
67
|
+
|
68
|
+
def add(filter, conjunction=Idol::Conjunctions::AND)
|
69
|
+
self << filter
|
70
|
+
@conjunctions << conjunction
|
71
|
+
return self
|
72
|
+
end
|
73
|
+
|
74
|
+
def each(&block)
|
75
|
+
@filters.each(&block)
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_idol_syntax
|
79
|
+
idol_syntax = []
|
80
|
+
@filters.each_with_index do |filter, index|
|
81
|
+
idol_syntax << @conjunctions[index] unless index == 0
|
82
|
+
idol_syntax << filter.to_idol_syntax
|
83
|
+
end
|
84
|
+
idol_syntax.join(" ").strip
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
data/lib/idol-search.rb
CHANGED
@@ -1,42 +1,9 @@
|
|
1
1
|
require 'curb'
|
2
2
|
require_relative 'hash_from_xml'
|
3
|
-
|
4
|
-
|
5
|
-
module Conjunctions
|
6
|
-
AND = "AND"
|
7
|
-
OR = "OR"
|
8
|
-
NOT = "NOT"
|
9
|
-
BEFORE = "BEFORE"
|
10
|
-
AFTER = "AFTER"
|
11
|
-
end
|
12
|
-
|
13
|
-
module Filters
|
14
|
-
MATCH = "MATCH"
|
15
|
-
EQUAL = "EQUAL"
|
16
|
-
GREATER = "GREATER"
|
17
|
-
LESS = "LESS"
|
18
|
-
NRANGE = "NRANGE"
|
19
|
-
NOT_EQUAL = "NOTEQUAL"
|
20
|
-
WILD = "WILD"
|
21
|
-
|
22
|
-
MATCH_ALL = "MATCHALL"
|
23
|
-
EQUAL_ALL = "EQUALALL"
|
24
|
-
|
25
|
-
NOT_MATCH = "NOTMATCH"
|
26
|
-
NOT_STRING = "NOTSTRING"
|
27
|
-
NOT_WILD = "NOTWILD"
|
28
|
-
|
29
|
-
STRING = "STRING"
|
30
|
-
STRING_ALL = "STRINGALL"
|
31
|
-
SUBSTRING = "SUBSTRING"
|
3
|
+
require_relative 'abridged_results_parser'
|
4
|
+
require_relative 'filters'
|
32
5
|
|
33
|
-
|
34
|
-
TERM_ALL = "TERMALL"
|
35
|
-
TERM_EXACT = "TERMEXACT"
|
36
|
-
TERM_EXACT_ALL = "TERMEXACTALL"
|
37
|
-
TERM_EXACT_PHRASE = "TERMEXACTPHRASE"
|
38
|
-
TERM_PHRASE = "TERMPHRASE"
|
39
|
-
end
|
6
|
+
module Idol
|
40
7
|
|
41
8
|
module OptionalParams
|
42
9
|
def has_optional_params(*params)
|
@@ -44,18 +11,13 @@ module Idol
|
|
44
11
|
|
45
12
|
# write the value to params
|
46
13
|
define_method :"#{opt_param}" do |value|
|
47
|
-
|
48
|
-
self.class.send(:attr_accessor, opt_param)
|
49
|
-
@parameters[opt_param.gsub("_", "")] = value
|
14
|
+
@parameters[opt_param.to_sym] = value
|
50
15
|
return self
|
51
16
|
end
|
52
|
-
|
53
17
|
end
|
54
18
|
end
|
55
19
|
end
|
56
20
|
|
57
|
-
|
58
|
-
|
59
21
|
module BasicIdolFunctionality
|
60
22
|
attr_accessor :url, :filters, :parameters, :raw_results
|
61
23
|
attr_reader :action
|
@@ -67,6 +29,10 @@ module Idol
|
|
67
29
|
@filters = FieldTextFilterCollection.new
|
68
30
|
end
|
69
31
|
|
32
|
+
def to_hash
|
33
|
+
@parameters
|
34
|
+
end
|
35
|
+
|
70
36
|
def filters
|
71
37
|
@filters
|
72
38
|
end
|
@@ -103,86 +69,12 @@ module Idol
|
|
103
69
|
end
|
104
70
|
|
105
71
|
@parameters.each do |name, values|
|
106
|
-
post_fields << Curl::PostField.content(name, values)
|
72
|
+
post_fields << Curl::PostField.content(name.gsub("_", ""), values)
|
107
73
|
end
|
108
74
|
post_fields
|
109
75
|
end
|
110
76
|
end
|
111
77
|
|
112
|
-
class AbridgedResultsParser
|
113
|
-
attr_accessor :result, :parsed_result
|
114
|
-
def initialize(result)
|
115
|
-
@result = result
|
116
|
-
end
|
117
|
-
|
118
|
-
def parse
|
119
|
-
fields = []
|
120
|
-
autoparsed_result = Hash.from_xml(@result)
|
121
|
-
xml = Nokogiri::XML(@result)
|
122
|
-
|
123
|
-
autn_ids = xml.xpath('//autn:abrid').first.content.split(",")
|
124
|
-
weights = xml.xpath('//autn:abrweight')[0].content.split(',').map{|w|w.to_i}
|
125
|
-
|
126
|
-
# parse out the field meta data
|
127
|
-
xml.xpath('//autn:abrfield').each do |field_data|
|
128
|
-
name = field_data.xpath('autn:abrname')[0].content
|
129
|
-
lengths = field_data.xpath('autn:abrlength')[0].content.split(',').map{|l| l.to_i }
|
130
|
-
values = field_data.xpath('autn:abrvalue')[0].content.strip
|
131
|
-
array_size_of_values = field_data.xpath('autn:abrnumber')[0].content.split(',').map{|n| n.to_i }
|
132
|
-
|
133
|
-
current_values_position = 0
|
134
|
-
parsed_values = []
|
135
|
-
|
136
|
-
# the abridged results store everything in a big long string with the lengths to
|
137
|
-
# split on in a different comma seperated string. so it's parse out the values based
|
138
|
-
# on the value length
|
139
|
-
lengths.each do |length|
|
140
|
-
parsed_values << values[current_values_position, length]
|
141
|
-
current_values_position += length
|
142
|
-
end
|
143
|
-
|
144
|
-
# if the value is an array there's some additional magic that needs to be done to get the right array value
|
145
|
-
final_values = []
|
146
|
-
index = 0
|
147
|
-
array_size_of_values.each do |array_size|
|
148
|
-
if array_size == 1
|
149
|
-
final_values << parsed_values[index]
|
150
|
-
elsif array_size > 1
|
151
|
-
final_values << parsed_values[index, array_size]
|
152
|
-
end
|
153
|
-
index += 1
|
154
|
-
end
|
155
|
-
|
156
|
-
fields << {:name => name, :values => final_values}
|
157
|
-
end
|
158
|
-
|
159
|
-
normalized_results = []
|
160
|
-
index = 0
|
161
|
-
|
162
|
-
# build a hash that mimics the hash from the unabridged normal results
|
163
|
-
autn_ids.each do |id|
|
164
|
-
result = {:id => id, :weight => weights[index], :content => {}}
|
165
|
-
fields.each do |field|
|
166
|
-
section, name = field[:name].split("/")
|
167
|
-
unless result[:content].has_key?(section)
|
168
|
-
result[:content][section] = {}
|
169
|
-
end
|
170
|
-
result[:content][section][name] = field[:values][index]
|
171
|
-
end
|
172
|
-
normalized_results << result
|
173
|
-
index += 1
|
174
|
-
end
|
175
|
-
|
176
|
-
response_data = autoparsed_result[:autnresponse][:responsedata]
|
177
|
-
response_data[:hit] = normalized_results
|
178
|
-
response_data.delete(:abrid)
|
179
|
-
response_data.delete(:abrweight)
|
180
|
-
response_data.delete(:abrfield)
|
181
|
-
@parsed_result = autoparsed_result
|
182
|
-
@parsed_result
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
78
|
class Query
|
187
79
|
extend OptionalParams
|
188
80
|
include BasicIdolFunctionality
|
@@ -206,55 +98,5 @@ module Idol
|
|
206
98
|
end
|
207
99
|
end
|
208
100
|
|
209
|
-
class FieldTextFilter
|
210
|
-
attr_accessor :fields, :specifier, :values
|
211
|
-
def initialize(fields, specifier, values)
|
212
|
-
@fields = fields.is_a?(Array) ? fields : [fields]
|
213
|
-
@specifier = specifier
|
214
|
-
@values = values.is_a?(Array) ? values : [values]
|
215
|
-
end
|
216
|
-
|
217
|
-
def to_idol_syntax
|
218
|
-
values_string = @values.map{|v| escape(v) }.join(",")
|
219
|
-
"#{specifier}{#{values_string}}:#{fields.join(':')}"
|
220
|
-
end
|
221
|
-
|
222
|
-
private
|
223
|
-
def escape(value)
|
224
|
-
value.gsub("&", "%26").gsub("\\", "%5C").gsub("%", "%25").gsub("{", "%257B").gsub("{", "%257D")
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
class FieldTextFilterCollection
|
229
|
-
include Enumerable
|
230
|
-
def initialize
|
231
|
-
@filters = []
|
232
|
-
@conjunctions = []
|
233
|
-
end
|
234
|
-
|
235
|
-
def <<(filter)
|
236
|
-
@filters << filter
|
237
|
-
end
|
238
|
-
|
239
|
-
def add(filter, conjunction=Idol::Conjunctions::AND)
|
240
|
-
self << filter
|
241
|
-
@conjunctions << conjunction
|
242
|
-
return self
|
243
|
-
end
|
244
|
-
|
245
|
-
def each(&block)
|
246
|
-
@filters.each(&block)
|
247
|
-
end
|
248
|
-
|
249
|
-
def to_idol_syntax
|
250
|
-
idol_syntax = []
|
251
|
-
@filters.each_with_index do |filter, index|
|
252
|
-
idol_syntax << @conjunctions[index] unless index == 0
|
253
|
-
idol_syntax << filter.to_idol_syntax
|
254
|
-
end
|
255
|
-
idol_syntax.join(" ").strip
|
256
|
-
end
|
257
|
-
|
258
|
-
end
|
259
101
|
|
260
102
|
end
|
data/test/test_idol-search.rb
CHANGED
@@ -125,8 +125,20 @@ END_DATA
|
|
125
125
|
should "parse the data correctly" do
|
126
126
|
assert_equal 6, @parsed_result[:autnresponse][:responsedata][:hit].count
|
127
127
|
end
|
128
|
+
end
|
128
129
|
|
130
|
+
context "a idol query with various options set" do
|
131
|
+
setup do
|
132
|
+
@query = Idol::Query.new("http://autonomy.moxiesoft.com")
|
133
|
+
@query.text("test").print_fields("id,summary").combine("simple").max_results(500)
|
134
|
+
end
|
129
135
|
|
136
|
+
should "properly set the options" do
|
137
|
+
assert_equal "test", @query.to_hash[:text]
|
138
|
+
assert_equal "id,summary", @query.to_hash[:print_fields]
|
139
|
+
assert_equal "simple", @query.to_hash[:combine]
|
140
|
+
assert_equal 500, @query.to_hash[:max_results]
|
141
|
+
end
|
130
142
|
end
|
131
143
|
|
132
144
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: idol-search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -140,6 +140,8 @@ files:
|
|
140
140
|
- VERSION
|
141
141
|
- examples.rb
|
142
142
|
- idol-search.gemspec
|
143
|
+
- lib/abridged_results_parser.rb
|
144
|
+
- lib/filters.rb
|
143
145
|
- lib/hash_from_xml.rb
|
144
146
|
- lib/idol-search.rb
|
145
147
|
- test/helper.rb
|
@@ -159,7 +161,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
159
161
|
version: '0'
|
160
162
|
segments:
|
161
163
|
- 0
|
162
|
-
hash: -
|
164
|
+
hash: -2690028528026669019
|
163
165
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
166
|
none: false
|
165
167
|
requirements:
|