picky 0.9.0 → 0.9.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/lib/picky/indexes.rb CHANGED
@@ -128,8 +128,8 @@ module Indexes
128
128
  #
129
129
  def self.clear_caches
130
130
  each_bundle do |exact, partial|
131
- exact.delete_all
132
- partial.delete_all
131
+ exact.delete
132
+ partial.delete
133
133
  end
134
134
  end
135
135
 
data/lib/picky/loader.rb CHANGED
@@ -155,14 +155,20 @@ module Loader
155
155
  load_relative 'cacher/weights_generator'
156
156
  load_relative 'cacher/similarity_generator'
157
157
 
158
+ # Index file handling.
159
+ #
160
+ load_relative 'index/file/basic'
161
+ load_relative 'index/file/text'
162
+ load_relative 'index/file/marshal'
163
+ load_relative 'index/file/json'
164
+ load_relative 'index/files'
165
+
158
166
  # Index types.
159
167
  #
160
168
  load_relative 'index/bundle'
161
169
  load_relative 'index/category'
162
170
  load_relative 'index/type'
163
171
 
164
- load_relative 'index/bundle_checker'
165
-
166
172
  load_relative 'index/wrappers/exact_first'
167
173
 
168
174
  # Tokens.
@@ -3,10 +3,16 @@ module Sources
3
3
  class Delicious < Base
4
4
 
5
5
  def initialize username, password
6
- require 'www/delicious'
6
+ check_gem
7
7
  @username = username
8
8
  @password = password
9
9
  end
10
+ def check_gem
11
+ require 'www/delicious'
12
+ rescue LoadError
13
+ puts "Delicious gem missing!\nTo use the delicious source, you need to:\n 1. Add the following line to Gemfile:\n gem 'www-delicious'\n 2. Then, run:\n bundle update\n"
14
+ exit(1)
15
+ end
10
16
 
11
17
  # Harvests the data to index.
12
18
  #
@@ -17,14 +17,16 @@ class PickySearch < Application
17
17
  books_index = index :books,
18
18
  Sources::CSV.new(:title, :author, :isbn, :year, :publisher, :subjects, :file => 'app/library.csv'),
19
19
  # Use a database as source:
20
- # Sources::DB.new('SELECT id, title, author, isbn13 as isbn FROM books', :file => 'app/db.yml'),
20
+ # Sources::DB.new('SELECT id, title, author, isbn13 as isbn FROM books', :file => 'app/db.yml'),
21
+ # Or delicious:
22
+ # Sources::Delicious.new('username', 'password'), # offers title, tags, url fields.
21
23
  field(:title,
22
- :partial => Partial::Subtoken.new(:down_to => 1), # Index partial down to character 1 (default: -3),
23
- # e.g. florian -> floria, flori, flor, flo, fl, f
24
- # Like this, you'll find florian even when entering just an "f".
25
- :similarity => Similarity::DoubleLevenshtone.new(3)), # Up to three similar title word indexed.
26
- field(:author, :partial => Partial::Subtoken.new(:down_to => 1)),
27
- field(:isbn, :partial => Partial::None.new) # Partially searching on an ISBN makes not much sense, neither does similarity.
24
+ :partial => Partial::Substring.new(:from => 1), # Index substrings upwards from character 1 (default: -3),
25
+ # e.g. picky -> p, pi, pic, pick, picky
26
+ # Like this, you'll find picky even when entering just a "p".
27
+ :similarity => Similarity::DoubleLevenshtone.new(3)), # Up to three similar title word indexed (default: no similarity).
28
+ field(:author, :partial => Partial::Substring.new(:from => 1)),
29
+ field(:isbn, :partial => Partial::None.new) # Partial substring searching on an ISBN makes not much sense, neither does similarity.
28
30
 
29
31
  # Defines the maximum tokens (words) that pass through to the engine.
30
32
  #
