Skip to content

Instantly share code, notes, and snippets.

@regedarek
Created December 13, 2012 23:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save regedarek/6738554e438c741fba45 to your computer and use it in GitHub Desktop.
Save regedarek/6738554e438c741fba45 to your computer and use it in GitHub Desktop.
class SearchController < ApplicationController
MAX_RESULTS = 5
before_filter :require_user
def new
search_term = params[:term].strip.gsub(/\\/,'')
app = App.find_by_name(params[:app_id])
conditions = {:app_id => (app.nil? ? current_user.subscriptions.map{|s| s.app_id}.join(' OR ') : app.id)}
logger.debug("Term is #{search_term} app is #{app.nil? ? 'nil' : app.id}")
quot_count = search_term.count("\"")
if quot_count % 2 == 1
search_term = search_term.reverse.sub("\"", "").reverse
quot_count = quot_count - 1
end
search_term = "#{search_term}*" if quot_count == 0 and search_term.length > 0
results = []
matched_qs = []
search_regex = search_term.gsub(/\*|\"|\'/, "").split(" ").map { |s| "\\b#{s}" }.join('|')
['content', 'answers', 'comments'].each do |t|
break if results.length >= MAX_RESULTS
Question.search_tank('', :conditions => conditions.merge(t => "#{search_term}"), :page => 1, :per_page => 5).each do |q|
next if matched_qs.include? q.id
matched_qs << q.id
r = {:title => q.content, :value => app_question_url(q.app, q.id)}
if t == 'content'
r[:label] = highlight_matched(search_regex, q.content)
r[:label] << "<span class='search-type'>Question</span>"
else
r[:label] = q.content
end
if t == 'answers'
r[:label] = "<span class='search-type snippet'>Answer</span>" + [r[:label], get_snippet(search_regex, q.answers)].compact.join('<br />')
end
if t == 'comments'
r[:label] = "<span class='search-type snippet'>Comment</span>" + [r[:type], r[:label], get_snippet(search_regex, q.answers.map(&:comments).flatten)].compact.join('<br />')
end
results << r
break if results.length >= MAX_RESULTS
end
end
render :json => results.to_json
end
protected
HIGHLIGHTER = '<span class="bold">\1</span>'
def highlight_matched(regex, text)
return text if (text.blank? || regex.blank?)
text.gsub(/(#{regex})/i, HIGHLIGHTER)
end
def get_snippet(regex, targits)
return nil if (targits.blank? || regex.blank?)
snippet = nil
targits.each do |t|
text = t.content.gsub(/<\/?[^>]*>/, "")
if i = text.index(/(#{regex})/i)
if i < 23
low = 0
high = [text.length, 46].min
elsif text.length - i < 23
low = [0, text.length - 46].max
high = text.length
else
low = i - 23
high = i + 23
end
snippet = "<span class='search-sublabel'>#{'...' unless low == 0}#{highlight_matched(regex, text[low...high])}#{'...' unless high == text.length}</span>"
break
end
end
snippet
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment