tanker 0.0.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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'jeweler'
4
+ gem 'will_paginate', '>= 2.3.15'
5
+
6
+ group :test do
7
+ gem 'rspec', '>= 2.0.0.beta.22'
8
+ end
9
+
10
+
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ gemcutter (0.6.1)
6
+ git (1.2.5)
7
+ jeweler (1.4.0)
8
+ gemcutter (>= 0.1.0)
9
+ git (>= 1.2.5)
10
+ rubyforge (>= 2.0.0)
11
+ json_pure (1.4.6)
12
+ rspec (2.0.0.beta.22)
13
+ rspec-core (= 2.0.0.beta.22)
14
+ rspec-expectations (= 2.0.0.beta.22)
15
+ rspec-mocks (= 2.0.0.beta.22)
16
+ rspec-core (2.0.0.beta.22)
17
+ rspec-expectations (2.0.0.beta.22)
18
+ diff-lcs (>= 1.1.2)
19
+ rspec-mocks (2.0.0.beta.22)
20
+ rspec-core (= 2.0.0.beta.22)
21
+ rspec-expectations (= 2.0.0.beta.22)
22
+ rubyforge (2.0.4)
23
+ json_pure (>= 1.1.7)
24
+ will_paginate (2.3.15)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ jeweler
31
+ rspec (>= 2.0.0.beta.22)
32
+ will_paginate
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 @kidpollo
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,17 @@
1
+ = tanker
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 @kidpollo. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "tanker"
8
+ gem.summary = %Q{IndexTank integration to your favorite orm}
9
+ gem.description = %Q{IndexTank is a great search indexing service, this gem tries to make any orm keep in sync with indextank with ease}
10
+ gem.email = "kidpollo@gmail.com"
11
+ gem.homepage = "http://github.com/kidpollo/tanker"
12
+ gem.authors = ["@kidpollo"]
13
+ gem.add_development_dependency "rspec", ">= 2.0.0.beta.22"
14
+ gem.add_dependency 'will_paginate', '>= 2.3.15'
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'lib' << 'test'
25
+ test.pattern = 'test/**/test_*.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ begin
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => :test
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "tanker #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
@@ -0,0 +1,256 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'rubygems'
4
+ require 'json'
5
+
6
+ module IndexTank
7
+
8
+ private
9
+
10
+ class RestClient
11
+ def GET(path, params={})
12
+ path = "#{path}?#{to_query(params)}" if params
13
+ request = Net::HTTP::Get.new "#{@uri}#{path}"
14
+ authorize request
15
+ return execute(request)
16
+ end
17
+
18
+ def PUT(path, body={})
19
+ request = Net::HTTP::Put.new "#{@uri}#{path}"
20
+ authorize request
21
+ request.body = body.to_json if body
22
+ return execute(request)
23
+ end
24
+
25
+ def DELETE(path, params={})
26
+ path = "#{path}?#{to_query(params)}" if params
27
+ request = Net::HTTP::Delete.new "#{@uri}#{path}"
28
+ authorize request
29
+ return execute(request)
30
+ end
31
+
32
+ private
33
+
34
+ def to_query(params)
35
+ require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
36
+ r = ''
37
+ params.each do |k,v|
38
+ r << "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}&"
39
+ end
40
+ return r
41
+ end
42
+
43
+ def authorize(req)
44
+ req.basic_auth(@uri.user, @uri.password)
45
+ end
46
+
47
+ def execute(req)
48
+ res = Net::HTTP.new(@uri.host).start { |http| http.request(req) }
49
+ if res.is_a? Net::HTTPSuccess
50
+ if res.body.nil? or res.body.empty?
51
+ return res.code, nil
52
+ else
53
+ begin
54
+ return res.code, JSON.parse(res.body)
55
+ rescue
56
+ raise "Invalid JSON response: #{res.body}"
57
+ end
58
+ end
59
+ elsif res.is_a? Net::HTTPUnauthorized
60
+ raise SecurityError, "Authorization required"
61
+ elsif res.is_a? Net::HTTPBadRequest
62
+ raise ArgumentError, res.body
63
+ else
64
+ raise HttpCodeException.new(res.code, res.body)
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ public
71
+
72
+ class ApiClient < RestClient
73
+ def initialize(api_url)
74
+ @uri = URI.parse(api_url)
75
+ end
76
+
77
+ def get_index(name)
78
+ require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
79
+ return IndexClient.new("#{@uri}/v1/indexes/#{CGI.escape(name)}")
80
+ end
81
+
82
+ def create_index(name)
83
+ index = get_index(name)
84
+ index.create_index()
85
+ return index
86
+ end
87
+
88
+ def delete_index(name)
89
+ return get_index(name).delete_index()
90
+ end
91
+
92
+ def list_indexes()
93
+ code, indexes = GET "/v1/indexes"
94
+ return indexes.map do |name,metadata| IndexClient.new "#{@uri}/v1/indexes/#{name}", metadata end
95
+ end
96
+ end
97
+
98
+ class IndexClient < RestClient
99
+ def initialize(index_url, metadata=nil)
100
+ @uri = URI.parse(index_url)
101
+ @metadata = metadata
102
+ end
103
+
104
+ def code
105
+ return metadata['code']
106
+ end
107
+
108
+ def running?
109
+ return metadata!['started']
110
+ end
111
+
112
+ def creation_time
113
+ return metadata['creation_time']
114
+ end
115
+
116
+ def size
117
+ return metadata['size']
118
+ end
119
+
120
+ def exists?
121
+ begin
122
+ metadata!
123
+ return true
124
+ rescue HttpCodeException
125
+ if $!.code == "404"
126
+ return false
127
+ end
128
+ raise
129
+ end
130
+ end
131
+
132
+ # the options argument may contain a :variables key
133
+ # with a Hash from variable numbers to their float values
134
+ # this variables can be used in the scoring functions
135
+ # when sorting a search
136
+ def add_document(docid, fields, options={})
137
+ options.merge!( :docid => docid, :fields => fields )
138
+ code, r = PUT "/docs", options
139
+ return r
140
+ end
141
+
142
+ def update_variables(docid, variables, options={})
143
+ options.merge!( :docid => docid, :variables => variables )
144
+ code, r = PUT "/docs/variables", options
145
+ return r
146
+ end
147
+
148
+ def delete_document(docid, options={})
149
+ options.merge!( :docid => docid )
150
+ code, r = DELETE "/docs", options
151
+ return r
152
+ end
153
+
154
+ # the options argument may contain an :index_code definition to override
155
+ # this instance's default index_code
156
+ def promote(docid, query, options={})
157
+ options.merge!( :docid => docid, :query => query )
158
+ code, r = PUT "/promote", options
159
+ return r
160
+ end
161
+
162
+
163
+ # the options argument may contain an :index_code definition to override
164
+ # this instance's default index_code
165
+ # it can also contain any of the following:
166
+ # :start => an int with the number of results to skip
167
+ # :len => an int with the number of results to return
168
+ # :snippet => a comma separated list of field names for which a snippet
169
+ # should be returned. (requires an index that supports snippets)
170
+ # :fetch => a comma separated list of field names for which its content
171
+ # should be returned. (requires an index that supports storage)
172
+ # :function => an int with the index of the scoring function to be used
173
+ # for this query
174
+ def search(query, options={})
175
+ options = { :start => 0, :len => 10 }.merge(options)
176
+ options.merge!( :q => query )
177
+ begin
178
+ code, r = GET "/search", options
179
+ return r
180
+ rescue HttpCodeException
181
+ raise
182
+ end
183
+ end
184
+
185
+ def add_function(function_index, definition, options={})
186
+ options.merge!( :definition => definition )
187
+ code, r = PUT "/functions/#{function_index}", options
188
+ return r
189
+ end
190
+
191
+ def del_function(function_index, options={})
192
+ code, r = DELETE "/functions/#{function_index}", options
193
+ return r
194
+ end
195
+
196
+ def list_functions(options={})
197
+ code, r = GET "/functions"
198
+ return r
199
+ end
200
+
201
+ def create_index()
202
+ begin
203
+ code, r = PUT ""
204
+ raise IndexAlreadyExists if code == "204"
205
+ return r
206
+ rescue HttpCodeException
207
+ if $!.code == "409"
208
+ puts $!.code
209
+ raise TooManyIndexes
210
+ end
211
+ raise
212
+ end
213
+ end
214
+
215
+ def delete_index()
216
+ code, r = DELETE ""
217
+ return r
218
+ end
219
+
220
+ def metadata
221
+ metadata! if @metadata.nil?
222
+ return @metadata
223
+ end
224
+
225
+ def metadata!
226
+ code, @metadata = GET ""
227
+ return @metadata
228
+ end
229
+
230
+ end
231
+
232
+ class IndexAlreadyExists < StandardError
233
+ end
234
+ class TooManyIndexes < StandardError
235
+ end
236
+
237
+ class HttpCodeException < StandardError
238
+ def initialize(code, message)
239
+ @code = code
240
+ @message = message
241
+ super("#{code}: #{message}")
242
+ end
243
+
244
+ attr_accessor :code
245
+ attr_accessor :message
246
+ end
247
+
248
+ class HerokuClient < ApiClient
249
+ def initialize()
250
+ super(ENV['HEROKUTANK_API_URL'])
251
+ end
252
+ end
253
+
254
+
255
+ end
256
+
@@ -0,0 +1,15 @@
1
+ module Tanker
2
+
3
+ module Configuration
4
+
5
+ def configuration
6
+ @@configuration || raise(NotConfigured, "Please configure Tanker. Set Tanker.configuration = {:url => ''}")
7
+ end
8
+
9
+ def configuration=(new_configuration)
10
+ @@configuration = new_configuration
11
+ end
12
+
13
+ end
14
+
15
+ end
data/lib/tanker.rb ADDED
@@ -0,0 +1,97 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ require 'indextank_client'
4
+
5
+ require 'tanker/configuration'
6
+ require 'will_paginate/collection'
7
+
8
+ Bundler.setup :default
9
+
10
+ module Tanker
11
+
12
+ class NotConfigured < StandardError; end
13
+ class NoBlockGiven < StandardError; end
14
+
15
+ autoload :Configuration, 'tanker/configuration'
16
+
17
+ extend Configuration
18
+
19
+ class << self
20
+ def included(klass)
21
+ klass.instance_variable_set('@tanker_configuration', configuration)
22
+ klass.instance_variable_set('@tanker_indexes', [])
23
+ klass.send :include, InstanceMethods
24
+ klass.extend ClassMethods
25
+
26
+ class << klass
27
+ define_method(:per_page) { 10 } unless respond_to?(:per_page)
28
+ end
29
+
30
+ end
31
+ end
32
+
33
+ # these are the class methods added when Tanker is included
34
+ module ClassMethods
35
+
36
+ attr_reader :tanker_indexes, :index_name
37
+
38
+ def tankit(name, &block)
39
+ if block_given?
40
+ @index_name = name
41
+ self.instance_exec(&block)
42
+ else
43
+ raise(NoBlockGiven, 'Please provide a block')
44
+ end
45
+ end
46
+
47
+ def indexes(field)
48
+ @tanker_indexes << field
49
+ end
50
+
51
+ end
52
+
53
+ # these are the instace methods included que
54
+ module InstanceMethods
55
+
56
+ def tanker_indexes
57
+ self.class.tanker_indexes
58
+ end
59
+
60
+ def api
61
+ @api ||= IndexTank::ApiClient.new(Tanker.configuration[:url])
62
+ end
63
+
64
+ def index
65
+ @index ||= api.get_index(self.class.index_name)
66
+ end
67
+
68
+ def search_tank(query, page = 1, per_page = self.class.per_page)
69
+
70
+ results = index.search(query, :start => page, :len => per_page )
71
+ ids = results[:results].map{|res| res[:docid]}
72
+
73
+ @entries = WillPaginate::Collection.create(page, per_page) do |pager|
74
+ result = self.class.find(ids)
75
+ # inject the result array into the paginated collection:
76
+ pager.replace(result)
77
+
78
+ unless pager.total_entries
79
+ # the pager didn't manage to guess the total count, do it manually
80
+ pager.total_entries = results[:matches]
81
+ end
82
+ end
83
+ end
84
+ def update_tank_indexes
85
+ hash = {}
86
+ tanker_indexes.each do |idx|
87
+ hash[idx] = self.send(idx.to_s)
88
+ end
89
+ index.add_document(id, hash)
90
+ end
91
+
92
+ def delete_tank_indexes
93
+ index.delete_document(id)
94
+ end
95
+
96
+ end
97
+ end
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ Bundler.setup :test
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'tanker'
7
+ require 'rspec'
8
+
9
+ Rspec.configure do |c|
10
+ c.mock_with :rspec
11
+ end
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ Tanker.configuration = {:url => 'http://api.indextank.com'}
4
+
5
+ class Dummy
6
+
7
+ end
8
+
9
+
10
+ class Person
11
+ include Tanker
12
+
13
+ tankit 'persons' do
14
+ indexes :name
15
+ end
16
+
17
+ def id
18
+ 1
19
+ end
20
+
21
+ def name
22
+ 'paco'
23
+ end
24
+ end
25
+
26
+ describe Tanker do
27
+
28
+ it 'sets configuration' do
29
+ conf = {:url => 'http://api.indextank.com'}
30
+ Tanker.configuration = conf
31
+
32
+ Tanker.configuration.should == conf
33
+ end
34
+
35
+ it 'checks for configuration when the module is included' do
36
+ Tanker.configuration = nil
37
+
38
+ lambda {
39
+ Dummy.send(:include, Tanker)
40
+ }.should raise_error(Tanker::NotConfigured)
41
+ end
42
+
43
+ it 'should requiquire a block when seting up tanker model' do
44
+ Tanker.configuration = {:url => 'http://api.indextank.com'}
45
+ Dummy.send(:include, Tanker)
46
+ lambda {
47
+ Dummy.send(:tankit, 'dummy index')
48
+ }.should raise_error(Tanker::NoBlockGiven)
49
+ end
50
+
51
+ it 'should set indexable fields' do
52
+ Tanker.configuration = {:url => 'http://api.indextank.com'}
53
+ Dummy.send(:include, Tanker)
54
+ Dummy.send(:tankit, 'dummy index') do
55
+ indexes :field
56
+ end
57
+
58
+ dummy_instance = Dummy.new
59
+ dummy_instance.tanker_indexes.include?(:field).should == true
60
+ end
61
+
62
+ describe 'tanker instance' do
63
+ it 'should create an api instance' do
64
+ person = Person.new
65
+
66
+ person.api.class.should == IndexTank::ApiClient
67
+ end
68
+
69
+ it 'should create a connexion to index tank' do
70
+ person = Person.new
71
+
72
+ person.index.class.should == IndexTank::IndexClient
73
+ end
74
+
75
+ it 'should be able to perform a seach query' do
76
+ person = Person.new
77
+
78
+ person.index.should_receive(:search).and_return(
79
+ {
80
+ :matches => 1,
81
+ :results => [{
82
+ :docid => 1,
83
+ :name => 'pedro'
84
+ }],
85
+ :search_time => 1
86
+ }
87
+ )
88
+
89
+ person.class.should_receive(:find).and_return(
90
+ [person]
91
+ )
92
+
93
+ collection = person.search_tank('hey!')
94
+ collection.class.should == WillPaginate::Collection
95
+ collection.total_entries.should == 1
96
+ collection.total_pages.should == 1
97
+ collection.per_page.should == 10
98
+ collection.current_page.should == 1
99
+ end
100
+
101
+ it 'should be able to update the index' do
102
+ person = Person.new
103
+
104
+ person.index.should_receive(:add_document)
105
+
106
+ person.update_tank_indexes
107
+ end
108
+
109
+ it 'should be able to delete de document from the index' do
110
+ person = Person.new
111
+
112
+ person.index.should_receive(:delete_document)
113
+
114
+ person.delete_tank_indexes
115
+ end
116
+
117
+ end
118
+ end
data/tanker.gemspec ADDED
@@ -0,0 +1,62 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{tanker}
8
+ s.version = "0.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["@kidpollo"]
12
+ s.date = %q{2010-10-04}
13
+ s.description = %q{IndexTank is a great search indexing service, this gem tries to make any orm keep in sync with indextank with ease}
14
+ s.email = %q{kidpollo@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "autotest/discover.rb",
29
+ "lib/indextank_client.rb",
30
+ "lib/tanker.rb",
31
+ "lib/tanker/configuration.rb",
32
+ "spec/spec_helper.rb",
33
+ "spec/tanker_spec.rb",
34
+ "tanker.gemspec"
35
+ ]
36
+ s.homepage = %q{http://github.com/kidpollo/tanker}
37
+ s.rdoc_options = ["--charset=UTF-8"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.7}
40
+ s.summary = %q{IndexTank integration to your favorite orm}
41
+ s.test_files = [
42
+ "spec/spec_helper.rb",
43
+ "spec/tanker_spec.rb"
44
+ ]
45
+
46
+ if s.respond_to? :specification_version then
47
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
+ s.add_development_dependency(%q<rspec>, [">= 2.0.0.beta.22"])
52
+ s.add_runtime_dependency(%q<will_paginate>, [">= 2.3.15"])
53
+ else
54
+ s.add_dependency(%q<rspec>, [">= 2.0.0.beta.22"])
55
+ s.add_dependency(%q<will_paginate>, [">= 2.3.15"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<rspec>, [">= 2.0.0.beta.22"])
59
+ s.add_dependency(%q<will_paginate>, [">= 2.3.15"])
60
+ end
61
+ end
62
+
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tanker
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 0
9
+ version: 0.0.0
10
+ platform: ruby
11
+ authors:
12
+ - "@kidpollo"
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-04 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 0
31
+ - 0
32
+ - beta
33
+ - 22
34
+ version: 2.0.0.beta.22
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: will_paginate
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ segments:
46
+ - 2
47
+ - 3
48
+ - 15
49
+ version: 2.3.15
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ description: IndexTank is a great search indexing service, this gem tries to make any orm keep in sync with indextank with ease
53
+ email: kidpollo@gmail.com
54
+ executables: []
55
+
56
+ extensions: []
57
+
58
+ extra_rdoc_files:
59
+ - LICENSE
60
+ - README.rdoc
61
+ files:
62
+ - .document
63
+ - .gitignore
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - LICENSE
67
+ - README.rdoc
68
+ - Rakefile
69
+ - VERSION
70
+ - autotest/discover.rb
71
+ - lib/indextank_client.rb
72
+ - lib/tanker.rb
73
+ - lib/tanker/configuration.rb
74
+ - spec/spec_helper.rb
75
+ - spec/tanker_spec.rb
76
+ - tanker.gemspec
77
+ has_rdoc: true
78
+ homepage: http://github.com/kidpollo/tanker
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options:
83
+ - --charset=UTF-8
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ requirements: []
103
+
104
+ rubyforge_project:
105
+ rubygems_version: 1.3.7
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: IndexTank integration to your favorite orm
109
+ test_files:
110
+ - spec/spec_helper.rb
111
+ - spec/tanker_spec.rb