@@ -3,13 +3,13 @@ require 'spec_helper'
3
3
  describe Cacher::Partial::Default do
4
4
 
5
5
  it "should be a subtoken" do
6
- Cacher::Partial::Default.should be_kind_of(Cacher::Partial::Subtoken)
6
+ Cacher::Partial::Default.should be_kind_of(Cacher::Partial::Substring)
7
7
  end
8
8
  it "should be a the right down to" do
9
- Cacher::Partial::Default.down_to.should == -3
9
+ Cacher::Partial::Default.from.should == -3
10
10
  end
11
11
  it "should be a the right starting at" do
12
- Cacher::Partial::Default.starting_at.should == -1
12
+ Cacher::Partial::Default.to.should == -1
13
13
  end
14
14
 
15
15
  end
@@ -1,14 +1,14 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Cacher::Partial::Subtoken do
3
+ describe Cacher::Partial::Substring do
4
4
 
5
- context 'default down_to' do
5
+ context 'default from' do
6
6
  before(:each) do
7
- @cacher = Cacher::Partial::Subtoken.new
7
+ @cacher = Cacher::Partial::Substring.new
8
8
  end
9
- describe 'down_to' do
9
+ describe 'from' do
10
10
  it 'should return the right value' do
11
- @cacher.down_to.should == 1
11
+ @cacher.from.should == 1
12
12
  end
13
13
  end
14
14
  describe 'generate_from' do
@@ -40,10 +40,10 @@ describe Cacher::Partial::Subtoken do
40
40
  end
41
41
  end
42
42
  end
43
- context 'down_to set' do
44
- describe 'negative down_to' do
43
+ context 'from set' do
44
+ describe 'negative from' do
45
45
  before(:each) do
46
- @cacher = Cacher::Partial::Subtoken.new :down_to => -2
46
+ @cacher = Cacher::Partial::Substring.new :from => -2
47
47
  end
48
48
  it 'should generate the right index' do
49
49
  @cacher.generate_from( :florian => [1], :flavia => [2] ).should == {
@@ -54,9 +54,9 @@ describe Cacher::Partial::Subtoken do
54
54
  }
55
55
  end
56
56
  end
57
- context "large down_to" do
57
+ context "large from" do
58
58
  before(:each) do
59
- @cacher = Cacher::Partial::Subtoken.new :down_to => 10
59
+ @cacher = Cacher::Partial::Substring.new :from => 10
60
60
  end
61
61
  describe 'generate_from' do
62
62
  it 'should generate the right index' do
@@ -68,18 +68,18 @@ describe Cacher::Partial::Subtoken do
68
68
  end
69
69
  end
70
70
  end
71
- context 'default starting_at' do
71
+ context 'default to' do
72
72
  before(:each) do
73
- @cacher = Cacher::Partial::Subtoken.new :down_to => 4
73
+ @cacher = Cacher::Partial::Substring.new :from => 4
74
74
  end
75
- describe 'starting_at' do
75
+ describe 'to' do
76
76
  it 'should return the right value' do
77
- @cacher.starting_at.should == -1
77
+ @cacher.to.should == -1
78
78
  end
79
79
  end
80
- describe 'down_to' do
80
+ describe 'from' do
81
81
  it 'should return the right value' do
82
- @cacher.down_to.should == 4
82
+ @cacher.from.should == 4
83
83
  end
84
84
  end
85
85
  describe 'generate_from' do
@@ -122,18 +122,18 @@ describe Cacher::Partial::Subtoken do
122
122
  end
123
123
  end
124
124
  end
125
- context 'starting_at set' do
125
+ context 'to set' do
126
126
  before(:each) do
127
- @cacher = Cacher::Partial::Subtoken.new :down_to => 4, :starting_at => -2
127
+ @cacher = Cacher::Partial::Substring.new :from => 4, :to => -2
128
128
  end
129
- describe 'starting_at' do
129
+ describe 'to' do
130
130
  it 'should return the right value' do
