Commit 9360007aeab70797ad039eaa2ff677e81b541fb2

Authored by Rodrigo Souto
1 parent e1b600b8

Solr on the way...

app/controllers/my_profile/cms_controller.rb
@@ -271,6 +271,7 @@ class CmsController < MyProfileController @@ -271,6 +271,7 @@ class CmsController < MyProfileController
271 def search 271 def search
272 query = params[:q] 272 query = params[:q]
273 results = profile.files.published.find_by_contents(query)[:results] 273 results = profile.files.published.find_by_contents(query)[:results]
  274 + # results = @plugins.first(:find_by_contents, profile.files.published, query)[:results]
274 render :text => article_list_to_json(results), :content_type => 'application/json' 275 render :text => article_list_to_json(results), :content_type => 'application/json'
275 end 276 end
276 277
app/controllers/public/profile_search_controller.rb
@@ -11,7 +11,7 @@ class ProfileSearchController < PublicController @@ -11,7 +11,7 @@ class ProfileSearchController < PublicController
11 if params[:where] == 'environment' 11 if params[:where] == 'environment'
12 redirect_to :controller => 'search', :query => @q 12 redirect_to :controller => 'search', :query => @q
13 else 13 else
14 - @results = profile.articles.published.find_by_contents(@q, {:per_page => 10, :page => params[:page]})[:results] 14 + @results = @plugins.first(:find_by_contents, profile.articles.published, @q, {:per_page => 10, :page => params[:page]})[:results]
15 end 15 end
16 end 16 end
17 end 17 end
app/controllers/public/search_controller.rb
@@ -19,7 +19,7 @@ class SearchController < PublicController @@ -19,7 +19,7 @@ class SearchController < PublicController
19 no_design_blocks 19 no_design_blocks
20 20
21 def index 21 def index
22 - @results = {} 22 + @searches = {}
23 @order = [] 23 @order = []
24 @names = {} 24 @names = {}
25 @results_only = true 25 @results_only = true
@@ -33,12 +33,12 @@ class SearchController < PublicController @@ -33,12 +33,12 @@ class SearchController < PublicController
33 end 33 end
34 @asset = nil 34 @asset = nil
35 35
36 - render :action => @results.keys.first if @results.keys.size == 1 36 + render :action => @searches.keys.first if @searches.keys.size == 1
37 end 37 end
38 38
39 # view the summary of one category 39 # view the summary of one category
40 def category_index 40 def category_index
41 - @results = {} 41 + @searches = {}
42 @order = [] 42 @order = []
43 @names = {} 43 @names = {}
44 limit = MULTIPLE_SEARCH_LIMIT 44 limit = MULTIPLE_SEARCH_LIMIT
@@ -51,8 +51,8 @@ class SearchController < PublicController @@ -51,8 +51,8 @@ class SearchController < PublicController
51 [ :articles, _('Contents'), :recent_articles ] 51 [ :articles, _('Contents'), :recent_articles ]
52 ].each do |asset, name, filter| 52 ].each do |asset, name, filter|
53 @order << asset 53 @order << asset
54 - @results[asset] = @category.send(filter, limit)  
55 - raise "No total_entries for: #{asset}" unless @results[asset].respond_to?(:total_entries) 54 + @searches[asset] = @category.send(filter, limit)
  55 + raise "No total_entries for: #{asset}" unless @searches[asset][:results].respond_to?(:total_entries)
56 @names[asset] = name 56 @names[asset] = name
57 end 57 end
58 end 58 end
@@ -61,7 +61,8 @@ class SearchController &lt; PublicController @@ -61,7 +61,8 @@ class SearchController &lt; PublicController
61 if @search_engine && !@empty_query 61 if @search_engine && !@empty_query
62 full_text_search 62 full_text_search
63 else 63 else
64 - @results[@asset] = @environment.articles.public.send(@filter).paginate(paginate_options) 64 + @searches[@asset] = {}
  65 + @searches[@asset][:results] = @environment.articles.public.send(@filter).paginate(paginate_options)
