picky 2.6.0 → 2.7.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/analyzer.rb +4 -4
- data/lib/picky/application.rb +6 -7
- data/lib/picky/backend/{backend.rb → base.rb} +31 -14
- data/lib/picky/backend/file/basic.rb +12 -4
- data/lib/picky/backend/file/json.rb +5 -5
- data/lib/picky/backend/file/text.rb +1 -1
- data/lib/picky/backend/files.rb +3 -9
- data/lib/picky/backend/redis/basic.rb +8 -0
- data/lib/picky/backend/redis/list_hash.rb +5 -5
- data/lib/picky/backend/redis/string_hash.rb +5 -5
- data/lib/picky/backend/redis.rb +5 -5
- data/lib/picky/bundle.rb +62 -0
- data/lib/picky/categories.rb +10 -9
- data/lib/picky/categories_indexed.rb +12 -7
- data/lib/picky/categories_indexing.rb +7 -9
- data/lib/picky/category.rb +38 -26
- data/lib/picky/category_indexed.rb +4 -20
- data/lib/picky/category_indexing.rb +71 -68
- data/lib/picky/generators/base.rb +6 -6
- data/lib/picky/generators/partial/substring.rb +28 -26
- data/lib/picky/generators/partial_generator.rb +3 -3
- data/lib/picky/generators/similarity/phonetic.rb +5 -5
- data/lib/picky/generators/similarity_generator.rb +2 -2
- data/lib/picky/generators/weights/logarithmic.rb +3 -3
- data/lib/picky/generators/weights_generator.rb +2 -2
- data/lib/picky/index/base.rb +13 -10
- data/lib/picky/index/base_indexed.rb +2 -0
- data/lib/picky/index/base_indexing.rb +65 -57
- data/lib/picky/indexed/bundle/base.rb +21 -86
- data/lib/picky/indexed/bundle/memory.rb +5 -12
- data/lib/picky/indexed/bundle/redis.rb +42 -0
- data/lib/picky/indexed/wrappers/bundle/wrapper.rb +3 -3
- data/lib/picky/indexers/base.rb +20 -3
- data/lib/picky/indexers/parallel.rb +32 -14
- data/lib/picky/indexers/serial.rb +29 -26
- data/lib/picky/indexes.rb +5 -3
- data/lib/picky/indexes_indexed.rb +3 -15
- data/lib/picky/indexes_indexing.rb +18 -21
- data/lib/picky/indexing/bundle/base.rb +64 -45
- data/lib/picky/indexing/bundle/memory.rb +0 -4
- data/lib/picky/loader.rb +7 -6
- data/lib/picky/query/allocation.rb +3 -3
- data/lib/picky/query/token.rb +5 -1
- data/lib/picky/search.rb +5 -0
- data/lib/picky/sources/base.rb +21 -2
- data/lib/picky/sources/db.rb +0 -7
- data/lib/picky/statistics.rb +9 -12
- data/lib/picky/tokenizers/location.rb +1 -1
- data/lib/tasks/checks.rake +8 -6
- data/lib/tasks/index.rake +14 -20
- data/lib/tasks/server.rake +18 -2
- data/lib/tasks/statistics.rake +27 -14
- data/lib/tasks/todo.rake +2 -2
- data/lib/tasks/try.rake +12 -27
- data/spec/lib/application_spec.rb +1 -1
- data/spec/lib/backend/file/basic_spec.rb +6 -6
- data/spec/lib/backend/file/json_spec.rb +11 -6
- data/spec/lib/backend/file/marshal_spec.rb +11 -6
- data/spec/lib/backend/files_spec.rb +21 -7
- data/spec/lib/backend/redis/basic_spec.rb +6 -0
- data/spec/lib/backend/redis/list_hash_spec.rb +9 -3
- data/spec/lib/backend/redis/string_hash_spec.rb +7 -1
- data/spec/lib/backend/redis_spec.rb +22 -12
- data/spec/lib/categories_indexed_spec.rb +2 -2
- data/spec/lib/category_indexing_spec.rb +12 -33
- data/spec/lib/category_spec.rb +22 -0
- data/spec/lib/index/base_indexing_spec.rb +30 -0
- data/spec/lib/indexed/bundle/memory_spec.rb +13 -20
- data/spec/lib/indexers/base_spec.rb +39 -4
- data/spec/lib/indexers/parallel_spec.rb +2 -10
- data/spec/lib/indexers/serial_spec.rb +11 -26
- data/spec/lib/indexes_class_spec.rb +4 -4
- data/spec/lib/indexes_indexed_spec.rb +2 -2
- data/spec/lib/indexes_indexing_spec.rb +6 -10
- data/spec/lib/indexes_spec.rb +3 -3
- data/spec/lib/indexing/bundle/{super_base_spec.rb → base_spec.rb} +2 -2
- data/spec/lib/indexing/bundle/memory_partial_generation_speed_spec.rb +3 -3
- data/spec/lib/indexing/bundle/memory_spec.rb +16 -14
- data/spec/lib/indexing/bundle/redis_spec.rb +18 -16
- data/spec/lib/query/allocation_spec.rb +1 -1
- data/spec/lib/query/token_spec.rb +5 -7
- data/spec/lib/sources/base_spec.rb +53 -0
- data/spec/lib/sources/db_spec.rb +0 -7
- metadata +11 -12
- data/lib/picky/indexers/solr.rb +0 -56
- data/lib/picky/indexing/bundle/super_base.rb +0 -61
- data/lib/picky/solr/schema_generator.rb +0 -74
- data/lib/tasks/search.rake +0 -9
- data/lib/tasks/shortcuts.rake +0 -32
- data/lib/tasks/solr.rake +0 -36
data/lib/picky/analyzer.rb
CHANGED
@@ -17,11 +17,11 @@ class Analyzer # :nodoc:all
|
|
17
17
|
#
|
18
18
|
#
|
19
19
|
def analyze bundle
|
20
|
-
bundle.
|
21
|
-
analysis[:__keys] = bundle.size
|
22
|
-
cardinality :index, bundle.
|
20
|
+
bundle.load_inverted
|
21
|
+
analysis[:__keys] = bundle.inverted.size
|
22
|
+
cardinality :index, bundle.inverted
|
23
23
|
index_analysis
|
24
|
-
bundle.
|
24
|
+
bundle.clear_inverted
|
25
25
|
|
26
26
|
bundle.load_weights
|
27
27
|
weights bundle.weights
|
data/lib/picky/application.rb
CHANGED
@@ -68,7 +68,7 @@
|
|
68
68
|
# In full glory:
|
69
69
|
# class MyGreatSearch < Application
|
70
70
|
#
|
71
|
-
# books =
|
71
|
+
# books = Index::Memory.new :books do
|
72
72
|
# source Sources::CSV.new(:title, :author, :isbn, file:'app/library.csv')
|
73
73
|
# category :title
|
74
74
|
# end
|
@@ -227,12 +227,6 @@ class Application
|
|
227
227
|
"WARNING: No routes defined for application configuration in #{self.class}." if rack_adapter.empty?
|
228
228
|
end
|
229
229
|
|
230
|
-
def to_s # :nodoc:
|
231
|
-
<<-APPLICATION
|
232
|
-
\033[1m#{name}\033[m
|
233
|
-
#{to_stats.indented_to_s}
|
234
|
-
APPLICATION
|
235
|
-
end
|
236
230
|
def to_stats
|
237
231
|
<<-APP
|
238
232
|
\033[1mIndexing (default)\033[m:
|
@@ -248,10 +242,15 @@ APPLICATION
|
|
248
242
|
#{to_routes.indented_to_s}
|
249
243
|
APP
|
250
244
|
end
|
245
|
+
|
251
246
|
def to_routes
|
252
247
|
rack_adapter.to_s
|
253
248
|
end
|
254
249
|
|
250
|
+
def to_s # :nodoc:
|
251
|
+
self.name
|
252
|
+
end
|
253
|
+
|
255
254
|
end
|
256
255
|
|
257
256
|
end
|
@@ -1,13 +1,20 @@
|
|
1
1
|
module Backend
|
2
2
|
|
3
|
-
class
|
3
|
+
class Base
|
4
4
|
|
5
|
-
attr_reader :bundle_name
|
6
|
-
|
5
|
+
attr_reader :bundle_name,
|
6
|
+
:prepared,
|
7
|
+
:inverted,
|
8
|
+
:weights,
|
9
|
+
:similarity,
|
10
|
+
:configuration,
|
11
|
+
:category,
|
12
|
+
:identifier
|
7
13
|
|
8
14
|
delegate :index_name, :category_name, :to => :@category
|
9
15
|
|
10
16
|
def initialize bundle_name, category
|
17
|
+
@identifier = "#{category.identifier}:#{bundle_name}"
|
11
18
|
@bundle_name = bundle_name
|
12
19
|
@category = category
|
13
20
|
@prepared = File::Text.new category.prepared_index_path
|
@@ -24,23 +31,27 @@ module Backend
|
|
24
31
|
|
25
32
|
# Dumping.
|
26
33
|
#
|
27
|
-
def
|
28
|
-
|
34
|
+
def dump_inverted inverted_hash
|
35
|
+
timed_exclaim %Q{"#{identifier}": => #{inverted}.}
|
36
|
+
inverted.dump inverted_hash
|
29
37
|
end
|
30
38
|
def dump_weights weights_hash
|
39
|
+
timed_exclaim %Q{"#{identifier}": => #{weights}.}
|
31
40
|
weights.dump weights_hash
|
32
41
|
end
|
33
42
|
def dump_similarity similarity_hash
|
43
|
+
timed_exclaim %Q{"#{identifier}": => #{similarity}.}
|
34
44
|
similarity.dump similarity_hash
|
35
45
|
end
|
36
46
|
def dump_configuration configuration_hash
|
47
|
+
timed_exclaim %Q{"#{identifier}": => #{configuration}.}
|
37
48
|
configuration.dump configuration_hash
|
38
49
|
end
|
39
50
|
|
40
51
|
# Loading.
|
41
52
|
#
|
42
|
-
def
|
43
|
-
|
53
|
+
def load_inverted
|
54
|
+
inverted.load
|
44
55
|
end
|
45
56
|
def load_similarity
|
46
57
|
similarity.load
|
@@ -54,8 +65,8 @@ module Backend
|
|
54
65
|
|
55
66
|
# Cache ok?
|
56
67
|
#
|
57
|
-
def
|
58
|
-
|
68
|
+
def inverted_cache_ok?
|
69
|
+
inverted.cache_ok?
|
59
70
|
end
|
60
71
|
def similarity_cache_ok?
|
61
72
|
similarity.cache_ok?
|
@@ -66,8 +77,8 @@ module Backend
|
|
66
77
|
|
67
78
|
# Cache small?
|
68
79
|
#
|
69
|
-
def
|
70
|
-
|
80
|
+
def inverted_cache_small?
|
81
|
+
inverted.cache_small?
|
71
82
|
end
|
72
83
|
def similarity_cache_small?
|
73
84
|
similarity.cache_small?
|
@@ -79,7 +90,7 @@ module Backend
|
|
79
90
|
# Copies the indexes to the "backup" directory.
|
80
91
|
#
|
81
92
|
def backup
|
82
|
-
|
93
|
+
inverted.backup
|
83
94
|
weights.backup
|
84
95
|
similarity.backup
|
85
96
|
configuration.backup
|
@@ -88,7 +99,7 @@ module Backend
|
|
88
99
|
# Restores the indexes from the "backup" directory.
|
89
100
|
#
|
90
101
|
def restore
|
91
|
-
|
102
|
+
inverted.restore
|
92
103
|
weights.restore
|
93
104
|
similarity.restore
|
94
105
|
configuration.restore
|
@@ -97,12 +108,18 @@ module Backend
|
|
97
108
|
# Delete all index files.
|
98
109
|
#
|
99
110
|
def delete
|
100
|
-
|
111
|
+
inverted.delete
|
101
112
|
weights.delete
|
102
113
|
similarity.delete
|
103
114
|
configuration.delete
|
104
115
|
end
|
105
116
|
|
117
|
+
#
|
118
|
+
#
|
119
|
+
def to_s
|
120
|
+
"#{self.class}(#{prepared}, #{bundle_name}, #{category.identifier})"
|
121
|
+
end
|
122
|
+
|
106
123
|
end
|
107
124
|
|
108
125
|
end
|
@@ -13,6 +13,8 @@ module Backend
|
|
13
13
|
#
|
14
14
|
class Basic
|
15
15
|
|
16
|
+
# This file's location.
|
17
|
+
#
|
16
18
|
attr_reader :cache_path
|
17
19
|
|
18
20
|
# An index cache takes a path, without file extension,
|
@@ -22,10 +24,6 @@ module Backend
|
|
22
24
|
@cache_path = "#{cache_path}.#{extension}"
|
23
25
|
end
|
24
26
|
|
25
|
-
def to_s
|
26
|
-
cache_path
|
27
|
-
end
|
28
|
-
|
29
27
|
# The default extension for index files is "index".
|
30
28
|
#
|
31
29
|
def extension
|
@@ -40,12 +38,15 @@ module Backend
|
|
40
38
|
prepare_backup backup_directory
|
41
39
|
FileUtils.cp cache_path, target, verbose: true
|
42
40
|
end
|
41
|
+
|
43
42
|
# The backup directory of this file.
|
44
43
|
# Equal to the file's dirname plus /backup
|
45
44
|
#
|
45
|
+
|
46
46
|
def backup_directory
|
47
47
|
::File.join ::File.dirname(cache_path), 'backup'
|
48
48
|
end
|
49
|
+
|
49
50
|
# Prepares the backup directory for the file.
|
50
51
|
#
|
51
52
|
def prepare_backup target
|
@@ -58,6 +59,7 @@ module Backend
|
|
58
59
|
def restore
|
59
60
|
FileUtils.cp backup_file_path_of(cache_path), cache_path, verbose: true
|
60
61
|
end
|
62
|
+
|
61
63
|
# The backup filename.
|
62
64
|
#
|
63
65
|
def backup_file_path_of path
|
@@ -94,6 +96,12 @@ module Backend
|
|
94
96
|
`ls -l #{path} | awk '{print $5}'`.to_i
|
95
97
|
end
|
96
98
|
|
99
|
+
#
|
100
|
+
#
|
101
|
+
def to_s
|
102
|
+
"#{self.class}(#{cache_path})"
|
103
|
+
end
|
104
|
+
|
97
105
|
end
|
98
106
|
|
99
107
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Backend
|
2
|
-
|
2
|
+
|
3
3
|
module File
|
4
|
-
|
4
|
+
|
5
5
|
# Index files dumped in the JSON format.
|
6
6
|
#
|
7
7
|
class JSON < Basic
|
8
|
-
|
8
|
+
|
9
9
|
# Uses the extension "json".
|
10
10
|
#
|
11
11
|
def extension
|
@@ -26,9 +26,9 @@ module Backend
|
|
26
26
|
def retrieve
|
27
27
|
raise "Can't retrieve from JSON file. Use text file."
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
end
|
33
33
|
|
34
34
|
end
|
data/lib/picky/backend/files.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Backend
|
2
2
|
|
3
|
-
class Files <
|
3
|
+
class Files < Base
|
4
4
|
|
5
5
|
def initialize bundle_name, category
|
6
6
|
super bundle_name, category
|
@@ -9,20 +9,14 @@ module Backend
|
|
9
9
|
# Yajl json lib cannot load symbolized
|
10
10
|
# values, just keys.
|
11
11
|
#
|
12
|
-
@
|
12
|
+
@inverted = File::JSON.new category.index_path(bundle_name, :inverted)
|
13
13
|
@weights = File::JSON.new category.index_path(bundle_name, :weights)
|
14
14
|
@similarity = File::Marshal.new category.index_path(bundle_name, :similarity)
|
15
15
|
@configuration = File::JSON.new category.index_path(bundle_name, :configuration)
|
16
16
|
end
|
17
17
|
|
18
18
|
def to_s
|
19
|
-
|
20
|
-
Files:
|
21
|
-
#{"Index: #{@index}".indented_to_s}
|
22
|
-
#{"Weights: #{@weights}".indented_to_s}
|
23
|
-
#{"Similarity: #{@similarity}".indented_to_s}
|
24
|
-
#{"Config: #{@configuration}".indented_to_s}
|
25
|
-
FILES
|
19
|
+
"#{self.class}(#{[@prepared, @inverted, @weights, @similarity, @configuration].join(', ')})"
|
26
20
|
end
|
27
21
|
|
28
22
|
end
|
@@ -61,6 +61,7 @@ module Backend
|
|
61
61
|
def cache_small?
|
62
62
|
size < 1
|
63
63
|
end
|
64
|
+
|
64
65
|
# Is the cache ok?
|
65
66
|
#
|
66
67
|
# A small cache is still ok.
|
@@ -68,6 +69,7 @@ module Backend
|
|
68
69
|
def cache_ok?
|
69
70
|
size > 0
|
70
71
|
end
|
72
|
+
|
71
73
|
# Extracts the size of the file in Bytes.
|
72
74
|
#
|
73
75
|
# Note: This is a very forgiving implementation.
|
@@ -78,6 +80,12 @@ module Backend
|
|
78
80
|
backend.dbsize
|
79
81
|
end
|
80
82
|
|
83
|
+
#
|
84
|
+
#
|
85
|
+
def to_s
|
86
|
+
"#{self.class}(#{namespace}:*)"
|
87
|
+
end
|
88
|
+
|
81
89
|
end
|
82
90
|
|
83
91
|
end
|
@@ -17,7 +17,7 @@ module Backend
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
# Clear the index for this list.
|
22
22
|
#
|
23
23
|
# Note: Perhaps we can use a server only command.
|
@@ -32,14 +32,14 @@ module Backend
|
|
32
32
|
|
33
33
|
# Get a collection.
|
34
34
|
#
|
35
|
-
def collection
|
36
|
-
backend.
|
35
|
+
def collection key
|
36
|
+
backend.zrange "#{namespace}:#{key}", 0, -1
|
37
37
|
end
|
38
38
|
|
39
39
|
# Get a single value.
|
40
40
|
#
|
41
|
-
def member
|
42
|
-
raise "Can't retrieve
|
41
|
+
def member key
|
42
|
+
raise "Can't retrieve single value :#{key} from a Redis ListHash. Use Index::Redis::StringHash."
|
43
43
|
end
|
44
44
|
|
45
45
|
end
|
@@ -14,7 +14,7 @@ module Backend
|
|
14
14
|
backend.hset namespace, key, value
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
# Clears the hash.
|
19
19
|
#
|
20
20
|
def clear
|
@@ -23,14 +23,14 @@ module Backend
|
|
23
23
|
|
24
24
|
# Get a collection.
|
25
25
|
#
|
26
|
-
def collection
|
27
|
-
raise "Can't retrieve
|
26
|
+
def collection key
|
27
|
+
raise "Can't retrieve collection for :#{key} from a StringHash. Use Index::Redis::ListHash."
|
28
28
|
end
|
29
29
|
|
30
30
|
# Get a single value.
|
31
31
|
#
|
32
|
-
def member
|
33
|
-
backend.hget namespace,
|
32
|
+
def member key
|
33
|
+
backend.hget namespace, key
|
34
34
|
end
|
35
35
|
|
36
36
|
end
|
data/lib/picky/backend/redis.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
module Backend
|
2
2
|
|
3
|
-
# TODO Needs a reconnect to be run after forking.
|
4
3
|
#
|
5
|
-
|
4
|
+
#
|
5
|
+
class Redis < Base
|
6
6
|
|
7
7
|
def initialize bundle_name, category
|
8
8
|
super bundle_name, category
|
9
9
|
|
10
10
|
# Refine a few Redis "types".
|
11
11
|
#
|
12
|
-
@
|
12
|
+
@inverted = Redis::ListHash.new "#{category.identifier}:#{bundle_name}:inverted"
|
13
13
|
@weights = Redis::StringHash.new "#{category.identifier}:#{bundle_name}:weights"
|
14
|
-
@similarity = Redis::ListHash.new
|
14
|
+
@similarity = Redis::ListHash.new "#{category.identifier}:#{bundle_name}:similarity"
|
15
15
|
@configuration = Redis::StringHash.new "#{category.identifier}:#{bundle_name}:configuration"
|
16
16
|
end
|
17
17
|
|
18
18
|
# Delegate to the right collection.
|
19
19
|
#
|
20
20
|
def ids sym
|
21
|
-
|
21
|
+
inverted.collection sym
|
22
22
|
end
|
23
23
|
|
24
24
|
# Delegate to the right member value.
|
data/lib/picky/bundle.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# A Bundle is a number of indexes
|
2
|
+
# per [index, category] combination.
|
3
|
+
#
|
4
|
+
# At most, there are three indexes:
|
5
|
+
# * *core* index (always used)
|
6
|
+
# * *weights* index (always used)
|
7
|
+
# * *similarity* index (used with similarity)
|
8
|
+
#
|
9
|
+
# In Picky, indexing is separated from the index
|
10
|
+
# handling itself through a parallel structure.
|
11
|
+
#
|
12
|
+
# Both use methods provided by this base class, but
|
13
|
+
# have very different goals:
|
14
|
+
#
|
15
|
+
# * *Indexing*::*Bundle*::*Base* is just concerned with creating index
|
16
|
+
# files / redis entries and providing helper functions to e.g. check
|
17
|
+
# the indexes.
|
18
|
+
#
|
19
|
+
# * *Index*::*Bundle*::*Base* is concerned with loading these index files into
|
20
|
+
# memory / redis and looking up search data as fast as possible.
|
21
|
+
#
|
22
|
+
class Bundle
|
23
|
+
|
24
|
+
attr_reader :identifier,
|
25
|
+
:files
|
26
|
+
attr_accessor :inverted,
|
27
|
+
:weights,
|
28
|
+
:similarity,
|
29
|
+
:configuration,
|
30
|
+
:similarity_strategy
|
31
|
+
|
32
|
+
delegate :clear, :to => :inverted
|
33
|
+
delegate :[], :[]=, :to => :configuration
|
34
|
+
|
35
|
+
def initialize name, category, similarity_strategy
|
36
|
+
@identifier = "#{category.identifier}:#{name}"
|
37
|
+
@files = Backend::Files.new name, category
|
38
|
+
|
39
|
+
@inverted = {}
|
40
|
+
@weights = {}
|
41
|
+
@similarity = {}
|
42
|
+
@configuration = {} # A hash with config options.
|
43
|
+
|
44
|
+
@similarity_strategy = similarity_strategy
|
45
|
+
end
|
46
|
+
|
47
|
+
# Get a list of similar texts.
|
48
|
+
#
|
49
|
+
# Note: Does not return itself.
|
50
|
+
#
|
51
|
+
def similar text
|
52
|
+
code = similarity_strategy.encoded text
|
53
|
+
similar_codes = code && @similarity[code]
|
54
|
+
similar_codes.delete text if similar_codes
|
55
|
+
similar_codes || []
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
"#{self.class}(#{identifier}, #{files})"
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/lib/picky/categories.rb
CHANGED
@@ -8,6 +8,7 @@ class Categories
|
|
8
8
|
:to => :categories
|
9
9
|
|
10
10
|
each_delegate :reindex,
|
11
|
+
:each_category,
|
11
12
|
:to => :categories
|
12
13
|
|
13
14
|
# A list of indexed categories.
|
@@ -26,18 +27,25 @@ class Categories
|
|
26
27
|
# Nifty! :)
|
27
28
|
#
|
28
29
|
def initialize options = {}
|
29
|
-
|
30
|
+
clear_categories
|
30
31
|
|
31
32
|
@ignore_unassigned_tokens = options[:ignore_unassigned_tokens] || false
|
32
33
|
end
|
33
34
|
|
34
35
|
# Clears both the array of categories and the hash of categories.
|
35
36
|
#
|
36
|
-
def
|
37
|
+
def clear_categories
|
37
38
|
@categories = []
|
38
39
|
@category_hash = {}
|
39
40
|
end
|
40
41
|
|
42
|
+
# Add the given category to the list of categories.
|
43
|
+
#
|
44
|
+
def << category
|
45
|
+
categories << category
|
46
|
+
category_hash[category.name] = category
|
47
|
+
end
|
48
|
+
|
41
49
|
# Find a given category in the categories.
|
42
50
|
#
|
43
51
|
def [] category_name
|
@@ -48,13 +56,6 @@ class Categories
|
|
48
56
|
raise %Q{Index category "#{category_name}" not found. Possible categories: "#{categories.map(&:name).join('", "')}".}
|
49
57
|
end
|
50
58
|
|
51
|
-
# Add the given category to the list of categories.
|
52
|
-
#
|
53
|
-
def << category
|
54
|
-
categories << category
|
55
|
-
category_hash[category.name] = category
|
56
|
-
end
|
57
|
-
|
58
59
|
def to_s
|
59
60
|
categories.join(', ')
|
60
61
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class Categories
|
2
|
-
|
2
|
+
|
3
3
|
attr_reader :ignore_unassigned_tokens
|
4
4
|
|
5
5
|
each_delegate :load_from_cache,
|
@@ -15,17 +15,17 @@ class Categories
|
|
15
15
|
def possible_combinations_for token
|
16
16
|
token.similar? ? similar_possible_for(token) : possible_for(token)
|
17
17
|
end
|
18
|
+
|
18
19
|
# Gets all similar tokens and puts together the possible combinations
|
19
20
|
# for each found similar token.
|
20
21
|
#
|
21
22
|
def similar_possible_for token
|
22
|
-
# Get as many tokens as necessary
|
23
|
-
#
|
24
23
|
tokens = similar_tokens_for token
|
25
|
-
# possible combinations
|
26
|
-
#
|
27
24
|
inject_possible_for tokens
|
28
25
|
end
|
26
|
+
|
27
|
+
# Returns all possible similar tokens for the given token.
|
28
|
+
#
|
29
29
|
def similar_tokens_for token
|
30
30
|
text = token.text
|
31
31
|
categories.inject([]) do |result, category|
|
@@ -41,6 +41,9 @@ class Categories
|
|
41
41
|
result
|
42
42
|
end
|
43
43
|
end
|
44
|
+
|
45
|
+
#
|
46
|
+
#
|
44
47
|
def inject_possible_for tokens
|
45
48
|
tokens.inject([]) do |result, token|
|
46
49
|
possible = possible_categories token
|
@@ -65,8 +68,9 @@ class Categories
|
|
65
68
|
# This is an optimization to mark tokens that are ignored.
|
66
69
|
#
|
67
70
|
return if ignore_unassigned_tokens && possible.empty?
|
68
|
-
possible
|
71
|
+
possible
|
69
72
|
end
|
73
|
+
|
70
74
|
# This returns the possible categories for this token.
|
71
75
|
# If the user has already preselected a category for this token,
|
72
76
|
# like "artist:moby", if not just return all for the given token,
|
@@ -77,6 +81,7 @@ class Categories
|
|
77
81
|
def possible_categories token
|
78
82
|
user_defined_categories(token) || categories
|
79
83
|
end
|
84
|
+
|
80
85
|
# This returns the array of categories if the user has defined
|
81
86
|
# an existing category.
|
82
87
|
#
|
@@ -89,5 +94,5 @@ class Categories
|
|
89
94
|
category_hash[name]
|
90
95
|
end.compact
|
91
96
|
end
|
92
|
-
|
97
|
+
|
93
98
|
end
|
@@ -1,12 +1,10 @@
|
|
1
1
|
class Categories
|
2
|
-
|
3
|
-
each_delegate :
|
4
|
-
:
|
5
|
-
:
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:generate_caches,
|
9
|
-
:restore_caches,
|
2
|
+
|
3
|
+
each_delegate :cache,
|
4
|
+
:check,
|
5
|
+
:clear,
|
6
|
+
:backup,
|
7
|
+
:restore,
|
10
8
|
:to => :categories
|
11
|
-
|
9
|
+
|
12
10
|
end
|