131
- @cacher.starting_at.should == -2
131
+ @cacher.to.should == -2
132
132
  end
133
133
  end
134
- describe 'down_to' do
134
+ describe 'from' do
135
135
  it 'should return the right value' do
136
- @cacher.down_to.should == 4
136
+ @cacher.from.should == 4
137
137
  end
138
138
  end
139
139
  describe 'generate_from' do
@@ -148,18 +148,18 @@ describe Cacher::Partial::Subtoken do
148
148
  end
149
149
  end
150
150
  end
151
- context 'starting_at set' do
151
+ context 'to set' do
152
152
  before(:each) do
153
- @cacher = Cacher::Partial::Subtoken.new :down_to => 4, :starting_at => 0
153
+ @cacher = Cacher::Partial::Substring.new :from => 4, :to => 0
154
154
  end
155
- describe 'starting_at' do
155
+ describe 'to' do
156
156
  it 'should return the right value' do
157
- @cacher.starting_at.should == 0
157
+ @cacher.to.should == 0
158
158
  end
159
159
  end
160
- describe 'down_to' do
160
+ describe 'from' do
161
161
  it 'should return the right value' do
162
- @cacher.down_to.should == 4
162
+ @cacher.from.should == 4
163
163
  end
164
164
  end
165
165
  describe 'generate_from' do
@@ -6,7 +6,7 @@ describe Cacher::PartialGenerator do
6
6
  it 'should generate the correct values with a given strategy' do
7
7
  generator = Cacher::PartialGenerator.new :meier => [1], :maier => [2]
8
8
 