65 end 66 end
66 end 67 end
67 68
@@ -73,7 +74,8 @@ class SearchController &lt; PublicController @@ -73,7 +74,8 @@ class SearchController &lt; PublicController
73 if @search_engine && !@empty_query 74 if @search_engine && !@empty_query
74 full_text_search 75 full_text_search
75 else 76 else
76 - @results[@asset] = visible_profiles(Person).send(@filter).paginate(paginate_options) 77 + @searches[@asset] = {}
  78 + @searches[@asset][:results] = visible_profiles(Person).send(@filter).paginate(paginate_options)
77 end 79 end
78 end 80 end
79 81
@@ -81,7 +83,8 @@ class SearchController &lt; PublicController @@ -81,7 +83,8 @@ class SearchController &lt; PublicController
81 if @search_engine 83 if @search_engine
82 full_text_search 84 full_text_search
83 else 85 else
84 - @results[@asset] = @environment.products.send(@filter).paginate(paginate_options) 86 + @searches[@asset] = {}
  87 + @searches[@asset][:results] = @environment.products.send(@filter).paginate(paginate_options)
85 end 88 end
86 end 89 end
87 90
@@ -90,7 +93,8 @@ class SearchController &lt; PublicController @@ -90,7 +93,8 @@ class SearchController &lt; PublicController
90 full_text_search 93 full_text_search
91 else 94 else
92 @filter_title = _('Enterprises from network') 95 @filter_title = _('Enterprises from network')
93 - @results[@asset] = visible_profiles(Enterprise, [{:products => :product_category}]).paginate(paginate_options) 96 + @searches[@asset] = {}
  97 + @searches[@asset][:results] = visible_profiles(Enterprise, [{:products => :product_category}]).paginate(paginate_options)
94 end 98 end
95 end 99 end
96 100
@@ -98,7 +102,8 @@ class SearchController &lt; PublicController @@ -98,7 +102,8 @@ class SearchController &lt; PublicController
98 if @search_engine && !@empty_query 102 if @search_engine && !@empty_query
99 full_text_search 103 full_text_search
100 else 104 else
101 - @results[@asset] = visible_profiles(Community).send(@filter).paginate(paginate_options) 105 + @searches[@asset] = {}
  106 + @searches[@asset][:results] = visible_profiles(Community).send(@filter).paginate(paginate_options)
102 end 107 end
103 end 108 end
104 109
@@ -121,10 +126,11 @@ class SearchController &lt; PublicController @@ -121,10 +126,11 @@ class SearchController &lt; PublicController
121 if @search_engine && !@empty_query 126 if @search_engine && !@empty_query
122 full_text_search 127 full_text_search
123 else 128 else
124 - @results[@asset] = date_range ? environment.events.by_range(date_range) : environment.events 129 + @searches[@asset] = {}
  130 + @searches[@asset][:results] = date_range ? environment.events.by_range(date_range) : environment.events
