Commit 44bc22ee8491f70adec6e6edbd269c609fe88b07

Authored by Braulio Bhavamitra
1 parent 925fd62d

Remove acts_as_ferret

Showing 37 changed files with 0 additions and 3679 deletions   Show diff stats
vendor/plugins/acts_as_ferret/LICENSE
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -Copyright (c) 2006 Kasper Weibel, Jens Kraemer  
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.  
vendor/plugins/acts_as_ferret/README
@@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
1 -= acts_as_ferret  
2 -  
3 -This ActiveRecord mixin adds full text search capabilities to any Rails model.  
4 -  
5 -It is heavily based on the original acts_as_ferret plugin done by  
6 -Kasper Weibel and a modified version done by Thomas Lockney, which  
7 -both can be found on http://ferret.davebalmain.com/trac/wiki/FerretOnRails  
8 -  
9 -== Installation  
10 -  
11 -=== Installation inside your Rails project via script/plugin  
12 -  
13 -script/plugin install svn://projects.jkraemer.net/acts_as_ferret/trunk/plugin/acts_as_ferret  
14 -  
15 -Aaf is is also available via git from Rubyforge:  
16 -git clone git://rubyforge.org/actsasferret.git  
17 -  
18 -=== System-wide installation with Rubygems  
19 -  
20 -<tt>sudo gem install acts_as_ferret</tt>  
21 -  
22 -To use acts_as_ferret in your project, add the following line to your  
23 -project's config/environment.rb:  
24 -  
25 -<tt>require 'acts_as_ferret'</tt>  
26 -  
27 -Call the aaf_install script inside your project directory to install the sample  
28 -config file and the drb server start/stop script.  
29 -  
30 -  
31 -== Usage  
32 -  
33 -include the following in your model class (specifiying the fields you want to get indexed):  
34 -  
35 -<tt>acts_as_ferret :fields => [ :title, :description ]</tt>  
36 -  
37 -now you can use ModelClass.find_by_contents(query) to find instances of your model  
38 -whose indexed fields match a given query. All query terms are required by default,  
39 -but explicit OR queries are possible. This differs from the ferret default, but  
40 -imho is the more often needed/expected behaviour (more query terms result in  
41 -less results).  
42 -  
43 -Please see ActsAsFerret::ActMethods#acts_as_ferret for more information.  
44 -  
45 -== License  
46 -  
47 -Released under the MIT license.  
48 -  
49 -== Authors  
50 -  
51 -* Kasper Weibel Nielsen-Refs (original author)  
52 -* Jens Kraemer <jk@jkraemer.net> (current maintainer)  
53 -  
vendor/plugins/acts_as_ferret/bin/aaf_install
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -# acts_as_ferret gem install script  
2 -# Use inside the root of your Rails project  
3 -require 'fileutils'  
4 -  
5 -@basedir = File.join(File.dirname(__FILE__), '..')  
6 -  
7 -def install(dir, file, executable=false)  
8 - puts "Installing: #{file}"  
9 - target = File.join('.', dir, file)  
10 - if File.exists?(target)  
11 - puts "#{target} already exists, skipping"  
12 - else  
13 - FileUtils.cp File.join(@basedir, dir, file), target  
14 - FileUtils.chmod 0755, target if executable  
15 - end  
16 -end  
17 -  
18 -  
19 -install 'script', 'ferret_server', true  
20 -install 'config', 'ferret_server.yml'  
21 -  
22 -puts IO.read(File.join(@basedir, 'README'))  
23 -  
vendor/plugins/acts_as_ferret/config/ferret_server.yml
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -# configuration for the acts_as_ferret DRb server  
2 -# host: where to reach the DRb server (used by application processes to contact the server)  
3 -# port: which port the server should listen on  
4 -# socket: where the DRb server should create the socket (absolute path), this setting overrides host:port configuration  
5 -# pid_file: location of the server's pid file (relative to RAILS_ROOT)  
6 -# log_file: log file (default: RAILS_ROOT/log/ferret_server.log  
7 -# log_level: log level for the server's logger  
8 -production:  
9 - host: localhost  
10 - port: 9010  
11 - pid_file: log/ferret.pid  
12 - log_file: log/ferret_server.log  
13 - log_level: warn  
14 -  
15 -# aaf won't try to use the DRb server in environments that are not  
16 -# configured here.  
17 -#development:  
18 -# host: localhost  
19 -# port: 9010  
20 -# pid_file: log/ferret.pid  
21 -#test:  
22 -# host: localhost  
23 -# port: 9009  
24 -# pid_file: log/ferret.pid  
vendor/plugins/acts_as_ferret/doc/README.win32
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -Credits  
2 -=======  
3 -  
4 -The Win32 service support scripts have been written by  
5 -Herryanto Siatono <herryanto@pluitsolutions.com>.  
6 -  
7 -See his accompanying blog posting at  
8 -http://www.pluitsolutions.com/2007/07/30/acts-as-ferret-drbserver-win32-service/  
9 -  
10 -  
11 -Usage  
12 -=====  
13 -  
14 -There are two scripts:  
15 -  
16 -script/ferret_service is used to install/remove/start/stop the win32 service.  
17 -  
18 -script/ferret_daemon is to be called by Win32 service to start/stop the  
19 -DRbServer.  
20 -  
21 -Run 'ruby script/ferret_service -h' for more info.  
22 -  
23 -  
vendor/plugins/acts_as_ferret/doc/monit-example
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -# monit configuration snippet to watch the Ferret DRb server shipped with  
2 -# acts_as_ferret  
3 -check process ferret with pidfile /path/to/ferret.pid  
4 -  
5 - # username is the user the drb server should be running as (It's good practice  
6 - # to run such services as a non-privileged user)  
7 - start program = "/bin/su -c 'cd /path/to/your/app/current/ && script/ferret_server -e production start' username"  
8 - stop program = "/bin/su -c 'cd /path/to/your/app/current/ && script/ferret_server -e production stop' username"  
9 -  
10 - # cpu usage boundaries  
11 - if cpu > 60% for 2 cycles then alert  
12 - if cpu > 90% for 5 cycles then restart  
13 -  
14 - # memory usage varies with index size and usage scenarios, so check how  
15 - # much memory your DRb server uses up usually and add some spare to that  
16 - # before enabling this rule:  
17 - # if totalmem > 50.0 MB for 5 cycles then restart  
18 -  
19 - # adjust port numbers according to your setup:  
20 - if failed port 9010 then alert  
21 - if failed port 9010 for 2 cycles then restart  
22 - group ferret  
vendor/plugins/acts_as_ferret/init.rb
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -# Copyright (c) 2006 Kasper Weibel Nielsen-Refs, Thomas Lockney, Jens Krämer  
2 -#  
3 -# Permission is hereby granted, free of charge, to any person obtaining a copy  
4 -# of this software and associated documentation files (the "Software"), to deal  
5 -# in the Software without restriction, including without limitation the rights  
6 -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
7 -# copies of the Software, and to permit persons to whom the Software is  
8 -# furnished to do so, subject to the following conditions:  
9 -#  
10 -# The above copyright notice and this permission notice shall be included in all  
11 -# copies or substantial portions of the Software.  
12 -#  
13 -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
14 -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
15 -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
16 -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
17 -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  
18 -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  
19 -# SOFTWARE.  
20 -  
21 -require 'acts_as_ferret'  
22 -  
23 -config.after_initialize { ActsAsFerret::load_config }  
24 -config.to_prepare { ActsAsFerret::load_config }  
vendor/plugins/acts_as_ferret/install.rb
@@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
1 -# acts_as_ferret install script  
2 -require 'fileutils'  
3 -  
4 -def install(file)  
5 - puts "Installing: #{file}"  
6 - target = File.join(File.dirname(__FILE__), '..', '..', '..', file)  
7 - if File.exists?(target)  
8 - puts "target #{target} already exists, skipping"  
9 - else  
10 - FileUtils.cp File.join(File.dirname(__FILE__), file), target  
11 - end  
12 -end  
13 -  
14 -install File.join( 'script', 'ferret_server' )  
15 -install File.join( 'config', 'ferret_server.yml' )  
16 -  
17 -puts IO.read(File.join(File.dirname(__FILE__), 'README'))  
18 -  
vendor/plugins/acts_as_ferret/lib/act_methods.rb
@@ -1,155 +0,0 @@ @@ -1,155 +0,0 @@
1 -module ActsAsFerret #:nodoc:  
2 -  
3 - # This module defines the acts_as_ferret method and is included into  
4 - # ActiveRecord::Base  
5 - module ActMethods  
6 -  
7 -  
8 - def reloadable?; false end  
9 -  
10 - # declares a class as ferret-searchable.  
11 - #  
12 - # ====options:  
13 - # fields:: names all fields to include in the index. If not given,  
14 - # all attributes of the class will be indexed. You may also give  
15 - # symbols pointing to instance methods of your model here, i.e.  
16 - # to retrieve and index data from a related model.  
17 - #  
18 - # additional_fields:: names fields to include in the index, in addition  
19 - # to those derived from the db scheme. use if you want  
20 - # to add custom fields derived from methods to the db  
21 - # fields (which will be picked by aaf). This option will  
22 - # be ignored when the fields option is given, in that  
23 - # case additional fields get specified there.  
24 - #  
25 - # if:: Can be set to a block that will be called with the record in question  
26 - # to determine if it should be indexed or not.  
27 - #  
28 - # index_dir:: declares the directory where to put the index for this class.  
29 - # The default is RAILS_ROOT/index/RAILS_ENV/CLASSNAME.  
30 - # The index directory will be created if it doesn't exist.  
31 - #  
32 - # reindex_batch_size:: reindexing is done in batches of this size, default is 1000  
33 - # mysql_fast_batches:: set this to false to disable the faster mysql batching  
34 - # algorithm if this model uses a non-integer primary key named  
35 - # 'id' on MySQL.  
36 - #  
37 - # ferret:: Hash of Options that directly influence the way the Ferret engine works. You  
38 - # can use most of the options the Ferret::I class accepts here, too. Among the  
39 - # more useful are:  
40 - #  
41 - # or_default:: whether query terms are required by  
42 - # default (the default, false), or not (true)  
43 - #  
44 - # analyzer:: the analyzer to use for query parsing (default: nil,  
45 - # which means the ferret StandardAnalyzer gets used)  
46 - #  
47 - # default_field:: use to set one or more fields that are searched for query terms  
48 - # that don't have an explicit field list. This list should *not*  
49 - # contain any untokenized fields. If it does, you're asking  
50 - # for trouble (i.e. not getting results for queries having  
51 - # stop words in them). Aaf by default initializes the default field  
52 - # list to contain all tokenized fields. If you use :single_index => true,  
53 - # you really should set this option specifying your default field  
54 - # list (which should be equal in all your classes sharing the index).  
55 - # Otherwise you might get incorrect search results and you won't get  
56 - # any lazy loading of stored field data.  
57 - #  
58 - # For downwards compatibility reasons you can also specify the Ferret options in the  
59 - # last Hash argument.  
60 - def acts_as_ferret(options={})  
61 -  
62 - extend ClassMethods  
63 -  
64 - include InstanceMethods  
65 - include MoreLikeThis::InstanceMethods  
66 -  
67 - if options[:rdig]  
68 - cattr_accessor :rdig_configuration  
69 - self.rdig_configuration = options[:rdig]  
70 - require 'rdig_adapter'  
71 - include ActsAsFerret::RdigAdapter  
72 - end  
73 -  
74 - unless included_modules.include?(ActsAsFerret::WithoutAR)  
75 - # set up AR hooks  
76 - after_create :ferret_create  
77 - after_update :ferret_update  
78 - after_destroy :ferret_destroy  
79 - end  
80 -  
81 - cattr_accessor :aaf_configuration  
82 -  
83 - # apply default config for rdig based models  
84 - if options[:rdig]  
85 - options[:fields] ||= { :title => { :boost => 3, :store => :yes },  
86 - :content => { :store => :yes } }  
87 - end  
88 -  
89 - # name of this index  
90 - index_name = options.delete(:index) || self.name.underscore  
91 -  
92 - index = ActsAsFerret::register_class_with_index(self, index_name, options)  
93 - self.aaf_configuration = index.index_definition.dup  
94 - logger.debug "configured index for class #{self.name}:\n#{aaf_configuration.inspect}"  
95 -  
96 - # update our copy of the global index config with options local to this class  
97 - aaf_configuration[:class_name] ||= self.name  
98 - aaf_configuration[:if] ||= options[:if]  
99 -  
100 - # add methods for retrieving field values  
101 - add_fields options[:fields]  
102 - add_fields options[:additional_fields]  
103 - add_fields aaf_configuration[:fields]  
104 - add_fields aaf_configuration[:additional_fields]  
105 -  
106 - # not good at class level, index might get initialized too early  
107 - #if options[:remote]  
108 - # aaf_index.ensure_index_exists  
109 - #end  
110 - end  
111 -  
112 -  
113 - protected  
114 -  
115 -  
116 - # helper to defines a method which adds the given field to a ferret  
117 - # document instance  
118 - def define_to_field_method(field, options = {})  
119 - method_name = "#{field}_to_ferret"  
120 - return if instance_methods.include?(method_name) # already defined  
121 - aaf_configuration[:defined_fields] ||= {}  
122 - aaf_configuration[:defined_fields][field] = options  
123 - dynamic_boost = options[:boost] if options[:boost].is_a?(Symbol)  
124 - via = options[:via] || field  
125 - define_method(method_name.to_sym) do  
126 - val = begin  
127 - content_for_field_name(field, via, dynamic_boost)  
128 - rescue  
129 - logger.warn("Error retrieving value for field #{field}: #{$!}")  
130 - ''  
131 - end  
132 - logger.debug("Adding field #{field} with value '#{val}' to index")  
133 - val  
134 - end  
135 - end  
136 -  
137 - def add_fields(field_config)  
138 - # TODO  
139 - #field_config.each do |*args|  
140 - # define_to_field_method *args  
141 - #end  
142 - if field_config.is_a? Hash  
143 - field_config.each_pair do |field, options|  
144 - define_to_field_method field, options  
145 - end  
146 - elsif field_config.respond_to?(:each)  
147 - field_config.each do |field|  
148 - define_to_field_method field  
149 - end  
150 - end  
151 - end  
152 -  
153 - end  
154 -  
155 -end  
vendor/plugins/acts_as_ferret/lib/acts_as_ferret.rb
@@ -1,567 +0,0 @@ @@ -1,567 +0,0 @@
1 -# Copyright (c) 2006 Kasper Weibel Nielsen-Refs, Thomas Lockney, Jens Krämer  
2 -#  
3 -# Permission is hereby granted, free of charge, to any person obtaining a copy  
4 -# of this software and associated documentation files (the "Software"), to deal  
5 -# in the Software without restriction, including without limitation the rights  
6 -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
7 -# copies of the Software, and to permit persons to whom the Software is  
8 -# furnished to do so, subject to the following conditions:  
9 -#  
10 -# The above copyright notice and this permission notice shall be included in all  
11 -# copies or substantial portions of the Software.  
12 -#  
13 -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
14 -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
15 -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
16 -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
17 -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  
18 -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  
19 -# SOFTWARE.  
20 -  
21 -require 'active_support'  
22 -require 'active_record'  
23 -require 'set'  
24 -require 'enumerator'  
25 -require 'ferret'  
26 -  
27 -require 'ferret_find_methods'  
28 -require 'remote_functions'  
29 -require 'blank_slate'  
30 -require 'bulk_indexer'  
31 -require 'ferret_extensions'  
32 -require 'act_methods'  
33 -require 'search_results'  
34 -require 'class_methods'  
35 -require 'ferret_result'  
36 -require 'instance_methods'  
37 -require 'without_ar'  
38 -  
39 -require 'multi_index'  
40 -require 'remote_multi_index'  
41 -require 'more_like_this'  
42 -  
43 -require 'index'  
44 -require 'local_index'  
45 -require 'remote_index'  
46 -  
47 -require 'ferret_server'  
48 -  
49 -require 'rdig_adapter'  
50 -  
51 -# The Rails ActiveRecord Ferret Mixin.  
52 -#  
53 -# This mixin adds full text search capabilities to any Rails model.  
54 -#  
55 -# The current version emerged from on the original acts_as_ferret plugin done by  
56 -# Kasper Weibel and a modified version done by Thomas Lockney, which both can be  
57 -# found on the Ferret Wiki: http://ferret.davebalmain.com/trac/wiki/FerretOnRails.  
58 -#  
59 -# basic usage:  
60 -# include the following in your model class (specifiying the fields you want to get indexed):  
61 -# acts_as_ferret :fields => [ :title, :description ]  
62 -#  
63 -# now you can use ModelClass.find_by_contents(query) to find instances of your model  
64 -# whose indexed fields match a given query. All query terms are required by default, but  
65 -# explicit OR queries are possible. This differs from the ferret default, but imho is the more  
66 -# often needed/expected behaviour (more query terms result in less results).  
67 -#  
68 -# Released under the MIT license.  
69 -#  
70 -# Authors:  
71 -# Kasper Weibel Nielsen-Refs (original author)  
72 -# Jens Kraemer <jk@jkraemer.net> (active maintainer since 2006)  
73 -#  
74 -#  
75 -# == Global properties  
76 -#  
77 -# raise_drb_errors:: Set this to true if you want aaf to raise Exceptions  
78 -# in case the DRb server cannot be reached (in other word - behave like  
79 -# versions up to 0.4.3). Defaults to false so DRb exceptions  
80 -# are logged but not raised. Be sure to set up some  
81 -# monitoring so you still detect when your DRb server died for  
82 -# whatever reason.  
83 -#  
84 -# remote:: Set this to false to force acts_as_ferret into local (non-DRb) mode even if  
85 -# config/ferret_server.yml contains a section for the current RAILS_ENV  
86 -# Usually you won't need to touch this option - just configure DRb for  
87 -# production mode in ferret_server.yml.  
88 -#  
89 -module ActsAsFerret  
90 -  
91 - class ActsAsFerretError < StandardError; end  
92 - class IndexNotDefined < ActsAsFerretError; end  
93 - class IndexAlreadyDefined < ActsAsFerretError; end  
94 -  
95 - # global Hash containing all multi indexes created by all classes using the plugin  
96 - # key is the concatenation of alphabetically sorted names of the classes the  
97 - # searcher searches.  
98 - @@multi_indexes = Hash.new  
99 - def self.multi_indexes; @@multi_indexes end  
100 -  
101 - # global Hash containing the ferret indexes of all classes using the plugin  
102 - # key is the index name.  
103 - @@ferret_indexes = Hash.new  
104 - def self.ferret_indexes; @@ferret_indexes end  
105 -  
106 - # mapping from class name to index name  
107 - @@index_using_classes = {}  
108 -  
109 - @@logger = Logger.new "#{RAILS_ROOT}/log/acts_as_ferret.log"  
110 - @@logger.level = ActiveRecord::Base.logger.level rescue Logger::DEBUG  
111 - mattr_accessor :logger  
112 -  
113 -  
114 - # Default ferret configuration for index fields  
115 - DEFAULT_FIELD_OPTIONS = {  
116 - :store => :no,  
117 - :highlight => :yes,  
118 - :index => :yes,  
119 - :term_vector => :with_positions_offsets,  
120 - :boost => 1.0  
121 - }  
122 -  
123 - @@raise_drb_errors = false  
124 - mattr_writer :raise_drb_errors  
125 - def self.raise_drb_errors?; @@raise_drb_errors end  
126 -  
127 - @@remote = nil  
128 - mattr_accessor :remote  
129 - def self.remote?  
130 - if @@remote.nil?  
131 - if ENV["FERRET_USE_LOCAL_INDEX"] || ActsAsFerret::Remote::Server.running  
132 - @@remote = false  
133 - else  
134 - @@remote = ActsAsFerret::Remote::Config.new.uri rescue false  
135 - end  
136 - if @@remote  
137 - logger.info "Will use remote index server which should be available at #{@@remote}"  
138 - else  
139 - logger.info "Will use local index."  
140 - end  
141 - end  
142 - @@remote  
143 - end  
144 - remote?  
145 -  
146 -  
147 - # Globally declares an index.  
148 - #  
149 - # This method is also used to implicitly declare an index when you use the  
150 - # acts_as_ferret call in your class. Returns the created index instance.  
151 - #  
152 - # === Options are:  
153 - #  
154 - # +models+:: Hash of model classes and their per-class option hashes which should  
155 - # use this index. Any models mentioned here will automatically use  
156 - # the index, there is no need to explicitly call +acts_as_ferret+ in the  
157 - # model class definition.  
158 - def self.define_index(name, options = {})  
159 - name = name.to_sym  
160 - pending_classes = nil  
161 - if ferret_indexes.has_key?(name)  
162 - # seems models have been already loaded. remove that index for now,  
163 - # re-register any already loaded classes later on.  
164 - idx = get_index(name)  
165 - pending_classes = idx.index_definition[:registered_models]  
166 - pending_classes_configs = idx.registered_models_config  
167 - idx.close  
168 - ferret_indexes.delete(name)  
169 - end  
170 -  
171 - index_definition = {  
172 - :index_dir => "#{ActsAsFerret::index_dir}/#{name}",  
173 - :name => name,  
174 - :single_index => false,  
175 - :reindex_batch_size => 1000,  
176 - :ferret => {},  
177 - :ferret_fields => {}, # list of indexed fields that will be filled later  
178 - :enabled => true, # used for class-wide disabling of Ferret  
179 - :mysql_fast_batches => true, # turn off to disable the faster, id based batching mechanism for MySQL  
180 - :raise_drb_errors => false # handle DRb connection errors by default  
181 - }.update( options )  
182 -  
183 - index_definition[:registered_models] = []  
184 -  
185 - # build ferret configuration  
186 - index_definition[:ferret] = {  
187 - :or_default => false,  
188 - :handle_parse_errors => true,  
189 - :default_field => nil, # will be set later on  
190 - #:max_clauses => 512,  
191 - #:analyzer => Ferret::Analysis::StandardAnalyzer.new,  
192 - # :wild_card_downcase => true  
193 - }.update( options[:ferret] || {} )  
194 -  
195 - index_definition[:user_default_field] = index_definition[:ferret][:default_field]  
196 -  
197 - unless remote?  
198 - ActsAsFerret::ensure_directory index_definition[:index_dir]  
199 - index_definition[:index_base_dir] = index_definition[:index_dir]  
200 - index_definition[:index_dir] = find_last_index_version(index_definition[:index_dir])  
201 - logger.debug "using index in #{index_definition[:index_dir]}"  
202 - end  
203 -  
204 - # these properties are somewhat vital to the plugin and shouldn't  
205 - # be overwritten by the user:  
206 - index_definition[:ferret].update(  
207 - :key => ((Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql?) ? [:id, :class_name, :schema_name] : [:id, :class_name]),  
208 - :path => index_definition[:index_dir],  
209 - :auto_flush => true, # slower but more secure in terms of locking problems TODO disable when running in drb mode?  
210 - :create_if_missing => true  
211 - )  
212 -  
213 - # field config  
214 - index_definition[:ferret_fields] = build_field_config( options[:fields] )  
215 - index_definition[:ferret_fields].update build_field_config( options[:additional_fields] )  
216 -  
217 - idx = ferret_indexes[name] = create_index_instance( index_definition )  
218 -  
219 - # re-register early loaded classes  
220 - if pending_classes  
221 - pending_classes.each { |clazz| idx.register_class clazz, { :force_re_registration => true }.merge(pending_classes_configs[clazz]) }  
222 - end  
223 -  
224 - if models = options[:models]  
225 - models.each do |clazz, config|  
226 - clazz.send :include, ActsAsFerret::WithoutAR unless clazz.respond_to?(:acts_as_ferret)  
227 - clazz.acts_as_ferret config.merge(:index => name)  
228 - end  
229 - end  
230 -  
231 - return idx  
232 - end  
233 -  
234 - # called internally by the acts_as_ferret method  
235 - #  
236 - # returns the index  
237 - def self.register_class_with_index(clazz, index_name, options = {})  
238 - index_name = index_name.to_sym  
239 - @@index_using_classes[clazz.name] = index_name  
240 - unless index = ferret_indexes[index_name]  
241 - # index definition on the fly  
242 - # default to all attributes of this class  
243 - options[:fields] ||= clazz.new.attributes.keys.map { |k| k.to_sym }  
244 - index = define_index index_name, options  
245 - end  
246 - index.register_class(clazz, options)  
247 - return index  
248 - end  
249 -  
250 - def self.load_config  
251 - # using require_dependency to make the reloading in dev mode work.  
252 - require_dependency "#{RAILS_ROOT}/config/aaf.rb"  
253 - ActsAsFerret::logger.info "loaded configuration file aaf.rb"  
254 - rescue LoadError  
255 - ensure  
256 - @aaf_config_loaded = true  
257 - end  
258 -  
259 - # returns the index with the given name.  
260 - def self.get_index(name)  
261 - name = name.to_sym rescue nil  
262 - unless ferret_indexes.has_key?(name)  
263 - if @aaf_config_loaded  
264 - raise IndexNotDefined.new(name.to_s)  
265 - else  
266 - load_config and return get_index name  
267 - end  
268 - end  
269 - ferret_indexes[name]  
270 - end  
271 -  
272 - # count hits for a query with multiple models  
273 - def self.total_hits(query, models, options = {})  
274 - find_index(models).total_hits query, options.merge( :models => models )  
275 - end  
276 -  
277 - # find ids of records with multiple models  
278 - # TODO pagination logic?  
279 - def self.find_ids(query, models, options = {}, &block)  
280 - find_index(models).find_ids query, options.merge( :models => models ), &block  
281 - end  
282 -  
283 - def self.find_index(models_or_index_name)  
284 - case models_or_index_name  
285 - when Symbol  
286 - get_index models_or_index_name  
287 - when String  
288 - get_index models_or_index_name.to_sym  
289 - #when Array  
290 - # get_index_for models_or_index_name  
291 - else  
292 - get_index_for models_or_index_name  
293 - end  
294 - end  
295 -  
296 - def self.find(query, models_or_index_name, options = {}, ar_options = {})  
297 - # TODO generalize local/remote index so we can remove the workaround below  
298 - # (replace logic in class_methods#find_with_ferret)  
299 - # maybe put pagination stuff in a module to be included by all index  
300 - # implementations  
301 - models = [ models_or_index_name ] if Class === models_or_index_name  
302 - if models && models.size == 1  
303 - return models.shift.find_with_ferret query, options, ar_options  
304 - end  
305 - index = find_index(models_or_index_name)  
306 - multi = (MultiIndex === index or index.shared?)  
307 - if options[:per_page]  
308 - options[:page] = options[:page] ? options[:page].to_i : 1  
309 - limit = options[:per_page]  
310 - offset = (options[:page] - 1) * limit  
311 - if ar_options[:conditions] && !multi  
312 - ar_options[:limit] = limit  
313 - ar_options[:offset] = offset  
314 - options[:limit] = :all  
315 - options.delete :offset  
316 - else  
317 - # do pagination with ferret (or after everything is done in the case  
318 - # of multi_search)  
319 - options[:limit] = limit  
320 - options[:offset] = offset  
321 - end  
322 - elsif ar_options[:conditions]  
323 - if multi  
324 - # multisearch ignores find_options limit and offset  
325 - options[:limit] ||= ar_options.delete(:limit)  
326 - options[:offset] ||= ar_options.delete(:offset)  
327 - else  
328 - # let the db do the limiting and offsetting for single-table searches  
329 - unless options[:limit] == :all  
330 - ar_options[:limit] ||= options.delete(:limit)  
331 - end  
332 - ar_options[:offset] ||= options.delete(:offset)  
333 - options[:limit] = :all  
334 - end  
335 - end  
336 -  
337 - total_hits, result = index.find_records query, options.merge(:models => models), ar_options  
338 - logger.debug "Query: #{query}\ntotal hits: #{total_hits}, results delivered: #{result.size}"  
339 - SearchResults.new(result, total_hits, options[:page], options[:per_page])  
340 - end  
341 -  
342 - # returns the index used by the given class.  
343 - #  
344 - # If multiple classes are given, either the single index shared by these  
345 - # classes, or a multi index (to be used for search only) across the indexes  
346 - # of all models, is returned.  
347 - def self.get_index_for(*classes)  
348 - classes.flatten!  
349 - raise ArgumentError.new("no class specified") unless classes.any?  
350 - classes.map!(&:constantize) unless Class === classes.first  
351 - logger.debug "index_for #{classes.inspect}"  
352 - index = if classes.size > 1  
353 - indexes = classes.map { |c| get_index_for c }.uniq  
354 - indexes.size > 1 ? multi_index(indexes) : indexes.first  
355 - else  
356 - clazz = classes.first  
357 - clazz = clazz.superclass while clazz && !@@index_using_classes.has_key?(clazz.name)  
358 - get_index @@index_using_classes[clazz.name]  
359 - end  
360 - raise IndexNotDefined.new("no index found for class: #{classes.map(&:name).join(',')}") if index.nil?  
361 - return index  
362 - end  
363 -  
364 -  
365 - # creates a new Index instance.  
366 - def self.create_index_instance(definition)  
367 - (remote? ? RemoteIndex : LocalIndex).new(definition)  
368 - end  
369 -  
370 - def self.rebuild_index(name)  
371 - get_index(name).rebuild_index  
372 - end  
373 -  
374 - def self.change_index_dir(name, new_dir)  
375 - get_index(name).change_index_dir new_dir  
376 - end  
377 -  
378 - # find the most recent version of an index  
379 - def self.find_last_index_version(basedir)  
380 - # check for versioned index  
381 - versions = Dir.entries(basedir).select do |f|  
382 - dir = File.join(basedir, f)  
383 - File.directory?(dir) && File.file?(File.join(dir, 'segments')) && f =~ /^\d+(_\d+)?$/  
384 - end  
385 - if versions.any?  
386 - # select latest version  
387 - versions.sort!  
388 - File.join basedir, versions.last  
389 - else  
390 - basedir  
391 - end  
392 - end  
393 -  
394 - # returns a MultiIndex instance operating on a MultiReader  
395 - def self.multi_index(indexes)  
396 - index_names = indexes.dup  
397 - index_names = index_names.map(&:to_s) if Symbol === index_names.first  
398 - if String === index_names.first  
399 - indexes = index_names.map{ |name| get_index name }  
400 - else  
401 - index_names = index_names.map{ |i| i.index_name.to_s }  
402 - end  
403 - key = index_names.sort.join(",")  
404 - ActsAsFerret::multi_indexes[key] ||= (remote? ? ActsAsFerret::RemoteMultiIndex : ActsAsFerret::MultiIndex).new(indexes)  
405 - end  
406 -  
407 - # check for per-model conditions and return these if provided  
408 - def self.conditions_for_model(model, conditions = {})  
409 - if Hash === conditions  
410 - key = model.name.underscore.to_sym  
411 - conditions = conditions[key]  
412 - end  
413 - return conditions  
414 - end  
415 -  
416 - # retrieves search result records from a data structure like this:  
417 - # { 'Model1' => { '1' => [ rank, score ], '2' => [ rank, score ] }  
418 - #  
419 - # TODO: in case of STI AR will filter out hits from other  
420 - # classes for us, but this  
421 - # will lead to less results retrieved --> scoping of ferret query  
422 - # to self.class is still needed.  
423 - # from the ferret ML (thanks Curtis Hatter)  
424 - # > I created a method in my base STI class so I can scope my query. For scoping  
425 - # > I used something like the following line:  
426 - # >  
427 - # > query << " role:#{self.class.eql?(Contents) '*' : self.class}"  
428 - # >  
429 - # > Though you could make it more generic by simply asking  
430 - # > "self.descends_from_active_record?" which is how rails decides if it should  
431 - # > scope your "find" query for STI models. You can check out "base.rb" in  
432 - # > activerecord to see that.  
433 - # but maybe better do the scoping in find_ids_with_ferret...  
434 - def self.retrieve_records(id_arrays, find_options = {})  
435 - result = []  
436 - # get objects for each model  
437 - id_arrays.each do |model, id_array|  
438 - next if id_array.empty?  
439 - model_class = model.constantize  
440 -  
441 - # merge conditions  
442 - conditions = conditions_for_model model_class, find_options[:conditions]  
443 - conditions = combine_conditions([ "#{model_class.table_name}.#{model_class.primary_key} in (?)",  
444 - id_array.keys ],  
445 - conditions)  
446 -  
447 - # check for include association that might only exist on some models in case of multi_search  
448 - filtered_include_options = []  
449 - if include_options = find_options[:include]  
450 - include_options = [ include_options ] unless include_options.respond_to?(:each)  
451 - include_options.each do |include_option|  
452 - filtered_include_options << include_option if model_class.reflections.has_key?(include_option.is_a?(Hash) ? include_option.keys[0].to_sym : include_option.to_sym)  
453 - end  
454 - end  
455 - filtered_include_options = nil if filtered_include_options.empty?  
456 -  
457 - # fetch  
458 - tmp_result = model_class.find(:all, find_options.merge(:conditions => conditions,  
459 - :include => filtered_include_options))  
460 -  
461 - # set scores and rank  
462 - tmp_result.each do |record|  
463 - record.ferret_rank, record.ferret_score = id_array[record.id.to_s]  
464 - end  
465 - # merge with result array  
466 - result += tmp_result  
467 - end  
468 -  
469 - # order results as they were found by ferret, unless an AR :order  
470 - # option was given  
471 - result.sort! { |a, b| a.ferret_rank <=> b.ferret_rank } unless find_options[:order]  
472 - return result  
473 - end  
474 -  
475 - # combine our conditions with those given by user, if any  
476 - def self.combine_conditions(conditions, additional_conditions = [])  
477 - returning conditions do  
478 - if additional_conditions && additional_conditions.any?  
479 - cust_opts = (Array === additional_conditions) ? additional_conditions.dup : [ additional_conditions ]  
480 - logger.debug "cust_opts: #{cust_opts.inspect}"  
481 - conditions.first << " and " << cust_opts.shift  
482 - conditions.concat(cust_opts)  
483 - end  
484 - end  
485 - end  
486 -  
487 - def self.build_field_config(fields)  
488 - field_config = {}  
489 - case fields  
490 - when Array  
491 - fields.each { |name| field_config[name] = field_config_for name }  
492 - when Hash  
493 - fields.each { |name, options| field_config[name] = field_config_for name, options }  
494 - else raise InvalidArgumentError.new(":fields option must be Hash or Array")  
495 - end if fields  
496 - return field_config  
497 - end  
498 -  
499 - def self.ensure_directory(dir)  
500 - FileUtils.mkdir_p dir unless (File.directory?(dir) || File.symlink?(dir))  
501 - end  
502 -  
503 -  
504 - # make sure the default index base dir exists. by default, all indexes are created  
505 - # under RAILS_ROOT/index/RAILS_ENV  
506 - def self.init_index_basedir  
507 - index_base = "#{RAILS_ROOT}/index"  
508 - @@index_dir = "#{index_base}/#{RAILS_ENV}"  
509 - end  
510 -  
511 - mattr_accessor :index_dir  
512 - init_index_basedir  
513 -  
514 - def self.append_features(base)  
515 - super  
516 - base.extend(ClassMethods)  
517 - end  
518 -  
519 - # builds a FieldInfos instance for creation of an index  
520 - def self.field_infos(index_definition)  
521 - # default attributes for fields  
522 - fi = Ferret::Index::FieldInfos.new(:store => :no,  
523 - :index => :yes,  
524 - :term_vector => :no,  
525 - :boost => 1.0)  
526 - # primary key  
527 - fi.add_field(:id, :store => :yes, :index => :untokenized)  
528 - # class_name  
529 - fi.add_field(:class_name, :store => :yes, :index => :untokenized)  
530 -  
531 - # other fields  
532 - index_definition[:ferret_fields].each_pair do |field, options|  
533 - options = options.dup  
534 - options.delete :via  
535 - options.delete :boost if options[:boost].is_a?(Symbol) # dynamic boost  
536 - fi.add_field(field, options)  
537 - end  
538 - return fi  
539 - end  
540 -  
541 - def self.close_multi_indexes  
542 - # close combined index readers, just in case  
543 - # this seems to fix a strange test failure that seems to relate to a  
544 - # multi_index looking at an old version of the content_base index.  
545 - multi_indexes.each_pair do |key, index|  
546 - # puts "#{key} -- #{self.name}"  
547 - # TODO only close those where necessary (watch inheritance, where  
548 - # self.name is base class of a class where key is made from)  
549 - index.close #if key =~ /#{self.name}/  
550 - end  
551 - multi_indexes.clear  
552 - end  
553 -  
554 - protected  
555 -  
556 - def self.field_config_for(fieldname, options = {})  
557 - config = DEFAULT_FIELD_OPTIONS.merge options  
558 - config[:via] ||= fieldname  
559 - config[:term_vector] = :no if config[:index] == :no  
560 - return config  
561 - end  
562 -  
563 -end  
564 -  
565 -# include acts_as_ferret method into ActiveRecord::Base  
566 -ActiveRecord::Base.extend ActsAsFerret::ActMethods  
567 -  
vendor/plugins/acts_as_ferret/lib/ar_mysql_auto_reconnect_patch.rb
@@ -1,41 +0,0 @@ @@ -1,41 +0,0 @@
1 -# Source: http://pastie.caboo.se/154842  
2 -#  
3 -# in /etc/my.cnf on the MySQL server, you can set the interactive-timeout parameter,  
4 -# for example, 12 hours = 28800 sec  
5 -# interactive-timeout=28800  
6 -  
7 -# in ActiveRecord, setting the verification_timeout to something less than  
8 -# the interactive-timeout parameter; 14400 sec = 6 hours  
9 -ActiveRecord::Base.verification_timeout = 14400  
10 -ActiveRecord::Base.establish_connection  
11 -  
12 -# Below is a monkey patch for keeping ActiveRecord connections alive.  
13 -# http://www.sparecycles.org/2007/7/2/saying-goodbye-to-lost-connections-in-rails  
14 -  
15 -module ActiveRecord  
16 - module ConnectionAdapters  
17 - class MysqlAdapter  
18 - def execute(sql, name = nil) #:nodoc:  
19 - reconnect_lost_connections = true  
20 - begin  
21 - log(sql, name) { @connection.query(sql) }  
22 - rescue ActiveRecord::StatementInvalid => exception  
23 - if reconnect_lost_connections and exception.message =~ /(Lost connection to MySQL server during query  
24 -|MySQL server has gone away)/  
25 - reconnect_lost_connections = false  
26 - reconnect!  
27 - retry  
28 - elsif exception.message.split(":").first =~ /Packets out of order/  
29 - raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database.  
30 - Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hash  
31 -ing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql  
32 -bindings."  
33 - else  
34 - raise  
35 - end  
36 - end  
37 - end  
38 - end  
39 - end  
40 -end  
41 -  
vendor/plugins/acts_as_ferret/lib/blank_slate.rb
@@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
1 -if defined?(BlankSlate)  
2 - # Rails 2.x has it already  
3 - module ActsAsFerret  
4 - class BlankSlate < ::BlankSlate  
5 - end  
6 - end  
7 -else  
8 - module ActsAsFerret  
9 - # 'backported' for Rails pre 2.0  
10 - #  
11 - #--  
12 - # Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).  
13 - # All rights reserved.  
14 -  
15 - # Permission is granted for use, copying, modification, distribution,  
16 - # and distribution of modified versions of this work as long as the  
17 - # above copyright notice is included.  
18 - #++  
19 -  
20 - ######################################################################  
21 - # BlankSlate provides an abstract base class with no predefined  
22 - # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).  
23 - # BlankSlate is useful as a base class when writing classes that  
24 - # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).  
25 - #  
26 - class BlankSlate  
27 - class << self  
28 - # Hide the method named +name+ in the BlankSlate class. Don't  
29 - # hide +instance_eval+ or any method beginning with "__".  
30 - def hide(name)  
31 - if instance_methods.include?(name.to_s) and name !~ /^(__|instance_eval|methods)/  
32 - @hidden_methods ||= {}  
33 - @hidden_methods[name.to_sym] = instance_method(name)  
34 - undef_method name  
35 - end  
36 - end  
37 -  
38 - # Redefine a previously hidden method so that it may be called on a blank  
39 - # slate object.  
40 - #  
41 - # no-op here since we don't hide the methods we reveal where this is  
42 - # used in this implementation  
43 - def reveal(name)  
44 - end  
45 - end  
46 -  
47 - instance_methods.each { |m| hide(m) }  
48 -  
49 - end  
50 - end  
51 -  
52 -end  
53 -  
vendor/plugins/acts_as_ferret/lib/bulk_indexer.rb
@@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
1 -module ActsAsFerret  
2 - class BulkIndexer  
3 - def initialize(args = {})  
4 - @batch_size = args[:batch_size] || 1000  
5 - @logger = args[:logger]  
6 - @model = args[:model]  
7 - @work_done = 0  
8 - @index = args[:index]  
9 - if args[:reindex]  
10 - @reindex = true  
11 - @model_count = @model.count.to_f  
12 - else  
13 - @model_count = args[:total]  
14 - end  
15 - end  
16 -  
17 - def index_records(records, offset)  
18 - batch_time = measure_time {  
19 - records.each { |rec| @index.add_document(rec.to_doc, rec.ferret_analyzer) if rec.ferret_enabled?(true) }  
20 - }.to_f  
21 - @work_done = offset.to_f / @model_count * 100.0 if @model_count > 0  
22 - remaining_time = ( batch_time / @batch_size ) * ( @model_count - offset + @batch_size )  
23 - @logger.info "#{@reindex ? 're' : 'bulk '}index model #{@model.name} : #{'%.2f' % @work_done}% complete : #{'%.2f' % remaining_time} secs to finish"  
24 -  
25 - end  
26 -  
27 - def measure_time  
28 - t1 = Time.now  
29 - yield  
30 - Time.now - t1  
31 - end  
32 -  
33 - end  
34 -  
35 -end  
vendor/plugins/acts_as_ferret/lib/class_methods.rb
@@ -1,295 +0,0 @@ @@ -1,295 +0,0 @@
1 -module ActsAsFerret  
2 -  
3 - module ClassMethods  
4 -  
5 - # Disables ferret index updates for this model. When a block is given,  
6 - # Ferret will be re-enabled again after executing the block.  
7 - def disable_ferret  
8 - aaf_configuration[:enabled] = false  
9 - if block_given?  
10 - yield  
11 - enable_ferret  
12 - end  
13 - end  
14 -  
15 - def enable_ferret  
16 - aaf_configuration[:enabled] = true  
17 - end  
18 -  
19 - def ferret_enabled?  
20 - aaf_configuration[:enabled]  
21 - end  
22 -  
23 - # rebuild the index from all data stored for this model, and any other  
24 - # model classes associated with the same index.  
25 - # This is called automatically when no index exists yet.  
26 - #  
27 - def rebuild_index  
28 - aaf_index.rebuild_index  
29 - end  
30 -  
31 - # re-index a number records specified by the given ids. Use for large  
32 - # indexing jobs i.e. after modifying a lot of records with Ferret disabled.  
33 - # Please note that the state of Ferret (enabled or disabled at class or  
34 - # record level) is not checked by this method, so if you need to do so  
35 - # (e.g. because of a custom ferret_enabled? implementation), you have to do  
36 - # so yourself.  
37 - def bulk_index(*ids)  
38 - options = Hash === ids.last ? ids.pop : {}  
39 - ids = ids.first if ids.size == 1 && ids.first.is_a?(Enumerable)  
40 - aaf_index.bulk_index(self.name, ids, options)  
41 - end  
42 -  
43 - # true if our db and table appear to be suitable for the mysql fast batch  
44 - # hack (see  
45 - # http://weblog.jamisbuck.org/2007/4/6/faking-cursors-in-activerecord)  
46 - def use_fast_batches?  
47 - if connection.class.name =~ /Mysql/ && primary_key == 'id' && aaf_configuration[:mysql_fast_batches]  
48 - logger.info "using mysql specific batched find :all. Turn off with :mysql_fast_batches => false if you encounter problems (i.e. because of non-integer UUIDs in the id column)"  
49 - true  
50 - end  
51 - end  
52 -  
53 - # Returns all records modified or created after the specified time.  
54 - # Used by the rake rebuild task to find models that need to be updated in  
55 - # the index after the rebuild finished because they changed while the  
56 - # rebuild was running.  
57 - # Override if your models don't stick to the created_at/updated_at  
58 - # convention.  
59 - def records_modified_since(time)  
60 - condition = []  
61 - %w(updated_at created_at).each do |col|  
62 - condition << "#{col} >= ?" if column_names.include? col  
63 - end  
64 - if condition.empty?  
65 - logger.warn "#{self.name}: Override records_modified_since(time) to keep the index up to date with records changed during rebuild."  
66 - []  
67 - else  
68 - find :all, :conditions => [ condition.join(' AND '), *([time]*condition.size) ]  
69 - end  
70 - end  
71 -  
72 - # runs across all records yielding those to be indexed when the index is rebuilt  
73 - def records_for_rebuild(batch_size = 1000)  
74 - transaction do  
75 - if use_fast_batches?  
76 - offset = 0  
77 - while (rows = find :all, :conditions => [ "#{table_name}.id > ?", offset ], :limit => batch_size).any?  
78 - offset = rows.last.id  
79 - yield rows, offset  
80 - end  
81 - else  
82 - order = "#{primary_key} ASC" # fixes #212  
83 - 0.step(self.count, batch_size) do |offset|  
84 - yield find( :all, :limit => batch_size, :offset => offset, :order => order ), offset  
85 - end  
86 - end  
87 - end  
88 - end  
89 -  
90 - # yields the records with the given ids, in batches of batch_size  
91 - def records_for_bulk_index(ids, batch_size = 1000)  
92 - transaction do  
93 - offset = 0  
94 - ids.each_slice(batch_size) do |id_slice|  
95 - records = find( :all, :conditions => ["id in (?)", id_slice] )  
96 - #yield records, offset  
97 - yield find( :all, :conditions => ["id in (?)", id_slice] ), offset  
98 - offset += batch_size  
99 - end  
100 - end  
101 - end  
102 -  
103 - # Retrieve the index instance for this model class. This can either be a  
104 - # LocalIndex, or a RemoteIndex instance.  
105 - #  
106 - def aaf_index  
107 - @index ||= ActsAsFerret::get_index(aaf_configuration[:name])  
108 - end  
109 -  
110 - # Finds instances by searching the Ferret index. Terms are ANDed by default, use  
111 - # OR between terms for ORed queries. Or specify +:or_default => true+ in the  
112 - # +:ferret+ options hash of acts_as_ferret.  
113 - #  
114 - # You may either use the +offset+ and +limit+ options to implement your own  
115 - # pagination logic, or use the +page+ and +per_page+ options to use the  
116 - # built in pagination support which is compatible with will_paginate's view  
117 - # helpers. If +page+ and +per_page+ are given, +offset+ and +limit+ will be  
118 - # ignored.  
119 - #  
120 - # == options:  
121 - # page:: page of search results to retrieve  
122 - # per_page:: number of search results that are displayed per page  
123 - # offset:: first hit to retrieve (useful for paging)  
124 - # limit:: number of hits to retrieve, or :all to retrieve  
125 - # all results  
126 - # lazy:: Array of field names whose contents should be read directly  
127 - # from the index. Those fields have to be marked  
128 - # +:store => :yes+ in their field options. Give true to get all  
129 - # stored fields. Note that if you have a shared index, you have  
130 - # to explicitly state the fields you want to fetch, true won't  
131 - # work here)  
132 - #  
133 - # +find_options+ is a hash passed on to active_record's find when  
134 - # retrieving the data from db, useful to i.e. prefetch relationships with  
135 - # :include or to specify additional filter criteria with :conditions.  
136 - #  
137 - # This method returns a +SearchResults+ instance, which really is an Array that has  
138 - # been decorated with a total_hits attribute holding the total number of hits.  
139 - # Additionally, SearchResults is compatible with the pagination helper  
140 - # methods of the will_paginate plugin.  
141 - #  
142 - # Please keep in mind that the number of results delivered might be less than  
143 - # +limit+ if you specify any active record conditions that further limit  
144 - # the result. Use +limit+ and +offset+ as AR find_options instead.  
145 - # +page+ and +per_page+ are supposed to work regardless of any  
146 - # +conitions+ present in +find_options+.  
147 - def find_with_ferret(q, options = {}, find_options = {})  
148 - aaf_index.register_class(self, {})  
149 -  
150 - if respond_to?(:scope) && scope(:find, :conditions)  
151 - if find_options[:conditions]  
152 - find_options[:conditions] = "(#{find_options[:conditions]}) AND (#{scope(:find, :conditions)})"  
153 - else  
154 - find_options[:conditions] = scope(:find, :conditions)  
155 - end  
156 - end  
157 -  
158 - if options[:per_page]  
159 - options[:page] = options[:page] ? options[:page].to_i : 1  
160 - limit = options[:per_page]  
161 - offset = (options[:page] - 1) * limit  
162 - if find_options[:conditions]  
163 - find_options[:limit] = limit  
164 - find_options[:offset] = offset  
165 - options[:limit] = :all  
166 - options.delete :offset  
167 - else  
168 - # do pagination with ferret  
169 - options[:limit] = limit  
170 - options[:offset] = offset  
171 - end  
172 - elsif find_options[:conditions]  
173 - find_options[:limit] ||= options.delete(:limit) unless options[:limit] == :all  
174 - find_options[:offset] ||= options.delete(:offset)  
175 - options[:limit] = :all  
176 - end  
177 -  
178 - total_hits, result = aaf_index.find_records q, options.merge(:models => [self]), find_options  
179 - logger.debug "Query: #{q}\ntotal hits: #{total_hits}, results delivered: #{result.size}"  
180 - SearchResults.new(result, total_hits, options[:page], options[:per_page])  
181 - end  
182 -  
183 -  
184 - # Returns the total number of hits for the given query  
185 - #  
186 - # Note that since we don't query the database here, this method won't deliver  
187 - # the expected results when used on an AR association.  
188 - #  
189 - def total_hits(q, options={})  
190 - aaf_index.total_hits(q, options)  
191 - end  
192 -  
193 - # Finds instance model name, ids and scores by contents.  
194 - # Useful e.g. if you want to search across models or do not want to fetch  
195 - # all result records (yet).  
196 - #  
197 - # Options are the same as for find_by_contents  
198 - #  
199 - # A block can be given too, it will be executed with every result:  
200 - # find_ids_with_ferret(q, options) do |model, id, score|  
201 - # id_array << id  
202 - # scores_by_id[id] = score  
203 - # end  
204 - # NOTE: in case a block is given, only the total_hits value will be returned  
205 - # instead of the [total_hits, results] array!  
206 - #  
207 - def find_ids_with_ferret(q, options = {}, &block)  
208 - aaf_index.find_ids(q, options, &block)  
209 - end  
210 -  
211 -  
212 - protected  
213 -  
214 -# def find_records_lazy_or_not(q, options = {}, find_options = {})  
215 -# if options[:lazy]  
216 -# logger.warn "find_options #{find_options} are ignored because :lazy => true" unless find_options.empty?  
217 -# lazy_find_by_contents q, options  
218 -# else  
219 -# ar_find_by_contents q, options, find_options  
220 -# end  
221 -# end  
222 -#  
223 -# def ar_find_by_contents(q, options = {}, find_options = {})  
224 -# result_ids = {}  
225 -# total_hits = find_ids_with_ferret(q, options) do |model, id, score, data|  
226 -# # stores ids, index and score of each hit for later ordering of  
227 -# # results  
228 -# result_ids[id] = [ result_ids.size + 1, score ]  
229 -# end  
230 -#  
231 -# result = ActsAsFerret::retrieve_records( { self.name => result_ids }, find_options )  
232 -#  
233 -# # count total_hits via sql when using conditions or when we're called  
234 -# # from an ActiveRecord association.  
235 -# if find_options[:conditions] or caller.find{ |call| call =~ %r{active_record/associations} }  
236 -# # chances are the ferret result count is not our total_hits value, so  
237 -# # we correct this here.  
238 -# if options[:limit] != :all || options[:page] || options[:offset] || find_options[:limit] || find_options[:offset]  
239 -# # our ferret result has been limited, so we need to re-run that  
240 -# # search to get the full result set from ferret.  
241 -# result_ids = {}  
242 -# find_ids_with_ferret(q, options.update(:limit => :all, :offset => 0)) do |model, id, score, data|  
243 -# result_ids[id] = [ result_ids.size + 1, score ]  
244 -# end  
245 -# # Now ask the database for the total size of the final result set.  
246 -# total_hits = count_records( { self.name => result_ids }, find_options )  
247 -# else  
248 -# # what we got from the database is our full result set, so take  
249 -# # it's size  
250 -# total_hits = result.length  
251 -# end  
252 -# end  
253 -#  
254 -# [ total_hits, result ]  
255 -# end  
256 -#  
257 -# def lazy_find_by_contents(q, options = {})  
258 -# logger.debug "lazy_find_by_contents: #{q}"  
259 -# result = []  
260 -# rank = 0  
261 -# total_hits = find_ids_with_ferret(q, options) do |model, id, score, data|  
262 -# logger.debug "model: #{model}, id: #{id}, data: #{data}"  
263 -# result << FerretResult.new(model, id, score, rank += 1, data)  
264 -# end  
265 -# [ total_hits, result ]  
266 -# end  
267 -  
268 -  
269 - def model_find(model, id, find_options = {})  
270 - model.constantize.find(id, find_options)  
271 - end  
272 -  
273 -  
274 -# def count_records(id_arrays, find_options = {})  
275 -# count_options = find_options.dup  
276 -# count_options.delete :limit  
277 -# count_options.delete :offset  
278 -# count = 0  
279 -# id_arrays.each do |model, id_array|  
280 -# next if id_array.empty?  
281 -# model = model.constantize  
282 -# # merge conditions  
283 -# conditions = ActsAsFerret::combine_conditions([ "#{model.table_name}.#{model.primary_key} in (?)", id_array.keys ],  
284 -# find_options[:conditions])  
285 -# opts = find_options.merge :conditions => conditions  
286 -# opts.delete :limit; opts.delete :offset  
287 -# count += model.count opts  
288 -# end  
289 -# count  
290 -# end  
291 -  
292 - end  
293 -  
294 -end  
295 -  
vendor/plugins/acts_as_ferret/lib/ferret_extensions.rb
@@ -1,115 +0,0 @@ @@ -1,115 +0,0 @@
1 -module Ferret  
2 -  
3 - module Analysis  
4 -  
5 - # = PerFieldAnalyzer  
6 - #  
7 - # This PerFieldAnalyzer is a workaround to a memory leak in  
8 - # ferret 0.11.4. It does basically do the same as the original  
9 - # Ferret::Analysis::PerFieldAnalyzer, but without the leak :)  
10 - #  
11 - # http://ferret.davebalmain.com/api/classes/Ferret/Analysis/PerFieldAnalyzer.html  
12 - #  
13 - # Thanks to Ben from omdb.org for tracking this down and creating this  
14 - # workaround.  
15 - # You can read more about the issue there:  
16 - # http://blog.omdb-beta.org/2007/7/29/tracking-down-a-memory-leak-in-ferret-0-11-4  
17 - class PerFieldAnalyzer < ::Ferret::Analysis::Analyzer  
18 - def initialize( default_analyzer = StandardAnalyzer.new )  
19 - @analyzers = {}  
20 - @default_analyzer = default_analyzer  
21 - end  
22 -  
23 - def add_field( field, analyzer )  
24 - @analyzers[field] = analyzer  
25 - end  
26 - alias []= add_field  
27 -  
28 - def token_stream(field, string)  
29 - @analyzers.has_key?(field) ? @analyzers[field].token_stream(field, string) :  
30 - @default_analyzer.token_stream(field, string)  
31 - end  
32 - end  
33 - end  
34 -  
35 - class Index::Index  
36 - attr_accessor :batch_size, :logger  
37 -  
38 - def index_models(models)  
39 - models.each { |model| index_model model }  
40 - flush  
41 - optimize  
42 - close  
43 - ActsAsFerret::close_multi_indexes  
44 - end  
45 -  
46 - def index_model(model)  
47 - bulk_indexer = ActsAsFerret::BulkIndexer.new(:batch_size => @batch_size, :logger => logger,  
48 - :model => model, :index => self, :reindex => true)  
49 - logger.info "reindexing model #{model.name}"  
50 -  
51 - model.records_for_rebuild(@batch_size) do |records, offset|  
52 - bulk_indexer.index_records(records, offset)  
53 - end  
54 - end  
55 -  
56 - def bulk_index(model, ids, options = {})  
57 - options.reverse_merge! :optimize => true  
58 - orig_flush = @auto_flush  
59 - @auto_flush = false  
60 - bulk_indexer = ActsAsFerret::BulkIndexer.new(:batch_size => @batch_size, :logger => logger,  
61 - :model => model, :index => self, :total => ids.size)  
62 - model.records_for_bulk_index(ids, @batch_size) do |records, offset|  
63 - logger.debug "#{model} bulk indexing #{records.size} at #{offset}"  
64 - bulk_indexer.index_records(records, offset)  
65 - end  
66 - logger.info 'finishing bulk index...'  
67 - flush  
68 - if options[:optimize]  
69 - logger.info 'optimizing...'  
70 - optimize  
71 - end  
72 - @auto_flush = orig_flush  
73 - end  
74 -  
75 - end  
76 -  
77 - # add marshalling support to SortFields  
78 - class Search::SortField  
79 - def _dump(depth)  
80 - to_s  
81 - end  
82 -  
83 - def self._load(string)  
84 - case string  
85 - when /<DOC(_ID)?>!/ : Ferret::Search::SortField::DOC_ID_REV  
86 - when /<DOC(_ID)?>/ : Ferret::Search::SortField::DOC_ID  
87 - when '<SCORE>!' : Ferret::Search::SortField::SCORE_REV  
88 - when '<SCORE>' : Ferret::Search::SortField::SCORE  
89 - when /^(\w+):<(\w+)>(!)?$/ : new($1.to_sym, :type => $2.to_sym, :reverse => !$3.nil?)  
90 - else raise "invalid value: #{string}"  
91 - end  
92 - end  
93 - end  
94 -  
95 - # add marshalling support to Sort  
96 - class Search::Sort  
97 - def _dump(depth)  
98 - to_s  
99 - end  
100 -  
101 - def self._load(string)  
102 - # we exclude the last <DOC> sorting as it is appended by new anyway  
103 - if string =~ /^Sort\[(.*?)(<DOC>(!)?)?\]$/  
104 - sort_fields = $1.split(',').map do |value|  
105 - value.strip!  
106 - Ferret::Search::SortField._load value unless value.blank?  
107 - end  
108 - new sort_fields.compact  
109 - else  
110 - raise "invalid value: #{string}"  
111 - end  
112 - end  
113 - end  
114 -  
115 -end  
vendor/plugins/acts_as_ferret/lib/ferret_find_methods.rb
@@ -1,118 +0,0 @@ @@ -1,118 +0,0 @@
1 -module ActsAsFerret  
2 - # Ferret search logic common to single-class indexes, shared indexes and  
3 - # multi indexes.  
4 - module FerretFindMethods  
5 -  
6 - def find_records(q, options = {}, ar_options = {})  
7 - if options[:lazy]  
8 - logger.warn "find_options #{ar_options} are ignored because :lazy => true" unless ar_options.empty?  
9 - lazy_find q, options  
10 - else  
11 - ar_find q, options, ar_options  
12 - end  
13 - end  
14 -  
15 - def lazy_find(q, options = {})  
16 - logger.debug "lazy_find: #{q}"  
17 - result = []  
18 - rank = 0  
19 - total_hits = find_ids(q, options) do |model, id, score, data|  
20 - logger.debug "model: #{model}, id: #{id}, data: #{data}"  
21 - result << FerretResult.new(model, id, score, rank += 1, data)  
22 - end  
23 - [ total_hits, result ]  
24 - end  
25 -  
26 - def ar_find(q, options = {}, ar_options = {})  
27 - total_hits, id_arrays = find_id_model_arrays q, options  
28 - result = ActsAsFerret::retrieve_records(id_arrays, ar_options)  
29 -  
30 - # count total_hits via sql when using conditions, multiple models, or when we're called  
31 - # from an ActiveRecord association.  
32 - if id_arrays.size > 1 or ar_options[:conditions]  
33 - # chances are the ferret result count is not our total_hits value, so  
34 - # we correct this here.  
35 - if options[:limit] != :all || options[:page] || options[:offset] || ar_options[:limit] || ar_options[:offset]  
36 - # our ferret result has been limited, so we need to re-run that  
37 - # search to get the full result set from ferret.  
38 - new_th, id_arrays = find_id_model_arrays( q, options.merge(:limit => :all, :offset => 0) )  
39 - # Now ask the database for the total size of the final result set.  
40 - total_hits = count_records( id_arrays, ar_options )  
41 - else  
42 - # what we got from the database is our full result set, so take  
43 - # it's size  
44 - total_hits = result.length  
45 - end  
46 - end  
47 - [ total_hits, result ]  
48 - end  
49 -  
50 - def count_records(id_arrays, ar_options = {})  
51 - count_options = ar_options.dup  
52 - count_options.delete :limit  
53 - count_options.delete :offset  
54 - count = 0  
55 - id_arrays.each do |model, id_array|  
56 - next if id_array.empty?  
57 - model = model.constantize  
58 - # merge conditions  
59 - conditions = ActsAsFerret::conditions_for_model model, ar_options[:conditions]  
60 - count_options[:conditions] = ActsAsFerret::combine_conditions([ "#{model.table_name}.#{model.primary_key} in (?)", id_array.keys ], conditions)  
61 - count += model.count count_options  
62 - end  
63 - count  
64 - end  
65 -  
66 - def find_id_model_arrays(q, options)  
67 - id_arrays = {}  
68 - rank = 0  
69 - total_hits = find_ids(q, options) do |model, id, score, data|  
70 - id_arrays[model] ||= {}  
71 - id_arrays[model][id] = [ rank += 1, score ]  
72 - end  
73 - [total_hits, id_arrays]  
74 - end  
75 -  
76 - # Queries the Ferret index to retrieve model class, id, score and the  
77 - # values of any fields stored in the index for each hit.  
78 - # If a block is given, these are yielded and the number of total hits is  
79 - # returned. Otherwise [total_hits, result_array] is returned.  
80 - def find_ids(query, options = {})  
81 -  
82 - result = []  
83 - stored_fields = determine_stored_fields options  
84 -  
85 - q = process_query(query, options)  
86 - q = scope_query_to_models q, options[:models] #if shared?  
87 - logger.debug "query: #{query}\n-->#{q}"  
88 - s = searcher  
89 - total_hits = s.search_each(q, options) do |hit, score|  
90 - doc = s[hit]  
91 - model = doc[:class_name]  
92 - # fetch stored fields if lazy loading  
93 - data = extract_stored_fields(doc, stored_fields)  
94 - if block_given?  
95 - yield model, doc[:id], score, data  
96 - else  
97 - result << { :model => model, :id => doc[:id], :score => score, :data => data }  
98 - end  
99 - end  
100 - #logger.debug "id_score_model array: #{result.inspect}"  
101 - return block_given? ? total_hits : [total_hits, result]  
102 - end  
103 -  
104 - def scope_query_to_models(query, models)  
105 - return query if models.nil? or models == :all  
106 - models = [ models ] if Class === models  
107 - q = Ferret::Search::BooleanQuery.new  
108 - q.add_query(query, :must)  
109 - model_query = Ferret::Search::BooleanQuery.new  
110 - models.each do |model|  
111 - model_query.add_query(Ferret::Search::TermQuery.new(:class_name, model.name), :should)  
112 - end  
113 - q.add_query(model_query, :must)  
114 - return q  
115 - end  
116 -  
117 - end  
118 -end  
vendor/plugins/acts_as_ferret/lib/ferret_result.rb
@@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
1 -module ActsAsFerret  
2 -  
3 - # mixed into the FerretResult and AR classes calling acts_as_ferret  
4 - module ResultAttributes  
5 - # holds the score this record had when it was found via  
6 - # acts_as_ferret  
7 - attr_accessor :ferret_score  
8 -  
9 - attr_accessor :ferret_rank  
10 - end  
11 -  
12 - class FerretResult < ActsAsFerret::BlankSlate  
13 - include ResultAttributes  
14 - attr_accessor :id  
15 - reveal :methods  
16 -  
17 - def initialize(model, id, score, rank, data = {})  
18 - @model = model.constantize  
19 - @id = id  
20 - @ferret_score = score  
21 - @ferret_rank = rank  
22 - @data = data  
23 - @use_record = false  
24 - end  
25 -  
26 - def inspect  
27 - "#<FerretResult wrapper for #{@model} with id #{@id}"  
28 - end  
29 -  
30 - def method_missing(method, *args, &block)  
31 - if (@ar_record && @use_record) || !@data.has_key?(method)  
32 - to_record.send method, *args, &block  
33 - else  
34 - @data[method]  
35 - end  
36 - end  
37 -  
38 - def respond_to?(name)  
39 - methods.include?(name.to_s) || @data.has_key?(name.to_sym) || to_record.respond_to?(name)  
40 - end  
41 -  
42 - def to_record  
43 - unless @ar_record  
44 - @ar_record = @model.find(id)  
45 - @ar_record.ferret_rank = ferret_rank  
46 - @ar_record.ferret_score = ferret_score  
47 - # don't try to fetch attributes from RDig based records  
48 - @use_record = !@ar_record.class.included_modules.include?(ActsAsFerret::RdigAdapter)  
49 - end  
50 - @ar_record  
51 - end  
52 - end  
53 -end  
vendor/plugins/acts_as_ferret/lib/ferret_server.rb
@@ -1,238 +0,0 @@ @@ -1,238 +0,0 @@
1 -require 'drb'  
2 -require 'thread'  
3 -require 'yaml'  
4 -require 'erb'  
5 -  
6 -################################################################################  
7 -module ActsAsFerret  
8 - module Remote  
9 -  
10 - ################################################################################  
11 - class Config  
12 -  
13 - ################################################################################  
14 - DEFAULTS = {  
15 - 'host' => 'localhost',  
16 - 'port' => '9009',  
17 - 'cf' => "#{RAILS_ROOT}/config/ferret_server.yml",  
18 - 'pid_file' => "#{RAILS_ROOT}/log/ferret_server.pid",  
19 - 'log_file' => "#{RAILS_ROOT}/log/ferret_server.log",  
20 - 'log_level' => 'debug',  
21 - 'socket' => nil,  
22 - 'script' => nil  
23 - }  
24 -  
25 - ################################################################################  
26 - # load the configuration file and apply default settings  
27 - def initialize (file=DEFAULTS['cf'])  
28 - @everything = YAML.load(ERB.new(IO.read(file)).result)  
29 - raise "malformed ferret server config" unless @everything.is_a?(Hash)  
30 - @config = DEFAULTS.merge(@everything[RAILS_ENV] || {})  
31 - if @everything[RAILS_ENV]  
32 - @config['uri'] = socket.nil? ? "druby://#{host}:#{port}" : "drbunix:#{socket}"  
33 - end  
34 - end  
35 -  
36 - ################################################################################  
37 - # treat the keys of the config data as methods  
38 - def method_missing (name, *args)  
39 - @config.has_key?(name.to_s) ? @config[name.to_s] : super  
40 - end  
41 -  
42 - end  
43 -  
44 - #################################################################################  
45 - # This class acts as a drb server listening for indexing and  
46 - # search requests from models declared to 'acts_as_ferret :remote => true'  
47 - #  
48 - # Usage:  
49 - # - modify RAILS_ROOT/config/ferret_server.yml to suit your needs.  
50 - # - environments for which no section in the config file exists will use  
51 - # the index locally (good for unit tests/development mode)  
52 - # - run script/ferret_server to start the server:  
53 - # script/ferret_server -e production start  
54 - # - to stop the server run  
55 - # script/ferret_server -e production stop  
56 - #  
57 - class Server  
58 -  
59 - #################################################################################  
60 - # FIXME include detection of OS and include the correct file  
61 - require 'unix_daemon'  
62 - include(ActsAsFerret::Remote::UnixDaemon)  
63 -  
64 -  
65 - ################################################################################  
66 - cattr_accessor :running  
67 -  
68 - ################################################################################  
69 - def initialize  
70 - ActiveRecord::Base.allow_concurrency = true  
71 - require 'ar_mysql_auto_reconnect_patch'  
72 - @cfg = ActsAsFerret::Remote::Config.new  
73 - ActiveRecord::Base.logger = @logger = Logger.new(@cfg.log_file)  
74 - ActiveRecord::Base.logger.level = Logger.const_get(@cfg.log_level.upcase) rescue Logger::DEBUG  
75 - if @cfg.script  
76 - path = File.join(RAILS_ROOT, @cfg.script)  
77 - load path  
78 - @logger.info "loaded custom startup script from #{path}"  
79 - end  
80 - end  
81 -  
82 - ################################################################################  
83 - # start the server as a daemon process  
84 - def start  
85 - raise "ferret_server not configured for #{RAILS_ENV}" unless (@cfg.uri rescue nil)  
86 - platform_daemon { run_drb_service }  
87 - end  
88 -  
89 - ################################################################################  
90 - # run the server and block until it exits  
91 - def run  
92 - raise "ferret_server not configured for #{RAILS_ENV}" unless (@cfg.uri rescue nil)  
93 - run_drb_service  
94 - end  
95 -  
96 - def run_drb_service  
97 - $stdout.puts("starting ferret server...")  
98 - self.class.running = true  
99 - DRb.start_service(@cfg.uri, self)  
100 - DRb.thread.join  
101 - rescue Exception => e  
102 - @logger.error(e.to_s)  
103 - raise  
104 - end  
105 -  
106 - #################################################################################  
107 - # handles all incoming method calls, and sends them on to the correct local index  
108 - # instance.  
109 - #  
110 - # Calls are not queued, so this will block until the call returned.  
111 - #  
112 - def method_missing(name, *args)  
113 - @logger.debug "\#method_missing(#{name.inspect}, #{args.inspect})"  
114 -  
115 -  
116 - index_name = args.shift  
117 - index = if name.to_s =~ /^multi_(.+)/  
118 - name = $1  
119 - ActsAsFerret::multi_index(index_name)  
120 - else  
121 - ActsAsFerret::get_index(index_name)  
122 - end  
123 -  
124 - if index.nil?  
125 - @logger.error "\#index with name #{index_name} not found in call to #{name} with args #{args.inspect}"  
126 - raise ActsAsFerret::IndexNotDefined.new(index_name)  
127 - end  
128 -  
129 -  
130 - # TODO find another way to implement the reconnection logic (maybe in  
131 - # local_index or class_methods)  
132 - # reconnect_when_needed(clazz) do  
133 -  
134 - # using respond_to? here so we not have to catch NoMethodError  
135 - # which would silently catch those from deep inside the indexing  
136 - # code, too...  
137 -  
138 - if index.respond_to?(name)  
139 - index.send name, *args  
140 - # TODO check where we need this:  
141 - #elsif clazz.respond_to?(name)  
142 - # @logger.debug "no luck, trying to call class method instead"  
143 - # clazz.send name, *args  
144 - else  
145 - raise NoMethodError.new("method #{name} not supported by DRb server")  
146 - end  
147 - rescue => e  
148 - @logger.error "ferret server error #{$!}\n#{$!.backtrace.join "\n"}"  
149 - raise e  
150 - end  
151 -  
152 - def register_class(class_name)  
153 - @logger.debug "############ registerclass #{class_name}"  
154 - class_name.constantize  
155 - @logger.debug "index for class #{class_name}: #{ActsAsFerret::ferret_indexes[class_name.underscore.to_sym]}"  
156 -  
157 - end  
158 -  
159 - # make sure we have a versioned index in place, building one if necessary  
160 - def ensure_index_exists(index_name)  
161 - @logger.debug "DRb server: ensure_index_exists for index #{index_name}"  
162 - definition = ActsAsFerret::get_index(index_name).index_definition  
163 - dir = definition[:index_dir]  
164 - unless File.directory?(dir) && File.file?(File.join(dir, 'segments')) && dir =~ %r{/\d+(_\d+)?$}  
165 - rebuild_index(index_name)  
166 - end  
167 - end  
168 -  
169 - # disconnects the db connection for the class specified by class_name  
170 - # used only in unit tests to check the automatic reconnection feature  
171 - def db_disconnect!(class_name)  
172 - with_class class_name do |clazz|  
173 - clazz.connection.disconnect!  
174 - end  
175 - end  
176 -  
177 - # hides LocalIndex#rebuild_index to implement index versioning  
178 - def rebuild_index(index_name)  
179 - definition = ActsAsFerret::get_index(index_name).index_definition.dup  
180 - models = definition[:registered_models]  
181 - index = new_index_for(definition)  
182 - # TODO fix reconnection stuff  
183 - # reconnect_when_needed(clazz) do  
184 - # @logger.debug "DRb server: rebuild index for class(es) #{models.inspect} in #{index.options[:path]}"  
185 - index.index_models models  
186 - # end  
187 - new_version = File.join definition[:index_base_dir], Time.now.utc.strftime('%Y%m%d%H%M%S')  
188 - # create a unique directory name (needed for unit tests where  
189 - # multiple rebuilds per second may occur)  
190 - if File.exists?(new_version)  
191 - i = 0  
192 - i+=1 while File.exists?("#{new_version}_#{i}")  
193 - new_version << "_#{i}"  
194 - end  
195 -  
196 - File.rename index.options[:path], new_version  
197 - ActsAsFerret::change_index_dir index_name, new_version  
198 - end  
199 -  
200 -  
201 - protected  
202 -  
203 - def reconnect_when_needed(clazz)  
204 - retried = false  
205 - begin  
206 - yield  
207 - rescue ActiveRecord::StatementInvalid => e  
208 - if e.message =~ /MySQL server has gone away/  
209 - if retried  
210 - raise e  
211 - else  
212 - @logger.info "StatementInvalid caught, trying to reconnect..."  
213 - clazz.connection.reconnect!  
214 - retried = true  
215 - retry  
216 - end  
217 - else  
218 - @logger.error "StatementInvalid caught, but unsure what to do with it: #{e}"  
219 - raise e  
220 - end  
221 - end  
222 - end  
223 -  
224 - def new_index_for(index_definition)  
225 - ferret_cfg = index_definition[:ferret].dup  
226 - ferret_cfg.update :auto_flush => false,  
227 - :create => true,  
228 - :field_infos => ActsAsFerret::field_infos(index_definition),  
229 - :path => File.join(index_definition[:index_base_dir], 'rebuild')  
230 - returning Ferret::Index::Index.new(ferret_cfg) do |i|  
231 - i.batch_size = index_definition[:reindex_batch_size]  
232 - i.logger = @logger  
233 - end  
234 - end  
235 -  
236 - end  
237 - end  
238 -end  
vendor/plugins/acts_as_ferret/lib/index.rb
@@ -1,99 +0,0 @@ @@ -1,99 +0,0 @@
1 -module ActsAsFerret  
2 -  
3 - class IndexLogger  
4 - def initialize(logger, name)  
5 - @logger = logger  
6 - @index_name = name  
7 - end  
8 - %w(debug info warn error).each do |m|  
9 - define_method(m) do |message|  
10 - @logger.send m, "[#{@index_name}] #{message}"  
11 - end  
12 - question = :"#{m}?"  
13 - define_method(question) do  
14 - @logger.send question  
15 - end  
16 - end  
17 - end  
18 -  
19 - # base class for local and remote indexes  
20 - class AbstractIndex  
21 - include FerretFindMethods  
22 -  
23 - attr_reader :logger, :index_name, :index_definition, :registered_models_config  
24 - def initialize(index_definition)  
25 - @index_definition = index_definition  
26 - @registered_models_config = {}  
27 - @index_name = index_definition[:name]  
28 - @logger = IndexLogger.new(ActsAsFerret::logger, @index_name)  
29 - end  
30 -  
31 - # TODO allow for per-class field configuration (i.e. different via, boosts  
32 - # for the same field among different models)  
33 - def register_class(clazz, options = {})  
34 - logger.info "register class #{clazz} with index #{index_name}"  
35 -  
36 - if force = options.delete(:force_re_registration)  
37 - index_definition[:registered_models].delete(clazz)  
38 - end  
39 -  
40 - if index_definition[:registered_models].map(&:name).include?(clazz.name)  
41 - logger.info("refusing re-registration of class #{clazz}")  
42 - else  
43 - index_definition[:registered_models] << clazz  
44 - @registered_models_config[clazz] = options  
45 -  
46 - # merge fields from this acts_as_ferret call with predefined fields  
47 - already_defined_fields = index_definition[:ferret_fields]  
48 - field_config = ActsAsFerret::build_field_config options[:fields]  
49 - field_config.update ActsAsFerret::build_field_config( options[:additional_fields] )  
50 - field_config.each do |field, config|  
51 - if already_defined_fields.has_key?(field)  
52 - logger.info "ignoring redefinition of ferret field #{field}" if shared?  
53 - else  
54 - already_defined_fields[field] = config  
55 - logger.info "adding new field #{field} from class #{clazz.name} to index #{index_name}"  
56 - end  
57 - end  
58 -  
59 - # update default field list to be used by the query parser, unless it  
60 - # was explicitly given by user.  
61 - #  
62 - # It will include all content fields *not* marked as :untokenized.  
63 - # This fixes the otherwise failing CommentTest#test_stopwords. Basically  
64 - # this means that by default only tokenized fields (which all fields are  
65 - # by default) will be searched. If you want to search inside the contents  
66 - # of an untokenized field, you'll have to explicitly specify it in your  
67 - # query.  
68 - unless index_definition[:user_default_field]  
69 - # grab all tokenized fields  
70 - ferret_fields = index_definition[:ferret_fields]  
71 - index_definition[:ferret][:default_field] = ferret_fields.keys.select do |field|  
72 - ferret_fields[field][:index] != :untokenized  
73 - end  
74 - logger.info "default field list for index #{index_name}: #{index_definition[:ferret][:default_field].inspect}"  
75 - end  
76 - end  
77 -  
78 - return index_definition  
79 - end  
80 -  
81 - # true if this index is used by more than one model class  
82 - def shared?  
83 - index_definition[:registered_models].size > 1  
84 - end  
85 -  
86 - # Switches the index to a new index directory.  
87 - # Used by the DRb server when switching to a new index version.  
88 - def change_index_dir(new_dir)  
89 - logger.debug "[#{index_name}] changing index dir to #{new_dir}"  
90 - index_definition[:index_dir] = index_definition[:ferret][:path] = new_dir  
91 - reopen!  
92 - logger.debug "[#{index_name}] index dir is now #{new_dir}"  
93 - end  
94 -  
95 - protected  
96 -  
97 - end  
98 -  
99 -end  
vendor/plugins/acts_as_ferret/lib/instance_methods.rb
@@ -1,165 +0,0 @@ @@ -1,165 +0,0 @@
1 -module ActsAsFerret #:nodoc:  
2 -  
3 - module InstanceMethods  
4 - include ResultAttributes  
5 -  
6 - # Returns an array of strings with the matches highlighted. The +query+ can  
7 - # either be a String or a Ferret::Search::Query object.  
8 - #  
9 - # === Options  
10 - #  
11 - # field:: field to take the content from. This field has  
12 - # to have it's content stored in the index  
13 - # (:store => :yes in your call to aaf). If not  
14 - # given, all stored fields are searched, and the  
15 - # highlighted content found in all of them is returned.  
16 - # set :highlight => :no in the field options to  
17 - # avoid highlighting of contents from a :stored field.  
18 - # excerpt_length:: Default: 150. Length of excerpt to show. Highlighted  
19 - # terms will be in the centre of the excerpt.  
20 - # num_excerpts:: Default: 2. Number of excerpts to return.  
21 - # pre_tag:: Default: "<em>". Tag to place to the left of the  
22 - # match.  
23 - # post_tag:: Default: "</em>". This tag should close the  
24 - # +:pre_tag+.  
25 - # ellipsis:: Default: "...". This is the string that is appended  
26 - # at the beginning and end of excerpts (unless the  
27 - # excerpt hits the start or end of the field. You'll  
28 - # probably want to change this to a Unicode elipsis  
29 - # character.  
30 - def highlight(query, options = {})  
31 - self.class.aaf_index.highlight(self.send(self.class.primary_key), self.class.name, query, options)  
32 - end  
33 -  
34 - # re-eneable ferret indexing for this instance after a call to #disable_ferret  
35 - def enable_ferret  
36 - @ferret_disabled = nil  
37 - end  
38 - alias ferret_enable enable_ferret # compatibility  
39 -  
40 - # returns true if ferret indexing is enabled for this record.  
41 - #  
42 - # The optional is_bulk_index parameter will be true if the method is called  
43 - # by rebuild_index or bulk_index, and false otherwise.  
44 - #  
45 - # If is_bulk_index is true, the class level ferret_enabled state will be  
46 - # ignored by this method (per-instance ferret_enabled checks however will  
47 - # take place, so if you override this method to forbid indexing of certain  
48 - # records you're still safe).  
49 - def ferret_enabled?(is_bulk_index = false)  
50 - @ferret_disabled.nil? && (is_bulk_index || self.class.ferret_enabled?) && (aaf_configuration[:if].nil? || aaf_configuration[:if].call(self))  
51 - end  
52 -  
53 - # Returns the analyzer to use when adding this record to the index.  
54 - #  
55 - # Override to return a specific analyzer for any record that is to be  
56 - # indexed, i.e. specify a different analyzer based on language. Returns nil  
57 - # by default so the global analyzer (specified with the acts_as_ferret  
58 - # call) is used.  
59 - def ferret_analyzer  
60 - nil  
61 - end  
62 -  
63 - # Disable Ferret for this record for a specified amount of time. ::once will  
64 - # disable Ferret for the next call to #save (this is the default), ::always  
65 - # will do so for all subsequent calls.  
66 - #  
67 - # Note that this will turn off only the create and update hooks, but not the  
68 - # destroy hook. I think that's reasonable, if you think the opposite, please  
69 - # tell me.  
70 - #  
71 - # To manually trigger reindexing of a record after you're finished modifying  
72 - # it, you can call #ferret_update directly instead of #save (remember to  
73 - # enable ferret again before).  
74 - #  
75 - # When given a block, this will be executed without any ferret indexing of  
76 - # this object taking place. The optional argument in this case can be used  
77 - # to indicate if the object should be indexed after executing the block  
78 - # (::index_when_finished). Automatic Ferret indexing of this object will be  
79 - # turned on after the block has been executed. If passed ::index_when_true,  
80 - # the index will only be updated if the block evaluated not to false or nil.  
81 - #  
82 - def disable_ferret(option = :once)  
83 - if block_given?  
84 - @ferret_disabled = :always  
85 - result = yield  
86 - ferret_enable  
87 - ferret_update if option == :index_when_finished || (option == :index_when_true && result)  
88 - result  
89 - elsif [:once, :always].include?(option)  
90 - @ferret_disabled = option  
91 - else  
92 - raise ArgumentError.new("Invalid Argument #{option}")  
93 - end  
94 - end  
95 -  
96 - # add to index  
97 - def ferret_create  
98 - if ferret_enabled?  
99 - logger.debug "ferret_create/update: #{self.class.name} : #{self.id}"  
100 - self.class.aaf_index << self  
101 - else  
102 - ferret_enable if @ferret_disabled == :once  
103 - end  
104 - true # signal success to AR  
105 - end  
106 - alias :ferret_update :ferret_create  
107 -  
108 -  
109 - # remove from index  
110 - def ferret_destroy  
111 - logger.debug "ferret_destroy: #{self.class.name} : #{self.id}"  
112 - begin  
113 - self.class.aaf_index.remove self.id, self.class.name  
114 - rescue  
115 - logger.warn("Could not find indexed value for this object: #{$!}\n#{$!.backtrace}")  
116 - end  
117 - true # signal success to AR  
118 - end  
119 -  
120 - # turn this instance into a ferret document (which basically is a hash of  
121 - # fieldname => value pairs)  
122 - def to_doc  
123 - logger.debug "creating doc for class: #{self.class.name}, id: #{self.id}"  
124 - returning Ferret::Document.new do |doc|  
125 - # store the id and class name of each item  
126 - doc[:id] = self.id  
127 - doc[:class_name] = self.class.name  
128 -  
129 - # iterate through the fields and add them to the document  
130 - aaf_configuration[:defined_fields].each_pair do |field, config|  
131 - doc[field] = self.send("#{field}_to_ferret") unless config[:ignore]  
132 - end  
133 - if aaf_configuration[:boost]  
134 - if self.respond_to?(aaf_configuration[:boost])  
135 - boost = self.send aaf_configuration[:boost]  
136 - doc.boost = boost.to_i if boost  
137 - else  
138 - logger.error "boost option should point to an instance method: #{aaf_configuration[:boost]}"  
139 - end  
140 - end  
141 - end  
142 - end  
143 -  
144 - def document_number  
145 - self.class.aaf_index.document_number(id, self.class.name)  
146 - end  
147 -  
148 - def query_for_record  
149 - self.class.aaf_index.query_for_record(id, self.class.name)  
150 - end  
151 -  
152 - def content_for_field_name(field, via = field, dynamic_boost = nil)  
153 - return nil if field.to_sym == :type  
154 - field_data = self.send(via) || self.instance_variable_get("@#{via}")  
155 - if (dynamic_boost && boost_value = self.send(dynamic_boost))  
156 - field_data = Ferret::Field.new(field_data)  
157 - field_data.boost = boost_value.to_i  
158 - end  
159 - field_data  
160 - end  
161 -  
162 -  
163 - end  
164 -  
165 -end  
vendor/plugins/acts_as_ferret/lib/local_index.rb
@@ -1,199 +0,0 @@ @@ -1,199 +0,0 @@
1 -module ActsAsFerret  
2 - class LocalIndex < AbstractIndex  
3 - include MoreLikeThis::IndexMethods  
4 -  
5 - def initialize(index_name)  
6 - super  
7 - ensure_index_exists  
8 - end  
9 -  
10 - def reopen!  
11 - logger.debug "reopening index at #{index_definition[:ferret][:path]}"  
12 - close  
13 - ferret_index  
14 - end  
15 -  
16 - # The 'real' Ferret Index instance  
17 - def ferret_index  
18 - ensure_index_exists  
19 - returning @ferret_index ||= Ferret::Index::Index.new(index_definition[:ferret]) do  
20 - @ferret_index.batch_size = index_definition[:reindex_batch_size]  
21 - @ferret_index.logger = logger  
22 - end  
23 - end  
24 -  
25 - # Checks for the presence of a segments file in the index directory  
26 - # Rebuilds the index if none exists.  
27 - def ensure_index_exists  
28 - #logger.debug "LocalIndex: ensure_index_exists at #{index_definition[:index_dir]}"  
29 - unless File.file? "#{index_definition[:index_dir]}/segments"  
30 - ActsAsFerret::ensure_directory(index_definition[:index_dir])  
31 - rebuild_index  
32 - end  
33 - end  
34 -  
35 - # Closes the underlying index instance  
36 - def close  
37 - @ferret_index.close if @ferret_index  
38 - rescue StandardError  
39 - # is raised when index already closed  
40 - ensure  
41 - @ferret_index = nil  
42 - end  
43 -  
44 - # rebuilds the index from all records of the model classes associated with this index  
45 - def rebuild_index  
46 - models = index_definition[:registered_models]  
47 - logger.debug "rebuild index with models: #{models.inspect}"  
48 - close  
49 - index = Ferret::Index::Index.new(index_definition[:ferret].dup.update(:auto_flush => false,  
50 - :field_infos => ActsAsFerret::field_infos(index_definition),  
51 - :create => true))  
52 - index.batch_size = index_definition[:reindex_batch_size]  
53 - index.logger = logger  
54 - index.index_models models  
55 - reopen!  
56 - end  
57 -  
58 - def bulk_index(class_name, ids, options)  
59 - ferret_index.bulk_index(class_name.constantize, ids, options)  
60 - end  
61 -  
62 - # Parses the given query string into a Ferret Query object.  
63 - def process_query(query, options = {})  
64 - return query unless String === query  
65 - ferret_index.synchronize do  
66 - if options[:analyzer]  
67 - # use per-query analyzer if present  
68 - qp = Ferret::QueryParser.new ferret_index.instance_variable_get('@options').merge(options)  
69 - reader = ferret_index.reader  
70 - qp.fields =  
71 - reader.fields unless options[:all_fields] || options[:fields]  
72 - qp.tokenized_fields =  
73 - reader.tokenized_fields unless options[:tokenized_fields]  
74 - return qp.parse query  
75 - else  
76 - # work around ferret bug in #process_query (doesn't ensure the  
77 - # reader is open)  
78 - ferret_index.send(:ensure_reader_open)  
79 - return ferret_index.process_query(query)  
80 - end  
81 - end  
82 - end  
83 -  
84 - # Total number of hits for the given query.  
85 - def total_hits(query, options = {})  
86 - ferret_index.search(query, options).total_hits  
87 - end  
88 -  
89 - def searcher  
90 - ferret_index  
91 - end  
92 -  
93 -  
94 - ######################################  
95 - # methods working on a single record  
96 - # called from instance_methods, here to simplify interfacing with the  
97 - # remote ferret server  
98 - # TODO having to pass id and class_name around like this isn't nice  
99 - ######################################  
100 -  
101 - # add record to index  
102 - # record may be the full AR object, a Ferret document instance or a Hash  
103 - def add(record, analyzer = nil)  
104 - unless Hash === record || Ferret::Document === record  
105 - analyzer = record.ferret_analyzer  
106 - record = record.to_doc  
107 - end  
108 - ferret_index.add_document(record, analyzer)  
109 - end  
110 - alias << add  
111 -  
112 - # delete record from index  
113 - def remove(id, class_name)  
114 - ferret_index.query_delete query_for_record(id, class_name)  
115 - end  
116 -  
117 - # highlight search terms for the record with the given id.  
118 - def highlight(id, class_name, query, options = {})  
119 - logger.debug("highlight: #{class_name} / #{id} query: #{query}")  
120 - options.reverse_merge! :num_excerpts => 2, :pre_tag => '<em>', :post_tag => '</em>'  
121 - highlights = []  
122 - ferret_index.synchronize do  
123 - doc_num = document_number(id, class_name)  
124 -  
125 - if options[:field]  
126 - highlights << ferret_index.highlight(query, doc_num, options)  
127 - else  
128 - query = process_query(query) # process only once  
129 - index_definition[:ferret_fields].each_pair do |field, config|  
130 - next if config[:store] == :no || config[:highlight] == :no  
131 - options[:field] = field  
132 - highlights << ferret_index.highlight(query, doc_num, options)  
133 - end  
134 - end  
135 - end  
136 - return highlights.compact.flatten[0..options[:num_excerpts]-1]  
137 - end  
138 -  
139 - # retrieves the ferret document number of the record with the given id.  
140 - def document_number(id, class_name)  
141 - hits = ferret_index.search(query_for_record(id, class_name))  
142 - return hits.hits.first.doc if hits.total_hits == 1  
143 - raise "cannot determine document number for class #{class_name} / primary key: #{id}\nresult was: #{hits.inspect}"  
144 - end  
145 -  
146 - # build a ferret query matching only the record with the given id  
147 - # the class name only needs to be given in case of a shared index configuration  
148 - def query_for_record(id, class_name = nil)  
149 - if shared?  
150 - raise InvalidArgumentError.new("shared index needs class_name argument") if class_name.nil?  
151 - returning bq = Ferret::Search::BooleanQuery.new do  
152 - bq.add_query(Ferret::Search::TermQuery.new(:id, id.to_s), :must)  
153 - bq.add_query(Ferret::Search::TermQuery.new(:class_name, class_name), :must)  
154 - end  
155 - else  
156 - Ferret::Search::TermQuery.new(:id, id.to_s)  
157 - end  
158 - end  
159 -  
160 -  
161 -  
162 - def determine_stored_fields(options = {})  
163 - stored_fields = options[:lazy]  
164 - if stored_fields && !(Array === stored_fields)  
165 - stored_fields = index_definition[:ferret_fields].select { |field, config| config[:store] == :yes }.map(&:first)  
166 - end  
167 - logger.debug "stored_fields: #{stored_fields.inspect}"  
168 - return stored_fields  
169 - end  
170 -  
171 - # loads data for fields declared as :lazy from the Ferret document  
172 - def extract_stored_fields(doc, stored_fields)  
173 - fields = index_definition[:ferret_fields]  
174 - data = {}  
175 - logger.debug "extracting stored fields #{stored_fields.inspect} from document #{doc[:class_name]} / #{doc[:id]}"  
176 - stored_fields.each do |field|  
177 - if field_cfg = fields[field]  
178 - data[field_cfg[:via]] = doc[field]  
179 - end  
180 - end if stored_fields  
181 - logger.debug "done: #{data.inspect}"  
182 - return data  
183 - end  
184 -  
185 - protected  
186 -  
187 - # returns a MultiIndex instance operating on a MultiReader  
188 - #def multi_index(model_classes)  
189 - # model_classes.map!(&:constantize) if String === model_classes.first  
190 - # model_classes.sort! { |a, b| a.name <=> b.name }  
191 - # key = model_classes.inject("") { |s, clazz| s + clazz.name }  
192 - # multi_config = index_definition[:ferret].dup  
193 - # multi_config.delete :default_field # we don't want the default field list of *this* class for multi_searching  
194 - # ActsAsFerret::multi_indexes[key] ||= MultiIndex.new(model_classes, multi_config)  
195 - #end  
196 -  
197 - end  
198 -  
199 -end  
vendor/plugins/acts_as_ferret/lib/more_like_this.rb
@@ -1,217 +0,0 @@ @@ -1,217 +0,0 @@
1 -module ActsAsFerret #:nodoc:  
2 -  
3 - module MoreLikeThis  
4 -  
5 - module InstanceMethods  
6 -  
7 - # returns other instances of this class, which have similar contents  
8 - # like this one. Basically works like this: find out n most interesting  
9 - # (i.e. characteristic) terms from this document, and then build a  
10 - # query from those which is run against the whole index. Which terms  
11 - # are interesting is decided on variour criteria which can be  
12 - # influenced by the given options.  
13 - #  
14 - # The algorithm used here is a quite straight port of the MoreLikeThis class  
15 - # from Apache Lucene.  
16 - #  
17 - # options are:  
18 - # :field_names : Array of field names to use for similarity search (mandatory)  
19 - # :min_term_freq => 2, # Ignore terms with less than this frequency in the source doc.  
20 - # :min_doc_freq => 5, # Ignore words which do not occur in at least this many docs  
21 - # :min_word_length => nil, # Ignore words shorter than this length (longer words tend to  
22 - # be more characteristic for the document they occur in).  
23 - # :max_word_length => nil, # Ignore words if greater than this len.  
24 - # :max_query_terms => 25, # maximum number of terms in the query built  
25 - # :max_num_tokens => 5000, # maximum number of tokens to examine in a single field  
26 - # :boost => false, # when true, a boost according to the relative score of  
27 - # a term is applied to this Term's TermQuery.  
28 - # :similarity => 'DefaultAAFSimilarity' # the similarity implementation to use (the default  
29 - # equals Ferret's internal similarity implementation)  
30 - # :analyzer => 'Ferret::Analysis::StandardAnalyzer' # class name of the analyzer to use  
31 - # :append_to_query => nil # proc taking a query object as argument, which will be called after generating the query. can be used to further manipulate the query used to find related documents, i.e. to constrain the search to a given class in single table inheritance scenarios  
32 - # ferret_options : Ferret options handed over to find_by_contents (i.e. for limits and sorting)  
33 - # ar_options : options handed over to find_by_contents for AR scoping  
34 - def more_like_this(options = {}, ferret_options = {}, ar_options = {})  
35 - options = {  
36 - :field_names => nil, # Default field names  
37 - :min_term_freq => 2, # Ignore terms with less than this frequency in the source doc.  
38 - :min_doc_freq => 5, # Ignore words which do not occur in at least this many docs  
39 - :min_word_length => 0, # Ignore words if less than this len. Default is not to ignore any words.  
40 - :max_word_length => 0, # Ignore words if greater than this len. Default is not to ignore any words.  
41 - :max_query_terms => 25, # maximum number of terms in the query built  
42 - :max_num_tokens => 5000, # maximum number of tokens to analyze when analyzing contents  
43 - :boost => false,  
44 - :similarity => 'ActsAsFerret::MoreLikeThis::DefaultAAFSimilarity', # class name of the similarity implementation to use  
45 - :analyzer => 'Ferret::Analysis::StandardAnalyzer', # class name of the analyzer to use  
46 - :append_to_query => nil,  
47 - :base_class => self.class # base class to use for querying, useful in STI scenarios where BaseClass.find_by_contents can be used to retrieve results from other classes, too  
48 - }.update(options)  
49 - #index.search_each('id:*') do |doc, score|  
50 - # puts "#{doc} == #{index[doc][:description]}"  
51 - #end  
52 - clazz = options[:base_class]  
53 - options[:base_class] = clazz.name  
54 - query = clazz.aaf_index.build_more_like_this_query(self.id, self.class.name, options)  
55 - options[:append_to_query].call(query) if options[:append_to_query]  
56 - clazz.find_with_ferret(query, ferret_options, ar_options)  
57 - end  
58 -  
59 - end  
60 -  
61 - module IndexMethods  
62 -  
63 - # TODO to allow morelikethis for unsaved records, we have to give the  
64 - # unsaved record's data to this method. check how this will work out  
65 - # via drb...  
66 - def build_more_like_this_query(id, class_name, options)  
67 - [:similarity, :analyzer].each { |sym| options[sym] = options[sym].constantize.new }  
68 - ferret_index.synchronize do # avoid that concurrent writes close our reader  
69 - ferret_index.send(:ensure_reader_open)  
70 - reader = ferret_index.send(:reader)  
71 - term_freq_map = retrieve_terms(id, class_name, reader, options)  
72 - priority_queue = create_queue(term_freq_map, reader, options)  
73 - create_query(id, class_name, priority_queue, options)  
74 - end  
75 - end  
76 -  
77 - protected  
78 -  
79 - def create_query(id, class_name, priority_queue, options={})  
80 - query = Ferret::Search::BooleanQuery.new  
81 - qterms = 0  
82 - best_score = nil  
83 - while(cur = priority_queue.pop)  
84 - term_query = Ferret::Search::TermQuery.new(cur.field, cur.word)  
85 -  
86 - if options[:boost]  
87 - # boost term according to relative score  
88 - # TODO untested  
89 - best_score ||= cur.score  
90 - term_query.boost = cur.score / best_score  
91 - end  
92 - begin  
93 - query.add_query(term_query, :should)  
94 - rescue Ferret::Search::BooleanQuery::TooManyClauses  
95 - break  
96 - end  
97 - qterms += 1  
98 - break if options[:max_query_terms] > 0 && qterms >= options[:max_query_terms]  
99 - end  
100 - # exclude the original record  
101 - query.add_query(query_for_record(id, class_name), :must_not)  
102 - return query  
103 - end  
104 -  
105 -  
106 -  
107 - # creates a term/term_frequency map for terms from the fields  
108 - # given in options[:field_names]  
109 - def retrieve_terms(id, class_name, reader, options)  
110 - raise "more_like_this atm only works on saved records" if id.nil?  
111 - document_number = document_number(id, class_name) rescue nil  
112 - field_names = options[:field_names]  
113 - max_num_tokens = options[:max_num_tokens]  
114 - term_freq_map = Hash.new(0)  
115 - doc = nil  
116 - record = nil  
117 - field_names.each do |field|  
118 - #puts "field: #{field}"  
119 - term_freq_vector = reader.term_vector(document_number, field) if document_number  
120 - #if false  
121 - if term_freq_vector  
122 - # use stored term vector  
123 - # puts 'using stored term vector'  
124 - term_freq_vector.terms.each do |term|  
125 - term_freq_map[term.text] += term.positions.size unless noise_word?(term.text, options)  
126 - end  
127 - else  
128 - # puts 'no stored term vector'  
129 - # no term vector stored, but we have stored the contents in the index  
130 - # -> extract terms from there  
131 - content = nil  
132 - if document_number  
133 - doc = reader[document_number]  
134 - content = doc[field]  
135 - end  
136 - unless content  
137 - # no term vector, no stored content, so try content from this instance  
138 - record ||= options[:base_class].constantize.find(id)  
139 - content = record.content_for_field_name(field.to_s)  
140 - end  
141 - puts "have doc: #{doc[:id]} with #{field} == #{content}"  
142 - token_count = 0  
143 -  
144 - ts = options[:analyzer].token_stream(field, content)  
145 - while token = ts.next  
146 - break if (token_count+=1) > max_num_tokens  
147 - next if noise_word?(token.text, options)  
148 - term_freq_map[token.text] += 1  
149 - end  
150 - end  
151 - end  
152 - term_freq_map  
153 - end  
154 -  
155 - # create an ordered(by score) list of word,fieldname,score  
156 - # structures  
157 - def create_queue(term_freq_map, reader, options)  
158 - pq = Array.new(term_freq_map.size)  
159 -  
160 - similarity = options[:similarity]  
161 - num_docs = reader.num_docs  
162 - term_freq_map.each_pair do |word, tf|  
163 - # filter out words that don't occur enough times in the source  
164 - next if options[:min_term_freq] && tf < options[:min_term_freq]  
165 -  
166 - # go through all the fields and find the largest document frequency  
167 - top_field = options[:field_names].first  
168 - doc_freq = 0  
169 - options[:field_names].each do |field_name|  
170 - freq = reader.doc_freq(field_name, word)  
171 - if freq > doc_freq  
172 - top_field = field_name  
173 - doc_freq = freq  
174 - end  
175 - end  
176 - # filter out words that don't occur in enough docs  
177 - next if options[:min_doc_freq] && doc_freq < options[:min_doc_freq]  
178 - next if doc_freq == 0 # index update problem ?  
179 -  
180 - idf = similarity.idf(doc_freq, num_docs)  
181 - score = tf * idf  
182 - pq << FrequencyQueueItem.new(word, top_field, score)  
183 - end  
184 - pq.compact!  
185 - pq.sort! { |a,b| a.score<=>b.score }  
186 - return pq  
187 - end  
188 -  
189 - def noise_word?(text, options)  
190 - len = text.length  
191 - (  
192 - (options[:min_word_length] > 0 && len < options[:min_word_length]) ||  
193 - (options[:max_word_length] > 0 && len > options[:max_word_length]) ||  
194 - (options[:stop_words] && options.include?(text))  
195 - )  
196 - end  
197 -  
198 - end  
199 -  
200 - class DefaultAAFSimilarity  
201 - def idf(doc_freq, num_docs)  
202 - return 0.0 if num_docs == 0  
203 - return Math.log(num_docs.to_f/(doc_freq+1)) + 1.0  
204 - end  
205 - end  
206 -  
207 -  
208 - class FrequencyQueueItem  
209 - attr_reader :word, :field, :score  
210 - def initialize(word, field, score)  
211 - @word = word; @field = field; @score = score  
212 - end  
213 - end  
214 -  
215 - end  
216 -end  
217 -  
vendor/plugins/acts_as_ferret/lib/multi_index.rb
@@ -1,126 +0,0 @@ @@ -1,126 +0,0 @@
1 -module ActsAsFerret #:nodoc:  
2 -  
3 - # Base class for remote and local multi-indexes  
4 - class MultiIndexBase  
5 - include FerretFindMethods  
6 - attr_accessor :logger  
7 -  
8 - def initialize(indexes, options = {})  
9 - # ensure all models indexes exist  
10 - @indexes = indexes  
11 - indexes.each { |i| i.ensure_index_exists }  
12 - default_fields = indexes.inject([]) do |fields, idx|  
13 - fields + [ idx.index_definition[:ferret][:default_field] ]  
14 - end.flatten.uniq  
15 - @options = {  
16 - :default_field => default_fields  
17 - }.update(options)  
18 - @logger = IndexLogger.new(ActsAsFerret::logger, "multi: #{indexes.map(&:index_name).join(',')}")  
19 - end  
20 -  
21 - def ar_find(query, options = {}, ar_options = {})  
22 - limit = options.delete(:limit)  
23 - offset = options.delete(:offset) || 0  
24 - options[:limit] = :all  
25 - total_hits, result = super query, options, ar_options  
26 - total_hits = result.size if ar_options[:conditions]  
27 - if limit && limit != :all  
28 - result = result[offset..limit+offset-1]  
29 - end  
30 - [total_hits, result]  
31 - end  
32 -  
33 - def determine_stored_fields(options)  
34 - return nil unless options.has_key?(:lazy)  
35 - stored_fields = []  
36 - @indexes.each do |index|  
37 - stored_fields += index.determine_stored_fields(options)  
38 - end  
39 - return stored_fields.uniq  
40 - end  
41 -  
42 - def shared?  
43 - false  
44 - end  
45 -  
46 - end  
47 -  
48 - # This class can be used to search multiple physical indexes at once.  
49 - class MultiIndex < MultiIndexBase  
50 -  
51 - def extract_stored_fields(doc, stored_fields)  
52 - ActsAsFerret::get_index_for(doc[:class_name]).extract_stored_fields(doc, stored_fields) unless stored_fields.blank?  
53 - end  
54 -  
55 - def total_hits(q, options = {})  
56 - search(q, options).total_hits  
57 - end  
58 -  
59 - def search(query, options={})  
60 - query = process_query(query, options)  
61 - logger.debug "parsed query: #{query.to_s}"  
62 - searcher.search(query, options)  
63 - end  
64 -  
65 - def search_each(query, options = {}, &block)  
66 - query = process_query(query, options)  
67 - searcher.search_each(query, options, &block)  
68 - end  
69 -  
70 - # checks if all our sub-searchers still are up to date  
71 - def latest?  
72 - #return false unless @reader  
73 - # segfaults with 0.10.4 --> TODO report as bug @reader.latest?  
74 - @reader and @reader.latest?  
75 - #@sub_readers.each do |r|  
76 - # return false unless r.latest?  
77 - #end  
78 - #true  
79 - end  
80 -  
81 - def searcher  
82 - ensure_searcher  
83 - @searcher  
84 - end  
85 -  
86 - def doc(i)  
87 - searcher[i]  
88 - end  
89 - alias :[] :doc  
90 -  
91 - def query_parser  
92 - @query_parser ||= Ferret::QueryParser.new(@options)  
93 - end  
94 -  
95 - def process_query(query, options = {})  
96 - query = query_parser.parse(query) if query.is_a?(String)  
97 - return query  
98 - end  
99 -  
100 - def close  
101 - @searcher.close if @searcher  
102 - @reader.close if @reader  
103 - end  
104 -  
105 - protected  
106 -  
107 - def ensure_searcher  
108 - unless latest?  
109 - @sub_readers = @indexes.map { |idx|  
110 - begin  
111 - reader = Ferret::Index::IndexReader.new(idx.index_definition[:index_dir])  
112 - logger.debug "sub-reader opened: #{reader}"  
113 - reader  
114 - rescue Exception  
115 - raise "error opening reader on index for class #{clazz.inspect}: #{$!}"  
116 - end  
117 - }  
118 - close  
119 - @reader = Ferret::Index::IndexReader.new(@sub_readers)  
120 - @searcher = Ferret::Search::Searcher.new(@reader)  
121 - end  
122 - end  
123 -  
124 - end # of class MultiIndex  
125 -  
126 -end  
vendor/plugins/acts_as_ferret/lib/rdig_adapter.rb
@@ -1,141 +0,0 @@ @@ -1,141 +0,0 @@
1 -begin  
2 - require 'rdig'  
3 -rescue LoadError  
4 -end  
5 -module ActsAsFerret  
6 -  
7 - # The RdigAdapter is automatically included into your model if you specify  
8 - # the +:rdig+ options hash in your call to acts_as_ferret. It overrides  
9 - # several methods declared by aaf to retrieve documents with the help of  
10 - # RDig's http crawler when you call rebuild_index.  
11 - module RdigAdapter  
12 -  
13 - if defined?(RDig)  
14 -  
15 - def self.included(target)  
16 - target.extend ClassMethods  
17 - target.send :include, InstanceMethods  
18 - end  
19 -  
20 - # Indexer class to replace RDig's original indexer  
21 - class Indexer  
22 - include MonitorMixin  
23 - def initialize(batch_size, model_class, &block)  
24 - @batch_size = batch_size  
25 - @model_class = model_class  
26 - @documents = []  
27 - @offset = 0  
28 - @block = block  
29 - super()  
30 - end  
31 -  
32 - def add(doc)  
33 - synchronize do  
34 - @documents << @model_class.new(doc.uri.to_s, doc)  
35 - process_batch if @documents.size >= @batch_size  
36 - end  
37 - end  
38 - alias << add  
39 -  
40 - def close  
41 - synchronize do  
42 - process_batch  
43 - end  
44 - end  
45 -  
46 - protected  
47 - def process_batch  
48 - ActsAsFerret::logger.info "RdigAdapter::Indexer#process_batch: #{@documents.size} docs in queue, offset #{@offset}"  
49 - @block.call @documents, @offset  
50 - @offset += @documents.size  
51 - @documents = []  
52 - end  
53 - end  
54 -  
55 - module ClassMethods  
56 - # overriding aaf to return the documents fetched via RDig  
57 - def records_for_rebuild(batch_size = 1000, &block)  
58 - indexer = Indexer.new(batch_size, self, &block)  
59 - configure_rdig do  
60 - crawler = RDig::Crawler.new RDig.configuration, ActsAsFerret::logger  
61 - crawler.instance_variable_set '@indexer', indexer  
62 - ActsAsFerret::logger.debug "now crawling..."  
63 - crawler.crawl  
64 - end  
65 - rescue => e  
66 - ActsAsFerret::logger.error e  
67 - ActsAsFerret::logger.debug e.backtrace.join("\n")  
68 - ensure  
69 - indexer.close if indexer  
70 - end  
71 -  
72 - # overriding aaf to skip reindexing records changed during the rebuild  
73 - # when rebuilding with the rake task  
74 - def records_modified_since(time)  
75 - []  
76 - end  
77 -  
78 - # unfortunately need to modify global RDig.configuration because it's  
79 - # used everywhere in RDig  
80 - def configure_rdig  
81 - # back up original config  
82 - old_logger = RDig.logger  
83 - old_cfg = RDig.configuration.dup  
84 - RDig.logger = ActsAsFerret.logger  
85 - rdig_configuration[:crawler].each { |k,v| RDig.configuration.crawler.send :"#{k}=", v } if rdig_configuration[:crawler]  
86 - if ce_config = rdig_configuration[:content_extraction]  
87 - RDig.configuration.content_extraction = OpenStruct.new( :hpricot => OpenStruct.new( ce_config ) )  
88 - end  
89 - yield  
90 - ensure  
91 - # restore original config  
92 - RDig.configuration.crawler = old_cfg.crawler  
93 - RDig.configuration.content_extraction = old_cfg.content_extraction  
94 - RDig.logger = old_logger  
95 - end  
96 -  
97 - # overriding aaf to enforce loading page title and content from the  
98 - # ferret index  
99 - def find_with_ferret(q, options = {}, find_options = {})  
100 - options[:lazy] = true  
101 - super  
102 - end  
103 -  
104 - def find_for_id(id)  
105 - new id  
106 - end  
107 - end  
108 -  
109 - module InstanceMethods  
110 - def initialize(uri, rdig_document = nil)  
111 - @id = uri  
112 - @rdig_document = rdig_document  
113 - end  
114 -  
115 - # Title of the document.  
116 - # Use the +:title_tag_selector+ option to declare the hpricot expression  
117 - # that should be used for selecting the content for this field.  
118 - def title  
119 - @rdig_document.title  
120 - end  
121 -  
122 - # Content of the document.  
123 - # Use the +:content_tag_selector+ option to declare the hpricot expression  
124 - # that should be used for selecting the content for this field.  
125 - def content  
126 - @rdig_document.body  
127 - end  
128 -  
129 - # Url of this document.  
130 - def id  
131 - @id  
132 - end  
133 -  
134 - def to_s  
135 - "Page at #{id}, title: #{title}"  
136 - end  
137 - end  
138 - end  
139 - end  
140 -  
141 -end  
vendor/plugins/acts_as_ferret/lib/remote_functions.rb
@@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
1 -module ActsAsFerret  
2 - module RemoteFunctions  
3 -  
4 - private  
5 -  
6 - def yield_results(total_hits, results)  
7 - results.each do |result|  
8 - yield result[:model], result[:id], result[:score], result[:data]  
9 - end  
10 - total_hits  
11 - end  
12 -  
13 -  
14 - def handle_drb_error(return_value_in_case_of_error = false)  
15 - yield  
16 - rescue DRb::DRbConnError => e  
17 - logger.error "DRb connection error: #{e}"  
18 - logger.warn e.backtrace.join("\n")  
19 - raise e if ActsAsFerret::raise_drb_errors?  
20 - return_value_in_case_of_error  
21 - end  
22 - end  
23 -end  
vendor/plugins/acts_as_ferret/lib/remote_index.rb
@@ -1,54 +0,0 @@ @@ -1,54 +0,0 @@
1 -require 'drb'  
2 -module ActsAsFerret  
3 -  
4 - # This index implementation connects to a remote ferret server instance. It  
5 - # basically forwards all calls to the remote server.  
6 - class RemoteIndex < AbstractIndex  
7 - include RemoteFunctions  
8 -  
9 - def initialize(config)  
10 - super  
11 - @server = DRbObject.new(nil, ActsAsFerret::remote)  
12 - end  
13 -  
14 - # Cause model classes to be loaded (and indexes get declared) on the DRb  
15 - # side of things.  
16 - def register_class(clazz, options)  
17 - handle_drb_error { @server.register_class clazz.name }  
18 - end  
19 -  
20 - def method_missing(method_name, *args)  
21 - args.unshift index_name  
22 - handle_drb_error { @server.send(method_name, *args) }  
23 - end  
24 -  
25 - # Proxy any methods that require special return values in case of errors  
26 - {  
27 - :highlight => []  
28 - }.each do |method_name, default_result|  
29 - define_method method_name do |*args|  
30 - args.unshift index_name  
31 - handle_drb_error(default_result) { @server.send method_name, *args }  
32 - end  
33 - end  
34 -  
35 - def find_ids(q, options = {}, &proc)  
36 - total_hits, results = handle_drb_error([0, []]) { @server.find_ids(index_name, q, options) }  
37 - block_given? ? yield_results(total_hits, results, &proc) : [ total_hits, results ]  
38 - end  
39 -  
40 - # add record to index  
41 - def add(record)  
42 - handle_drb_error { @server.add index_name, record.to_doc }  
43 - end  
44 - alias << add  
45 -  
46 - private  
47 -  
48 - #def model_class_name  
49 - # index_definition[:class_name]  
50 - #end  
51 -  
52 - end  
53 -  
54 -end  
vendor/plugins/acts_as_ferret/lib/remote_multi_index.rb
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -module ActsAsFerret  
2 - class RemoteMultiIndex < MultiIndexBase  
3 - include RemoteFunctions  
4 -  
5 - def initialize(indexes, options = {})  
6 - @index_names = indexes.map(&:index_name)  
7 - @server = DRbObject.new(nil, ActsAsFerret::remote)  
8 - super  
9 - end  
10 -  
11 - def find_ids(query, options, &proc)  
12 - total_hits, results = handle_drb_error([0, []]) { @server.multi_find_ids(@index_names, query, options) }  
13 - block_given? ? yield_results(total_hits, results, &proc) : [ total_hits, results ]  
14 - end  
15 -  
16 - def method_missing(name, *args)  
17 - handle_drb_error { @server.send(:"multi_#{name}", @index_names, *args) }  
18 - end  
19 - end  
20 -end  
vendor/plugins/acts_as_ferret/lib/search_results.rb
@@ -1,50 +0,0 @@ @@ -1,50 +0,0 @@
1 -module ActsAsFerret  
2 -  
3 - # decorator that adds a total_hits accessor and will_paginate compatible  
4 - # paging support to search result arrays  
5 - class SearchResults < ActsAsFerret::BlankSlate  
6 - reveal :methods  
7 - attr_reader :current_page, :per_page, :total_hits, :total_pages  
8 - alias total_entries total_hits # will_paginate compatibility  
9 - alias page_count total_pages # will_paginate backwards compatibility  
10 -  
11 - def initialize(results, total_hits, current_page = 1, per_page = nil)  
12 - @results = results  
13 - @total_hits = total_hits  
14 - @current_page = current_page  
15 - @per_page = (per_page || total_hits)  
16 - @total_pages = @per_page > 0 ? (@total_hits / @per_page.to_f).ceil : 0  
17 - end  
18 -  
19 - def method_missing(symbol, *args, &block)  
20 - @results.send(symbol, *args, &block)  
21 - end  
22 -  
23 - def respond_to?(name)  
24 - methods.include?(name.to_s) || @results.respond_to?(name)  
25 - end  
26 -  
27 -  
28 - # code from here on was directly taken from will_paginate's collection.rb  
29 -  
30 - # Current offset of the paginated collection. If we're on the first page,  
31 - # it is always 0. If we're on the 2nd page and there are 30 entries per page,  
32 - # the offset is 30. This property is useful if you want to render ordinals  
33 - # besides your records: simply start with offset + 1.  
34 - #  
35 - def offset  
36 - (current_page - 1) * per_page  
37 - end  
38 -  
39 - # current_page - 1 or nil if there is no previous page  
40 - def previous_page  
41 - current_page > 1 ? (current_page - 1) : nil  
42 - end  
43 -  
44 - # current_page + 1 or nil if there is no next page  
45 - def next_page  
46 - current_page < total_pages ? (current_page + 1) : nil  
47 - end  
48 - end  
49 -  
50 -end  
vendor/plugins/acts_as_ferret/lib/server_manager.rb
@@ -1,58 +0,0 @@ @@ -1,58 +0,0 @@
1 -################################################################################  
2 -require 'optparse'  
3 -  
4 -################################################################################  
5 -$ferret_server_options = {  
6 - 'environment' => nil,  
7 - 'debug' => nil,  
8 - 'root' => nil  
9 -}  
10 -  
11 -################################################################################  
12 -OptionParser.new do |optparser|  
13 - optparser.banner = "Usage: #{File.basename($0)} [options] {start|stop|run}"  
14 -  
15 - optparser.on('-h', '--help', "This message") do  
16 - puts optparser  
17 - exit  
18 - end  
19 -  
20 - optparser.on('-R', '--root=PATH', 'Set RAILS_ROOT to the given string') do |r|  
21 - $ferret_server_options['root'] = r  
22 - end  
23 -  
24 - optparser.on('-e', '--environment=NAME', 'Set RAILS_ENV to the given string') do |e|  
25 - $ferret_server_options['environment'] = e  
26 - end  
27 -  
28 - optparser.on('--debug', 'Include full stack traces on exceptions') do  
29 - $ferret_server_options['debug'] = true  
30 - end  
31 -  
32 - $ferret_server_action = optparser.permute!(ARGV)  
33 - (puts optparser; exit(1)) unless $ferret_server_action.size == 1  
34 -  
35 - $ferret_server_action = $ferret_server_action.first  
36 - (puts optparser; exit(1)) unless %w(start stop run).include?($ferret_server_action)  
37 -end  
38 -  
39 -################################################################################  
40 -begin  
41 - ENV['FERRET_USE_LOCAL_INDEX'] = 'true'  
42 - ENV['RAILS_ENV'] = $ferret_server_options['environment']  
43 -  
44 - # determine RAILS_ROOT unless already set  
45 - RAILS_ROOT = $ferret_server_options['root'] || File.join(File.dirname(__FILE__), *(['..']*4)) unless defined? RAILS_ROOT  
46 - # check if environment.rb is present  
47 - rails_env_file = File.join(RAILS_ROOT, 'config', 'environment')  
48 - raise "Unable to find Rails environment.rb at \n#{rails_env_file}.rb\nPlease use the --root option of ferret_server to point it to your RAILS_ROOT." unless File.exists?(rails_env_file+'.rb')  
49 - # load it  
50 - require rails_env_file  
51 -  
52 - require 'acts_as_ferret'  
53 - ActsAsFerret::Remote::Server.new.send($ferret_server_action)  
54 -rescue Exception => e  
55 - $stderr.puts(e.message)  
56 - $stderr.puts(e.backtrace.join("\n")) if $ferret_server_options['debug']  
57 - exit(1)  
58 -end  
vendor/plugins/acts_as_ferret/lib/unix_daemon.rb
@@ -1,64 +0,0 @@ @@ -1,64 +0,0 @@
1 -################################################################################  
2 -module ActsAsFerret  
3 - module Remote  
4 -  
5 - ################################################################################  
6 - # methods for becoming a daemon on Unix-like operating systems  
7 - module UnixDaemon  
8 -  
9 - ################################################################################  
10 - def platform_daemon (&block)  
11 - safefork do  
12 - write_pid_file  
13 - trap("TERM") { exit(0) }  
14 - sess_id = Process.setsid  
15 - STDIN.reopen("/dev/null")  
16 - STDOUT.reopen("#{RAILS_ROOT}/log/ferret_server.out", "a")  
17 - STDERR.reopen(STDOUT)  
18 - block.call  
19 - end  
20 - end  
21 -  
22 - ################################################################################  
23 - # stop the daemon, nicely at first, and then forcefully if necessary  
24 - def stop  
25 - pid = read_pid_file  
26 - raise "ferret_server doesn't appear to be running" unless pid  
27 - $stdout.puts("stopping ferret server...")  
28 - Process.kill("TERM", pid)  
29 - 30.times { Process.kill(0, pid); sleep(0.5) }  
30 - $stdout.puts("using kill -9 #{pid}")  
31 - Process.kill(9, pid)  
32 - rescue Errno::ESRCH => e  
33 - $stdout.puts("process #{pid} has stopped")  
34 - ensure  
35 - File.unlink(@cfg.pid_file) if File.exist?(@cfg.pid_file)  
36 - end  
37 -  
38 - ################################################################################  
39 - def safefork (&block)  
40 - @fork_tries ||= 0  
41 - fork(&block)  
42 - rescue Errno::EWOULDBLOCK  
43 - raise if @fork_tries >= 20  
44 - @fork_tries += 1  
45 - sleep 5  
46 - retry  
47 - end  
48 -  
49 - #################################################################################  
50 - # create the PID file and install an at_exit handler  
51 - def write_pid_file  
52 - raise "ferret_server may already be running, a pid file exists: #{@cfg.pid_file}" if read_pid_file  
53 - open(@cfg.pid_file, "w") {|f| f << Process.pid << "\n"}  
54 - at_exit { File.unlink(@cfg.pid_file) if read_pid_file == Process.pid }  
55 - end  
56 -  
57 - #################################################################################  
58 - def read_pid_file  
59 - File.read(@cfg.pid_file).to_i if File.exist?(@cfg.pid_file)  
60 - end  
61 -  
62 - end  
63 - end  
64 -end  
vendor/plugins/acts_as_ferret/lib/without_ar.rb
@@ -1,49 +0,0 @@ @@ -1,49 +0,0 @@
1 -module ActsAsFerret  
2 -  
3 - # Include this module to use acts_as_ferret with model classes  
4 - # not based on ActiveRecord.  
5 - #  
6 - # Implement the find_for_id(id) class method in your model class in  
7 - # order to make search work.  
8 - module WithoutAR  
9 - def self.included(target)  
10 - target.extend ClassMethods  
11 - target.extend ActsAsFerret::ActMethods  
12 - target.send :include, InstanceMethods  
13 - end  
14 -  
15 - module ClassMethods  
16 - def logger  
17 - RAILS_DEFAULT_LOGGER  
18 - end  
19 - def table_name  
20 - self.name.underscore  
21 - end  
22 - def primary_key  
23 - 'id'  
24 - end  
25 - def find(what, args = {})  
26 - case what  
27 - when :all  
28 - ids = args[:conditions][1]  
29 - ids.map { |id| find id }  
30 - else  
31 - find_for_id what  
32 - end  
33 - end  
34 - def find_for_id(id)  
35 - raise NotImplementedError.new("implement find_for_id in class #{self.name}")  
36 - end  
37 - def count  
38 - 0  
39 - end  
40 - end  
41 -  
42 - module InstanceMethods  
43 - def logger  
44 - self.class.logger  
45 - end  
46 - end  
47 - end  
48 -  
49 -end  
vendor/plugins/acts_as_ferret/rakefile
@@ -1,134 +0,0 @@ @@ -1,134 +0,0 @@
1 -# rakefile for acts_as_ferret.  
2 -# use to create a gem or generate rdoc api documentation.  
3 -#  
4 -# RELEASE creation:  
5 -# rake release REL=x.y.z  
6 -  
7 -require 'rake'  
8 -require 'rake/rdoctask'  
9 -require 'rake/packagetask'  
10 -require 'rake/gempackagetask'  
11 -require 'rake/testtask'  
12 -require 'rake/contrib/rubyforgepublisher'  
13 -  
14 -def announce(msg='')  
15 - STDERR.puts msg  
16 -end  
17 -  
18 -  
19 -PKG_NAME = 'acts_as_ferret'  
20 -PKG_VERSION = ENV['REL']  
21 -PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"  
22 -RUBYFORGE_PROJECT = 'actsasferret'  
23 -RUBYFORGE_USER = 'jkraemer'  
24 -  
25 -desc 'Default: run unit tests.'  
26 -task :default => :test  
27 -  
28 -desc 'Test the acts_as_ferret plugin.'  
29 -Rake::TestTask.new(:test) do |t|  
30 - t.libs << 'lib'  
31 - t.pattern = 'test/**/*_test.rb'  
32 - t.verbose = true  
33 -end  
34 -  
35 -desc 'Generate documentation for the acts_as_ferret plugin.'  
36 -Rake::RDocTask.new(:rdoc) do |rdoc|  
37 - rdoc.rdoc_dir = 'html'  
38 - rdoc.title = "acts_as_ferret - Ferret based full text search for any ActiveRecord model"  
39 - rdoc.options << '--line-numbers' << '--inline-source'  
40 - rdoc.options << '--main' << 'README'  
41 - rdoc.rdoc_files.include('README', 'LICENSE')  
42 - rdoc.template = "#{ENV['template']}.rb" if ENV['template']  
43 - rdoc.rdoc_files.include('lib/**/*.rb')  
44 -end  
45 -  
46 -desc "Publish the API documentation"  
47 -task :pdoc => [:rdoc] do  
48 - Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, RUBYFORGE_USER).upload  
49 -end  
50 -  
51 -if PKG_VERSION  
52 - spec = Gem::Specification.new do |s|  
53 - s.name = PKG_NAME  
54 - s.version = PKG_VERSION  
55 - s.platform = Gem::Platform::RUBY  
56 - s.summary = "acts_as_ferret - Ferret based full text search for any ActiveRecord model"  
57 - s.files = Dir.glob('**/*', File::FNM_DOTMATCH).reject do |f|  
58 - [ /\.$/, /sqlite$/, /\.log$/, /^pkg/, /\.svn/, /\.\w+\.sw.$/,  
59 - /^html/, /\~$/, /\/\._/, /\/#/ ].any? {|regex| f =~ regex }  
60 - end  
61 - #s.files = FileList["{lib,test}/**/*"].to_a + %w(README MIT-LICENSE CHANGELOG)  
62 - # s.files.delete ...  
63 - s.require_path = 'lib'  
64 - s.bindir = "bin"  
65 - s.executables = ["aaf_install"]  
66 - s.default_executable = "aaf_install"  
67 - s.autorequire = 'acts_as_ferret'  
68 - s.has_rdoc = true  
69 - # s.test_files = Dir['test/**/*_test.rb']  
70 - s.author = "Jens Kraemer"  
71 - s.email = "jk@jkraemer.net"  
72 - s.homepage = "http://projects.jkraemer.net/acts_as_ferret"  
73 - end  
74 -  
75 - package_task = Rake::GemPackageTask.new(spec) do |pkg|  
76 - pkg.need_tar = true  
77 - end  
78 -  
79 - # Validate that everything is ready to go for a release.  
80 - task :prerelease do  
81 - announce  
82 - announce "**************************************************************"  
83 - announce "* Making RubyGem Release #{PKG_VERSION}"  
84 - announce "**************************************************************"  
85 - announce  
86 - # Are all source files checked in?  
87 - if ENV['RELTEST']  
88 - announce "Release Task Testing, skipping checked-in file test"  
89 - else  
90 - announce "Pulling in svn..."  
91 - `svk pull .`  
92 - announce "Checking for unchecked-in files..."  
93 - data = `svk st`  
94 - unless data =~ /^$/  
95 - fail "SVK status is not clean ... do you have unchecked-in files?"  
96 - end  
97 - announce "No outstanding checkins found ... OK"  
98 -# announce "Pushing to svn..."  
99 -# `svk push .`  
100 - end  
101 - end  
102 -  
103 -  
104 - desc "tag the new release"  
105 - task :tag => [ :prerelease ] do  
106 - reltag = "REL_#{PKG_VERSION.gsub(/\./, '_')}"  
107 - reltag << ENV['REUSE'].gsub(/\./, '_') if ENV['REUSE']  
108 - announce "Tagging with [#{PKG_VERSION}]"  
109 - if ENV['RELTEST']  
110 - announce "Release Task Testing, skipping tagging"  
111 - else  
112 - `svn copy -m 'tagging version #{PKG_VERSION}' svn://projects.jkraemer.net/acts_as_ferret/trunk/plugin svn://projects.jkraemer.net/acts_as_ferret/tags/#{PKG_VERSION}`  
113 - `svn del -m 'remove old stable' svn://projects.jkraemer.net/acts_as_ferret/tags/stable`  
114 - `svn copy -m 'tagging version #{PKG_VERSION} as stable' svn://projects.jkraemer.net/acts_as_ferret/tags/#{PKG_VERSION} svn://projects.jkraemer.net/acts_as_ferret/tags/stable`  
115 - end  
116 - end  
117 -  
118 - # Upload release to rubyforge  
119 - desc "Upload release to rubyforge"  
120 - task :prel => [ :tag, :prerelease, :package ] do  
121 - `rubyforge login`  
122 - release_command = "rubyforge add_release #{RUBYFORGE_PROJECT} #{PKG_NAME} '#{PKG_VERSION}' pkg/#{PKG_NAME}-#{PKG_VERSION}.gem"  
123 - puts release_command  
124 - system(release_command)  
125 - `rubyforge config #{RUBYFORGE_PROJECT}`  
126 - release_command = "rubyforge add_file #{RUBYFORGE_PROJECT} #{PKG_NAME} '#{PKG_VERSION}' pkg/#{PKG_NAME}-#{PKG_VERSION}.tgz"  
127 - puts release_command  
128 - system(release_command)  
129 - end  
130 -  
131 - desc 'Publish the gem and API docs'  
132 - task :release => [:pdoc, :prel ]  
133 -  
134 -end  
vendor/plugins/acts_as_ferret/recipes/aaf_recipes.rb
@@ -1,97 +0,0 @@ @@ -1,97 +0,0 @@
1 -# Ferret DRb server Capistrano tasks  
2 -#  
3 -# Usage:  
4 -# in your Capfile, add acts_as_ferret's recipes directory to your load path and  
5 -# load the ferret tasks:  
6 -#  
7 -# load_paths << 'vendor/plugins/acts_as_ferret/recipes'  
8 -# load 'aaf_recipes'  
9 -#  
10 -# This will hook aaf's DRb start/stop tasks into the standard  
11 -# deploy:{start|restart|stop} tasks so the server will be restarted along with  
12 -# the rest of your application.  
13 -# Also an index directory in the shared folder will be created and symlinked  
14 -# into current/ when you deploy.  
15 -#  
16 -# In order to use the ferret:index:rebuild task, declare the indexes you intend to  
17 -# rebuild remotely in config/deploy.rb:  
18 -#  
19 -# set :ferret_indexes, %w( model another_model shared )  
20 -#  
21 -# HINT: To be very sure that your DRb server and application are always using  
22 -# the same model and schema versions, and you never lose any index updates because  
23 -# of the DRb server being restarted in that moment, use the following sequence  
24 -# to update your application:  
25 -#  
26 -# cap deploy:stop deploy:update deploy:migrate deploy:start  
27 -#  
28 -# That will stop the DRb server after stopping your application, and bring it  
29 -# up before starting the application again. Plus they'll never use different  
30 -# versions of model classes (which might happen otherwise)  
31 -# Downside: Your downtime is a bit longer than with the usual deploy, so be sure to  
32 -# put up some maintenance page for the meantime. Obviously this won't work if  
33 -# your migrations need acts_as_ferret (i.e. if you update model instances which  
34 -# would lead to index updates). In this case bring up the DRb server before  
35 -# running your migrations:  
36 -#  
37 -# cap deploy:stop deploy:update ferret:start deploy:migrate ferret:stop deploy:start  
38 -#  
39 -# Chances are that you're still not safe if your migrations not only modify the index,  
40 -# but also change the structure of your models. So just don't do both things in  
41 -# one go - I can't think of an easy way to handle this case automatically.  
42 -# Suggestions and patches are of course very welcome :-)  
43 -  
44 -namespace :ferret do  
45 -  
46 - desc "Stop the Ferret DRb server"  
47 - task :stop, :roles => :app do  
48 - rails_env = fetch(:rails_env, 'production')  
49 - run "cd #{current_path}; script/ferret_server -e #{rails_env} stop || true"  
50 - end  
51 -  
52 - desc "Start the Ferret DRb server"  
53 - task :start, :roles => :app do  
54 - rails_env = fetch(:rails_env, 'production')  
55 - run "cd #{current_path}; script/ferret_server -e #{rails_env} start"  
56 - end  
57 -  
58 - desc "Restart the Ferret DRb server"  
59 - task :restart, :roles => :app do  
60 - top.ferret.stop  
61 - sleep 1  
62 - top.ferret.start  
63 - end  
64 -  
65 - namespace :index do  
66 -  
67 - desc "Rebuild the Ferret index. See aaf_recipes.rb for instructions."  
68 - task :rebuild => :environment, :roles => :app do  
69 - rake = fetch(:rake, 'rake')  
70 - rails_env = fetch(:rails_env, 'production')  
71 - indexes = fetch(:ferret_indexes, nil)  
72 - if indexes and indexes.any?  
73 - run "cd #{current_path}; RAILS_ENV=#{rails_env} INDEXES='#{indexes.join(' ')}' #{rake} ferret:rebuild"  
74 - end  
75 - end  
76 -  
77 - desc "purges all indexes for the current environment"  
78 - task :purge, :roles => :app do  
79 - run "rm -fr #{shared_path}/index/#{rails_env}"  
80 - end  
81 -  
82 - desc "symlinks index folder"  
83 - task :symlink, :roles => :app do  
84 - run "mkdir -p #{shared_path}/index && rm -rf #{release_path}/index && ln -nfs #{shared_path}/index #{release_path}/index"  
85 - end  
86 -  
87 - end  
88 -  
89 -end  
90 -  
91 -after "deploy:stop", "ferret:stop"  
92 -before "deploy:start", "ferret:start"  
93 -  
94 -before "deploy:restart", "ferret:stop"  
95 -after "deploy:restart", "ferret:start"  
96 -after "deploy:symlink", "ferret:index:symlink"  
97 -  
vendor/plugins/acts_as_ferret/script/ferret_daemon
@@ -1,94 +0,0 @@ @@ -1,94 +0,0 @@
1 -# Ferret Win32 Service Daemon, called by Win 32 service,  
2 -# created by Herryanto Siatono <herryanto@pluitsolutions.com>  
3 -#  
4 -# see doc/README.win32 for usage instructions  
5 -#  
6 -require 'optparse'  
7 -require 'win32/service'  
8 -include Win32  
9 -  
10 -# Read options  
11 -options = {}  
12 -ARGV.options do |opts|  
13 - opts.banner = 'Usage: ferret_daemon [options]'  
14 - opts.on("-l", "--log FILE", "Daemon log file") {|file| options[:log] = file }  
15 - opts.on("-c","--console","Run Ferret server on console.") {options[:console] = true}  
16 - opts.on_tail("-h","--help", "Show this help message") {puts opts; exit}  
17 - opts.on("-e", "--environment ENV ", "Rails environment") {|env|  
18 - options[:environment] = env  
19 - ENV['RAILS_ENV'] = env  
20 - }  
21 - opts.parse!  
22 -end  
23 -  
24 -require File.dirname(__FILE__) + '/../config/environment'  
25 -  
26 -# Ferret Win32 Service Daemon, called by Win 32 service,  
27 -# to run on the console, use -c or --console option.  
28 -module Ferret  
29 - class FerretDaemon < Daemon  
30 - # Standard logger to redirect STDOUT and STDERR to a log file  
31 - class FerretStandardLogger  
32 - def initialize(logger)  
33 - @logger = logger  
34 - end  
35 -  
36 - def write(s)  
37 - @logger.info s  
38 - end  
39 - end  
40 -  
41 - def initialize(options={})  
42 - @options = options  
43 -  
44 - # initialize logger  
45 - if options[:log]  
46 - @logger = Logger.new @options[:log]  
47 - else  
48 - @logger = Logger.new RAILS_ROOT + "/log/ferret_service_#{RAILS_ENV}.log"  
49 - end  
50 -  
51 - # redirect stout and stderr to Ferret logger if running as windows service  
52 - $stdout = $stderr = FerretStandardLogger.new(@logger) unless @options[:console]  
53 -  
54 - log "Initializing FerretDaemon..."  
55 - if @options[:console]  
56 - self.service_init  
57 - self.service_main  
58 - end  
59 - end  
60 -  
61 - def service_main  
62 - log "Service main enterred..."  
63 -  
64 - while running?  
65 - log "Listening..."  
66 - sleep  
67 - end  
68 -  
69 - log "Service main exit..."  
70 - end  
71 -  
72 - def service_init  
73 - log "Starting Ferret DRb server..."  
74 - ActsAsFerret::Remote::Server.start  
75 - log "FerretDaemon started."  
76 - end  
77 -  
78 - def service_stop  
79 - log "Stopping service..."  
80 - DRb.stop_service  
81 - log "FerretDaemon stopped."  
82 - end  
83 -  
84 - def log(msg)  
85 - @logger.info msg  
86 - puts msg if @options[:console]  
87 - end  
88 - end  
89 -end  
90 -  
91 -if __FILE__ == $0  
92 - d = Ferret::FerretDaemon.new(options)  
93 - d.mainloop  
94 -end  
vendor/plugins/acts_as_ferret/script/ferret_server
@@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
1 -#!/usr/bin/env ruby  
2 -  
3 -begin  
4 - require File.join(File.dirname(__FILE__), '../vendor/plugins/acts_as_ferret/lib/server_manager')  
5 -rescue LoadError  
6 - # try the gem  
7 - require 'rubygems'  
8 - gem 'acts_as_ferret'  
9 - require 'server_manager'  
10 -end  
vendor/plugins/acts_as_ferret/script/ferret_service
@@ -1,178 +0,0 @@ @@ -1,178 +0,0 @@
1 -# Ferret Win32 Service Daemon install script  
2 -# created by Herryanto Siatono <herryanto@pluitsolutions.com>  
3 -#  
4 -# see doc/README.win32 for usage instructions  
5 -#  
6 -require 'optparse'  
7 -require 'win32/service'  
8 -include Win32  
9 -  
10 -module Ferret  
11 - # Parse and validate service command and options  
12 - class FerretServiceCommand  
13 - COMMANDS = ['install', 'remove', 'start', 'stop', 'help']  
14 - BANNER = "Usage: ruby script/ferret_service <command> [options]"  
15 -  
16 - attr_reader :options, :command  
17 -  
18 - def initialize  
19 - @options = {}  
20 - end  
21 -  
22 - def valid_command?  
23 - COMMANDS.include?@command  
24 - end  
25 -  
26 - def valid_options?  
27 - @options[:name] and !@options[:name].empty?  
28 - end  
29 -  
30 - def print_command_list  
31 - puts BANNER  
32 - puts "\nAvailable commands:\n"  
33 - puts COMMANDS.map {|cmd| " - #{cmd}\n"}  
34 - puts "\nUse option -h for each command to help."  
35 - exit  
36 - end  
37 -  
38 - def validate_options  
39 - errors = []  
40 - errors << "Service name is required." unless @options[:name]  
41 -  
42 - if (errors.size > 0)  
43 - errors << "Error found. Use: 'ruby script/ferret_service #{@command} -h' for to get help."  
44 - puts errors.join("\n")  
45 - exit  
46 - end  
47 - end  
48 -  
49 - def run(args)  
50 - @command = args.shift  
51 - @command = @command.dup.downcase if @command  
52 -  
53 - # validate command and options  
54 - print_command_list unless valid_command? or @command == 'help'  
55 -  
56 - opts_parser = create_options_parser  
57 - begin  
58 - opts_parser.parse!(args)  
59 - rescue OptionParser::ParseError => e  
60 - puts e  
61 - puts opts_parser  
62 - end  
63 -  
64 - # validate required options  
65 - validate_options  
66 - end  
67 -  
68 - def create_options_parser  
69 - opts_parser = OptionParser.new  
70 - opts_parser.banner = BANNER  
71 - opts_parser.on("-n", "--name=NAME", "Service name") {|name| @options[:name] = name }  
72 - opts_parser.on_tail("-t", "--trace", "Display stack trace when exception thrown") { @options[:trace] = true }  
73 - opts_parser.on_tail("-h", "--help", "Show this help message") { puts opts_parser; exit }  
74 -  
75 - if ['install'].include?@command  
76 - opts_parser.on("-d", "--display=NAME", "Service display name") {|name| @options[:display] = name }  
77 -  
78 - opts_parser.on("-l", "--log FILE", "Service log file") {|file| @options[:log] = file }  
79 - opts_parser.on("-e", "--environment ENV ", "Rails environment") { |env|  
80 - @options[:environment] = env  
81 - ENV['RAILS_ENV'] = env  
82 - }  
83 - end  
84 - opts_parser  
85 - end  
86 - end  
87 -  
88 - # Install, Remove, Start and Stop Ferret DRb server Win32 service  
89 - class FerretService  
90 - FERRET_DAEMON = 'ferret_daemon'  
91 -  
92 - def initialize  
93 - end  
94 -  
95 - def install  
96 - svc = Service.new  
97 -  
98 - begin  
99 - if Service.exists?(@options[:name])  
100 - puts "Service name '#{@options[:name]}' already exists."  
101 - return  
102 - end  
103 -  
104 - svc.create_service do |s|  
105 - s.service_name = @options[:name]  
106 - s.display_name = @options[:display]  
107 - s.binary_path_name = binary_path_name  
108 - s.dependencies = []  
109 - end  
110 -  
111 - svc.close  
112 - puts "'#{@options[:name]}' service installed."  
113 - rescue => e  
114 - handle_error(e)  
115 - end  
116 - end  
117 -  
118 - def remove  
119 - begin  
120 - Service.stop(@options[:name])  
121 - rescue  
122 - end  
123 -  
124 - begin  
125 - Service.delete(@options[:name])  
126 - puts "'#{@options[:name]}' service removed."  
127 - rescue => e  
128 - handle_error(e)  
129 - end  
130 - end  
131 -  
132 - def start  
133 - begin  
134 - Service.start(@options[:name])  
135 - puts "'#{@options[:name]}' successfully started."  
136 - rescue => e  
137 - handle_error(e)  
138 - end  
139 - end  
140 -  
141 - def stop  
142 - begin  
143 - Service.stop(@options[:name])  
144 - puts "'#{@options[:name]}' successfully stopped.\n"  
145 - rescue => e  
146 - handle_error(e)  
147 - end  
148 - end  
149 -  
150 - def run(args)  
151 - svc_cmd = FerretServiceCommand.new  
152 - svc_cmd.run(args)  
153 - @options = svc_cmd.options  
154 - self.send(svc_cmd.command.to_sym)  
155 - end  
156 -  
157 - protected  
158 - def handle_error(e)  
159 - if @options[:trace]  
160 - raise e  
161 - else  
162 - puts e  
163 - end  
164 - end  
165 -  
166 - def binary_path_name  
167 - path = ""  
168 - path << "#{ENV['RUBY_HOME']}/bin/" if ENV['RUBY_HOME']  
169 - path << "ruby.exe "  
170 - path << File.expand_path("script/" + FERRET_DAEMON)  
171 - path << " -e #{@options[:environment]} " if @options[:environment]  
172 - path << " -l #{@options[:log]} " if @options[:log]  
173 - path  
174 - end  
175 - end  
176 -end  
177 -  
178 -Ferret::FerretService.new.run(ARGV)  
vendor/plugins/acts_as_ferret/tasks/ferret.rake
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -namespace :ferret do  
2 -  
3 - # Rebuild index task. Declare the indexes to be rebuilt with the INDEXES  
4 - # environment variable:  
5 - #  
6 - # INDEXES="my_model shared" rake ferret:rebuild  
7 - desc "Rebuild a Ferret index. Specify what model to rebuild with the MODEL environment variable."  
8 - task :rebuild do  
9 - require File.join(RAILS_ROOT, 'config', 'environment')  
10 -  
11 - indexes = ENV['INDEXES'].split  
12 - indexes.each do |index_name|  
13 - start = 1.minute.ago  
14 - ActsAsFerret::rebuild_index index_name  
15 - idx = ActsAsFerret::get_index index_name  
16 - # update records that have changed since the rebuild started  
17 - idx.index_definition[:registered_models].each do |m|  
18 - m.records_modified_since(start).each do |object|  
19 - object.ferret_update  
20 - end  
21 - end  
22 - end  
23 - end  
24 -end