orbit-4-2/app/controllers/site_search_controller.rb

92 lines
3.1 KiB
Ruby
Raw Normal View History

2014-03-18 22:20:42 +00:00
class SiteSearchController < ApplicationController
def search
startTime = Time.now
if params[:keywords].present?
modules = [
{:key=>"announcement", :model=>"Bulletin", :fields=>["title","subtitle","text"], :url=>"/panel/announcement/front_end/bulletin/"}
]
key_string = params[:keywords]
keywords = key_string.split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/)
regex = Regexp.union(keywords.map{|word| Regexp.new(".*"+word+".*", "i")})
result = []
# Search Pages
Item.where(:app_frontend_url=>"page_contexts", :is_published=>true).each do |page|
title = page.title
2014-03-19 06:05:54 +00:00
context = PageContext.where(:page_id=>page.id).first.context rescue nil
next if title.nil? and context.nil?
context = context.gsub(/<\/?[^>]*>/, "").gsub(/&nbsp;/i," ") rescue ""
title_matches = title.match(regex)
context_matches = context.match(regex)
if title_matches or context_matches
2014-03-18 22:20:42 +00:00
tmp = {}
tmp[:id] = page.id
tmp[:module] = "page"
tmp[:url] = "/"+page.path
2014-03-19 06:05:54 +00:00
tmp[:title] = title
tmp[:content] = context
2014-03-18 22:20:42 +00:00
result.push(tmp)
end
end
# Search Modules
modules.each do |mod|
query = mod[:fields].map{|f| {f.to_sym => regex} }
res = Kernel.const_get(mod[:model]).any_of(query)
2014-03-19 06:05:54 +00:00
res.each do |r|
2014-03-18 22:20:42 +00:00
tmp = {}
tmp[:id] = r.id
tmp[:module] = mod[:key]
tmp[:url] = mod[:url]+r.id.to_s
tmp[:content] = ""
tmp[:matches] = 0
mod[:fields].each do |f|
2014-03-19 06:05:54 +00:00
value = eval("r.#{f}").gsub(/<\/?[^>]*>/, "").gsub(/&nbsp;/i,"")
2014-03-18 22:20:42 +00:00
if f=="title" or f=="name"
tmp[:title] = value
else
tmp[:content] << value
end
end
2014-03-19 06:05:54 +00:00
result.push(tmp)
2014-03-18 22:20:42 +00:00
end
end
end
2014-03-19 06:05:54 +00:00
result.each do |res|
res[:matches] = 0
2014-03-18 22:20:42 +00:00
2014-03-19 06:05:54 +00:00
res[:matches] += res[:title].match(/(#{key_string})/i) ? 100 : 0 rescue 0
res[:matches] += res[:content].match(/(#{key_string})/i) ? 100 : 0 rescue 0
keywords.each do |k|
res[:matches] += res[:title].scan(/(#{k})/i).size + res[:content].scan(/(#{k})/i).size
res[:title].gsub!(/(#{k})/i, '<b>\1</b>') rescue ""
res[:content].gsub!(/(#{k})/i, '<b>\1</b>') rescue ""
end
result.delete(res) if res[:matches]==0
next if res[:matches]==0
index = res[:content].index '<b>'
2014-03-18 22:20:42 +00:00
unless index.nil?
index = index>50 ? index-50 : 0
deadline = 150
2014-03-19 06:05:54 +00:00
res[:content] = res[:content][index, deadline]
2014-03-18 22:20:42 +00:00
else
2014-03-19 06:05:54 +00:00
res[:content] = res[:content][0, 150]
2014-03-18 22:20:42 +00:00
end
end
2014-03-19 06:05:54 +00:00
result = result.sort_by { |k| k[:matches] }.reverse rescue []
render :json => { "results" => result, "time"=> ((Time.now-startTime)*1000).to_i , "keywords"=>keywords}
2014-03-18 22:20:42 +00:00
end
end