9
- generator.generate(Cacher::Partial::Subtoken.new).should == {
9
+ generator.generate(Cacher::Partial::Substring.new).should == {
10
10
  :meier => [1],
11
11
  :meie => [1],
12
12
  :mei => [1],
@@ -21,7 +21,7 @@ describe Cacher::PartialGenerator do
21
21
  it 'should generate the correct values with a given specific strategy' do
22
22
  generator = Cacher::PartialGenerator.new :meier => [1], :maier => [2]
23
23
 
24
- generator.generate(Cacher::Partial::Subtoken.new(:down_to => 3)).should == {
24
+ generator.generate(Cacher::Partial::Substring.new(:from => 3)).should == {
25
25
  :meier => [1],
26
26
  :meie => [1],
27
27
  :mei => [1],
@@ -6,7 +6,7 @@ describe Hash do
6
6
  it 'uses the right file' do
7
7
  File.should_receive(:open).once.with('some/file/path.json', 'w')
8
8
 
9
- {}.dump_to_json 'some/file/path'
9
+ {}.dump_json 'some/file/path.json'
10
10
  end
11
11
  it "uses the right encoder" do
12
12
  file = stub :file
@@ -14,7 +14,7 @@ describe Hash do
14
14
 
15
15
  Yajl::Encoder.should_receive(:encode).once.with({ :some => :hash }, file)
16
16
 
17
- { :some => :hash }.dump_to_json 'unimportant'
17
+ { :some => :hash }.dump_json 'unimportant'
18
18
  end
19
19
  end
20
20
 
@@ -22,7 +22,7 @@ describe Hash do
22
22
  it 'uses the right file' do
23
23
  File.should_receive(:open).once.with('some/file/path.dump', 'w:binary')
24
24
 
25
- {}.dump_to_marshalled 'some/file/path'
25
+ {}.dump_marshalled 'some/file/path.dump'
26
26
  end
27
27
  it "uses the right encoder" do
28
28
  file = stub :file
@@ -30,7 +30,7 @@ describe Hash do
30
30
 
31
31
  Marshal.should_receive(:dump).once.with({ :some => :hash }, file)
32
32
 
33
- { :some => :hash }.dump_to_marshalled 'unimportant'
33
+ { :some => :hash }.dump_marshalled 'unimportant'
34
34
  end
35
35
  end
36
36
 
@@ -5,7 +5,7 @@ describe Index::Bundle do
5
5
  before(:each) do
6
6
  @category = stub :category, :name => :some_category
7
7
  @type = stub :type, :name => :some_type
8
- @partial_strategy = Cacher::Partial::Subtoken.new :down_to => 1
8
+ @partial_strategy = Cacher::Partial::Substring.new :from => 1
9
9
  @exact = Index::Bundle.new :some_name, @category, @type, @partial_strategy, nil, nil
10
10
  end
11
11
 
@@ -17,21 +17,7 @@ describe Index::Bundle do
17
17
  @index.identifier.should == 'some_name: some_type some_category'
18
18
  end
19
19
  end
20
-
21
- describe 'create_directory' do
22
- it 'should use makedirs to create the necessary directory structure' do
23
- FileUtils.should_receive(:mkdir_p).once.with 'some/search/root/index/test/some_type'
24
-
25
- @index.create_directory
26
- end
27
- end
28
-
29
- describe 'cache_directory' do
30
- it 'should be correct' do
31
- @index.cache_directory.should == 'some/search/root/index/test/some_type'
32
- end
33
- end
34
-
20
+
35
21
  describe 'initialize_index_for' do
36
22
  context 'token not yet assigned' do
37
23
  before(:each) do
@@ -127,17 +113,7 @@ describe Index::Bundle do
127
113
  @index.weight(:existing).should == :specific
128
114
  end
129
115
  end
130
-
131
- describe 'delete_all' do
132
- it 'should call delete with all paths' do
133
- @index.should_receive(:delete).once.with @index.index_cache_path
134
- @index.should_receive(:delete).once.with @index.similarity_cache_path
135
- @index.should_receive(:delete).once.with @index.weights_cache_path
136
-
137
- @index.delete_all
138
- end
139
- end
140
-
116
+
141
117
  describe 'load' do
142
118
  it 'should trigger loads' do
143
119
  @index.should_receive(:load_index).once.with
@@ -190,25 +166,56 @@ describe Index::Bundle do
190
166
  end
191
167
  end
192
168
 
193
- describe 'weights_cache_path' do
194
- it 'should return the correct file name' do
195
- @index.weights_cache_path.should == 'some/search/root/index/test/some_type/some_name_some_category_weights'
169
+ describe 'raise_unless_cache_exists' do
170
+ before(:each) do
171
+ @files = stub :files
172
+ @files.stub! :index_cache_ok? => true
173
+ @files.stub! :similarity_cache_ok? => true
174
+ @files.stub! :weights_cache_ok? => true
175
+ @files.stub! :index_cache_small? => false
176
+ @files.stub! :similarity_cache_small? => false
177
+ @files.stub! :weights_cache_small? => false
178
+
179
+ @index.stub! :files => @files
196
180
  end
197
- end
198
- describe 'similarity_cache_path' do
199
- it 'should return the correct file name' do
200
- @index.similarity_cache_path.should == 'some/search/root/index/test/some_type/some_name_some_category_similarity'
181
+ context 'weights cache missing' do
182
+ before(:each) do
183
+ @files.stub! :weights_cache_ok? => false
184
+ end
185
+ it 'should raise' do
186
+ lambda do
187
+ @index.raise_unless_cache_exists
188
+ end.should raise_error("weights cache for some_name: some_type some_category missing.")
189
+ end
201
190
  end
202
- end
203
- describe 'index_cache_path' do
204
- it 'should return the correct file name' do
205
- @index.index_cache_path.should == 'some/search/root/index/test/some_type/some_name_some_category_index'
191
+ context 'similarity cache missing' do
192
+ before(:each) do
193
+ @files.stub! :similarity_cache_ok? => false
194
+ end
195
+ it 'should raise' do
196
+ lambda do
197
+ @index.raise_unless_cache_exists
198
+ end.should raise_error("similarity cache for some_name: some_type some_category missing.")
199
+ end
200
+ end
201
+ context 'index cache missing' do
202
+ before(:each) do
203
+ @files.stub! :index_cache_ok? => false
204
+ end
205
+ it 'should raise' do
206
+ lambda do
207
+ @index.raise_unless_cache_exists
208
+ end.should raise_error("index cache for some_name: some_type some_category missing.")
209
+ end
206
210
  end
207
211
  end
208
-
212
+
209
213
  describe 'initialization' do
210
214
  before(:each) do
211
- @index = @index_class.new :some_name, :some_category, :some_type, :partial, :weights, :similarity
215
+ @category = stub :category, :name => :some_category
216
+ @type = stub :type, :name => :some_type
217
+
218
+ @index = @index_class.new :some_name, @category, @type, :partial, :weights, :similarity
212
219
  end
213
220
  it 'should initialize the index correctly' do
214
221
  @index.index.should == {}
@@ -220,13 +227,7 @@ describe Index::Bundle do
220
227
  @index.similarity.should == {}
221
228
  end
222
229
  it 'should initialize the name correctly' do
223
- @index.name.should == :some_name
224
- end
225
- it 'should initialize the name correctly' do
226
- @index.category.should == :some_category
227
- end
228
- it 'should initialize the name correctly' do
229
- @index.type.should == :some_type
230
+ @index.category.should == @category
230
231
  end
231
232
  it 'should initialize the partial strategy correctly' do
232
233
  @index.partial_strategy.should == :partial
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Index::File::Basic do
4
+
5
+ before(:each) do
6
+ @file = Index::File::Basic.new "some/cache/path/to/file"
7
+ end
8
+
9
+ describe "backup_file_path_of" do
10
+ it "returns a backup path relative to the path" do
11
+ @file.backup_file_path_of('some/path/to/some.index').should == 'some/path/to/backup/some.index'
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Index::File::JSON do
4
+
5
+ before(:each) do
6
+ @file = Index::File::JSON.new "some_cache_path"
7
+ end
8
+
9
+ describe "dump" do
10
+ it "delegates to the given hash" do
11
+ hash = stub :hash
12
+
13
+ hash.should_receive(:dump_json).once.with "some_cache_path.json"
14
+
15
+ @file.dump hash
16
+ end
17
+ end
18
+ describe "retrieve" do
19
+ it "raises" do
20
+ lambda do
21
+ @file.retrieve
22
+ end.should raise_error("Can't retrieve from marshalled file. Use text file.")
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Index::File::Marshal do
4
+
5
+ before(:each) do
6
+ @file = Index::File::Marshal.new "some_cache_path"
7
+ end
8
+
9
+ describe "dump" do
10
+ it "delegates to the given hash" do
11
+ hash = stub :hash
12
+
13
+ hash.should_receive(:dump_marshalled).once.with "some_cache_path.dump"
14
+
15
+ @file.dump hash
16
+ end
17
+ end
18
+ describe "retrieve" do
19
+ it "raises" do
20
+ lambda do
21
+ @file.retrieve
22
+ end.should raise_error("Can't retrieve from marshalled file. Use text file.")
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Index::File::Text do
4
+
5
+ before(:each) do
6
+ @file = Index::File::Text.new "some_cache_path"
7
+ end
8
+
9
+ describe "load" do
10
+ it "raises" do
11
+ lambda do
12
+ @file.load
13
+ end.should raise_error("Can't load from text file. Use JSON or Marshal.")
14
+ end
15
+ end
16
+ describe "dump" do
17
+ it "raises" do
18
+ lambda do
19
+ @file.dump :anything
20
+ end.should raise_error("Can't dump to text file. Use JSON or Marshal.")
21
+ end
22
+ end
23
+ describe "retrieve" do
24
+ it
25
+ end
26
+
27
+ end