search_generator 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +30 -0
- data/USAGE +50 -0
- data/search_generator.rb +97 -0
- data/templates/README +81 -0
- data/templates/app/controllers/controller.rb +48 -0
- data/templates/app/views/layouts/layout.rhtml +25 -0
- data/templates/app/views/opensearch/_generic.rhtml +11 -0
- data/templates/app/views/opensearch/description.rxml +9 -0
- data/templates/app/views/opensearch/rss.rhtml +23 -0
- data/templates/app/views/search/_generic.rhtml +7 -0
- data/templates/app/views/search/index.rhtml +14 -0
- data/templates/lib/search_system.rb +20 -0
- data/templates/script/indexer +82 -0
- data/templates/script/searcher +38 -0
- metadata +78 -0
data/LICENSE
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
Copyright (c) 2005 Jeremy Hinegardner <jeremy@hinegardner.org>
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are
|
6
|
+
met:
|
7
|
+
|
8
|
+
* Redistributions of source code must retain the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
* Redistributions in binary form must reproduce the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer in
|
13
|
+
the documentation and/or other materials provided with the
|
14
|
+
distribution.
|
15
|
+
|
16
|
+
* The name of the author may not be used to endorse or promote
|
17
|
+
products derived from this software without specific prior written
|
18
|
+
permission from the author.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
21
|
+
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
22
|
+
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
23
|
+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
24
|
+
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
25
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
26
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
27
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
28
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
29
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
30
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/USAGE
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
NAME
|
2
|
+
|
3
|
+
search - a search engine that can be added to any Rails application
|
4
|
+
|
5
|
+
SYNOPSIS
|
6
|
+
|
7
|
+
search [Search name] [options]
|
8
|
+
|
9
|
+
Good names, anything that means search would be good. Search,
|
10
|
+
Forage, Frisk or Shakedown.
|
11
|
+
|
12
|
+
search has an additional option --inspect which will travers your
|
13
|
+
Model objects and tell you which ones could be made searchable
|
14
|
+
|
15
|
+
DESCRIPTION
|
16
|
+
|
17
|
+
This generator integrates the SimpleSearch search engine into a
|
18
|
+
rails applicaiton. In addition, once configured for you site, it
|
19
|
+
provides an Open Search (http://opensearch.a9.com/) compatible
|
20
|
+
interface.
|
21
|
+
|
22
|
+
Included:
|
23
|
+
|
24
|
+
* a Controller to manage search request
|
25
|
+
* Views to customize for your Model objects
|
26
|
+
- regular html results
|
27
|
+
- Open Search RSS style results
|
28
|
+
* an indexer to run periodically against your data to keep the
|
29
|
+
search indexes up to date.
|
30
|
+
* a README on the additional hand coded tasks to intgerate
|
31
|
+
the search engine with your application
|
32
|
+
|
33
|
+
EXAMPLE
|
34
|
+
|
35
|
+
./script/generate search Search
|
36
|
+
|
37
|
+
This will create a basic search engine framework for you to
|
38
|
+
customize for your site.
|
39
|
+
|
40
|
+
./script/generate search Search --inspect
|
41
|
+
|
42
|
+
This will report which ones of your Model classes could be made
|
43
|
+
searchable.
|
44
|
+
|
45
|
+
DEPENDENCIES
|
46
|
+
|
47
|
+
- SimpleSearch (http://www.chadfowler.com/SimpleSearch)
|
48
|
+
Install : gem install SimpleSearch
|
49
|
+
|
50
|
+
|
data/search_generator.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
class SearchGenerator < Rails::Generator::NamedBase
|
2
|
+
|
3
|
+
def add_options!(opt)
|
4
|
+
opt.on('-i', '--inspect','Inspect models to see which ones can be searchable') { |value| options[:inspect] = true }
|
5
|
+
end
|
6
|
+
|
7
|
+
def inspect
|
8
|
+
puts <<howto_make_searchable
|
9
|
+
The following Models, and their associated fields,
|
10
|
+
in your application can be made searchable. Just copy
|
11
|
+
and paste the 'make_searchable' line from the report below
|
12
|
+
into the approrpaite models file (also reported below).
|
13
|
+
|
14
|
+
The 'make_searchable' line reports all the searchable fields
|
15
|
+
in that model. You probably do not want all of the fields
|
16
|
+
in your Model, so edit the line as appropriate
|
17
|
+
|
18
|
+
IMPORTANT:
|
19
|
+
|
20
|
+
Make sure to the following line to the top of any model file
|
21
|
+
you edit to make searchable.
|
22
|
+
|
23
|
+
require_dependency "search_system"
|
24
|
+
|
25
|
+
howto_make_searchable
|
26
|
+
|
27
|
+
Dir.glob(File.join(@destination_root,"app/models/*.rb")).each do |rbfile|
|
28
|
+
bname = File.basename(rbfile,'.rb')
|
29
|
+
classname = Inflector.camelize(bname)
|
30
|
+
classvar = eval(classname)
|
31
|
+
if classvar.respond_to?(:descends_from_active_record?) and
|
32
|
+
classvar.descends_from_active_record? then
|
33
|
+
attrs = classvar.columns_hash.keys.collect { |a| ":" + a.to_s}
|
34
|
+
|
35
|
+
puts "-----[ #{classname} => #{File.expand_path(rbfile)} ]-----"
|
36
|
+
if classvar.respond_to?(:searchable_fields) then
|
37
|
+
fields = classvar.searchable_fields
|
38
|
+
if fields.nil? or fields.size == 0 then
|
39
|
+
puts "#{classname} is searchable, but no fields are selected."
|
40
|
+
puts
|
41
|
+
puts " make_searchable [ #{attrs.join(", ")} ]"
|
42
|
+
else
|
43
|
+
fields = fields.collect { |f| ":" + f.to_s }
|
44
|
+
puts "#{classname} has the following fields marked as searchable:"
|
45
|
+
puts
|
46
|
+
puts " [ #{fields.join(", ")} ]"
|
47
|
+
end
|
48
|
+
else
|
49
|
+
puts " make_searchable [ #{attrs.join(", ")} ]"
|
50
|
+
end
|
51
|
+
puts
|
52
|
+
end
|
53
|
+
end
|
54
|
+
puts
|
55
|
+
end
|
56
|
+
|
57
|
+
def remove
|
58
|
+
manifest.rewind(Rails::Generator::Command::Destroy)
|
59
|
+
end
|
60
|
+
|
61
|
+
def manifest
|
62
|
+
record do |m|
|
63
|
+
|
64
|
+
if options[:inspect] then
|
65
|
+
m.inspect
|
66
|
+
else
|
67
|
+
# system
|
68
|
+
m.template "lib/search_system.rb", "lib/search_system.rb"
|
69
|
+
|
70
|
+
# controller
|
71
|
+
m.template "app/controllers/controller.rb", "app/controllers/#{file_name}_controller.rb"
|
72
|
+
|
73
|
+
# layout
|
74
|
+
m.template "app/views/layouts/layout.rhtml", "app/views/layouts/#{file_name}.rhtml"
|
75
|
+
|
76
|
+
# views
|
77
|
+
m.directory File.join("app/views", class_path, file_name)
|
78
|
+
m.template "app/views/search/index.rhtml", "app/views/#{file_name}/index.rhtml"
|
79
|
+
m.template "app/views/search/_generic.rhtml", "app/views/#{file_name}/_generic.rhtml"
|
80
|
+
|
81
|
+
m.directory "app/views/opensearch"
|
82
|
+
m.template "app/views/opensearch/rss.rhtml", "app/views/opensearch/rss.rhtml"
|
83
|
+
m.template "app/views/opensearch/description.rxml", "app/views/opensearch/description.rxml"
|
84
|
+
m.template "app/views/opensearch/_generic.rhtml", "app/views/opensearch/_generic.rhtml"
|
85
|
+
|
86
|
+
# scripts
|
87
|
+
m.template "script/indexer", "script/indexer", :chmod => 0755
|
88
|
+
m.template "script/searcher", "script/searcher", :chmod => 0755
|
89
|
+
|
90
|
+
# custom to this generation install README
|
91
|
+
m.template "README", "README_SEARCH"
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
data/templates/README
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
== Installation
|
2
|
+
|
3
|
+
After the search engine has been generated, there are still tasks to
|
4
|
+
fully integrate the search engine into your site.
|
5
|
+
|
6
|
+
=== Inspect
|
7
|
+
|
8
|
+
execute:
|
9
|
+
|
10
|
+
script/generate search <%= class_name %> --inspect
|
11
|
+
|
12
|
+
This will report which of your models can be made searchable. Feel
|
13
|
+
free to run it many times.
|
14
|
+
|
15
|
+
=== Models
|
16
|
+
|
17
|
+
In each of your Models in which you want to have the content
|
18
|
+
searched, and are ActiveRecord descendants, you need to add a
|
19
|
+
require_dependency "search_system". Then you are able to invoke the
|
20
|
+
class method 'make_searchable' with an Array of field symbols.
|
21
|
+
|
22
|
+
For example:
|
23
|
+
|
24
|
+
require_dependency "search_system"
|
25
|
+
class Article < ActiveRecord::Base
|
26
|
+
make_searchable [ :title, :author, :content ]
|
27
|
+
end
|
28
|
+
|
29
|
+
=== Routes
|
30
|
+
|
31
|
+
Add the following lines to your config/routes.rb to hook in search
|
32
|
+
|
33
|
+
# allow for searching view the route
|
34
|
+
map.connect '<%= file_name %>/:search_terms/:count', :controller => '<%= file_name %>', :action => 'index', :count => '-1'
|
35
|
+
|
36
|
+
# allow for Open Search RSS feeds searching
|
37
|
+
map.connect 'rss/opensearch/description.xml', :controller => '<%= file_name %>', :action => 'description'
|
38
|
+
map.connect 'rss/opensearch/:search_terms/:count', :controller => '<%= file_name %>', :action => 'rss', :count => '-1'
|
39
|
+
|
40
|
+
=== Layouts
|
41
|
+
|
42
|
+
A 'very' basic layout/<%= file_name %>.rhtml is installed that shows the basic
|
43
|
+
results. This should be customized for your site.
|
44
|
+
|
45
|
+
=== Views
|
46
|
+
|
47
|
+
Two new views have been added to your rails application.
|
48
|
+
|
49
|
+
1. Search
|
50
|
+
|
51
|
+
This view should be customized for your site so that the search
|
52
|
+
results fit in well with your site. The default _partial
|
53
|
+
template that exists will render out a generic table showing all
|
54
|
+
the fields and their values for the search results. You should
|
55
|
+
customize the index.rhtml file to integrate with your site, and
|
56
|
+
you should create a _partial.rhtml for each Model that you could
|
57
|
+
have search results for.
|
58
|
+
|
59
|
+
That is, if you have an application with an Article Model, you
|
60
|
+
should create a _article.rhtml file in this view to render out
|
61
|
+
the results of your search that are of Article class.
|
62
|
+
|
63
|
+
The generic index.rhtml that is present will automatically use
|
64
|
+
the appropriate _parital.rhtml file based upon the class name if
|
65
|
+
it is present.
|
66
|
+
|
67
|
+
2. Open Search
|
68
|
+
|
69
|
+
This view is to return results in the format of OpenSearch RSS
|
70
|
+
(http://opensearch.a9.com/spec/opensearchrss/1.0/). This
|
71
|
+
combined with the rss/opensearch Routes above and the
|
72
|
+
description.rxml file found in this view should provide you with
|
73
|
+
an OpenSearch-able site.
|
74
|
+
|
75
|
+
Again, you should create a _partial.rhtml file in this directory
|
76
|
+
for each Model you have that can return search results.
|
77
|
+
|
78
|
+
Also, the description.xml file should be configure with your
|
79
|
+
sites information.
|
80
|
+
|
81
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_dependency "search_system"
|
2
|
+
|
3
|
+
class <%= class_name %>Controller < ApplicationController
|
4
|
+
layout "<%= file_name %>" , :except => [:rss, :description]
|
5
|
+
|
6
|
+
def index
|
7
|
+
search
|
8
|
+
end
|
9
|
+
|
10
|
+
#-----------------------------------------------------------------------
|
11
|
+
# search through the index, get the ActiveRecord's that match and
|
12
|
+
# return those to the caller
|
13
|
+
#-----------------------------------------------------------------------
|
14
|
+
def search
|
15
|
+
@search_terms = @params['search_terms'].split
|
16
|
+
@count = @params['count'].to_i || -1
|
17
|
+
|
18
|
+
empty_contents = MockContents.new
|
19
|
+
simple_index = Search::Simple::Searcher.load(empty_contents,"#{File.dirname(__FILE__)}/../../db/search_cache")
|
20
|
+
|
21
|
+
# what to return to the caller
|
22
|
+
@results = Array.new
|
23
|
+
|
24
|
+
# TODO: sort by score at some point ?
|
25
|
+
search_results = simple_index.find_words(@search_terms)
|
26
|
+
|
27
|
+
if search_results.contains_matches then
|
28
|
+
search_results.results.sort.each do |result|
|
29
|
+
(classname,pk_id,column) = result.name.split(".")
|
30
|
+
classvar = eval(classname)
|
31
|
+
@results << classvar.find(pk_id)
|
32
|
+
break if @count > 0 and @results.size >= @count
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
@results.uniq!
|
37
|
+
end
|
38
|
+
|
39
|
+
def description
|
40
|
+
@headers["Content-Type"] = "text/xml"
|
41
|
+
render 'opensearch/description'
|
42
|
+
end
|
43
|
+
def rss
|
44
|
+
@headers["Content-Type"] = "text/xml"
|
45
|
+
search
|
46
|
+
render 'opensearch/rss'
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
5
|
+
<title>SITE TITLE</title>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
|
9
|
+
<h1>Search SITE</h1>
|
10
|
+
|
11
|
+
<form action="/search" method="get">
|
12
|
+
<%% if @search_terms.size > 0 %>
|
13
|
+
<input type="text" name="search_terms" value="<%%= @search_terms.join(" ") %>" size="30" />
|
14
|
+
<%% else %>
|
15
|
+
<input type="text" name="search_terms" value="" size="30" />
|
16
|
+
<%% end %>
|
17
|
+
</form>
|
18
|
+
|
19
|
+
<hr />
|
20
|
+
|
21
|
+
<h2>Results</h2>
|
22
|
+
<%%= @content_for_layout %>
|
23
|
+
|
24
|
+
</body>
|
25
|
+
</html>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<title><%%= generic.class.name %></title>
|
2
|
+
<link>INSERT CODE TO GET LINK TO THIS ITEM</link>
|
3
|
+
<description>
|
4
|
+
<div class="record">
|
5
|
+
<table>
|
6
|
+
<%% generic.class.searchable_fields.each do |field| %>
|
7
|
+
<tr> <th><%%= field.to_s %></th> <td><%%= generic.send(field) %></td> </tr>
|
8
|
+
<%% end %>
|
9
|
+
</table>
|
10
|
+
</div>
|
11
|
+
</description>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
xml.OpenSearchDescription(:xmlns => "http://a9.com/-/spec/opensearchrss/1.0/") do
|
2
|
+
xml.url("http://localhost:3000/opensearch/{searchTerms}/{count}")
|
3
|
+
xml.format("http://a9.com/-/spec/opensearchrss/1.0/")
|
4
|
+
xml.shortname("site shortname")
|
5
|
+
xml.longname("site longname")
|
6
|
+
xml.description("site description")
|
7
|
+
xml.syndicationright("open")
|
8
|
+
xml.adultcontent("false")
|
9
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<rss version="1.0" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">
|
3
|
+
<channel>
|
4
|
+
<title>Site title</title>
|
5
|
+
<link><%%= @request.env['REQUEST_URI'] %></link>
|
6
|
+
<description>Site description</description>
|
7
|
+
<language>en-us</language>
|
8
|
+
<copyright>&copy;2003-2005, site its affiliates.</copyright>
|
9
|
+
<openSearch:totalResults><%%= @results.size %></openSearch:totalResults>
|
10
|
+
<openSearch:startIndex>1</openSearch:startIndex>
|
11
|
+
<openSearch:itemsPerPage><%%= @results.size %></openSearch:itemsPerPage>
|
12
|
+
|
13
|
+
|
14
|
+
<%% for result in @results %>
|
15
|
+
<%% begin %>
|
16
|
+
<%%= render_partial "opensearch/#{Inflector.underscore(result.class)}", result %>
|
17
|
+
<%% rescue ActionView::ActionViewError %>
|
18
|
+
<%%= render_partial "opensearch/generic", result %>
|
19
|
+
<%% end %>
|
20
|
+
<%% end %>
|
21
|
+
</channel>
|
22
|
+
</rss>
|
23
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%% @results.each do |result| %>
|
2
|
+
<hr />
|
3
|
+
|
4
|
+
<%%# Try to render a partial based upon the class name %>
|
5
|
+
<%%# but if that does not work, reneder a generic one %>
|
6
|
+
|
7
|
+
<%% begin %>
|
8
|
+
<%%= render_partial Inflector.underscore(result.class), result %>
|
9
|
+
<%% rescue ActionView::ActionViewError %>
|
10
|
+
<pre>No parital available for <%%= result.class %>, using generic </pre>
|
11
|
+
<%%= render_partial "generic", result %>
|
12
|
+
<%% end %>
|
13
|
+
|
14
|
+
<%% end %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_gem "SimpleSearch"
|
2
|
+
|
3
|
+
class ActiveRecord::Base
|
4
|
+
|
5
|
+
def self.make_searchable(list_of_field_symbols)
|
6
|
+
@searchable_fields = list_of_field_symbols
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.searchable_fields
|
10
|
+
@searchable_fields
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
class MockContents
|
16
|
+
def latest_mtime
|
17
|
+
Time.at(0)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "#{File.dirname(__FILE__)}/../config/environment"
|
4
|
+
|
5
|
+
require_gem "SimpleSearch"
|
6
|
+
|
7
|
+
#-----------------------------------------------------------------------
|
8
|
+
# the container for all the contents to be indexed
|
9
|
+
#-----------------------------------------------------------------------
|
10
|
+
contents = Search::Simple::Contents.new
|
11
|
+
|
12
|
+
#-----------------------------------------------------------------------
|
13
|
+
# the current time is used to invalidate the Searcher's cache so it will
|
14
|
+
# force an indexing
|
15
|
+
#-----------------------------------------------------------------------
|
16
|
+
ts = Time.now
|
17
|
+
|
18
|
+
#-----------------------------------------------------------------------
|
19
|
+
# iterate over all the files in the models directory looking for those
|
20
|
+
# Models that are descendants of ActiveRecord
|
21
|
+
#-----------------------------------------------------------------------
|
22
|
+
puts "Searching for Models..."
|
23
|
+
Dir.glob("#{File.dirname(__FILE__)}/../app/models/*.rb").each do |rbfile|
|
24
|
+
|
25
|
+
bname = File.basename(rbfile,'.rb')
|
26
|
+
classname = Inflector.camelize(bname)
|
27
|
+
classvar = eval(classname)
|
28
|
+
|
29
|
+
if classvar.respond_to?(:descends_from_active_record?) and
|
30
|
+
classvar.descends_from_active_record? then
|
31
|
+
puts "\tFound #{classname} "
|
32
|
+
|
33
|
+
|
34
|
+
#---------------------------------------------------------------
|
35
|
+
# if the class that is a dscendant from ActiveRecord also has
|
36
|
+
# the special method :searchable_fields then those fields are
|
37
|
+
# considered searchable
|
38
|
+
#---------------------------------------------------------------
|
39
|
+
if classvar.respond_to?(:searchable_fields) then
|
40
|
+
|
41
|
+
if not classvar.searchable_fields.nil?
|
42
|
+
|
43
|
+
cnames = classvar.searchable_fields.collect {|c| c.to_s}
|
44
|
+
puts "\t\t- searching columns #{cnames.join(",")}"
|
45
|
+
indexed_records = 0
|
46
|
+
|
47
|
+
#-----------------------------------------------------------
|
48
|
+
# now we interate over all the records of the particular
|
49
|
+
# type and record all the information for indexing.
|
50
|
+
#-----------------------------------------------------------
|
51
|
+
classvar.find_all.each do |ar|
|
52
|
+
record_id = "#{classname}.#{ar.send(classvar.primary_key)}"
|
53
|
+
indexed_records = indexed_records + 1
|
54
|
+
|
55
|
+
classvar.searchable_fields.each do |column|
|
56
|
+
column_id = "#{record_id}.#{column.to_s}"
|
57
|
+
data = ar.send(column)
|
58
|
+
|
59
|
+
# only index non-nil content
|
60
|
+
if not data.nil? then
|
61
|
+
contents << Search::Simple::Content.new(ar.send(column), column_id, ts)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
puts "\t\t- indexed #{indexed_records} records"
|
67
|
+
else
|
68
|
+
puts "\t\t- no make_searchable fields"
|
69
|
+
end
|
70
|
+
|
71
|
+
else
|
72
|
+
puts "\t\t- class is not searchable"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#-----------------------------------------------------------------------
|
78
|
+
# this is where the actual indexing is done. There previous sections of
|
79
|
+
# code just collected the data to do the indexing.
|
80
|
+
#-----------------------------------------------------------------------
|
81
|
+
s = Search::Simple::Searcher.load(contents,"#{File.dirname(__FILE__)}/../db/search_cache")
|
82
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "#{File.dirname(__FILE__)}/../config/environment"
|
4
|
+
|
5
|
+
require_dependency "search_system"
|
6
|
+
|
7
|
+
#-----------------------------------------------------------------------
|
8
|
+
# grab the first word on the command line as the term to search for
|
9
|
+
#-----------------------------------------------------------------------
|
10
|
+
search_terms = Array.new
|
11
|
+
if ARGV.size > 0 then
|
12
|
+
search_terms << ARGV[0]
|
13
|
+
else
|
14
|
+
puts "no search term given, searching for 'ruby'"
|
15
|
+
search_terms << "ruby"
|
16
|
+
end
|
17
|
+
|
18
|
+
#-----------------------------------------------------------------------
|
19
|
+
# a mock contents so that we use the cache
|
20
|
+
#-----------------------------------------------------------------------
|
21
|
+
contents = MockContents.new
|
22
|
+
s = Search::Simple::Searcher.load(contents,"#{File.dirname(__FILE__)}/../db/search_cache")
|
23
|
+
|
24
|
+
#-----------------------------------------------------------------------
|
25
|
+
# do the search
|
26
|
+
#-----------------------------------------------------------------------
|
27
|
+
sr = s.find_words(search_terms)
|
28
|
+
|
29
|
+
if sr.contains_matches then
|
30
|
+
puts "Score\t#File"
|
31
|
+
sr.results.sort.each do |res|
|
32
|
+
puts "#{res.score}\t#{res.name}"
|
33
|
+
end
|
34
|
+
else
|
35
|
+
puts sr.warnings
|
36
|
+
puts "No matches"
|
37
|
+
end
|
38
|
+
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.10
|
3
|
+
specification_version: 1
|
4
|
+
name: search_generator
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.4"
|
7
|
+
date: 2005-04-11
|
8
|
+
summary: "[Rails] Search generator."
|
9
|
+
require_paths:
|
10
|
+
- "."
|
11
|
+
email: jeremy@hinegardner.org
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description: Generates Rails code implementing a search system using SimpleSearch for your Rails app.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
authors:
|
28
|
+
- Jeremy Hinegardner
|
29
|
+
files:
|
30
|
+
- USAGE
|
31
|
+
- LICENSE
|
32
|
+
- search_generator.rb
|
33
|
+
- templates/README
|
34
|
+
- templates/lib
|
35
|
+
- templates/app
|
36
|
+
- templates/script
|
37
|
+
- templates/lib/search_system.rb
|
38
|
+
- templates/app/controllers
|
39
|
+
- templates/app/views
|
40
|
+
- templates/app/controllers/controller.rb
|
41
|
+
- templates/app/views/search
|
42
|
+
- templates/app/views/opensearch
|
43
|
+
- templates/app/views/layouts
|
44
|
+
- templates/app/views/search/index.rhtml
|
45
|
+
- templates/app/views/search/_generic.rhtml
|
46
|
+
- templates/app/views/opensearch/_generic.rhtml
|
47
|
+
- templates/app/views/opensearch/rss.rhtml
|
48
|
+
- templates/app/views/opensearch/description.rxml
|
49
|
+
- templates/app/views/layouts/layout.rhtml
|
50
|
+
- templates/script/indexer
|
51
|
+
- templates/script/searcher
|
52
|
+
test_files: []
|
53
|
+
rdoc_options: []
|
54
|
+
extra_rdoc_files: []
|
55
|
+
executables: []
|
56
|
+
extensions: []
|
57
|
+
requirements: []
|
58
|
+
dependencies:
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: rails
|
61
|
+
version_requirement:
|
62
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
63
|
+
requirements:
|
64
|
+
-
|
65
|
+
- ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.10.0
|
68
|
+
version:
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: SimpleSearch
|
71
|
+
version_requirement:
|
72
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
73
|
+
requirements:
|
74
|
+
-
|
75
|
+
- ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.5.0
|
78
|
+
version:
|