Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add suggestions to search results when nothing is found according to …

…user's query.
  • Loading branch information...
commit fba2f5462f1a90da089d7039b105782f5b48668f 1 parent bfdf210
@zuhao authored
View
1  Gemfile
@@ -35,6 +35,7 @@ gem 'gems'
gem 'recaptcha', :require => 'recaptcha/rails'
gem 'pkgwat'
gem 'ruby-bugzilla'
+gem 'text'
group :test, :development do
gem 'rspec-rails'
View
2  Gemfile.lock
@@ -189,6 +189,7 @@ GEM
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.7)
+ text (1.2.1)
therubyracer (0.10.2)
libv8 (~> 3.3.10)
thor (0.14.6)
@@ -237,6 +238,7 @@ DEPENDENCIES
ruby_parser
sass-rails (~> 3.2.3)
sqlite3
+ text
therubyracer (~> 0.10.2)
thor (= 0.14.6)
uglifier (>= 1.0.3)
View
6 TODO.txt
@@ -10,13 +10,13 @@
- [ ] Allow one to set update options interactively
- [ ] Allow one to pause/continue update
-** TODO Add decent robots.txt
+** TODO Add decent robots.txt
** TODO Fix "most wanted gems" (or erase)
-** TODO Make a nice error message appear when a user types a wrong URL
+** DONE Make a nice error message appear when a user types a wrong URL
-> Example: http://www.isitfedoraruby.com/fedorarpms/non-existent-rpm
-- [ ] It would be totally awesome to have a "did you mean...?" sign
+- [x] It would be totally awesome to have a "did you mean...?" sign
** TODO furthur improve import mechanism
- Instead of scraping websites, we should use the APIs for git, bugzilla,
View
19 app/controllers/searches_controller.rb
@@ -1,20 +1,35 @@
+require 'text'
+
class SearchesController < ApplicationController
def index
@page_title = 'Search'
searchphrase = params[:id]
@results = RubyGem.where('name LIKE ?', "%#{searchphrase}%").paginate(:page => params[:page], :per_page => 50, :group => "name", :order => "length(name) asc")
+ @suggests = []
+ if @results == []
+ all_gems = RubyGem.select('name').map{|x| x.name}
+ dist_score = Hash[all_gems.map{|x| [x, Text::Levenshtein.distance(x, searchphrase)]}]
+ dist_score = dist_score.sort_by{|x,d| d}.collect{|x,d| x}
+ sim_score = Hash[all_gems.map{|x| [x, Text::WhiteSimilarity.similarity(x, searchphrase)]}]
+ sim_score = sim_score.sort_by{|x,s| s}.reverse.collect{|x,s| x}
+ # suggestions are intersection of max similarity and min Levenshtein distance
+ # 50 is arbitrary, usually it is more than enough to give a good result.
+ @suggests = sim_score[0..50] & dist_score[0..50]
+ # give maximum 5 suggestions
+ @suggests = @suggests[0..4].map{|x| RubyGem.find_by_name(x)}
+ end
end
def suggest_gems (result = [])
@gems = RubyGem.where("name like ?", "%#{params[:q]}%").limit(10)
@gems.each { |g|
result << {:name => g.name}
- }
+ }
respond_to do |format|
format.json { render :json => result.to_json }
end
- end
+ end
def redirect
if params[:search]
View
24 app/views/searches/index.html.haml
@@ -1,3 +1,4 @@
+
%h1 Search Results
- if @results != []
@@ -23,4 +24,25 @@
%div.pagination
= will_paginate @results
- else
- %h2 Sorry, there were no results when searching for the Ruby Gem "#{params[:id]}"
+ %h2 Sorry, there were no results when searching for the Ruby Gem "#{params[:id]}"
+ %h2 However, did you mean...
+ - if @suggests != []
+ %table.table.table-striped.table-condensed
+ %thead
+ %tr
+ %th Gem Name
+ %th Gem Version
+ %th Rpm Name
+ %th Rpm Version (Rawhide)
+
+ %tbody
+ - @suggests.each do |gem|
+ %tr
+ %td= link_to gem.name, rubygem_path(gem.name)
+ %td= gem.version
+ - if gem.fedora_rpm != nil
+ %td= link_to gem.fedora_rpm.name, fedorarpm_path(gem.fedora_rpm.name)
+ %td= gem.fedora_rpm.version_for('rawhide')
+ -else
+ %td
+ %td
Please sign in to comment.
Something went wrong with that request. Please try again.