125 end 131 end
126 132
127 - events = @results[@asset] 133 + events = @searches[@asset][:results]
128 @calendar = populate_calendar(date, events) 134 @calendar = populate_calendar(date, events)
129 @previous_calendar = populate_calendar(date - 1.month, events) 135 @previous_calendar = populate_calendar(date - 1.month, events)
130 @next_calendar = populate_calendar(date + 1.month, events) 136 @next_calendar = populate_calendar(date + 1.month, events)
@@ -147,7 +153,7 @@ class SearchController &lt; PublicController @@ -147,7 +153,7 @@ class SearchController &lt; PublicController
147 @tag = params[:tag] 153 @tag = params[:tag]
148 @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}" 154 @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}"
149 if is_cache_expired?(@tag_cache_key) 155 if is_cache_expired?(@tag_cache_key)
150 - @results[@asset] = environment.articles.find_tagged_with(@tag).paginate(paginate_options) 156 + @searches[@asset] = environment.articles.find_tagged_with(@tag).paginate(paginate_options)
151 end 157 end
152 end 158 end
153 159
@@ -164,7 +170,7 @@ class SearchController &lt; PublicController @@ -164,7 +170,7 @@ class SearchController &lt; PublicController
164 @asset = (params[:asset] || params[:action]).to_sym 170 @asset = (params[:asset] || params[:action]).to_sym
165 @order ||= [@asset] 171 @order ||= [@asset]
166 params[:display] ||= 'list' 172 params[:display] ||= 'list'
167 - @results ||= {} 173 + @searches ||= {}
168 @filter = filter 174 @filter = filter
169 @filter_title = filter_description(@asset, @filter) 175 @filter_title = filter_description(@asset, @filter)
170 176
@@ -254,8 +260,8 @@ class SearchController &lt; PublicController @@ -254,8 +260,8 @@ class SearchController &lt; PublicController
254 { :per_page => limit, :page => page } 260 { :per_page => limit, :page => page }
255 end 261 end
256 262
257 - def full_text_search(options = {})  
258 - @results[@asset] = @plugins.first(:full_text_search, @asset, @query, @category, paginate_options(params[:page])) 263 + def full_text_search
  264 + @searches[@asset] = @plugins.first(:find_by_contents, asset_class(@asset), @query, paginate_options(params[:page]), {:category => @category})
259 end 265 end
260 266
261 private 267 private
app/helpers/search_helper.rb
@@ -18,13 +18,17 @@ module SearchHelper @@ -18,13 +18,17 @@ module SearchHelper
18 include EventsHelper 18 include EventsHelper
19 19
20 def multiple_search? 20 def multiple_search?
21 - ['index', 'category_index'].include?(params[:action]) or @results.size > 1 21 + ['index', 'category_index'].include?(params[:action]) or @searches.size > 1
22 end 22 end
23 23
24 def map_search? 24 def map_search?
25 !multiple_search? and params[:display] == 'map' 25 !multiple_search? and params[:display] == 'map'
26 end 26 end
27 27
  28 + def asset_class(asset)
  29 + asset.to_s.singularize.camelize.constantize
  30 + end
  31 +
28 def search_page_title(title, category = nil) 32 def search_page_title(title, category = nil)
29 title = "<h1>" + title 33 title = "<h1>" + title
30 title += ' - <small>' + category.name + '</small>' if category 34 title += ' - <small>' + category.name + '</small>' if category
app/models/region.rb
@@ -4,10 +4,12 @@ class Region &lt; Category @@ -4,10 +4,12 @@ class Region &lt; Category
4 4
5 require_dependency 'enterprise' # enterprises can also be validators 5 require_dependency 'enterprise' # enterprises can also be validators
6 6
  7 + include Noosfero::Plugin::HotSpot
  8 +
7 # searches for organizations that could become validators for this region. 9 # searches for organizations that could become validators for this region.
8 # <tt>search</tt> is passed as is to find_by_contents on Organization. 10 # <tt>search</tt> is passed as is to find_by_contents on Organization.
9 def search_possible_validators(search) 11 def search_possible_validators(search)
10 - Organization.find_by_contents(search)[:results].docs.reject {|item| self.validator_ids.include?(item.id) } 12 + plugins.find_by_contents(Organization, search)[:results].docs.reject {|item| self.validator_ids.include?(item.id) }
11 end 13 end
12 14
13 def has_validator? 15 def has_validator?
app/views/search/_display_results.rhtml
1 <div id="search-results" class="<%= !multiple_search? ? 'only-one-result-box' : 'multiple-results-boxes' %>"> 1 <div id="search-results" class="<%= !multiple_search? ? 'only-one-result-box' : 'multiple-results-boxes' %>">
2 <% @order.each do |name| %> 2 <% @order.each do |name| %>
3 - <% results = @results[name] %> 3 + <% search = @searches[name] %>
4 4
5 - <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if results.blank? %>">  
6 - <% if !results.blank? %> 5 + <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if search[:results].blank? %>">
  6 + <% if !search[:results].blank? %>
