bcms_google_mini_search 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,69 @@
1
+ # Google Mini Search Module
2
+
3
+ This module allows BrowserCMS to integrate with a Google Mini Search Appliance. Google Mini is a standalone search
4
+ server, which can be configured to crawl your website. This module submits queries to a Mini server, and formats the results.
5
+ It consists of the following two portlets.
6
+
7
+ 1. Search Box - Displays an input box that submits a search query.
8
+ 2. Google Mini Search Results Portlet - Sends query to the Mini, formats the XML response and displays the results.
9
+
10
+ Note: This module assume the BrowserCMS web site owner has access to their own Google Mini server, either hosted by
11
+ themselves or a third party service.
12
+
13
+ ## A. Instructions
14
+ There are two basic steps to setting up this module:
15
+
16
+ 1. Configure your Google Mini to crawl your site.
17
+ 2. Install the module and configure it to point to your Google Mini server.
18
+
19
+ These instructions assume the Mini is already set up and running.
20
+
21
+ ### B. Configuring Google Mini
22
+ Configuring the mini include three basic steps, configuring it to crawl your site, creating a collection which limits
23
+ what is returned to just your site, and creating a front end, which allows you to submit search queries.
24
+
25
+ #### B.1. Configuring the crawler
26
+ 1. Log into your search appliance (i.e. http://google.mini.mysite.com), and enter your account username/password.
27
+ 2. Click on the 'Crawl and Index' link in the left navigation.
28
+ 3. In the top box 'Start Crawling from the Following URLs:' add a new line with the full domain name of your site. (i.e. http://www.mysite.com)
29
+ 4. In the bottom box, 'Follow and Crawl Only URLs with the Following Patterns:', enter a pattern of urls you want to crawl. (i.e. www.mysite.com/)
30
+ 5. Click 'Save URLs to Crawl button'
31
+
32
+ Once the crawler is configured, it may take 15+ minutes for it to crawl your site. You can still finish configuring
33
+ the mini, but you may need to wait to test the results.
34
+
35
+ #### B.2. Configuring the collection
36
+ 1. Click the collections link in the left nav. This will allow use a create a search collection specifically for this site.
37
+ 2. Type the name of the new collection into the 'Collection Name' text box, and click 'Create Collection' (i.e. MYSITE).
38
+ 3. After the page refreshes, click the 'Edit' link to the right of the new collection.
39
+ 4. In the top box, 'Include Content Matching the Following Patterns:', enter the same pattern as step B.1.3 above (i.e. http://www.mysite.com/)
40
+ 5. Click 'Save Collection Defination'
41
+
42
+ #### B.3. Configuring the front end
43
+ 1. In the left nav, click the 'Serving' link
44
+ 2. In the 'Front End Name' text field, enter the name for your front end. (i.e. MYSITE_frontend.)
45
+ 3. Click 'Create Front End' to save it.
46
+
47
+ At this point, you should have the Google Mini appliance configured. If you want to test out the search results using
48
+ the Mini's default search UI, you can click the 'Test Center' link in the upper right hand corner. Select your new
49
+ collection and front end by name, and submit queries.
50
+
51
+ ### C. Configuring the BrowserCMS Google Mini Search Module
52
+ These instructions assume you have successfully installed the bcms_google_mini_search module into your project. To make
53
+ the module work, you will have to configure two portlets.
54
+
55
+ 1. In your sitemap, create a new section called 'Search', with a path '/search'.
56
+ 2. Create a page called 'Search Results', with a path '/search/search-results'.
57
+ 3. On that page, add a new 'Google Mini Search Engine' portlet. Keep the default for most fields.
58
+ 4. In the Service URL, field, enter in the domain name to your google mini server (i.e. http://google.mini.mysite.com)
59
+ 5. In the Colleciton Name field, enter the same name you gave your collection in B.2.2. (i.e. MYSITE)
60
+ 6. In the Front End Name field, enter the same name you have your frontend in B.3.2 (i.e. MYSITE_frontend)
61
+ 7. Make sure the 'path' attribute is the same as the page you are adding the portlet to (i.e. /search/search-results
62
+ 8. Save the portlet
63
+ 9. On another page create a Search Box portlet (alternatively, you can create the portlet and add it your templates via render_portlet)
64
+ 10. Set the 'Search Engine Name' field to the exact same name as the portlet in step C.3 above (i.e. Google Mini Search Engine)
65
+ 11. Save the portlet
66
+
67
+ At this point, you can test the search by entering in a term to the Search Box portlet. If its working, it should call
68
+ the Search Results page and display the same results as what you see in the Mini 'Test Center'. You can style the HTML in
69
+ the template to tweak how your search results will work.
@@ -0,0 +1,10 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ helper :all # include all helpers, all the time
6
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
7
+
8
+ # Scrub sensitive parameters from your log
9
+ # filter_parameter_logging :password
10
+ end
@@ -0,0 +1,3 @@
1
+ # Methods added to this helper will be available to all templates in the application.
2
+ module ApplicationHelper
3
+ end
@@ -0,0 +1,144 @@
1
+ class SearchResult
2
+
3
+ attr_accessor :number, :title, :url, :description, :size
4
+
5
+ #
6
+ # Queries google mini by a specific URL to find all the results. Converts XML results to
7
+ # a paging results of Search Results.
8
+ #
9
+ def self.find(query, options={})
10
+ xml_doc = fetch_xml_doc(query, options)
11
+ results = convert_to_results(xml_doc, options)
12
+ results.query = query
13
+ portlet = find_search_engine_portlet(options)
14
+ results.path = portlet.path
15
+ results
16
+ end
17
+
18
+ def self.parse_results_count(xml_doc)
19
+ root = xml_doc.root
20
+ count = root.elements["RES/M"]
21
+ count ? count.text.to_i : 0
22
+ end
23
+
24
+ def self.parse_results(xml_doc)
25
+ root = xml_doc.root
26
+ results = []
27
+ xml_doc.elements.each('GSP/RES/R') do |ele|
28
+ result = SearchResult.new
29
+ result.number = ele.attributes["N"]
30
+ result.title = ele.elements["T"].text
31
+ result.url = ele.elements["U"].text
32
+ result.description = ele.elements["S"].text
33
+ result.size = ele.elements["HAS/C"].attributes["SZ"]
34
+
35
+ results << result
36
+ end
37
+ results
38
+ end
39
+
40
+ def self.convert_to_results(xml_doc, options={})
41
+ array = parse_results(xml_doc)
42
+
43
+ results = PagingResults.new(array)
44
+ results.results_count = parse_results_count(xml_doc)
45
+ results.num_pages = calculate_results_pages(results.results_count)
46
+ results.start = options[:start] ? options[:start] : 0
47
+ results
48
+ end
49
+
50
+
51
+
52
+ def self.calculate_results_pages(results_count)
53
+ num_pages = results_count / 10
54
+ num_pages = num_pages + 1 if results_count % 10 > 0
55
+ num_pages
56
+ end
57
+
58
+
59
+ def self.build_mini_url(options, query)
60
+ portlet = find_search_engine_portlet(options)
61
+ url = "#{portlet.service_url}/search?q=#{query}&output=xml_no_dtd&client=#{portlet.front_end_name}&site=#{portlet.collection_name}&filter=0"
62
+ if options[:start]
63
+ url = url + "&start=#{options[:start]}"
64
+ end
65
+ return url
66
+ end
67
+
68
+ def self.find_search_engine_portlet(options)
69
+ portlet = GoogleMiniSearchEnginePortlet.new
70
+ if options[:portlet]
71
+ portlet = options[:portlet]
72
+ end
73
+ portlet
74
+ end
75
+
76
+ # Fetches the xml response from the google mini server.
77
+ def self.fetch_xml_doc(query, options={})
78
+ # Turns off automatic results filter (filter=0), which when set to 1, allows mini to reduces the # of similar/duplicate results,
79
+ # but makes it hard to determine the total # of results.
80
+ url = build_mini_url(options, query)
81
+ response = Net::HTTP.get(URI.parse(url))
82
+ xml_doc = REXML::Document.new(response)
83
+ return xml_doc
84
+ end
85
+
86
+
87
+
88
+ class PagingResults < Array
89
+
90
+ attr_accessor :results_count, :num_pages, :current_page, :start, :query, :pages
91
+ attr_writer :path
92
+
93
+ def path
94
+ @path ? @path : "/search/search-results"
95
+ end
96
+
97
+
98
+ def next_page?
99
+ next_start < results_count
100
+ end
101
+
102
+ def previous_page?
103
+ previous_start >= 0 && num_pages > 1
104
+ end
105
+
106
+ def pages
107
+ if num_pages > 1
108
+ return (1..num_pages)
109
+ end
110
+ []
111
+ end
112
+
113
+ def next_start
114
+ start + 10
115
+ end
116
+
117
+ def previous_start
118
+ start - 10
119
+ end
120
+
121
+ def current_page?(page_num)
122
+ (page_num * 10 - 10 == start )
123
+ end
124
+
125
+ def current_page
126
+ return page = start / 10 + 1 if start
127
+ 1
128
+ end
129
+
130
+ def next_page_path
131
+ "#{path}?query=#{query}&start=#{next_start}"
132
+ end
133
+
134
+ def previous_page_path
135
+ "#{path}?query=#{query}&start=#{previous_start}"
136
+ end
137
+
138
+ def page_path(page_num)
139
+ "#{path}?query=#{query}&start=#{page_num * 10 - 10}"
140
+ end
141
+ end
142
+
143
+
144
+ end
@@ -0,0 +1,9 @@
1
+ class GoogleMiniSearchEnginePortlet < Portlet
2
+
3
+ def render
4
+ @query = params[:query]
5
+ @start = params[:start] ? params[:start].to_i : 0
6
+ @results = SearchResult.find(@query, {:start => @start, :portlet => @portlet})
7
+ end
8
+
9
+ end
@@ -0,0 +1,10 @@
1
+ class SearchBoxPortlet < Portlet
2
+
3
+ def render
4
+ @search_engine = GoogleMiniSearchEnginePortlet.find_by_name(@portlet.search_engine_name)
5
+ unless @search_engine
6
+ raise "There is no Google Mini Search Engine Portlet with name = '#{@portlet.search_engine_name}'. You must create one for this portlet to work."
7
+ end
8
+ end
9
+
10
+ end
@@ -0,0 +1,6 @@
1
+ <%= f.cms_text_field :name, :default_value => "Google Mini Search Engine", :instructions=>"The Search Box portlet will look this up by name, so make it unique." %>
2
+ <%= f.cms_text_field :path, :default_value => "/search/search-results", :instructions=>"The path of the page this portlet will be embedded in." %>
3
+ <%= f.cms_text_field :service_url, :default_value=> "http://", :instructions => "Full Domain name where the Google Mini server is hosted, i.e. 'http://mini.somedomain.com'." %>
4
+ <%= f.cms_text_field :collection_name, :instructions => "Copy the name of the Collection from Google Mini here." %>
5
+ <%= f.cms_text_field :front_end_name, :instructions => "Copy the name of the Collection front end from Google Mini here." %>
6
+ <%= f.cms_text_area :template, :default_value => @block.class.default_template %>
@@ -0,0 +1,19 @@
1
+ <h2>Search Results</h2>
2
+ For '<%= @results.query %>', found <%= @results.results_count %> results. <br />
3
+ <% if @results.previous_page? %><%= link_to h("< Back"), @results.previous_page_path %><% end %>
4
+ <% if @results.next_page? %><%= link_to h("Next >"), @results.next_page_path %><% end %>
5
+ <ul>
6
+ <% @results.each do |result|%>
7
+ <li>
8
+ <%= result.number %> <%= link_to result.title, result.url, :class=>"search_result_title" %><br />
9
+ <span class="search_result_description"><%= result.description %></span> <br />
10
+ <span class="search_result_url"><%= result.url %></span> -
11
+ <span class="search_result_size"><%= result.size %></span>
12
+ </li>
13
+ <% end %>
14
+ </ul>
15
+ <% if @results.previous_page? %><%= link_to h("< Back"), @results.previous_page_path %><% end %>
16
+ <% @results.pages.each do |p| %>
17
+ <%= link_to_unless @results.current_page?(p), p, @results.page_path(p) %>
18
+ <% end %>
19
+ <% if @results.next_page? %><%= link_to h("Next >"), @results.next_page_path %><% end %>
@@ -0,0 +1,3 @@
1
+ <%= f.cms_text_field :name, :default_value => "Search Box" %>
2
+ <%= f.cms_text_field :search_engine_name, :default_value => "Google Mini Search Engine", :instructions => "Enter the name of the Google Mini Search Portlet which this form will submit queries to." %>
3
+ <%= f.cms_text_area :template, :default_value => @block.class.default_template %>
@@ -0,0 +1,4 @@
1
+ <% form_tag @search_engine.path, :method=>'GET' do %>
2
+ <%= text_field_tag 'query' %>
3
+ <%= submit_tag 'Go' %>
4
+ <% end %>
@@ -0,0 +1 @@
1
+ require 'bcms_google_mini_search/routes'
@@ -0,0 +1,7 @@
1
+ module Cms::Routes
2
+ def routes_for_bcms_google_mini_search
3
+ namespace(:cms) do |cms|
4
+ #cms.content_blocks :google_mini_searches
5
+ end
6
+ end
7
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ gem_root = File.expand_path(File.join(File.dirname(__FILE__), ".."))
2
+ Cms.add_to_rails_paths gem_root
3
+ Cms.add_generator_paths gem_root, "db/migrate/[0-9]*_*.rb"
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bcms_google_mini_search
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - BrowserMedia
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-24 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: github@browsermedia.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - app/controllers/application_controller.rb
26
+ - app/helpers/application_helper.rb
27
+ - app/portlets/google_mini_search_engine_portlet.rb
28
+ - app/portlets/search_box_portlet.rb
29
+ - app/models/search_result.rb
30
+ - app/views/portlets/search_box/render.html.erb
31
+ - app/views/portlets/search_box/_form.html.erb
32
+ - app/views/portlets/google_mini_search_engine/render.html.erb
33
+ - app/views/portlets/google_mini_search_engine/_form.html.erb
34
+ - lib/bcms_google_mini_search.rb
35
+ - lib/bcms_google_mini_search/routes.rb
36
+ - rails/init.rb
37
+ - README.markdown
38
+ has_rdoc: true
39
+ homepage: http://www.browsercms.org
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project: bcms_google_mini_search
62
+ rubygems_version: 1.3.5
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: A Google Mini Search Module for BrowserCMS
66
+ test_files: []
67
+