picky 4.10.0 → 4.11.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/lib/picky/backends/memory/json.rb +6 -3
- data/lib/picky/categories.rb +12 -0
- data/lib/picky/categories_indexed.rb +3 -1
- data/lib/picky/extensions/array.rb +1 -11
- data/lib/picky/extensions/class.rb +5 -3
- data/lib/picky/extensions/object.rb +13 -1
- data/lib/picky/generators/similarity/phonetic.rb +0 -2
- data/lib/picky/index.rb +33 -0
- data/lib/picky/index_facets.rb +9 -5
- data/lib/picky/loader.rb +4 -7
- data/lib/picky/pool.rb +10 -7
- data/lib/picky/qualifier_mapper.rb +51 -0
- data/lib/picky/query/boosts.rb +2 -2
- data/lib/picky/query/indexes.rb +1 -29
- data/lib/picky/query/token.rb +7 -3
- data/lib/picky/query/tokens.rb +0 -6
- data/lib/picky/search_facets.rb +45 -9
- data/lib/picky/sinatra.rb +2 -0
- data/lib/picky/tokenizer.rb +19 -11
- data/lib/picky.rb +3 -1
- data/spec/functional/facets_spec.rb +9 -13
- data/spec/functional/multi_index_qualifier_spec.rb +30 -0
- data/spec/functional/only_spec.rb +34 -32
- data/spec/functional/pool_spec.rb +82 -0
- data/spec/functional/remap_qualifiers_spec.rb +1 -9
- data/spec/lib/categories_indexed_spec.rb +2 -2
- data/spec/lib/extensions/array_spec.rb +19 -19
- data/spec/lib/extensions/object_spec.rb +14 -11
- data/spec/lib/extensions/symbol_spec.rb +1 -1
- data/spec/lib/generators/similarity/phonetic_spec.rb +14 -7
- data/spec/lib/picky_spec.rb +1 -1
- data/spec/lib/pool_spec.rb +17 -17
- data/spec/lib/{query/qualifier_category_mapper_spec.rb → qualifier_mapper_spec.rb} +8 -8
- data/spec/lib/query/token_spec.rb +17 -12
- data/spec/lib/rack/harakiri_spec.rb +5 -0
- data/spec/lib/tokenizer_spec.rb +44 -3
- metadata +11 -8
- data/lib/picky/migrations/from_30_to_31.rb +0 -61
- data/lib/picky/query/qualifier_category_mapper.rb +0 -61
@@ -33,12 +33,15 @@ module Picky
|
|
33
33
|
|
34
34
|
# Dump JSON into the cache file.
|
35
35
|
#
|
36
|
-
# TODO
|
37
|
-
# MultiJson.encode(object, out_file)
|
36
|
+
# TODO Add IO option:
|
37
|
+
# MultiJson.encode(object, io: out_file)
|
38
38
|
#
|
39
39
|
def dump_json internal
|
40
40
|
::File.open(cache_path, 'w') do |out_file|
|
41
|
-
#
|
41
|
+
# If using Yajl, this will stream write to out_file.
|
42
|
+
# Note: But it fails on oj.
|
43
|
+
#
|
44
|
+
# MultiJson.dump internal, [out_file]
|
42
45
|
out_file.write MultiJson.encode internal
|
43
46
|
end
|
44
47
|
end
|
data/lib/picky/categories.rb
CHANGED
@@ -29,10 +29,22 @@ module Picky
|
|
29
29
|
@categories = []
|
30
30
|
@category_hash = {}
|
31
31
|
end
|
32
|
+
|
33
|
+
# Updates the qualifier ("qualifier:searchterm") mapping.
|
34
|
+
#
|
35
|
+
# Example:
|
36
|
+
# You dynamically add a new category to an index.
|
37
|
+
# To add the qualifiers to a search, you call this
|
38
|
+
# method.
|
39
|
+
#
|
40
|
+
def mapper
|
41
|
+
@mapper ||= QualifierMapper.new self
|
42
|
+
end
|
32
43
|
|
33
44
|
# Add the given category to the list of categories.
|
34
45
|
#
|
35
46
|
def << category
|
47
|
+
@mapper = nil # TODO Move. (Resets category mapping)
|
36
48
|
categories << category
|
37
49
|
category_hash[category.name] = category
|
38
50
|
end
|
@@ -61,8 +61,10 @@ module Picky
|
|
61
61
|
#
|
62
62
|
# Note: Once I thought this was called too often. But it is not (18.01.2011).
|
63
63
|
#
|
64
|
+
# TODO Called too often?
|
65
|
+
#
|
64
66
|
def possible_categories token
|
65
|
-
token.predefined_categories || categories
|
67
|
+
token.predefined_categories(mapper) || categories
|
66
68
|
end
|
67
69
|
|
68
70
|
end
|
@@ -2,21 +2,11 @@
|
|
2
2
|
#
|
3
3
|
class Array
|
4
4
|
|
5
|
-
# Cluster-uniqs equal neighborly elements.
|
6
|
-
#
|
7
|
-
# Returns a copy.
|
8
|
-
#
|
9
|
-
def clustered_uniq
|
10
|
-
self.inject([]) do |result, element|
|
11
|
-
result << element if element != result.last
|
12
|
-
result
|
13
|
-
end
|
14
|
-
end
|
15
5
|
# Around 10% faster than the above.
|
16
6
|
#
|
17
7
|
# Returns a copy.
|
18
8
|
#
|
19
|
-
def
|
9
|
+
def clustered_uniq
|
20
10
|
result = []
|
21
11
|
self.inject(nil) do |last, element|
|
22
12
|
if last == element
|
@@ -2,9 +2,11 @@
|
|
2
2
|
#
|
3
3
|
class Class
|
4
4
|
|
5
|
-
def instance_delegate *
|
6
|
-
|
7
|
-
module_eval(
|
5
|
+
def instance_delegate *method_names
|
6
|
+
method_names.each do |method_name|
|
7
|
+
module_eval(<<-DELEGATION, "(__DELEGATION__)", 1)
|
8
|
+
def self.#{method_name}(*args, &block)\n self.instance.#{method_name}(*args, &block)\nend
|
9
|
+
DELEGATION
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
@@ -9,6 +9,8 @@ class Object
|
|
9
9
|
|
10
10
|
# Just outputs the given text to the logger.
|
11
11
|
#
|
12
|
+
# Note: stubbed in spec_helper.rb
|
13
|
+
#
|
12
14
|
def exclaim text
|
13
15
|
Picky.logger.info text
|
14
16
|
Picky.logger.flush
|
@@ -17,7 +19,17 @@ class Object
|
|
17
19
|
# Puts a text that informs the user of a missing gem.
|
18
20
|
#
|
19
21
|
def warn_gem_missing gem_name, message
|
20
|
-
Picky.logger.warn
|
22
|
+
Picky.logger.warn <<-WARNING
|
23
|
+
Warning: #{gem_name} gem missing!
|
24
|
+
To use #{message}, you need to:
|
25
|
+
1. Add the following line to Gemfile:
|
26
|
+
gem '#{gem_name}'
|
27
|
+
or
|
28
|
+
require '#{gem_name}'
|
29
|
+
for example at the top of your app.rb file.
|
30
|
+
2. Then, run:
|
31
|
+
bundle update
|
32
|
+
WARNING
|
21
33
|
end
|
22
34
|
|
23
35
|
# Indents each line by <tt>amount=2</tt> spaces.
|
data/lib/picky/index.rb
CHANGED
@@ -140,6 +140,23 @@ module Picky
|
|
140
140
|
@backend ||= Backends::Memory.new
|
141
141
|
end
|
142
142
|
end
|
143
|
+
|
144
|
+
# Ignore the categories with these qualifiers.
|
145
|
+
#
|
146
|
+
# Example:
|
147
|
+
# search = Search.new(index1, index2, index3) do
|
148
|
+
# ignore :name, :first_name
|
149
|
+
# end
|
150
|
+
#
|
151
|
+
# Cleans up / optimizes after being called.
|
152
|
+
#
|
153
|
+
# TODO This needs to move to the index.
|
154
|
+
#
|
155
|
+
def ignore *qualifiers
|
156
|
+
@ignored_categories ||= []
|
157
|
+
@ignored_categories += qualifiers.map { |qualifier| @mapper.map qualifier }.compact
|
158
|
+
@ignored_categories.uniq!
|
159
|
+
end
|
143
160
|
|
144
161
|
# SYMBOLS.
|
145
162
|
#
|
@@ -179,6 +196,22 @@ module Picky
|
|
179
196
|
new_category
|
180
197
|
end
|
181
198
|
|
199
|
+
# Restrict categories to the given ones.
|
200
|
+
#
|
201
|
+
# Functionally equivalent as if indexes didn't
|
202
|
+
# have the categories at all.
|
203
|
+
#
|
204
|
+
# Note: Probably only makes sense when an index
|
205
|
+
# is used in multiple searches. If not, why even
|
206
|
+
# have the categories?
|
207
|
+
#
|
208
|
+
# TODO Redesign.
|
209
|
+
#
|
210
|
+
def only *qualifiers
|
211
|
+
raise "Sorry, Picky::Search#only has been removed in version."
|
212
|
+
# @mapper.restrict_to *qualifiers
|
213
|
+
end
|
214
|
+
|
182
215
|
# The directory used by this index.
|
183
216
|
#
|
184
217
|
# Note: Used @directory ||=, but needs to be dynamic.
|
data/lib/picky/index_facets.rb
CHANGED
@@ -15,12 +15,16 @@ module Picky
|
|
15
15
|
text_ids = self[category_identifier].exact.inverted
|
16
16
|
no_counts = options[:counts] == false
|
17
17
|
minimal_counts = options[:at_least]
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
|
19
|
+
if no_counts
|
20
|
+
text_ids.inject([]) do |result, (text, ids)|
|
21
|
+
next result if minimal_counts && ids.size < minimal_counts
|
22
22
|
result << text
|
23
|
-
|
23
|
+
end
|
24
|
+
else
|
25
|
+
text_ids.inject({}) do |result, (text, ids)|
|
26
|
+
size = ids.size
|
27
|
+
next result if minimal_counts && size < minimal_counts
|
24
28
|
result[text] = size; result
|
25
29
|
end
|
26
30
|
end
|
data/lib/picky/loader.rb
CHANGED
@@ -170,8 +170,6 @@ module Picky
|
|
170
170
|
load_relative 'query/allocation',
|
171
171
|
'query/allocations'
|
172
172
|
|
173
|
-
load_relative 'query/qualifier_category_mapper'
|
174
|
-
|
175
173
|
load_relative 'query/boosts'
|
176
174
|
|
177
175
|
load_relative 'query/indexes',
|
@@ -219,6 +217,8 @@ module Picky
|
|
219
217
|
end
|
220
218
|
|
221
219
|
def load_inner_api
|
220
|
+
load_relative 'qualifier_mapper'
|
221
|
+
|
222
222
|
load_relative 'category',
|
223
223
|
'category_indexed',
|
224
224
|
'category_indexing',
|
@@ -235,7 +235,7 @@ module Picky
|
|
235
235
|
'indexes_indexed',
|
236
236
|
'indexes_indexing',
|
237
237
|
'indexes_convenience'
|
238
|
-
|
238
|
+
|
239
239
|
load_relative 'index',
|
240
240
|
'index_indexed',
|
241
241
|
'index_indexing',
|
@@ -261,14 +261,12 @@ module Picky
|
|
261
261
|
|
262
262
|
# Loads the user interface parts.
|
263
263
|
#
|
264
|
-
# TODO Move tokenizer etc.?
|
265
|
-
#
|
266
264
|
def load_user_interface
|
267
265
|
load_api
|
268
266
|
load_logging
|
269
267
|
load_relative 'source'
|
270
268
|
load_relative 'tokenizer'
|
271
|
-
load_relative 'rack/harakiri'
|
269
|
+
# load_relative 'rack/harakiri' # Needs to be explicitly loaded/required.
|
272
270
|
load_relative 'character_substituters/west_european'
|
273
271
|
load_generators
|
274
272
|
load_inner_api
|
@@ -276,7 +274,6 @@ module Picky
|
|
276
274
|
load_search
|
277
275
|
load_interfaces
|
278
276
|
load_relative 'scheduler'
|
279
|
-
load_relative 'migrations/from_30_to_31' # TODO Remove.
|
280
277
|
end
|
281
278
|
|
282
279
|
# Loads the framework.
|
data/lib/picky/pool.rb
CHANGED
@@ -12,7 +12,8 @@ module Picky
|
|
12
12
|
# Note: If you need to run two consecutive queries,
|
13
13
|
# this can't be used.
|
14
14
|
#
|
15
|
-
#
|
15
|
+
# Note: You need to call Picky::Pool.release_all after each query
|
16
|
+
# (or after a few queries).
|
16
17
|
#
|
17
18
|
def install
|
18
19
|
Query::Token.extend self
|
@@ -76,19 +77,21 @@ module Picky
|
|
76
77
|
# (And removes it from the used pool)
|
77
78
|
#
|
78
79
|
def release instance
|
79
|
-
|
80
|
+
@__free__ << instance
|
80
81
|
|
81
|
-
|
82
|
-
|
83
|
-
|
82
|
+
# Note: This is relatively fast as there are often only
|
83
|
+
# few instances in the used pool.
|
84
|
+
#
|
85
|
+
@__used__.delete instance
|
84
86
|
end
|
85
87
|
|
86
|
-
# After you have called release all, you can't
|
88
|
+
# After you have called release all, you can't externally
|
87
89
|
# use any reference that has formerly been obtained
|
88
90
|
# anymore.
|
89
91
|
#
|
90
92
|
def release_all
|
91
|
-
@__free__
|
93
|
+
@__used__.each { |used| @__free__ << used } # +0 Array per release_all
|
94
|
+
# @__used__ += @__free__ # +1 Array per release_all
|
92
95
|
@__used__.clear
|
93
96
|
end
|
94
97
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Picky
|
2
|
+
|
3
|
+
# Collection class for qualifiers.
|
4
|
+
#
|
5
|
+
class QualifierMapper
|
6
|
+
|
7
|
+
attr_reader :mapping
|
8
|
+
|
9
|
+
#
|
10
|
+
#
|
11
|
+
def initialize categories
|
12
|
+
@mapping = {}
|
13
|
+
categories.each { |category| add category }
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
#
|
18
|
+
def add category
|
19
|
+
category.qualifiers.each do |qualifier|
|
20
|
+
sym_qualifier = qualifier.intern
|
21
|
+
Picky.logger.warn %Q{Warning: Qualifier "#{qualifier}" already mapped to category #{mapping[sym_qualifier].identifier} (ambiguous qualifier mapping).} if mapping.has_key? sym_qualifier
|
22
|
+
mapping[sym_qualifier] = category
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Normalizes the given qualifier.
|
27
|
+
#
|
28
|
+
# Returns nil if it is not allowed, the normalized qualifier if it is.
|
29
|
+
#
|
30
|
+
def map qualifier
|
31
|
+
return nil if qualifier.empty?
|
32
|
+
|
33
|
+
mapping[qualifier.intern]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Restricts the given categories.
|
37
|
+
#
|
38
|
+
def restrict user_qualified
|
39
|
+
if @restricted
|
40
|
+
user_qualified ? @restricted & user_qualified : @restricted
|
41
|
+
else
|
42
|
+
user_qualified
|
43
|
+
end
|
44
|
+
end
|
45
|
+
def restrict_to *qualifiers
|
46
|
+
@restricted = qualifiers.map { |qualifier| map qualifier }.compact
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/lib/picky/query/boosts.rb
CHANGED
@@ -44,11 +44,11 @@ module Picky
|
|
44
44
|
# [:name, :height, :color] returns +3, but
|
45
45
|
# [:name, :height, :street] returns -1.
|
46
46
|
#
|
47
|
-
# Note: Use Array#
|
47
|
+
# Note: Use Array#clustered_uniq to make
|
48
48
|
# [:a, :a, :b, :a] => [:a, :b, :a]
|
49
49
|
#
|
50
50
|
def boost_for_categories names
|
51
|
-
@boosts[names.
|
51
|
+
@boosts[names.clustered_uniq] || 0
|
52
52
|
end
|
53
53
|
|
54
54
|
# API.
|
data/lib/picky/query/indexes.rb
CHANGED
@@ -29,19 +29,6 @@ module Picky
|
|
29
29
|
IndexesCheck.check_backends indexes
|
30
30
|
|
31
31
|
@indexes = indexes
|
32
|
-
|
33
|
-
remap_qualifiers
|
34
|
-
end
|
35
|
-
|
36
|
-
# Updates the qualifier ("qualifier:searchterm") mapping.
|
37
|
-
#
|
38
|
-
# Example:
|
39
|
-
# You dynamically add a new category to an index.
|
40
|
-
# To add the qualifiers to a search, you call this
|
41
|
-
# method.
|
42
|
-
#
|
43
|
-
def remap_qualifiers
|
44
|
-
@mapper = QualifierCategoryMapper.new @indexes # TODO Move into search?
|
45
32
|
end
|
46
33
|
|
47
34
|
# Ignore the categories with these qualifiers.
|
@@ -51,26 +38,13 @@ module Picky
|
|
51
38
|
# ignore :name, :first_name
|
52
39
|
# end
|
53
40
|
#
|
54
|
-
# Cleans up / optimizes after being called.
|
41
|
+
# Note: Cleans up / optimizes after being called.
|
55
42
|
#
|
56
43
|
def ignore *qualifiers
|
57
44
|
@ignored_categories ||= []
|
58
45
|
@ignored_categories += qualifiers.map { |qualifier| @mapper.map qualifier }.compact
|
59
46
|
@ignored_categories.uniq!
|
60
47
|
end
|
61
|
-
|
62
|
-
# Restrict categories to the given ones.
|
63
|
-
#
|
64
|
-
# Functionally equivalent as if indexes didn't
|
65
|
-
# have the categories at all.
|
66
|
-
#
|
67
|
-
# Note: Probably only makes sense when an index
|
68
|
-
# is used in multiple searches. If not, why even
|
69
|
-
# have the categories?
|
70
|
-
#
|
71
|
-
def only *qualifiers
|
72
|
-
@mapper.restrict_to *qualifiers
|
73
|
-
end
|
74
48
|
|
75
49
|
# Returns a number of prepared (sorted, reduced etc.) allocations for the given tokens.
|
76
50
|
#
|
@@ -105,8 +79,6 @@ module Picky
|
|
105
79
|
# Returns a number of possible allocations for the given tokens.
|
106
80
|
#
|
107
81
|
def allocations_for tokens
|
108
|
-
tokens.categorize @mapper
|
109
|
-
|
110
82
|
Allocations.new allocations_ary_for(tokens)
|
111
83
|
end
|
112
84
|
def allocations_ary_for tokens
|
data/lib/picky/query/token.rb
CHANGED
@@ -13,7 +13,7 @@ module Picky
|
|
13
13
|
|
14
14
|
attr_reader :text, :original
|
15
15
|
attr_writer :similar
|
16
|
-
|
16
|
+
attr_writer :predefined_categories
|
17
17
|
|
18
18
|
delegate :blank?, :to => :@text
|
19
19
|
|
@@ -22,6 +22,8 @@ module Picky
|
|
22
22
|
# Note:
|
23
23
|
# Use this if you do not want a normalized token.
|
24
24
|
#
|
25
|
+
# TODO Throw away @predefined_categories?
|
26
|
+
#
|
25
27
|
def initialize text, original = nil, categories = nil
|
26
28
|
@text = text
|
27
29
|
@original = original
|
@@ -59,8 +61,10 @@ module Picky
|
|
59
61
|
# Note: If this is not done, there is no mapping.
|
60
62
|
# Note: predefined is an Array of mapped categories.
|
61
63
|
#
|
62
|
-
|
63
|
-
|
64
|
+
# TODO Do we really need to set the predefined categories on the token?
|
65
|
+
#
|
66
|
+
def predefined_categories mapper
|
67
|
+
@predefined_categories || extract_predefined(mapper)
|
64
68
|
end
|
65
69
|
def extract_predefined mapper
|
66
70
|
user_qualified = categorize_with mapper, @qualifiers
|
data/lib/picky/query/tokens.rb
CHANGED
data/lib/picky/search_facets.rb
CHANGED
@@ -16,6 +16,8 @@ module Picky
|
|
16
16
|
# search.facets :name, filter: 'surname:peter', more_than: 0
|
17
17
|
#
|
18
18
|
def facets category_identifier, options = {}
|
19
|
+
# TODO Make it work. How should it work with multiple indexes?
|
20
|
+
#
|
19
21
|
raise "#{__method__} cannot be used on searches with more than 1 index yet. Sorry!" if indexes.size > 1
|
20
22
|
index = indexes.first
|
21
23
|
|
@@ -27,9 +29,21 @@ module Picky
|
|
27
29
|
#
|
28
30
|
return counts unless filter_query = options[:filter]
|
29
31
|
|
32
|
+
# Pre-tokenize query token category.
|
33
|
+
#
|
34
|
+
predefined_categories = [index[category_identifier]]
|
35
|
+
|
36
|
+
# Pre-tokenize key token – replace text below.
|
37
|
+
# Note: The original is not important.
|
38
|
+
#
|
39
|
+
# TODO Don't use predefined.
|
40
|
+
#
|
41
|
+
key_token = Query::Token.new '', nil, predefined_categories
|
42
|
+
|
30
43
|
# Pre-tokenize filter for reuse.
|
31
44
|
#
|
32
|
-
|
45
|
+
tokenized_filter_query = tokenized filter_query, false
|
46
|
+
tokenized_filter_query.tokens.push key_token
|
33
47
|
|
34
48
|
# Extract options.
|
35
49
|
#
|
@@ -38,15 +52,37 @@ module Picky
|
|
38
52
|
|
39
53
|
# Get actual counts.
|
40
54
|
#
|
41
|
-
|
42
|
-
|
43
|
-
|
55
|
+
if no_counts
|
56
|
+
facets_without_counts counts, minimal_counts, tokenized_filter_query, key_token.text
|
57
|
+
else
|
58
|
+
facets_with_counts counts, minimal_counts, tokenized_filter_query, key_token.text
|
59
|
+
end
|
60
|
+
end
|
61
|
+
def facets_without_counts counts, minimal_counts, tokenized_filter_query, last_token_text
|
62
|
+
counts.inject([]) do |result, (key, _)|
|
63
|
+
# Replace only the key token text because that
|
64
|
+
# is the only information that changes in between
|
65
|
+
# queries.
|
66
|
+
#
|
67
|
+
last_token_text.replace key
|
68
|
+
total = search_with(tokenized_filter_query, 0, 0).total
|
69
|
+
|
70
|
+
next result unless total >= minimal_counts
|
71
|
+
result << key
|
72
|
+
end
|
73
|
+
end
|
74
|
+
def facets_with_counts counts, minimal_counts, tokenized_filter_query, last_token_text
|
75
|
+
counts.inject({}) do |result, (key, _)|
|
76
|
+
# Replace only the key token text because that
|
77
|
+
# is the only information that changes in between
|
78
|
+
# queries.
|
79
|
+
#
|
80
|
+
last_token_text.replace key
|
81
|
+
total = search_with(tokenized_filter_query, 0, 0).total
|
82
|
+
|
44
83
|
next result unless total >= minimal_counts
|
45
|
-
|
46
|
-
|
47
|
-
else
|
48
|
-
result[key] = total; result
|
49
|
-
end
|
84
|
+
result[key] = total
|
85
|
+
result
|
50
86
|
end
|
51
87
|
end
|
52
88
|
|
data/lib/picky/sinatra.rb
CHANGED
data/lib/picky/tokenizer.rb
CHANGED
@@ -93,27 +93,37 @@ Case sensitive? #{@case_sensitive ? "Yes." : "-"}
|
|
93
93
|
|
94
94
|
# Splitting.
|
95
95
|
#
|
96
|
-
# We allow Strings and
|
96
|
+
# We allow Strings, Regexps, and things that respond to #split.
|
97
|
+
#
|
97
98
|
# Note: We do not test against to_str since symbols do not work with String#split.
|
98
99
|
#
|
99
|
-
def splits_text_on
|
100
|
-
raise ArgumentError.new "#{__method__} takes a Regexp or String as argument, not a #{
|
101
|
-
@splits_text_on =
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
def splits_text_on thing
|
101
|
+
raise ArgumentError.new "#{__method__} takes a Regexp or String or a thing that responds to #split as argument, not a #{thing.class}." unless Regexp === thing || thing.respond_to?(:split)
|
102
|
+
@splits_text_on = thing
|
103
|
+
if thing.respond_to? :split
|
104
|
+
def split text
|
105
|
+
@splits_text_on.split text
|
106
|
+
end
|
107
|
+
else
|
108
|
+
def split text
|
109
|
+
text.split @splits_text_on
|
110
|
+
end
|
111
|
+
end
|
105
112
|
end
|
106
113
|
|
107
114
|
# Normalizing.
|
108
115
|
#
|
109
116
|
# We only allow arrays.
|
110
117
|
#
|
118
|
+
# TODO 5.0 Rename to normalizes(config)
|
119
|
+
# TODO 5.0 Rename to normalize(text)
|
120
|
+
#
|
111
121
|
def normalizes_words regexp_replaces
|
112
|
-
raise ArgumentError.new "#{__method__} takes an Array of replaces as argument, not a #{regexp_replaces.class}." unless regexp_replaces.respond_to?(:to_ary)
|
122
|
+
raise ArgumentError.new "#{__method__} takes an Array of replaces as argument, not a #{regexp_replaces.class}." unless regexp_replaces.respond_to?(:to_ary) || regexp_replaces.respond_to?(:normalize_with_patterns)
|
113
123
|
@normalizes_words_regexp_replaces = regexp_replaces
|
114
124
|
end
|
115
125
|
def normalize_with_patterns text
|
116
|
-
return text unless @normalizes_words_regexp_replaces
|
126
|
+
return text unless @normalizes_words_regexp_replaces # TODO Remove.
|
117
127
|
|
118
128
|
@normalizes_words_regexp_replaces.each do |regex, replace|
|
119
129
|
# This should be sufficient
|
@@ -196,8 +206,6 @@ Case sensitive? #{@case_sensitive ? "Yes." : "-"}
|
|
196
206
|
send method_name, value unless value.nil?
|
197
207
|
end
|
198
208
|
rescue NoMethodError => e
|
199
|
-
# TODO Print out valid options.
|
200
|
-
#
|
201
209
|
raise <<-ERROR
|
202
210
|
The option "#{e.name}" is not a valid option for a Picky tokenizer.
|
203
211
|
Please see https://github.com/floere/picky/wiki/Indexing-configuration for valid options.
|
data/lib/picky.rb
CHANGED
@@ -18,6 +18,8 @@ module Picky
|
|
18
18
|
|
19
19
|
# External libraries.
|
20
20
|
#
|
21
|
+
# TODO Remove active support.
|
22
|
+
#
|
21
23
|
require 'active_support/core_ext/module/delegation'
|
22
24
|
require 'active_support/core_ext/logger'
|
23
25
|
require 'active_support/core_ext/object/blank'
|
@@ -69,7 +71,7 @@ module Picky
|
|
69
71
|
# * Loggers::Silent
|
70
72
|
# * Loggers::Concise (default)
|
71
73
|
# * Loggers::Verbose
|
72
|
-
#
|
74
|
+
#
|
73
75
|
self.logger = Loggers::Default
|
74
76
|
|
75
77
|
end
|