7 <% partial = partial_for_class(name.to_s.singularize.camelize.constantize) %> 7 <% partial = partial_for_class(name.to_s.singularize.camelize.constantize) %>
8 8
9 <% if multiple_search? %> 9 <% if multiple_search? %>
10 <h3><%= @names[name] %></h3> 10 <h3><%= @names[name] %></h3>
11 - <% if results.total_entries > SearchController::MULTIPLE_SEARCH_LIMIT %>  
12 - <%= link_to(_('see all (%d)') % results.total_entries, params.merge(:action => name), :class => 'see-more' ) %> 11 + <% if search[:results].total_entries > SearchController::MULTIPLE_SEARCH_LIMIT %>
  12 + <%= link_to(_('see all (%d)') % search[:results].total_entries, params.merge(:action => name), :class => 'see-more' ) %>
13 <% end %> 13 <% end %>
14 <% end %> 14 <% end %>
15 15
16 <div class="search-results-innerbox search-results-type-<%= partial %> <%= 'common-profile-list-block' if partial == 'profile' %>"> 16 <div class="search-results-innerbox search-results-type-<%= partial %> <%= 'common-profile-list-block' if partial == 'profile' %>">
17 <ul> 17 <ul>
18 - <% results.each do |hit| %> 18 + <% search[:results].each do |hit| %>
19 <%= render :partial => partial_for_class(hit.class), :object => hit %> 19 <%= render :partial => partial_for_class(hit.class), :object => hit %>
20 <% end %> 20 <% end %>
21 </ul> 21 </ul>
app/views/search/_google_maps.rhtml
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 <script type='text/javascript'> 13 <script type='text/javascript'>
14 mapLoad(<%= GoogleMaps.initial_zoom.to_json %>); 14 mapLoad(<%= GoogleMaps.initial_zoom.to_json %>);
15 15
16 - <% @results.each do |name,results| %> 16 + <% @searches.each do |name,results| %>
17 <% results.each do |item| %> 17 <% results.each do |item| %>
18 <% if item.lat && item.lng %> 18 <% if item.lat && item.lng %>
19 mapPutMarker(<%= item.lat.to_json %>, <%= item.lng.to_json %>, <%= item.name.to_json %>, '<%= icon %>', 19 mapPutMarker(<%= item.lat.to_json %>, <%= item.lng.to_json %>, <%= item.name.to_json %>, '<%= icon %>',
app/views/search/_results_header.rhtml
1 -<div class="search-results-header <%= "search-no-results" if @results[@asset].nil? or @results[@asset].length == 0 %>"> 1 +<div class="search-results-header <%= "search-no-results" if @searches[@asset].nil? or @searches[@asset].length == 0 %>">
2 <div id='search-filter-title'><%= @filter_title if @filter_title %></div> 2 <div id='search-filter-title'><%= @filter_title if @filter_title %></div>
3 <%= display_filter(@asset, params[:display]) if map_capable?(@asset) %> 3 <%= display_filter(@asset, params[:display]) if map_capable?(@asset) %>
4 <div style="clear: both"></div> 4 <div style="clear: both"></div>
app/views/search/search_page.html.erb
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 4
5 <%= display_results(@asset) %> 5 <%= display_results(@asset) %>
6 <% if params[:display] != 'map' %> 6 <% if params[:display] != 'map' %>
7 - <%= pagination_links @results[@asset] %> 7 + <%= pagination_links @searches[@asset] %>
8 <% end %> 8 <% end %>
9 9
10 <div style="clear: both"></div> 10 <div style="clear: both"></div>
lib/noosfero/plugin.rb
@@ -357,9 +357,12 @@ class Noosfero::Plugin @@ -357,9 +357,12 @@ class Noosfero::Plugin
357 false 357 false
358 end 358 end
359 359
360 - # -> Realizes a full text search  
361 - # returns = whatever the plugin needs to render the view  
362 - def full_text_search(asset, query, category, paginate_options) 360 + # -> Finds objects by their contents
  361 + # returns = {:results => [a, b, c, ...], ...}
  362 + # P.S.: The plugin might add other informations on the return hash for its
  363 + # own use in specific views
  364 + def find_by_contents(klass, query, paginate_options={}, options={})
  365 + {:results => []}
363 end 366 end
364 367
365 def method_missing(method, *args, &block) 368 def method_missing(method, *args, &block)
lib/noosfero/plugin/manager.rb
@@ -39,7 +39,7 @@ class Noosfero::Plugin::Manager @@ -39,7 +39,7 @@ class Noosfero::Plugin::Manager
39 result = plugin.send(event, *args) 39 result = plugin.send(event, *args)
40 break if result.present? 40 break if result.present?
41 end 41 end
42 - result 42 + result || Noosfero::Plugin.new.send(event, *args)
43 end 43 end
44 44
45 def first_plugin(event, *args) 45 def first_plugin(event, *args)
lib/set_profile_region_from_city_state.rb
@@ -11,6 +11,7 @@ module SetProfileRegionFromCityState @@ -11,6 +11,7 @@ module SetProfileRegionFromCityState
11 end 11 end
12 12
13 module InstanceMethods 13 module InstanceMethods
  14 + include Noosfero::Plugin::HotSpot
14 15
15 def city_with_region=(value) 16 def city_with_region=(value)
16 self.city_without_region = value 17 self.city_without_region = value
@@ -24,9 +25,9 @@ module SetProfileRegionFromCityState @@ -24,9 +25,9 @@ module SetProfileRegionFromCityState
24 25
25 def region_from_city_and_state 26 def region_from_city_and_state
26 if @change_region 27 if @change_region
27 - s = State.find_by_contents(self.state)[:results].first 28 + s = plugins.first(:find_by_contents, State, self.state)[:results].first
28 if s 29 if s
29 - c = City.find_by_contents(self.city, {}, :filter_queries => ["parent_id:#{s.id}"])[:results].first 30 + c = plugins.first(:find_by_contents, City, self.city, {}, {:filter_queries => ["parent_id:#{s.id}"]})[:results].first
30 self.region = c 31 self.region = c
31 else 32 else
32 self.region = nil 33 self.region = nil
plugins/solr/lib/solr_plugin.rb
@@ -16,16 +16,12 @@ class SolrPlugin &lt; Noosfero::Plugin @@ -16,16 +16,12 @@ class SolrPlugin &lt; Noosfero::Plugin
16 true 16 true
17 end 17 end
18 18
19 - def full_text_search(asset, query, category, paginate_options)  
20 - asset_class = asset_class(asset)  
21 - solr_options = solr_options(asset, category)  
22 - solr_options.merge!(products_options(context.send(:user))) if asset == :products && empty_query?(query, category)  
23 - search = asset_class.find_by_contents(query, paginate_options, solr_options)  
24 - if context.params[:action] == 'index'  
25 - return search[:results]  
26 - else  
27 - return search  
28 - end 19 + def find_by_contents(klass, query, paginate_options={}, options={})
  20 + category = options.delete(:category)
  21 + solr_options = solr_options(class_asset(klass), category)
  22 + user = context.respond_to?(:user) ? context.send(:user) : nil
  23 + solr_options.merge!(products_options(user)) if klass == Product && empty_query?(query, category)
  24 + klass.find_by_contents(query, paginate_options, solr_options.merge(options))
29 end 25 end
30 26
31 end 27 end
plugins/solr/lib/solr_plugin/results_helper.rb
@@ -5,12 +5,8 @@ class SolrPlugin &lt; Noosfero::Plugin @@ -5,12 +5,8 @@ class SolrPlugin &lt; Noosfero::Plugin
5 end 5 end
6 6
7 def set_results_variables 7 def set_results_variables
8 - if @results[@asset].kind_of?(Hash)  
9 - ret = @results[@asset]  
10 - @results[@asset] = ret[:results]  
11 - @facets = ret[:facets]  
12 - @all_facets = ret[:all_facets]  
13 - end 8 + @facets = @searches[@asset][:facets]
  9 + @all_facets = @searches[@asset][:all_facets]
14 end 10 end
15 11
16 def order_by(asset) 12 def order_by(asset)
plugins/solr/lib/solr_plugin/search_helper.rb
@@ -34,6 +34,10 @@ class SolrPlugin &lt; Noosfero::Plugin @@ -34,6 +34,10 @@ class SolrPlugin &lt; Noosfero::Plugin
34 def asset_class(asset) 34 def asset_class(asset)
35 asset.to_s.singularize.camelize.constantize 35 asset.to_s.singularize.camelize.constantize
36 end 36 end
  37 +
  38 + def class_asset(klass)
  39 + klass.name.underscore.pluralize.to_sym
  40 + end
37 41
38 def asset_table(asset) 42 def asset_table(asset)
39 asset_class(asset).table_name 43 asset_class(asset).table_name
plugins/solr/views/search/_results.html.erb
@@ -3,5 +3,5 @@ @@ -3,5 +3,5 @@
3 3
4 <%= display_results(@asset) %> 4 <%= display_results(@asset) %>
5 <% if params[:display] != 'map' %> 5 <% if params[:display] != 'map' %>
6 - <%= pagination_links @results[@asset] %> 6 + <%= pagination_links @searches[@asset][:results] %>
7 <% end %> 7 <% end %>
plugins/solr/views/search/_results_header.html.erb
1 -<div class="search-results-header <%= "search-no-results" if @results[@asset].nil? or @results[@asset].length == 0 %>"> 1 +<div class="search-results-header <%= "search-no-results" if @searches[@asset][:results].nil? or @searches[@asset][:results].length == 0 %>">
2 <% if !@empty_query %> 2 <% if !@empty_query %>
3 <div class="search-results-header-information"> 3 <div class="search-results-header-information">
4 - <% if @results[@asset].total_entries > 0 %>  
5 - <%= label_total_found(@asset, @results[@asset].total_entries) %> 4 + <% if @searches[@asset][:results].total_entries > 0 %>
  5 + <%= label_total_found(@asset, @searches[@asset][:results].total_entries) %>
6 <% if params[:display] != 'map' %> 6 <% if params[:display] != 'map' %>
7 - <span class="current-page"><%= _("Showing page %s of %s") % [@results[@asset].current_page, @results[@asset].total_pages] %></span> 7 + <span class="current-page"><%= _("Showing page %s of %s") % [@searches[@asset][:results].current_page, @searches[@asset][:results].total_pages] %></span>
8 <% end %> 8 <% end %>
9 <% end %> 9 <% end %>
10 </div> 10 </div>
test/unit/plugin_manager_test.rb
@@ -140,5 +140,15 @@ class PluginManagerTest &lt; ActiveSupport::TestCase @@ -140,5 +140,15 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
140 assert_equal Plugin2, manager.first_plugin(:random_event) 140 assert_equal Plugin2, manager.first_plugin(:random_event)
141 end 141 end
142 142
  143 + should 'use default value defined on the base plugin class when no plugin enabled for the first method' do
  144 + class Noosfero::Plugin
  145 + def random_event
  146 + 1
  147 + end
  148 + end
  149 +
  150 + assert_equal 1, manager.first(:random_event)
  151 + end
  152 +
143 end 153 end
144 154