Commit e7b5205f7980aa300dd7daf7fc8bd27d9aef9738
Exists in
master
and in
29 other branches
Merge branch 'pluginize-solr' into merge-solr
Showing
662 changed files
with
125601 additions
and
108485 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 662 files displayed.
INSTALL
@@ -33,7 +33,7 @@ You need to install some packages Noosfero depends on. On Debian GNU/Linux or | @@ -33,7 +33,7 @@ You need to install some packages Noosfero depends on. On Debian GNU/Linux or | ||
33 | Debian-based systems, all of these packages are available through the Debian | 33 | Debian-based systems, all of these packages are available through the Debian |
34 | archive. You can install them with the following command: | 34 | archive. You can install them with the following command: |
35 | 35 | ||
36 | - # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libwill-paginate-ruby iso-codes libfeedparser-ruby openjdk-6-jre libdaemons-ruby thin tango-icon-theme libhpricot-ruby | 36 | + # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libwill-paginate-ruby iso-codes libfeedparser-ruby libdaemons-ruby thin tango-icon-theme libhpricot-ruby |
37 | 37 | ||
38 | On other systems, they may or may not be available through your regular package | 38 | On other systems, they may or may not be available through your regular package |
39 | management system. Below are the links to their homepages. | 39 | management system. Below are the links to their homepages. |
@@ -43,7 +43,6 @@ management system. Below are the links to their homepages. | @@ -43,7 +43,6 @@ management system. Below are the links to their homepages. | ||
43 | * po4a: http://po4a.alioth.debian.org/ | 43 | * po4a: http://po4a.alioth.debian.org/ |
44 | * Ruby-sqlite3: http://rubyforge.org/projects/sqlite-ruby | 44 | * Ruby-sqlite3: http://rubyforge.org/projects/sqlite-ruby |
45 | * rcov: http://eigenclass.org/hiki/rcov | 45 | * rcov: http://eigenclass.org/hiki/rcov |
46 | -* Solr: http://lucene.apache.org/solr | ||
47 | * RMagick: http://rmagick.rubyforge.org/ | 46 | * RMagick: http://rmagick.rubyforge.org/ |
48 | * RedCloth: http://redcloth.org/ | 47 | * RedCloth: http://redcloth.org/ |
49 | * will_paginate: http://github.com/mislav/will_paginate/wikis | 48 | * will_paginate: http://github.com/mislav/will_paginate/wikis |
@@ -111,9 +110,6 @@ $ tar -zxvf noosfero-0.39.0.tar.gz | @@ -111,9 +110,6 @@ $ tar -zxvf noosfero-0.39.0.tar.gz | ||
111 | $ ln -s noosfero-0.39.0 current | 110 | $ ln -s noosfero-0.39.0 current |
112 | $ cd current | 111 | $ cd current |
113 | 112 | ||
114 | -Copy config/solr.yml.dist to config/solr.yml. You will | ||
115 | -probably not need to customize this configuration, but have a look at it. | ||
116 | - | ||
117 | Create the thin configuration file: | 113 | Create the thin configuration file: |
118 | 114 | ||
119 | $ thin -C config/thin.yml -e production config | 115 | $ thin -C config/thin.yml -e production config |
@@ -195,10 +191,6 @@ Compile the translations: | @@ -195,10 +191,6 @@ Compile the translations: | ||
195 | 191 | ||
196 | $ RAILS_ENV=production rake noosfero:translations:compile | 192 | $ RAILS_ENV=production rake noosfero:translations:compile |
197 | 193 | ||
198 | -Run Solr: | ||
199 | - | ||
200 | -$ rake solr:start | ||
201 | - | ||
202 | Now we must create some initial data. To create your default environment | 194 | Now we must create some initial data. To create your default environment |
203 | (the first one), run the command below: | 195 | (the first one), run the command below: |
204 | 196 |
Rakefile
@@ -7,6 +7,10 @@ require 'rake' | @@ -7,6 +7,10 @@ require 'rake' | ||
7 | require 'rake/testtask' | 7 | require 'rake/testtask' |
8 | require 'rake/rdoctask' | 8 | require 'rake/rdoctask' |
9 | 9 | ||
10 | -ACTS_AS_SEARCHABLE_ENABLED = false if Rake.application.top_level_tasks.detect{|t| t == 'db:data:minimal'} | ||
11 | - | 10 | +# rails tasks |
12 | require 'tasks/rails' | 11 | require 'tasks/rails' |
12 | + | ||
13 | +# plugins' tasks | ||
14 | +plugins_tasks = Dir.glob("config/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake").sort + | ||
15 | + Dir.glob("config/plugins/*/vendor/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake").sort | ||
16 | +plugins_tasks.each{ |ext| load ext } |
app/controllers/admin/region_validators_controller.rb
@@ -33,7 +33,7 @@ class RegionValidatorsController < AdminController | @@ -33,7 +33,7 @@ class RegionValidatorsController < AdminController | ||
33 | def load_region_and_search | 33 | def load_region_and_search |
34 | @region = environment.regions.find(params[:id]) | 34 | @region = environment.regions.find(params[:id]) |
35 | if params[:search] | 35 | if params[:search] |
36 | - @search = @region.search_possible_validators(params[:search]) | 36 | + @search = find_by_contents(:organizations, Organization, params[:search])[:results].reject {|item| @region.validator_ids.include?(item.id) } |
37 | end | 37 | end |
38 | end | 38 | end |
39 | 39 |
app/controllers/application_controller.rb
@@ -154,4 +154,18 @@ class ApplicationController < ActionController::Base | @@ -154,4 +154,18 @@ class ApplicationController < ActionController::Base | ||
154 | end | 154 | end |
155 | end | 155 | end |
156 | 156 | ||
157 | + def find_by_contents(asset, scope, query, paginate_options={:page => 1}, options={}) | ||
158 | + scope = scope.send(options[:filter]) if options[:filter] | ||
159 | + | ||
160 | + @plugins.first(:find_by_contents, asset, scope, query, paginate_options, options) || | ||
161 | + fallback_find_by_contents(asset, scope, query, paginate_options, options) | ||
162 | + end | ||
163 | + | ||
164 | + private | ||
165 | + | ||
166 | + def fallback_find_by_contents(asset, scope, query, paginate_options, options) | ||
167 | + return {:results => scope.paginate(paginate_options)} if query.blank? | ||
168 | + {:results => scope.like_search(query).paginate(paginate_options)} | ||
169 | + end | ||
170 | + | ||
157 | end | 171 | end |
app/controllers/my_profile/cms_controller.rb
@@ -270,7 +270,7 @@ class CmsController < MyProfileController | @@ -270,7 +270,7 @@ class CmsController < MyProfileController | ||
270 | 270 | ||
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 = find_by_contents(:uploaded_files, profile.files.published, query)[:results] |
274 | render :text => article_list_to_json(results), :content_type => 'application/json' | 274 | render :text => article_list_to_json(results), :content_type => 'application/json' |
275 | end | 275 | end |
276 | 276 |
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 = find_by_contents(:articles, 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
@@ -4,10 +4,11 @@ class SearchController < PublicController | @@ -4,10 +4,11 @@ class SearchController < PublicController | ||
4 | include SearchHelper | 4 | include SearchHelper |
5 | include ActionView::Helpers::NumberHelper | 5 | include ActionView::Helpers::NumberHelper |
6 | 6 | ||
7 | - before_filter :redirect_asset_param, :except => [:facets_browse, :assets] | 7 | + before_filter :redirect_asset_param, :except => :assets |
8 | before_filter :load_category | 8 | before_filter :load_category |
9 | before_filter :load_search_assets | 9 | before_filter :load_search_assets |
10 | before_filter :load_query | 10 | before_filter :load_query |
11 | + before_filter :load_filter | ||
11 | 12 | ||
12 | # Backwards compatibility with old URLs | 13 | # Backwards compatibility with old URLs |
13 | def redirect_asset_param | 14 | def redirect_asset_param |
@@ -17,25 +18,51 @@ class SearchController < PublicController | @@ -17,25 +18,51 @@ class SearchController < PublicController | ||
17 | 18 | ||
18 | no_design_blocks | 19 | no_design_blocks |
19 | 20 | ||
20 | - def facets_browse | ||
21 | - @asset = params[:asset] | ||
22 | - @asset_class = asset_class(@asset) | 21 | + def index |
22 | + @searches = {} | ||
23 | + @order = [] | ||
24 | + @names = {} | ||
25 | + @results_only = true | ||
23 | 26 | ||
24 | - @facets_only = true | ||
25 | - send(@asset) | 27 | + @enabled_searches.select { |key,description| @searching[key] }.each do |key, description| |
28 | + load_query | ||
29 | + @asset = key | ||
30 | + send(key) | ||
31 | + @order << key | ||
32 | + @names[key] = getterm(description) | ||
33 | + end | ||
34 | + @asset = nil | ||
26 | 35 | ||
27 | - @facet = @asset_class.map_facets_for(environment).find { |facet| facet[:id] == params[:facet_id] } | ||
28 | - raise 'Facet not found' if @facet.nil? | 36 | + if @searches.keys.size == 1 |
37 | + @asset = @searches.keys.first | ||
38 | + render :action => @asset | ||
39 | + end | ||
40 | + end | ||
29 | 41 | ||
30 | - render :layout => false | 42 | + # view the summary of one category |
43 | + def category_index | ||
44 | + @searches = {} | ||
45 | + @order = [] | ||
46 | + @names = {} | ||
47 | + limit = MULTIPLE_SEARCH_LIMIT | ||
48 | + [ | ||
49 | + [ :people, _('People'), :recent_people ], | ||
50 | + [ :enterprises, _('Enterprises'), :recent_enterprises ], | ||
51 | + [ :products, _('Products'), :recent_products ], | ||
52 | + [ :events, _('Upcoming events'), :upcoming_events ], | ||
53 | + [ :communities, _('Communities'), :recent_communities ], | ||
54 | + [ :articles, _('Contents'), :recent_articles ] | ||
55 | + ].each do |asset, name, filter| | ||
56 | + @order << asset | ||
57 | + @searches[asset]= {:results => @category.send(filter, limit)} | ||
58 | + raise "No total_entries for: #{asset}" unless @searches[asset][:results].respond_to?(:total_entries) | ||
59 | + @names[asset] = name | ||
60 | + end | ||
31 | end | 61 | end |
32 | 62 | ||
33 | def articles | 63 | def articles |
34 | - if !@empty_query | ||
35 | - full_text_search ['public:true'] | ||
36 | - else | ||
37 | - @results[@asset] = @environment.articles.public.send(@filter).paginate(paginate_options) | ||
38 | - end | 64 | + @scope = @environment.articles.public |
65 | + full_text_search | ||
39 | end | 66 | end |
40 | 67 | ||
41 | def contents | 68 | def contents |
@@ -43,49 +70,23 @@ class SearchController < PublicController | @@ -43,49 +70,23 @@ class SearchController < PublicController | ||
43 | end | 70 | end |
44 | 71 | ||
45 | def people | 72 | def people |
46 | - if !@empty_query | ||
47 | - full_text_search ['public:true'] | ||
48 | - else | ||
49 | - @results[@asset] = visible_profiles(Person).send(@filter).paginate(paginate_options) | ||
50 | - end | 73 | + @scope = visible_profiles(Person) |
74 | + full_text_search | ||
51 | end | 75 | end |
52 | 76 | ||
53 | def products | 77 | def products |
54 | - public_filters = ['public:true', 'enabled:true'] | ||
55 | - if !@empty_query | ||
56 | - full_text_search public_filters | ||
57 | - else | ||
58 | - @one_page = true | ||
59 | - @geosearch = logged_in? && current_user.person.lat && current_user.person.lng | ||
60 | - | ||
61 | - extra_limit = LIST_SEARCH_LIMIT*5 | ||
62 | - sql_options = {:limit => LIST_SEARCH_LIMIT, :order => 'random()'} | ||
63 | - if @geosearch | ||
64 | - full_text_search public_filters, :sql_options => sql_options, :extra_limit => extra_limit, | ||
65 | - :alternate_query => "{!boost b=recip(geodist(),#{"%e" % (1.to_f/DistBoost)},1,1)}", | ||
66 | - :radius => DistFilt, :latitude => current_user.person.lat, :longitude => current_user.person.lng | ||
67 | - else | ||
68 | - full_text_search public_filters, :sql_options => sql_options, :extra_limit => extra_limit, | ||
69 | - :boost_functions => ['recip(ms(NOW/HOUR,updated_at),1.3e-10,1,1)'] | ||
70 | - end | ||
71 | - end | 78 | + @scope = @environment.products |
79 | + full_text_search | ||
72 | end | 80 | end |
73 | 81 | ||
74 | def enterprises | 82 | def enterprises |
75 | - if !@empty_query | ||
76 | - full_text_search ['public:true'] | ||
77 | - else | ||
78 | - @filter_title = _('Enterprises from network') | ||
79 | - @results[@asset] = visible_profiles(Enterprise, [{:products => :product_category}]).paginate(paginate_options) | ||
80 | - end | 83 | + @scope = visible_profiles(Enterprise, [{:products => :product_category}]) |
84 | + full_text_search | ||
81 | end | 85 | end |
82 | 86 | ||
83 | def communities | 87 | def communities |
84 | - if !@empty_query | ||
85 | - full_text_search ['public:true'] | ||
86 | - else | ||
87 | - @results[@asset] = visible_profiles(Community).send(@filter).paginate(paginate_options) | ||
88 | - end | 88 | + @scope = visible_profiles(Community) |
89 | + full_text_search | ||
89 | end | 90 | end |
90 | 91 | ||
91 | def events | 92 | def events |
@@ -93,7 +94,7 @@ class SearchController < PublicController | @@ -93,7 +94,7 @@ class SearchController < PublicController | ||
93 | month = (params[:month] ? params[:month].to_i : Date.today.month) | 94 | month = (params[:month] ? params[:month].to_i : Date.today.month) |
94 | day = (params[:day] ? params[:day].to_i : Date.today.day) | 95 | day = (params[:day] ? params[:day].to_i : Date.today.day) |
95 | date = build_date(params[:year], params[:month], params[:day]) | 96 | date = build_date(params[:year], params[:month], params[:day]) |
96 | - date_range = (date - 1.month)..(date + 1.month).at_end_of_month | 97 | + date_range = (date - 1.month).at_beginning_of_month..(date + 1.month).at_end_of_month |
97 | 98 | ||
98 | @selected_day = nil | 99 | @selected_day = nil |
99 | @events_of_the_day = [] | 100 | @events_of_the_day = [] |
@@ -104,64 +105,21 @@ class SearchController < PublicController | @@ -104,64 +105,21 @@ class SearchController < PublicController | ||
104 | environment.events.by_day(@selected_day) | 105 | environment.events.by_day(@selected_day) |
105 | end | 106 | end |
106 | 107 | ||
107 | - if !@empty_query | ||
108 | - full_text_search | ||
109 | - else | ||
110 | - @results[@asset] = date_range ? environment.events.by_range(date_range) : environment.events | ||
111 | - end | 108 | + @scope = date_range ? environment.events.by_range(date_range) : environment.events |
109 | + full_text_search | ||
112 | 110 | ||
113 | - events = @results[@asset] | 111 | + events = @searches[@asset][:results] |
114 | @calendar = populate_calendar(date, events) | 112 | @calendar = populate_calendar(date, events) |
115 | @previous_calendar = populate_calendar(date - 1.month, events) | 113 | @previous_calendar = populate_calendar(date - 1.month, events) |
116 | @next_calendar = populate_calendar(date + 1.month, events) | 114 | @next_calendar = populate_calendar(date + 1.month, events) |
117 | end | 115 | end |
118 | 116 | ||
119 | - def index | ||
120 | - @results = {} | ||
121 | - @order = [] | ||
122 | - @names = {} | ||
123 | - @results_only = true | ||
124 | - | ||
125 | - @enabled_searches.select { |key,description| @searching[key] }.each do |key, description| | ||
126 | - load_query | ||
127 | - @asset = key | ||
128 | - send(key) | ||
129 | - @order << key | ||
130 | - @names[key] = getterm(description) | ||
131 | - end | ||
132 | - @asset = nil | ||
133 | - @facets = {} | ||
134 | - | ||
135 | - render :action => @results.keys.first if @results.keys.size == 1 | ||
136 | - end | ||
137 | - | ||
138 | # keep old URLs workings | 117 | # keep old URLs workings |
139 | def assets | 118 | def assets |
140 | params[:action] = params[:asset].is_a?(Array) ? :index : params.delete(:asset) | 119 | params[:action] = params[:asset].is_a?(Array) ? :index : params.delete(:asset) |
141 | redirect_to params | 120 | redirect_to params |
142 | end | 121 | end |
143 | 122 | ||
144 | - # view the summary of one category | ||
145 | - def category_index | ||
146 | - @results = {} | ||
147 | - @order = [] | ||
148 | - @names = {} | ||
149 | - limit = MULTIPLE_SEARCH_LIMIT | ||
150 | - [ | ||
151 | - [ :people, _('People'), :recent_people ], | ||
152 | - [ :enterprises, _('Enterprises'), :recent_enterprises ], | ||
153 | - [ :products, _('Products'), :recent_products ], | ||
154 | - [ :events, _('Upcoming events'), :upcoming_events ], | ||
155 | - [ :communities, _('Communities'), :recent_communities ], | ||
156 | - [ :articles, _('Contents'), :recent_articles ] | ||
157 | - ].each do |asset, name, filter| | ||
158 | - @order << asset | ||
159 | - @results[asset] = @category.send(filter, limit) | ||
160 | - raise "No total_entries for: #{asset}" unless @results[asset].respond_to?(:total_entries) | ||
161 | - @names[asset] = name | ||
162 | - end | ||
163 | - end | ||
164 | - | ||
165 | def tags | 123 | def tags |
166 | @tags_cache_key = "tags_env_#{environment.id.to_s}" | 124 | @tags_cache_key = "tags_env_#{environment.id.to_s}" |
167 | if is_cache_expired?(@tags_cache_key) | 125 | if is_cache_expired?(@tags_cache_key) |
@@ -173,7 +131,7 @@ class SearchController < PublicController | @@ -173,7 +131,7 @@ class SearchController < PublicController | ||
173 | @tag = params[:tag] | 131 | @tag = params[:tag] |
174 | @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}" | 132 | @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}" |
175 | if is_cache_expired?(@tag_cache_key) | 133 | if is_cache_expired?(@tag_cache_key) |
176 | - @results[@asset] = environment.articles.find_tagged_with(@tag).paginate(paginate_options) | 134 | + @searches[@asset] = {:results => environment.articles.find_tagged_with(@tag).paginate(paginate_options)} |
177 | end | 135 | end |
178 | end | 136 | end |
179 | 137 | ||
@@ -187,11 +145,9 @@ class SearchController < PublicController | @@ -187,11 +145,9 @@ class SearchController < PublicController | ||
187 | protected | 145 | protected |
188 | 146 | ||
189 | def load_query | 147 | def load_query |
190 | - @asset = params[:action].to_sym | 148 | + @asset = (params[:asset] || params[:action]).to_sym |
191 | @order ||= [@asset] | 149 | @order ||= [@asset] |
192 | - @results ||= {} | ||
193 | - @filter = filter | ||
194 | - @filter_title = filter_description(@asset, @filter) | 150 | + @searches ||= {} |
195 | 151 | ||
196 | @query = params[:query] || '' | 152 | @query = params[:query] || '' |
197 | @empty_query = @category.nil? && @query.blank? | 153 | @empty_query = @category.nil? && @query.blank? |
@@ -211,42 +167,13 @@ class SearchController < PublicController | @@ -211,42 +167,13 @@ class SearchController < PublicController | ||
211 | end | 167 | end |
212 | end | 168 | end |
213 | 169 | ||
214 | - FILTERS = %w( | ||
215 | - more_recent | ||
216 | - more_active | ||
217 | - more_popular | ||
218 | - more_comments | ||
219 | - ) | ||
220 | - def filter | ||
221 | - if FILTERS.include?(params[:filter]) | ||
222 | - params[:filter] | ||
223 | - else | ||
224 | - 'more_recent' | ||
225 | - end | ||
226 | - end | ||
227 | - | ||
228 | - def filter_description(asset, filter) | ||
229 | - { | ||
230 | - 'articles_more_recent' => _('More recent contents from network'), | ||
231 | - 'articles_more_popular' => _('More viewed contents from network'), | ||
232 | - 'articles_more_comments' => _('Most commented contents from network'), | ||
233 | - 'people_more_recent' => _('More recent people from network'), | ||
234 | - 'people_more_active' => _('More active people from network'), | ||
235 | - 'people_more_popular' => _('More popular people from network'), | ||
236 | - 'communities_more_recent' => _('More recent communities from network'), | ||
237 | - 'communities_more_active' => _('More active communities from network'), | ||
238 | - 'communities_more_popular' => _('More popular communities from network'), | ||
239 | - 'products_more_recent' => _('Highlights'), | ||
240 | - }[asset.to_s + '_' + filter] | ||
241 | - end | ||
242 | - | ||
243 | def load_search_assets | 170 | def load_search_assets |
244 | - if Searches.keys.include?(params[:action].to_sym) and environment.enabled?("disable_asset_#{params[:action]}") | 171 | + if SEARCHES.keys.include?(params[:action].to_sym) && environment.enabled?("disable_asset_#{params[:action]}") |
245 | render_not_found | 172 | render_not_found |
246 | return | 173 | return |
247 | end | 174 | end |
248 | 175 | ||
249 | - @enabled_searches = Searches.select {|key, name| environment.disabled?("disable_asset_#{params[:action]}") } | 176 | + @enabled_searches = SEARCHES.select {|key, name| environment.disabled?("disable_asset_#{key}") } |
250 | @searching = {} | 177 | @searching = {} |
251 | @titles = {} | 178 | @titles = {} |
252 | @enabled_searches.each do |key, name| | 179 | @enabled_searches.each do |key, name| |
@@ -256,13 +183,19 @@ class SearchController < PublicController | @@ -256,13 +183,19 @@ class SearchController < PublicController | ||
256 | @names = @titles if @names.nil? | 183 | @names = @titles if @names.nil? |
257 | end | 184 | end |
258 | 185 | ||
186 | + def load_filter | ||
187 | + @filter = 'more_recent' | ||
188 | + if SEARCHES.keys.include?(@asset.to_sym) | ||
189 | + available_filters = asset_class(@asset)::SEARCH_FILTERS | ||
190 | + @filter = params[:filter] if available_filters.include?(params[:filter]) | ||
191 | + end | ||
192 | + end | ||
193 | + | ||
259 | def limit | 194 | def limit |
260 | - if map_search? | 195 | + if map_search?(@searches) |
261 | MAP_SEARCH_LIMIT | 196 | MAP_SEARCH_LIMIT |
262 | elsif !multiple_search? | 197 | elsif !multiple_search? |
263 | - if [:people, :communities].include? @asset | ||
264 | - BLOCKS_SEARCH_LIMIT | ||
265 | - elsif @asset == :enterprises and @empty_query | 198 | + if [:people, :communities, :enterprises].include? @asset |
266 | BLOCKS_SEARCH_LIMIT | 199 | BLOCKS_SEARCH_LIMIT |
267 | else | 200 | else |
268 | LIST_SEARCH_LIMIT | 201 | LIST_SEARCH_LIMIT |
@@ -273,41 +206,12 @@ class SearchController < PublicController | @@ -273,41 +206,12 @@ class SearchController < PublicController | ||
273 | end | 206 | end |
274 | 207 | ||
275 | def paginate_options(page = params[:page]) | 208 | def paginate_options(page = params[:page]) |
276 | - page = 1 if multiple_search? or params[:display] == 'map' | 209 | + page = 1 if multiple_search?(@searches) || params[:display] == 'map' |
277 | { :per_page => limit, :page => page } | 210 | { :per_page => limit, :page => page } |
278 | end | 211 | end |
279 | 212 | ||
280 | - def full_text_search(filters = [], options = {}) | ||
281 | - paginate_options = paginate_options(params[:page]) | ||
282 | - asset_class = asset_class(@asset) | ||
283 | - solr_options = options | ||
284 | - pg_options = paginate_options(params[:page]) | ||
285 | - | ||
286 | - if !multiple_search? | ||
287 | - if !@results_only and asset_class.respond_to? :facets | ||
288 | - solr_options.merge! asset_class.facets_find_options(params[:facet]) | ||
289 | - solr_options[:all_facets] = true | ||
290 | - end | ||
291 | - solr_options[:filter_queries] ||= [] | ||
292 | - solr_options[:filter_queries] += filters | ||
293 | - solr_options[:filter_queries] << "environment_id:#{environment.id}" | ||
294 | - solr_options[:filter_queries] << asset_class.facet_category_query.call(@category) if @category | ||
295 | - | ||
296 | - solr_options[:boost_functions] ||= [] | ||
297 | - params[:order_by] = nil if params[:order_by] == 'none' | ||
298 | - if params[:order_by] | ||
299 | - order = SortOptions[@asset][params[:order_by].to_sym] | ||
300 | - raise "Unknown order by" if order.nil? | ||
301 | - order[:solr_opts].each do |opt, value| | ||
302 | - solr_options[opt] = value.is_a?(Proc) ? instance_eval(&value) : value | ||
303 | - end | ||
304 | - end | ||
305 | - end | ||
306 | - | ||
307 | - ret = asset_class.find_by_contents(@query, paginate_options, solr_options) | ||
308 | - @results[@asset] = ret[:results] | ||
309 | - @facets = ret[:facets] | ||
310 | - @all_facets = ret[:all_facets] | 213 | + def full_text_search |
214 | + @searches[@asset] = find_by_contents(@asset, @scope, @query, paginate_options, {:category => @category, :filter => @filter}) | ||
311 | end | 215 | end |
312 | 216 | ||
313 | private | 217 | private |
app/helpers/application_helper.rb
@@ -274,9 +274,9 @@ module ApplicationHelper | @@ -274,9 +274,9 @@ module ApplicationHelper | ||
274 | 274 | ||
275 | VIEW_EXTENSIONS = %w[.rhtml .html.erb] | 275 | VIEW_EXTENSIONS = %w[.rhtml .html.erb] |
276 | 276 | ||
277 | - def partial_for_class_in_view_path(klass, view_path, suffix = nil) | 277 | + def partial_for_class_in_view_path(klass, view_path, prefix = nil, suffix = nil) |
278 | return nil if klass.nil? | 278 | return nil if klass.nil? |
279 | - name = [klass.name.underscore, suffix].compact.map(&:to_s).join('_') | 279 | + name = [prefix, klass.name.underscore, suffix].compact.map(&:to_s).join('_') |
280 | 280 | ||
281 | search_name = String.new(name) | 281 | search_name = String.new(name) |
282 | if search_name.include?("/") | 282 | if search_name.include?("/") |
@@ -291,14 +291,14 @@ module ApplicationHelper | @@ -291,14 +291,14 @@ module ApplicationHelper | ||
291 | return name if File.exists?(File.join(path)) | 291 | return name if File.exists?(File.join(path)) |
292 | end | 292 | end |
293 | 293 | ||
294 | - partial_for_class_in_view_path(klass.superclass, view_path, suffix) | 294 | + partial_for_class_in_view_path(klass.superclass, view_path, prefix, suffix) |
295 | end | 295 | end |
296 | 296 | ||
297 | - def partial_for_class(klass, suffix=nil) | 297 | + def partial_for_class(klass, prefix=nil, suffix=nil) |
298 | raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' if klass.nil? | 298 | raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' if klass.nil? |
299 | name = klass.name.underscore | 299 | name = klass.name.underscore |
300 | @controller.view_paths.each do |view_path| | 300 | @controller.view_paths.each do |view_path| |
301 | - partial = partial_for_class_in_view_path(klass, view_path, suffix) | 301 | + partial = partial_for_class_in_view_path(klass, view_path, prefix, suffix) |
302 | return partial if partial | 302 | return partial if partial |
303 | end | 303 | end |
304 | 304 |
app/helpers/search_helper.rb
@@ -2,12 +2,10 @@ module SearchHelper | @@ -2,12 +2,10 @@ module SearchHelper | ||
2 | 2 | ||
3 | MAP_SEARCH_LIMIT = 2000 | 3 | MAP_SEARCH_LIMIT = 2000 |
4 | LIST_SEARCH_LIMIT = 20 | 4 | LIST_SEARCH_LIMIT = 20 |
5 | - BLOCKS_SEARCH_LIMIT = 18 | 5 | + BLOCKS_SEARCH_LIMIT = 24 |
6 | MULTIPLE_SEARCH_LIMIT = 8 | 6 | MULTIPLE_SEARCH_LIMIT = 8 |
7 | - DistFilt = 200 | ||
8 | - DistBoost = 50 | ||
9 | 7 | ||
10 | - Searches = ActiveSupport::OrderedHash[ | 8 | + SEARCHES = ActiveSupport::OrderedHash[ |
11 | :articles, _('Contents'), | 9 | :articles, _('Contents'), |
12 | :enterprises, _('Enterprises'), | 10 | :enterprises, _('Enterprises'), |
13 | :people, _('People'), | 11 | :people, _('People'), |
@@ -16,46 +14,31 @@ module SearchHelper | @@ -16,46 +14,31 @@ module SearchHelper | ||
16 | :events, _('Events'), | 14 | :events, _('Events'), |
17 | ] | 15 | ] |
18 | 16 | ||
19 | - SortOptions = { | ||
20 | - :products => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | ||
21 | - :more_recent, {:label => _('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}}, | ||
22 | - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | ||
23 | - :closest, {:label => _('Closest to me'), :if => proc{ logged_in? && (profile=current_user.person).lat && profile.lng }, | ||
24 | - :solr_opts => {:sort => "geodist() asc", | ||
25 | - :latitude => proc{ current_user.person.lat }, :longitude => proc{ current_user.person.lng }}}, | ||
26 | - ], | ||
27 | - :events => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | ||
28 | - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | ||
29 | - ], | ||
30 | - :articles => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | ||
31 | - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | ||
32 | - :more_recent, {:label => _('More recent'), :solr_opts => {:sort => 'updated_at desc, score desc'}}, | ||
33 | - ], | ||
34 | - :enterprises => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | ||
35 | - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | ||
36 | - ], | ||
37 | - :people => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | ||
38 | - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | ||
39 | - ], | ||
40 | - :communities => ActiveSupport::OrderedHash[ :none, {:label => _('Relevance')}, | ||
41 | - :name, {:label => _('Name'), :solr_opts => {:sort => 'name_sortable asc'}}, | ||
42 | - ], | 17 | + FILTER_TRANSLATION = { |
18 | + 'more_popular' => _('More popular'), | ||
19 | + 'more_active' => _('More active'), | ||
20 | + 'more_recent' => _('More recent'), | ||
21 | + 'more_comments' => _('More comments') | ||
43 | } | 22 | } |
44 | 23 | ||
45 | # FIXME remove it after search_controler refactored | 24 | # FIXME remove it after search_controler refactored |
46 | include EventsHelper | 25 | include EventsHelper |
47 | 26 | ||
48 | - def multiple_search? | ||
49 | - ['index', 'category_index'].include?(params[:action]) or @results.size > 1 | 27 | + def multiple_search?(searches=nil) |
28 | + ['index', 'category_index'].include?(params[:action]) || (searches && searches.size > 1) | ||
50 | end | 29 | end |
51 | 30 | ||
52 | - def map_search? | ||
53 | - !@empty_query and !multiple_search? and params[:display] == 'map' | 31 | + def map_search?(searches=nil) |
32 | + !multiple_search?(searches) && params[:display] == 'map' | ||
33 | + end | ||
34 | + | ||
35 | + def asset_class(asset) | ||
36 | + asset.to_s.singularize.camelize.constantize | ||
54 | end | 37 | end |
55 | 38 | ||
56 | def search_page_title(title, category = nil) | 39 | def search_page_title(title, category = nil) |
57 | title = "<h1>" + title | 40 | title = "<h1>" + title |
58 | - title += '<small>' + category.name + '</small>' if category | 41 | + title += ' - <small>' + category.name + '</small>' if category |
59 | title + "</h1>" | 42 | title + "</h1>" |
60 | end | 43 | end |
61 | 44 | ||
@@ -66,8 +49,12 @@ module SearchHelper | @@ -66,8 +49,12 @@ module SearchHelper | ||
66 | :align => 'center', :class => 'search-category-context') if category | 49 | :align => 'center', :class => 'search-category-context') if category |
67 | end | 50 | end |
68 | 51 | ||
69 | - def display_results(map_capable = false) | ||
70 | - if map_capable and map_search? | 52 | + def display?(asset, mode) |
53 | + defined?(asset_class(asset)::SEARCH_DISPLAYS) && asset_class(asset)::SEARCH_DISPLAYS.include?(mode.to_s) | ||
54 | + end | ||
55 | + | ||
56 | + def display_results(searches=nil, asset=nil) | ||
57 | + if display?(asset, :map) && map_search?(searches) | ||
71 | partial = 'google_maps' | 58 | partial = 'google_maps' |
72 | klass = 'map' | 59 | klass = 'map' |
73 | else | 60 | else |
@@ -78,10 +65,13 @@ module SearchHelper | @@ -78,10 +65,13 @@ module SearchHelper | ||
78 | content_tag('div', render(:partial => partial), :class => "map-or-list-search-results #{klass}") | 65 | content_tag('div', render(:partial => partial), :class => "map-or-list-search-results #{klass}") |
79 | end | 66 | end |
80 | 67 | ||
81 | - def display_map_list_button | ||
82 | - button(:search, params[:display] == 'map' ? _('Display in list') : _('Display in map'), | ||
83 | - params.merge(:display => (params[:display] == 'map' ? 'list' : 'map')), | ||
84 | - :class => "map-toggle-button" ) | 68 | + def display_filter(asset, display) |
69 | + asset = :articles if asset == :tag | ||
70 | + if display?(asset, display) | ||
71 | + display | ||
72 | + else | ||
73 | + asset_class(asset).default_search_display | ||
74 | + end | ||
85 | end | 75 | end |
86 | 76 | ||
87 | def city_with_state(city) | 77 | def city_with_state(city) |
@@ -97,120 +87,50 @@ module SearchHelper | @@ -97,120 +87,50 @@ module SearchHelper | ||
97 | end | 87 | end |
98 | end | 88 | end |
99 | 89 | ||
100 | - def facets_menu(asset, _facets) | ||
101 | - @asset_class = asset_class(asset) | ||
102 | - @facets = _facets | ||
103 | - render(:partial => 'facets_menu') | ||
104 | - end | ||
105 | - | ||
106 | - def facets_unselect_menu(asset) | ||
107 | - @asset_class = asset_class(asset) | ||
108 | - render(:partial => 'facets_unselect_menu') | ||
109 | - end | ||
110 | - | ||
111 | - def facet_javascript(input_id, facet, array) | ||
112 | - array = [] if array.nil? | ||
113 | - hintText = _('Type in an option') | ||
114 | - text_field_tag('facet['+input_id+']', '', :id => input_id) + | ||
115 | - javascript_tag("jQuery.TokenList(jQuery('##{input_id}'), #{array.to_json}, | ||
116 | - {searchDelay: 0, permanentDropdown: true, theme: 'facet', dontAdd: true, preventDuplicates: true, | ||
117 | - #{jquery_token_input_messages_json(hintText)}});") | ||
118 | - end | ||
119 | - | ||
120 | - def facet_link_html(facet, params, value, label, count) | ||
121 | - params = params ? params.dup : {} | ||
122 | - has_extra = label.kind_of?(Array) | ||
123 | - link_label = has_extra ? label[0] : label | ||
124 | - id = facet[:solr_field].to_s | ||
125 | - params[:facet] ||= {} | ||
126 | - params[:facet][id] ||= {} | ||
127 | - params[:page] = {} if params[:page] | ||
128 | - | ||
129 | - selected = facet[:label_id].nil? ? params[:facet][id] == value : params[:facet][id][facet[:label_id]].to_a.include?(value) | ||
130 | - | ||
131 | - if count > 0 | ||
132 | - url = params.merge(:facet => params[:facet].merge( | ||
133 | - id => facet[:label_id].nil? ? value : params[:facet][id].merge( facet[:label_id] => params[:facet][id][facet[:label_id]].to_a | [value] ) | ||
134 | - )) | ||
135 | - else | ||
136 | - # preserve others filters and change this filter | ||
137 | - url = params.merge(:facet => params[:facet].merge( | ||
138 | - id => facet[:label_id].nil? ? value : { facet[:label_id] => value } | ||
139 | - )) | 90 | + def display_selector(asset, display, float = 'right') |
91 | + display = nil if display.blank? | ||
92 | + display ||= asset_class(asset).default_search_display | ||
93 | + if [display?(asset, :map), display?(asset, :compact), display?(asset, :full)].select {|option| option}.count > 1 | ||
94 | + compact_link = display?(asset, :compact) ? (display == 'compact' ? _('Compact') : link_to(_('Compact'), params.merge(:display => 'compact'))) : nil | ||
95 | + map_link = display?(asset, :map) ? (display == 'map' ? _('Map') : link_to(_('Map'), params.merge(:display => 'map'))) : nil | ||
96 | + full_link = display?(asset, :full) ? (display == 'full' ? _('Full') : link_to(_('Full'), params.merge(:display => 'full'))) : nil | ||
97 | + content_tag('div', | ||
98 | + content_tag('strong', _('Display')) + ': ' + [compact_link, map_link, full_link].compact.join(' | ').html_safe, | ||
99 | + :class => 'search-customize-options' | ||
100 | + ) | ||
140 | end | 101 | end |
141 | - | ||
142 | - content_tag 'div', link_to(link_label, url, :class => 'facet-result-link-label') + | ||
143 | - content_tag('span', (has_extra ? label[1] : ''), :class => 'facet-result-extra-label') + | ||
144 | - (count > 0 ? content_tag('span', " (#{count})", :class => 'facet-result-count') : ''), | ||
145 | - :class => 'facet-menu-item' + (selected ? ' facet-result-link-selected' : '') | ||
146 | end | 102 | end |
147 | 103 | ||
148 | - def facet_selecteds_html_for(environment, klass, params) | ||
149 | - def name_with_extra(klass, facet, value) | ||
150 | - name = klass.facet_result_name(facet, value) | ||
151 | - name = name[0] + name[1] if name.kind_of?(Array) | ||
152 | - name | ||
153 | - end | ||
154 | - | ||
155 | - ret = [] | ||
156 | - params = params.dup | ||
157 | - params[:facet].each do |id, value| | ||
158 | - facet = klass.facet_by_id(id.to_sym) | ||
159 | - next unless facet | ||
160 | - if value.kind_of?(Hash) | ||
161 | - label_hash = facet[:label].call(environment) | ||
162 | - value.each do |label_id, value| | ||
163 | - facet[:label_id] = label_id | ||
164 | - facet[:label] = label_hash[label_id] | ||
165 | - value.to_a.each do |value| | ||
166 | - ret << [facet[:label], name_with_extra(klass, facet, value), | ||
167 | - params.merge(:facet => params[:facet].merge(id => params[:facet][id].merge(label_id => params[:facet][id][label_id].to_a.reject{ |v| v == value })))] | ||
168 | - end | ||
169 | - end | ||
170 | - else | ||
171 | - ret << [klass.facet_label(facet), name_with_extra(klass, facet, value), | ||
172 | - params.merge(:facet => params[:facet].reject{ |k,v| k == id })] | ||
173 | - end | 104 | + def filter_selector(asset, filter, float = 'right') |
105 | + klass = asset_class(asset) | ||
106 | + if klass::SEARCH_FILTERS.count > 1 | ||
107 | + options = options_for_select(klass::SEARCH_FILTERS.map {|f| [FILTER_TRANSLATION[f], f]}, filter) | ||
108 | + url_params = url_for(params.merge(:filter => 'FILTER')) | ||
109 | + onchange = "document.location.href = '#{url_params}'.replace('FILTER', this.value)" | ||
110 | + select_field = select_tag(:filter, options, :onchange => onchange) | ||
111 | + content_tag('div', | ||
112 | + content_tag('strong', _('Filter')) + ': ' + select_field, | ||
113 | + :class => "search-customize-options" | ||
114 | + ) | ||
174 | end | 115 | end |
175 | - | ||
176 | - ret.map do |label, name, url| | ||
177 | - content_tag('div', content_tag('span', label, :class => 'facet-selected-label') + | ||
178 | - content_tag('span', name, :class => 'facet-selected-name') + | ||
179 | - link_to('', url, :class => 'facet-selected-remove', :title => 'remove facet'), :class => 'facet-selected') | ||
180 | - end.join | ||
181 | - end | ||
182 | - | ||
183 | - def order_by(asset) | ||
184 | - options = SortOptions[asset].map do |name, options| | ||
185 | - next if options[:if] and ! instance_eval(&options[:if]) | ||
186 | - [_(options[:label]), name.to_s] | ||
187 | - end.compact | ||
188 | - | ||
189 | - content_tag('div', _('Sort results by ') + | ||
190 | - select_tag(asset.to_s + '[order]', options_for_select(options, params[:order_by] || 'none'), | ||
191 | - {:onchange => "window.location = jQuery.param.querystring(window.location.href, { 'order_by' : this.options[this.selectedIndex].value})"}), | ||
192 | - :class => "search-ordering") | ||
193 | - end | ||
194 | - | ||
195 | - def label_total_found(asset, total_found) | ||
196 | - labels = { | ||
197 | - :products => _("%s products offers found"), | ||
198 | - :articles => _("%s articles found"), | ||
199 | - :events => _("%s events found"), | ||
200 | - :people => _("%s people found"), | ||
201 | - :enterprises => _("%s enterprises found"), | ||
202 | - :communities => _("%s communities found"), | ||
203 | - } | ||
204 | - content_tag('span', labels[asset] % total_found, | ||
205 | - :class => "total-pages-found") if labels[asset] | ||
206 | - end | ||
207 | - | ||
208 | - def asset_class(asset) | ||
209 | - asset.to_s.singularize.camelize.constantize | ||
210 | end | 116 | end |
211 | 117 | ||
212 | - def asset_table(asset) | ||
213 | - asset_class(asset).table_name | 118 | + def filter_title(asset, filter) |
119 | + { | ||
120 | + 'articles_more_recent' => _('More recent contents from network'), | ||
121 | + 'articles_more_popular' => _('More viewed contents from network'), | ||
122 | + 'articles_more_comments' => _('Most commented contents from network'), | ||
123 | + 'people_more_recent' => _('More recent people from network'), | ||
124 | + 'people_more_active' => _('More active people from network'), | ||
125 | + 'people_more_popular' => _('More popular people from network'), | ||
126 | + 'communities_more_recent' => _('More recent communities from network'), | ||
127 | + 'communities_more_active' => _('More active communities from network'), | ||
128 | + 'communities_more_popular' => _('More popular communities from network'), | ||
129 | + 'enterprises_more_recent' => _('More recent enterprises from network'), | ||
130 | + 'enterprises_more_active' => _('More active enterprises from network'), | ||
131 | + 'enterprises_more_popular' => _('More popular enterprises from network'), | ||
132 | + 'products_more_recent' => _('Highlights'), | ||
133 | + }[asset.to_s + '_' + filter].to_s | ||
214 | end | 134 | end |
215 | 135 | ||
216 | end | 136 | end |
app/models/article.rb
@@ -2,6 +2,26 @@ require 'hpricot' | @@ -2,6 +2,26 @@ require 'hpricot' | ||
2 | 2 | ||
3 | class Article < ActiveRecord::Base | 3 | class Article < ActiveRecord::Base |
4 | 4 | ||
5 | + SEARCHABLE_FIELDS = { | ||
6 | + :name => 10, | ||
7 | + :abstract => 3, | ||
8 | + :body => 2, | ||
9 | + :slug => 1, | ||
10 | + :filename => 1, | ||
11 | + } | ||
12 | + | ||
13 | + SEARCH_FILTERS = %w[ | ||
14 | + more_recent | ||
15 | + more_popular | ||
16 | + more_comments | ||
17 | + ] | ||
18 | + | ||
19 | + SEARCH_DISPLAYS = %w[full] | ||
20 | + | ||
21 | + def self.default_search_display | ||
22 | + 'full' | ||
23 | + end | ||
24 | + | ||
5 | #FIXME This is necessary because html is being generated on the model... | 25 | #FIXME This is necessary because html is being generated on the model... |
6 | include ActionView::Helpers::TagHelper | 26 | include ActionView::Helpers::TagHelper |
7 | 27 | ||
@@ -147,7 +167,6 @@ class Article < ActiveRecord::Base | @@ -147,7 +167,6 @@ class Article < ActiveRecord::Base | ||
147 | else | 167 | else |
148 | ArticleCategorization.add_category_to_article(c, self) | 168 | ArticleCategorization.add_category_to_article(c, self) |
149 | self.categories(reload) | 169 | self.categories(reload) |
150 | - self.solr_save | ||
151 | end | 170 | end |
152 | end | 171 | end |
153 | 172 | ||
@@ -165,7 +184,6 @@ class Article < ActiveRecord::Base | @@ -165,7 +184,6 @@ class Article < ActiveRecord::Base | ||
165 | ArticleCategorization.add_category_to_article(item, self) | 184 | ArticleCategorization.add_category_to_article(item, self) |
166 | end | 185 | end |
167 | self.categories(true) | 186 | self.categories(true) |
168 | - self.solr_save | ||
169 | pending_categorizations.clear | 187 | pending_categorizations.clear |
170 | end | 188 | end |
171 | 189 | ||
@@ -201,20 +219,12 @@ class Article < ActiveRecord::Base | @@ -201,20 +219,12 @@ class Article < ActiveRecord::Base | ||
201 | named_scope :public, | 219 | named_scope :public, |
202 | :conditions => [ "advertise = ? AND published = ? AND profiles.visible = ? AND profiles.public_profile = ?", true, true, true, true ] | 220 | :conditions => [ "advertise = ? AND published = ? AND profiles.visible = ? AND profiles.public_profile = ?", true, true, true, true ] |
203 | 221 | ||
204 | - named_scope :more_recent, | ||
205 | - :conditions => [ "advertise = ? AND published = ? AND profiles.visible = ? AND profiles.public_profile = ? AND | ||
206 | - ((articles.type != ?) OR articles.type is NULL)", | ||
207 | - true, true, true, true, 'RssFeed' | ||
208 | - ], | ||
209 | - :order => 'articles.published_at desc, articles.id desc' | ||
210 | - | ||
211 | # retrives the most commented articles, sorted by the comment count (largest | 222 | # retrives the most commented articles, sorted by the comment count (largest |
212 | # first) | 223 | # first) |
213 | def self.most_commented(limit) | 224 | def self.most_commented(limit) |
214 | paginate(:order => 'comments_count DESC', :page => 1, :per_page => limit) | 225 | paginate(:order => 'comments_count DESC', :page => 1, :per_page => limit) |
215 | end | 226 | end |
216 | 227 | ||
217 | - named_scope :more_popular, :order => 'hits DESC' | ||
218 | named_scope :relevant_as_recent, :conditions => ["(articles.type != 'UploadedFile' and articles.type != 'RssFeed' and articles.type != 'Blog') OR articles.type is NULL"] | 228 | named_scope :relevant_as_recent, :conditions => ["(articles.type != 'UploadedFile' and articles.type != 'RssFeed' and articles.type != 'Blog') OR articles.type is NULL"] |
219 | 229 | ||
220 | def self.recent(limit = nil, extra_conditions = {}, pagination = true) | 230 | def self.recent(limit = nil, extra_conditions = {}, pagination = true) |
@@ -426,8 +436,8 @@ class Article < ActiveRecord::Base | @@ -426,8 +436,8 @@ class Article < ActiveRecord::Base | ||
426 | named_scope :images, :conditions => { :is_image => true } | 436 | named_scope :images, :conditions => { :is_image => true } |
427 | named_scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ] | 437 | named_scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ] |
428 | 438 | ||
439 | + named_scope :more_popular, :order => 'hits DESC' | ||
429 | named_scope :more_comments, :order => "comments_count DESC" | 440 | named_scope :more_comments, :order => "comments_count DESC" |
430 | - named_scope :more_views, :order => "hits DESC" | ||
431 | named_scope :more_recent, :order => "created_at DESC" | 441 | named_scope :more_recent, :order => "created_at DESC" |
432 | 442 | ||
433 | def self.display_filter(user, profile) | 443 | def self.display_filter(user, profile) |
@@ -479,10 +489,6 @@ class Article < ActiveRecord::Base | @@ -479,10 +489,6 @@ class Article < ActiveRecord::Base | ||
479 | allow_post_content?(user) || user && allow_members_to_edit && user.is_member_of?(profile) | 489 | allow_post_content?(user) || user && allow_members_to_edit && user.is_member_of?(profile) |
480 | end | 490 | end |
481 | 491 | ||
482 | - def comments_updated | ||
483 | - solr_save | ||
484 | - end | ||
485 | - | ||
486 | def accept_category?(cat) | 492 | def accept_category?(cat) |
487 | !cat.is_a?(ProductCategory) | 493 | !cat.is_a?(ProductCategory) |
488 | end | 494 | end |
@@ -620,7 +626,7 @@ class Article < ActiveRecord::Base | @@ -620,7 +626,7 @@ class Article < ActiveRecord::Base | ||
620 | 626 | ||
621 | end | 627 | end |
622 | 628 | ||
623 | - def more_views_label | 629 | + def more_popular_label |
624 | amount = self.hits | 630 | amount = self.hits |
625 | { | 631 | { |
626 | 0 => _('no views'), | 632 | 0 => _('no views'), |
@@ -648,98 +654,7 @@ class Article < ActiveRecord::Base | @@ -648,98 +654,7 @@ class Article < ActiveRecord::Base | ||
648 | img.nil? ? '' : img.attributes['src'] | 654 | img.nil? ? '' : img.attributes['src'] |
649 | end | 655 | end |
650 | 656 | ||
651 | - private | ||
652 | - | ||
653 | - # FIXME: workaround for development env. | ||
654 | - # Subclasses aren't (re)loaded, and acts_as_solr | ||
655 | - # depends on subclasses method to search | ||
656 | - # see http://stackoverflow.com/questions/4138957/activerecordsubclassnotfound-error-when-using-sti-in-rails/4139245 | ||
657 | - UploadedFile | ||
658 | - TextArticle | ||
659 | - TinyMceArticle | ||
660 | - TextileArticle | ||
661 | - Folder | ||
662 | - EnterpriseHomepage | ||
663 | - Gallery | ||
664 | - Blog | ||
665 | - Forum | ||
666 | - Event | ||
667 | - | ||
668 | - def self.f_type_proc(klass) | ||
669 | - klass.constantize.type_name | ||
670 | - end | ||
671 | - | ||
672 | - def self.f_profile_type_proc(klass) | ||
673 | - klass.constantize.type_name | ||
674 | - end | ||
675 | - | ||
676 | - def f_type | ||
677 | - #join common types | ||
678 | - case self.class.name | ||
679 | - when 'TinyMceArticle', 'TextileArticle' | ||
680 | - TextArticle.name | ||
681 | - else | ||
682 | - self.class.name | ||
683 | - end | ||
684 | - end | ||
685 | - | ||
686 | - def f_profile_type | ||
687 | - self.profile.class.name | ||
688 | - end | ||
689 | - | ||
690 | - def f_published_at | ||
691 | - self.published_at | ||
692 | - end | ||
693 | - | ||
694 | - def f_category | ||
695 | - self.categories.collect(&:name) | ||
696 | - end | ||
697 | - | ||
698 | delegate :region, :region_id, :environment, :environment_id, :to => :profile, :allow_nil => true | 657 | delegate :region, :region_id, :environment, :environment_id, :to => :profile, :allow_nil => true |
699 | - def name_sortable # give a different name for solr | ||
700 | - name | ||
701 | - end | ||
702 | - | ||
703 | - def public | ||
704 | - self.public? | ||
705 | - end | ||
706 | - | ||
707 | - def category_filter | ||
708 | - categories_including_virtual_ids | ||
709 | - end | ||
710 | - | ||
711 | - public | ||
712 | - | ||
713 | - acts_as_faceted :fields => { | ||
714 | - :f_type => {:label => _('Type'), :proc => proc{|klass| f_type_proc(klass)}}, | ||
715 | - :f_published_at => {:type => :date, :label => _('Published date'), :queries => {'[* TO NOW-1YEARS/DAY]' => _("Older than one year"), | ||
716 | - '[NOW-1YEARS TO NOW/DAY]' => _("In the last year"), '[NOW-1MONTHS TO NOW/DAY]' => _("In the last month"), '[NOW-7DAYS TO NOW/DAY]' => _("In the last week"), '[NOW-1DAYS TO NOW/DAY]' => _("In the last day")}, | ||
717 | - :queries_order => ['[NOW-1DAYS TO NOW/DAY]', '[NOW-7DAYS TO NOW/DAY]', '[NOW-1MONTHS TO NOW/DAY]', '[NOW-1YEARS TO NOW/DAY]', '[* TO NOW-1YEARS/DAY]']}, | ||
718 | - :f_profile_type => {:label => _('Profile'), :proc => proc{|klass| f_profile_type_proc(klass)}}, | ||
719 | - :f_category => {:label => _('Categories')}, | ||
720 | - }, :category_query => proc { |c| "category_filter:\"#{c.id}\"" }, | ||
721 | - :order => [:f_type, :f_published_at, :f_profile_type, :f_category] | ||
722 | - | ||
723 | - acts_as_searchable :fields => facets_fields_for_solr + [ | ||
724 | - # searched fields | ||
725 | - {:name => {:type => :text, :boost => 2.0}}, | ||
726 | - {:slug => :text}, {:body => :text}, | ||
727 | - {:abstract => :text}, {:filename => :text}, | ||
728 | - # filtered fields | ||
729 | - {:public => :boolean}, {:environment_id => :integer}, | ||
730 | - {:profile_id => :integer}, :language, | ||
731 | - {:category_filter => :integer}, | ||
732 | - # ordered/query-boosted fields | ||
733 | - {:name_sortable => :string}, :last_changed_by_id, :published_at, :is_image, | ||
734 | - :updated_at, :created_at, | ||
735 | - ], :include => [ | ||
736 | - {:profile => {:fields => [:name, :identifier, :address, :nickname, :region_id, :lat, :lng]}}, | ||
737 | - {:comments => {:fields => [:title, :body, :author_name, :author_email]}}, | ||
738 | - {:categories => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}}, | ||
739 | - ], :facets => facets_option_for_solr, | ||
740 | - :boost => proc { |a| 10 if a.profile && a.profile.enabled }, | ||
741 | - :if => proc{ |a| ! ['RssFeed'].include?(a.class.name) } | ||
742 | - handle_asynchronously :solr_save | ||
743 | 658 | ||
744 | private | 659 | private |
745 | 660 |
app/models/category.rb
1 | class Category < ActiveRecord::Base | 1 | class Category < ActiveRecord::Base |
2 | 2 | ||
3 | + SEARCHABLE_FIELDS = { | ||
4 | + :name => 10, | ||
5 | + :acronym => 5, | ||
6 | + :abbreviation => 5, | ||
7 | + :slug => 1, | ||
8 | + } | ||
9 | + | ||
3 | validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('%{fn} cannot be like that.').fix_i18n | 10 | validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('%{fn} cannot be like that.').fix_i18n |
4 | validates_presence_of :name, :environment_id | 11 | validates_presence_of :name, :environment_id |
5 | validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('%{fn} is already being used by another category.').fix_i18n | 12 | validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('%{fn} is already being used by another category.').fix_i18n |
@@ -100,23 +107,4 @@ class Category < ActiveRecord::Base | @@ -100,23 +107,4 @@ class Category < ActiveRecord::Base | ||
100 | self.children.find(:all, :conditions => {:display_in_menu => true}).empty? | 107 | self.children.find(:all, :conditions => {:display_in_menu => true}).empty? |
101 | end | 108 | end |
102 | 109 | ||
103 | - private | ||
104 | - def name_sortable # give a different name for solr | ||
105 | - name | ||
106 | - end | ||
107 | - public | ||
108 | - | ||
109 | - acts_as_searchable :fields => [ | ||
110 | - # searched fields | ||
111 | - {:name => {:type => :text, :boost => 2.0}}, | ||
112 | - {:path => :text}, {:slug => :text}, | ||
113 | - {:abbreviation => :text}, {:acronym => :text}, | ||
114 | - # filtered fields | ||
115 | - :parent_id, | ||
116 | - # ordered/query-boosted fields | ||
117 | - {:name_sortable => :string}, | ||
118 | - ] | ||
119 | - after_save_reindex [:articles, :profiles], :with => :delayed_job | ||
120 | - handle_asynchronously :solr_save | ||
121 | - | ||
122 | end | 110 | end |
app/models/certifier.rb
1 | class Certifier < ActiveRecord::Base | 1 | class Certifier < ActiveRecord::Base |
2 | 2 | ||
3 | + SEARCHABLE_FIELDS = { | ||
4 | + :name => 10, | ||
5 | + :description => 3, | ||
6 | + :link => 1, | ||
7 | + } | ||
8 | + | ||
3 | belongs_to :environment | 9 | belongs_to :environment |
4 | 10 | ||
5 | has_many :qualifier_certifiers, :dependent => :destroy | 11 | has_many :qualifier_certifiers, :dependent => :destroy |
@@ -24,6 +30,4 @@ class Certifier < ActiveRecord::Base | @@ -24,6 +30,4 @@ class Certifier < ActiveRecord::Base | ||
24 | self.name.downcase.transliterate <=> b.name.downcase.transliterate | 30 | self.name.downcase.transliterate <=> b.name.downcase.transliterate |
25 | end | 31 | end |
26 | 32 | ||
27 | - after_save_reindex [:products], :with => :delayed_job | ||
28 | - | ||
29 | end | 33 | end |
app/models/comment.rb
1 | class Comment < ActiveRecord::Base | 1 | class Comment < ActiveRecord::Base |
2 | 2 | ||
3 | + SEARCHABLE_FIELDS = { | ||
4 | + :title => 10, | ||
5 | + :name => 4, | ||
6 | + :body => 2, | ||
7 | + } | ||
8 | + | ||
3 | validates_presence_of :body | 9 | validates_presence_of :body |
4 | 10 | ||
5 | belongs_to :source, :counter_cache => true, :polymorphic => true | 11 | belongs_to :source, :counter_cache => true, :polymorphic => true |
@@ -78,12 +84,6 @@ class Comment < ActiveRecord::Base | @@ -78,12 +84,6 @@ class Comment < ActiveRecord::Base | ||
78 | self.article.profile.notification_emails - [self.author_email || self.email] | 84 | self.article.profile.notification_emails - [self.author_email || self.email] |
79 | end | 85 | end |
80 | 86 | ||
81 | - after_save :notify_article | ||
82 | - after_destroy :notify_article | ||
83 | - def notify_article | ||
84 | - article.comments_updated if article.kind_of?(Article) | ||
85 | - end | ||
86 | - | ||
87 | after_create :new_follower | 87 | after_create :new_follower |
88 | def new_follower | 88 | def new_follower |
89 | if source.kind_of?(Article) | 89 | if source.kind_of?(Article) |
app/models/enterprise.rb
@@ -2,6 +2,8 @@ | @@ -2,6 +2,8 @@ | ||
2 | # only enterprises can offer products and services. | 2 | # only enterprises can offer products and services. |
3 | class Enterprise < Organization | 3 | class Enterprise < Organization |
4 | 4 | ||
5 | + SEARCH_DISPLAYS += %w[map full] | ||
6 | + | ||
5 | def self.type_name | 7 | def self.type_name |
6 | _('Enterprise') | 8 | _('Enterprise') |
7 | end | 9 | end |
@@ -14,8 +16,6 @@ class Enterprise < Organization | @@ -14,8 +16,6 @@ class Enterprise < Organization | ||
14 | 16 | ||
15 | has_and_belongs_to_many :fans, :class_name => 'Person', :join_table => 'favorite_enteprises_people' | 17 | has_and_belongs_to_many :fans, :class_name => 'Person', :join_table => 'favorite_enteprises_people' |
16 | 18 | ||
17 | - after_save_reindex [:products], :with => :delayed_job | ||
18 | - extra_data_for_index :product_categories | ||
19 | def product_categories | 19 | def product_categories |
20 | products.includes(:product_category).map{|p| p.category_full_name}.compact | 20 | products.includes(:product_category).map{|p| p.category_full_name}.compact |
21 | end | 21 | end |
@@ -189,4 +189,8 @@ class Enterprise < Organization | @@ -189,4 +189,8 @@ class Enterprise < Organization | ||
189 | { :profile => identifier, :controller => 'catalog'} | 189 | { :profile => identifier, :controller => 'catalog'} |
190 | end | 190 | end |
191 | 191 | ||
192 | + def more_recent_label | ||
193 | + '' | ||
194 | + end | ||
195 | + | ||
192 | end | 196 | end |
app/models/environment.rb
@@ -268,8 +268,6 @@ class Environment < ActiveRecord::Base | @@ -268,8 +268,6 @@ class Environment < ActiveRecord::Base | ||
268 | 268 | ||
269 | settings_items :search_hints, :type => Hash, :default => {} | 269 | settings_items :search_hints, :type => Hash, :default => {} |
270 | 270 | ||
271 | - settings_items :top_level_category_as_facet_ids, :type => Array, :default => [] | ||
272 | - | ||
273 | def news_amount_by_folder=(amount) | 271 | def news_amount_by_folder=(amount) |
274 | settings[:news_amount_by_folder] = amount.to_i | 272 | settings[:news_amount_by_folder] = amount.to_i |
275 | end | 273 | end |
app/models/license.rb
1 | class License < ActiveRecord::Base | 1 | class License < ActiveRecord::Base |
2 | + | ||
3 | + SEARCHABLE_FIELDS = { | ||
4 | + :name => 10, | ||
5 | + :url => 5, | ||
6 | + } | ||
7 | + | ||
2 | belongs_to :environment | 8 | belongs_to :environment |
3 | has_many :content, :class_name => 'Article', :foreign_key => 'license_id' | 9 | has_many :content, :class_name => 'Article', :foreign_key => 'license_id' |
4 | 10 |
app/models/national_region.rb
1 | class NationalRegion < ActiveRecord::Base | 1 | class NationalRegion < ActiveRecord::Base |
2 | 2 | ||
3 | + SEARCHABLE_FIELDS = { | ||
4 | + :name => 1, | ||
5 | + :national_region_code => 1, | ||
6 | + } | ||
7 | + | ||
3 | def self.search_city(city_name, like = false, state = nil) | 8 | def self.search_city(city_name, like = false, state = nil) |
4 | 9 | ||
5 | operator = "=" | 10 | operator = "=" |
app/models/organization.rb
1 | # Represents any organization of the system | 1 | # Represents any organization of the system |
2 | class Organization < Profile | 2 | class Organization < Profile |
3 | 3 | ||
4 | + SEARCH_FILTERS += %w[ | ||
5 | + more_popular | ||
6 | + more_active | ||
7 | + ] | ||
8 | + | ||
4 | settings_items :closed, :type => :boolean, :default => false | 9 | settings_items :closed, :type => :boolean, :default => false |
5 | def closed? | 10 | def closed? |
6 | closed | 11 | closed |
app/models/person.rb
1 | # A person is the profile of an user holding all relationships with the rest of the system | 1 | # A person is the profile of an user holding all relationships with the rest of the system |
2 | class Person < Profile | 2 | class Person < Profile |
3 | 3 | ||
4 | + SEARCH_FILTERS += %w[ | ||
5 | + more_popular | ||
6 | + more_active | ||
7 | + ] | ||
8 | + | ||
4 | def self.type_name | 9 | def self.type_name |
5 | _('Person') | 10 | _('Person') |
6 | end | 11 | end |
app/models/product.rb
1 | class Product < ActiveRecord::Base | 1 | class Product < ActiveRecord::Base |
2 | 2 | ||
3 | + SEARCHABLE_FIELDS = { | ||
4 | + :name => 10, | ||
5 | + :description => 1, | ||
6 | + } | ||
7 | + | ||
8 | + SEARCH_FILTERS = %w[ | ||
9 | + more_recent | ||
10 | + ] | ||
11 | + | ||
12 | + SEARCH_DISPLAYS = %w[map full] | ||
13 | + | ||
14 | + def self.default_search_display | ||
15 | + 'full' | ||
16 | + end | ||
17 | + | ||
3 | belongs_to :enterprise | 18 | belongs_to :enterprise |
4 | has_one :region, :through => :enterprise | 19 | has_one :region, :through => :enterprise |
5 | validates_presence_of :enterprise | 20 | validates_presence_of :enterprise |
@@ -173,7 +188,7 @@ class Product < ActiveRecord::Base | @@ -173,7 +188,7 @@ class Product < ActiveRecord::Base | ||
173 | 188 | ||
174 | def price_described? | 189 | def price_described? |
175 | return false if price.blank? or price == 0 | 190 | return false if price.blank? or price == 0 |
176 | - (price - total_production_cost).zero? | 191 | + (price - total_production_cost.to_f).zero? |
177 | end | 192 | end |
178 | 193 | ||
179 | def update_price_details(price_details) | 194 | def update_price_details(price_details) |
@@ -215,89 +230,6 @@ class Product < ActiveRecord::Base | @@ -215,89 +230,6 @@ class Product < ActiveRecord::Base | ||
215 | end | 230 | end |
216 | end | 231 | end |
217 | 232 | ||
218 | - private | ||
219 | - def f_category | ||
220 | - self.product_category.name | ||
221 | - end | ||
222 | - def f_region | ||
223 | - self.enterprise.region.id if self.enterprise.region | ||
224 | - end | ||
225 | - def self.f_region_proc(id) | ||
226 | - c = Region.find(id) | ||
227 | - s = c.parent | ||
228 | - if c and c.kind_of?(City) and s and s.kind_of?(State) and s.acronym | ||
229 | - [c.name, ', ' + s.acronym] | ||
230 | - else | ||
231 | - c.name | ||
232 | - end | ||
233 | - end | ||
234 | - def self.f_qualifier_proc(ids) | ||
235 | - array = ids.split | ||
236 | - qualifier = Qualifier.find_by_id array[0] | ||
237 | - certifier = Certifier.find_by_id array[1] | ||
238 | - certifier ? [qualifier.name, _(' cert. ') + certifier.name] : qualifier.name | ||
239 | - end | ||
240 | - def f_qualifier | ||
241 | - product_qualifiers.map do |pq| | ||
242 | - "#{pq.qualifier_id} #{pq.certifier_id}" | ||
243 | - end | ||
244 | - end | ||
245 | - | ||
246 | - alias_method :name_sortable, :name | ||
247 | delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :enterprise | 233 | delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :enterprise |
248 | - def name_sortable # give a different name for solr | ||
249 | - name | ||
250 | - end | ||
251 | - def public | ||
252 | - self.public? | ||
253 | - end | ||
254 | - def price_sortable | ||
255 | - (price.nil? or price.zero?) ? nil : price | ||
256 | - end | ||
257 | - def category_filter | ||
258 | - enterprise.categories_including_virtual_ids << product_category_id | ||
259 | - end | ||
260 | - public | ||
261 | - | ||
262 | - acts_as_faceted :fields => { | ||
263 | - :f_category => {:label => _('Related products')}, | ||
264 | - :f_region => {:label => _('City'), :proc => proc { |id| f_region_proc(id) }}, | ||
265 | - :f_qualifier => {:label => _('Qualifiers'), :proc => proc { |id| f_qualifier_proc(id) }}, | ||
266 | - }, :category_query => proc { |c| "category_filter:#{c.id}" }, | ||
267 | - :order => [:f_category, :f_region, :f_qualifier] | ||
268 | - | ||
269 | - Boosts = [ | ||
270 | - [:image, 0.55, proc{ |p| p.image ? 1 : 0}], | ||
271 | - [:qualifiers, 0.45, proc{ |p| p.product_qualifiers.count > 0 ? 1 : 0}], | ||
272 | - [:open_price, 0.45, proc{ |p| p.price_described? ? 1 : 0}], | ||
273 | - [:solidarity, 0.45, proc{ |p| p.percentage_from_solidarity_economy[0].to_f/100 }], | ||
274 | - [:available, 0.35, proc{ |p| p.available ? 1 : 0}], | ||
275 | - [:price, 0.35, proc{ |p| (!p.price.nil? and p.price > 0) ? 1 : 0}], | ||
276 | - [:new_product, 0.35, proc{ |p| (p.updated_at.to_i - p.created_at.to_i) < 24*3600 ? 1 : 0}], | ||
277 | - [:description, 0.3, proc{ |p| !p.description.blank? ? 1 : 0}], | ||
278 | - [:enabled, 0.2, proc{ |p| p.enterprise.enabled ? 1 : 0}], | ||
279 | - ] | ||
280 | - | ||
281 | - acts_as_searchable :fields => facets_fields_for_solr + [ | ||
282 | - # searched fields | ||
283 | - {:name => {:type => :text, :boost => 2.0}}, | ||
284 | - {:description => :text}, {:category_full_name => :text}, | ||
285 | - # filtered fields | ||
286 | - {:public => :boolean}, {:environment_id => :integer}, | ||
287 | - {:enabled => :boolean}, {:category_filter => :integer}, | ||
288 | - # ordered/query-boosted fields | ||
289 | - {:price_sortable => :decimal}, {:name_sortable => :string}, | ||
290 | - {:lat => :float}, {:lng => :float}, | ||
291 | - :updated_at, :created_at, | ||
292 | - ], :include => [ | ||
293 | - {:product_category => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}}, | ||
294 | - {:region => {:fields => [:name, :path, :slug, :lat, :lng]}}, | ||
295 | - {:enterprise => {:fields => [:name, :identifier, :address, :nickname, :lat, :lng]}}, | ||
296 | - {:qualifiers => {:fields => [:name]}}, | ||
297 | - {:certifiers => {:fields => [:name]}}, | ||
298 | - ], :facets => facets_option_for_solr, | ||
299 | - :boost => proc{ |p| boost = 1; Boosts.each{ |b| boost = boost * (1 - ((1 - b[2].call(p)) * b[1])) }; boost} | ||
300 | - handle_asynchronously :solr_save | ||
301 | - after_save_reindex [:enterprise], :with => :delayed_job | ||
302 | 234 | ||
303 | end | 235 | end |
app/models/product_category.rb
@@ -11,6 +11,4 @@ class ProductCategory < Category | @@ -11,6 +11,4 @@ class ProductCategory < Category | ||
11 | top_category ? top_category.children : top_level_for(env).select{|c|c.kind_of?(ProductCategory)} | 11 | top_category ? top_category.children : top_level_for(env).select{|c|c.kind_of?(ProductCategory)} |
12 | end | 12 | end |
13 | 13 | ||
14 | - after_save_reindex [:products], :with => :delayed_job | ||
15 | - | ||
16 | end | 14 | end |
app/models/profile.rb
@@ -3,10 +3,20 @@ | @@ -3,10 +3,20 @@ | ||
3 | # which by default is the one returned by Environment:default. | 3 | # which by default is the one returned by Environment:default. |
4 | class Profile < ActiveRecord::Base | 4 | class Profile < ActiveRecord::Base |
5 | 5 | ||
6 | - # use for internationalizable human type names in search facets | ||
7 | - # reimplement on subclasses | ||
8 | - def self.type_name | ||
9 | - _('Profile') | 6 | + SEARCHABLE_FIELDS = { |
7 | + :name => 10, | ||
8 | + :identifier => 5, | ||
9 | + :nickname => 2, | ||
10 | + } | ||
11 | + | ||
12 | + SEARCH_FILTERS = %w[ | ||
13 | + more_recent | ||
14 | + ] | ||
15 | + | ||
16 | + SEARCH_DISPLAYS = %w[compact] | ||
17 | + | ||
18 | + def self.default_search_display | ||
19 | + 'compact' | ||
10 | end | 20 | end |
11 | 21 | ||
12 | module Roles | 22 | module Roles |
@@ -127,18 +137,6 @@ class Profile < ActiveRecord::Base | @@ -127,18 +137,6 @@ class Profile < ActiveRecord::Base | ||
127 | scrap.nil? ? Scrap.all_scraps(self) : Scrap.all_scraps(self).find(scrap) | 137 | scrap.nil? ? Scrap.all_scraps(self) : Scrap.all_scraps(self).find(scrap) |
128 | end | 138 | end |
129 | 139 | ||
130 | - class_inheritable_accessor :extra_index_methods | ||
131 | - self.extra_index_methods = [] | ||
132 | - | ||
133 | - def extra_data_for_index | ||
134 | - self.class.extra_index_methods.map { |meth| meth.to_proc.call(self) }.flatten | ||
135 | - end | ||
136 | - | ||
137 | - def self.extra_data_for_index(sym = nil, &block) | ||
138 | - self.extra_index_methods.push(sym) if sym | ||
139 | - self.extra_index_methods.push(block) if block_given? | ||
140 | - end | ||
141 | - | ||
142 | acts_as_having_settings :field => :data | 140 | acts_as_having_settings :field => :data |
143 | 141 | ||
144 | def settings | 142 | def settings |
@@ -262,7 +260,6 @@ class Profile < ActiveRecord::Base | @@ -262,7 +260,6 @@ class Profile < ActiveRecord::Base | ||
262 | else | 260 | else |
263 | ProfileCategorization.add_category_to_profile(c, self) | 261 | ProfileCategorization.add_category_to_profile(c, self) |
264 | self.categories(true) | 262 | self.categories(true) |
265 | - self.solr_save | ||
266 | end | 263 | end |
267 | self.categories(reload) | 264 | self.categories(reload) |
268 | end | 265 | end |
@@ -894,86 +891,6 @@ private :generate_url, :url_options | @@ -894,86 +891,6 @@ private :generate_url, :url_options | ||
894 | self.active_fields | 891 | self.active_fields |
895 | end | 892 | end |
896 | 893 | ||
897 | - private | ||
898 | - def self.f_categories_label_proc(environment) | ||
899 | - ids = environment.top_level_category_as_facet_ids | ||
900 | - r = Category.find(ids) | ||
901 | - map = {} | ||
902 | - ids.map{ |id| map[id.to_s] = r.detect{|c| c.id == id}.name } | ||
903 | - map | ||
904 | - end | ||
905 | - def self.f_categories_proc(facet, id) | ||
906 | - id = id.to_i | ||
907 | - return if id.zero? | ||
908 | - c = Category.find(id) | ||
909 | - c.name if c.top_ancestor.id == facet[:label_id].to_i or facet[:label_id] == 0 | ||
910 | - end | ||
911 | - def f_categories | ||
912 | - category_ids - [region_id] | ||
913 | - end | ||
914 | - | ||
915 | - def f_region | ||
916 | - self.region_id | ||
917 | - end | ||
918 | - def self.f_region_proc(id) | ||
919 | - c = Region.find(id) | ||
920 | - s = c.parent | ||
921 | - if c and c.kind_of?(City) and s and s.kind_of?(State) and s.acronym | ||
922 | - [c.name, ', ' + s.acronym] | ||
923 | - else | ||
924 | - c.name | ||
925 | - end | ||
926 | - end | ||
927 | - | ||
928 | - def self.f_enabled_proc(enabled) | ||
929 | - enabled = enabled == "true" ? true : false | ||
930 | - enabled ? s_('facets|Enabled') : s_('facets|Not enabled') | ||
931 | - end | ||
932 | - def f_enabled | ||
933 | - self.enabled | ||
934 | - end | ||
935 | - | ||
936 | - def name_sortable # give a different name for solr | ||
937 | - name | ||
938 | - end | ||
939 | - def public | ||
940 | - self.public? | ||
941 | - end | ||
942 | - def category_filter | ||
943 | - categories_including_virtual_ids | ||
944 | - end | ||
945 | - public | ||
946 | - | ||
947 | - acts_as_faceted :fields => { | ||
948 | - :f_enabled => {:label => _('Situation'), :type_if => proc { |klass| klass.kind_of?(Enterprise) }, | ||
949 | - :proc => proc { |id| f_enabled_proc(id) }}, | ||
950 | - :f_region => {:label => _('City'), :proc => proc { |id| f_region_proc(id) }}, | ||
951 | - :f_categories => {:multi => true, :proc => proc {|facet, id| f_categories_proc(facet, id)}, | ||
952 | - :label => proc { |env| f_categories_label_proc(env) }, :label_abbrev => proc{ |env| f_categories_label_abbrev_proc(env) }}, | ||
953 | - }, :category_query => proc { |c| "category_filter:#{c.id}" }, | ||
954 | - :order => [:f_region, :f_categories, :f_enabled] | ||
955 | - | ||
956 | - acts_as_searchable :fields => facets_fields_for_solr + [:extra_data_for_index, | ||
957 | - # searched fields | ||
958 | - {:name => {:type => :text, :boost => 2.0}}, | ||
959 | - {:identifier => :text}, {:nickname => :text}, | ||
960 | - # filtered fields | ||
961 | - {:public => :boolean}, {:environment_id => :integer}, | ||
962 | - {:category_filter => :integer}, | ||
963 | - # ordered/query-boosted fields | ||
964 | - {:name_sortable => :string}, {:user_id => :integer}, | ||
965 | - :enabled, :active, :validated, :public_profile, | ||
966 | - {:lat => :float}, {:lng => :float}, | ||
967 | - :updated_at, :created_at, | ||
968 | - ], | ||
969 | - :include => [ | ||
970 | - {:region => {:fields => [:name, :path, :slug, :lat, :lng]}}, | ||
971 | - {:categories => {:fields => [:name, :path, :slug, :lat, :lng, :acronym, :abbreviation]}}, | ||
972 | - ], :facets => facets_option_for_solr, | ||
973 | - :boost => proc{ |p| 10 if p.enabled } | ||
974 | - after_save_reindex [:articles], :with => :delayed_job | ||
975 | - handle_asynchronously :solr_save | ||
976 | - | ||
977 | def control_panel_settings_button | 894 | def control_panel_settings_button |
978 | {:title => _('Profile Info and settings'), :icon => 'edit-profile'} | 895 | {:title => _('Profile Info and settings'), :icon => 'edit-profile'} |
979 | end | 896 | end |
app/models/qualifier.rb
1 | class Qualifier < ActiveRecord::Base | 1 | class Qualifier < ActiveRecord::Base |
2 | 2 | ||
3 | + SEARCHABLE_FIELDS = { | ||
4 | + :name => 1, | ||
5 | + } | ||
6 | + | ||
3 | belongs_to :environment | 7 | belongs_to :environment |
4 | 8 | ||
5 | has_many :qualifier_certifiers, :dependent => :destroy | 9 | has_many :qualifier_certifiers, :dependent => :destroy |
@@ -15,6 +19,4 @@ class Qualifier < ActiveRecord::Base | @@ -15,6 +19,4 @@ class Qualifier < ActiveRecord::Base | ||
15 | self.name.downcase.transliterate <=> b.name.downcase.transliterate | 19 | self.name.downcase.transliterate <=> b.name.downcase.transliterate |
16 | end | 20 | end |
17 | 21 | ||
18 | - after_save_reindex [:products], :with => :delayed_job | ||
19 | - | ||
20 | end | 22 | end |
app/models/region.rb
@@ -4,12 +4,6 @@ class Region < Category | @@ -4,12 +4,6 @@ class Region < Category | ||
4 | 4 | ||
5 | require_dependency 'enterprise' # enterprises can also be validators | 5 | require_dependency 'enterprise' # enterprises can also be validators |
6 | 6 | ||
7 | - # searches for organizations that could become validators for this region. | ||
8 | - # <tt>search</tt> is passed as is to find_by_contents on Organization. | ||
9 | - def search_possible_validators(search) | ||
10 | - Organization.find_by_contents(search)[:results].docs.reject {|item| self.validator_ids.include?(item.id) } | ||
11 | - end | ||
12 | - | ||
13 | def has_validator? | 7 | def has_validator? |
14 | validators.count > 0 | 8 | validators.count > 0 |
15 | end | 9 | end |
app/models/scrap.rb
app/views/layouts/application-ng.rhtml
@@ -33,7 +33,6 @@ | @@ -33,7 +33,6 @@ | ||
33 | </div> | 33 | </div> |
34 | <div id="wrap-2"> | 34 | <div id="wrap-2"> |
35 | <%= render :partial => 'layouts/user' %> | 35 | <%= render :partial => 'layouts/user' %> |
36 | - | ||
37 | <h1 id="site-title"> | 36 | <h1 id="site-title"> |
38 | <%= theme_site_title %> | 37 | <%= theme_site_title %> |
39 | </h1> | 38 | </h1> |
app/views/map_balloon/product.rhtml
app/views/search/_article.rhtml
@@ -1,12 +0,0 @@ | @@ -1,12 +0,0 @@ | ||
1 | -<li class="search-article-item article-item"> | ||
2 | - <%= link_to(article.title, article.url, :class => "search-result-title") %> | ||
3 | - <div class="search-content-first-column"> | ||
4 | - <%= render :partial => 'image', :object => article %> | ||
5 | - </div> | ||
6 | - <table class="noborder search-content-second-column"> | ||
7 | - <%= render :partial => 'article_common', :object => article %> | ||
8 | - </table> | ||
9 | - <%= render :partial => 'article_last_change', :object => article %> | ||
10 | - | ||
11 | - <div style="clear:both"></div> | ||
12 | -</li> |
app/views/search/_blog.rhtml
@@ -1,24 +0,0 @@ | @@ -1,24 +0,0 @@ | ||
1 | -<li class="search-blog article-item"> | ||
2 | - <%= link_to blog.title, blog.view_url, :class => 'search-result-title' %> | ||
3 | - <div class="search-content-first-column"> | ||
4 | - <%= render :partial => 'image', :object => blog %> | ||
5 | - </div> | ||
6 | - <table class="noborder search-content-second-column"> | ||
7 | - <tr class="search-blog-items"> | ||
8 | - <td class="search-field-label"><%= _("Last posts") %></td> | ||
9 | - | ||
10 | - <% r = blog.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %> | ||
11 | - <td class="<%= "search-field-none" if r.empty? %>"> | ||
12 | - <% r.each do |a| %> | ||
13 | - <%= link_to a.title, a.view_url, :class => 'search-blog-sample-item '+icon_for_article(a) %> | ||
14 | - <% end %> | ||
15 | - <%= _('None') if r.empty? %> | ||
16 | - </td> | ||
17 | - </tr> | ||
18 | - | ||
19 | - <%= render :partial => 'article_common', :object => blog %> | ||
20 | - </table> | ||
21 | - <%= render :partial => 'article_last_change', :object => blog %> | ||
22 | - | ||
23 | - <div style="clear: both;"/></div> | ||
24 | -</li> |
app/views/search/_content.rhtml
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] %> | ||
4 | - <% empty = results.nil? || results.empty? %> | 3 | + <% search = @searches[name] %> |
5 | 4 | ||
6 | - <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if empty %>"> | ||
7 | - <% if not empty %> | ||
8 | - <% partial = partial_for_class(results.first.class.class_name.constantize) %> | 5 | + <div class="search-results-<%= name %> search-results-box <%= "search-results-empty" if search[:results].blank? %>"> |
6 | + <% if !search[:results].blank? %> | ||
9 | 7 | ||
10 | - <% if multiple_search? %> | 8 | + <% if multiple_search?(@searches) %> |
11 | <h3><%= @names[name] %></h3> | 9 | <h3><%= @names[name] %></h3> |
12 | - <% if results.total_entries > SearchController::MULTIPLE_SEARCH_LIMIT %> | ||
13 | - <%= link_to(_('see all (%d)') % results.total_entries, params.merge(:action => name), :class => 'see-more' ) %> | 10 | + <% if search[:results].total_entries > SearchController::MULTIPLE_SEARCH_LIMIT %> |
11 | + <%= link_to(_('see all (%d)') % search[:results].total_entries, params.merge(:action => name), :class => 'see-more' ) %> | ||
14 | <% end %> | 12 | <% end %> |
15 | <% end %> | 13 | <% end %> |
16 | 14 | ||
17 | - <div class="search-results-innerbox search-results-type-<%= partial %> <%= 'common-profile-list-block' if partial == 'profile' %>"> | 15 | + <% display = display_filter(name, params[:display]) %> |
16 | + | ||
17 | + <div class="search-results-innerbox search-results-type-<%= name.to_s.singularize %> <%= 'common-profile-list-block' if [:enterprises, :people, :communities].include?(name) %>"> | ||
18 | <ul> | 18 | <ul> |
19 | - <% results.each do |hit| %> | ||
20 | - <%= render :partial => partial_for_class(hit.class), :object => hit %> | ||
21 | - <% end %> | 19 | + <% search[:results].each do |hit| %> |
20 | + <% partial = partial_for_class(hit.class, display) %> | ||
21 | + <% variable_name = partial.gsub("#{display}_", '').to_sym %> | ||
22 | + <%= render :partial => partial, :locals => {variable_name => hit} %> | ||
23 | + <% end %> | ||
22 | </ul> | 24 | </ul> |
23 | </div> | 25 | </div> |
24 | <% else %> | 26 | <% else %> |
app/views/search/_event.rhtml
@@ -1,25 +0,0 @@ | @@ -1,25 +0,0 @@ | ||
1 | -<li class="search-event-item article-item"> | ||
2 | -<%= link_to(event.title, event.url, :class => "search-result-title") %> | ||
3 | -<div class="search-content-first-column"> | ||
4 | - <%= render :partial => 'image', :object => event %> | ||
5 | -</div> | ||
6 | -<table class="noborder search-content-second-column"> | ||
7 | - <% if event.start_date %> | ||
8 | - <tr class="search-article-event-date"> | ||
9 | - <td class="search-field-label"><%= _('Start date') %></td> | ||
10 | - <td class="article-item-date"><%= event.start_date %></td> | ||
11 | - </tr> | ||
12 | - <% end %> | ||
13 | - <% if event.end_date %> | ||
14 | - <tr class="search-article-event-date"> | ||
15 | - <td class="search-field-label"><%= _('End date') %></td> | ||
16 | - <td class="article-item-date"><%= event.end_date %></td> | ||
17 | - </tr> | ||
18 | - <% end %> | ||
19 | - | ||
20 | - <%= render :partial => 'article_common', :object => event %> | ||
21 | -</table> | ||
22 | -<%= render :partial => 'article_last_change', :object => event %> | ||
23 | - | ||
24 | -<div style="clear: both"></div> | ||
25 | -</li> |
app/views/search/_facets_menu.rhtml
@@ -1,36 +0,0 @@ | @@ -1,36 +0,0 @@ | ||
1 | -<% less_options_limit = 8 %> | ||
2 | - | ||
3 | -<div id="facets-menu"> | ||
4 | - <% @asset_class.map_facets_for(environment).each do |facet| %> | ||
5 | - | ||
6 | - <div id="facet-menu-<%= facet[:id].to_s %>" class="facet-menu"> | ||
7 | - <div class="facet-menu-label"> | ||
8 | - <%= @asset_class.facet_label(facet) %> | ||
9 | - </div> | ||
10 | - | ||
11 | - <% results = @asset_class.map_facet_results(facet, params[:facet], @facets, @all_facets, :limit => less_options_limit) %> | ||
12 | - <% facet_count = results.total_entries %> | ||
13 | - | ||
14 | - <% if facet_count > 0 %> | ||
15 | - <div class="facet-menu-options facet-menu-more-options" style="display: none"> | ||
16 | - </div> | ||
17 | - | ||
18 | - <div class="facet-menu-options facet-menu-less-options"> | ||
19 | - <% results.each do |id, label, count| %> | ||
20 | - <%= facet_link_html(facet, params, id, label, count) %><br /> | ||
21 | - <% end %> | ||
22 | - </div> <br /> | ||
23 | - | ||
24 | - <% if facet_count > less_options_limit %> | ||
25 | - <%= link_to_function _("Options"), | ||
26 | - "facet_options_toggle('#{facet[:id].to_s}', '#{url_for(params.merge(:action => 'facets_browse', :facet_id => facet[:id], :asset => @asset, :escape => false))}'); " + | ||
27 | - "jQuery(this).toggleClass('facet-less-options')", :class => "facet-options-toggle" %> | ||
28 | - <br /> | ||
29 | - <% end %> | ||
30 | - | ||
31 | - <% else %> | ||
32 | - <span class="facet-any-result-found"><%= _("No filter available") %></span> | ||
33 | - <% end %> | ||
34 | - </div> | ||
35 | - <% end %> | ||
36 | -</div> |
app/views/search/_facets_unselect_menu.rhtml
app/views/search/_folder.rhtml
@@ -1,24 +0,0 @@ | @@ -1,24 +0,0 @@ | ||
1 | -<li class="search-folder-item article-item"> | ||
2 | - <%= link_to folder.title, folder.view_url, :class => 'search-result-title' %> | ||
3 | - <div class="search-content-first-column"> | ||
4 | - <%= render :partial => 'image', :object => folder %> | ||
5 | - </div> | ||
6 | - <table class="noborder search-content-second-column"> | ||
7 | - <tr class="search-folder-items"> | ||
8 | - <td class="search-field-label"><%= _("Last items") %></td> | ||
9 | - | ||
10 | - <% r = folder.children.last(3) %> | ||
11 | - <td class="<%= "search-field-none" if r.empty? %>"> | ||
12 | - <% r.each do |a| %> | ||
13 | - <%= link_to a.title, a.view_url, :class => 'search-folder-sample-item '+icon_for_article(a) %> | ||
14 | - <% end %> | ||
15 | - <%= _('None') if r.empty? %> | ||
16 | - </td> | ||
17 | - </tr> | ||
18 | - | ||
19 | - <%= render :partial => 'article_common', :object => folder %> | ||
20 | - </table> | ||
21 | - <%= render :partial => 'article_last_change', :object => folder %> | ||
22 | - | ||
23 | - <div style="clear:both"></div> | ||
24 | -</li> |
app/views/search/_forum.rhtml
@@ -1,24 +0,0 @@ | @@ -1,24 +0,0 @@ | ||
1 | -<li class="search-forum-item article-item"> | ||
2 | - <%= link_to forum.title, forum.view_url, :class => 'search-result-title' %> | ||
3 | - <div class="search-content-first-column"> | ||
4 | - <%= render :partial => 'image', :object => forum %> | ||
5 | - </div> | ||
6 | - <table class="noborder search-content-second-column"> | ||
7 | - <tr class="search-forum-items"> | ||
8 | - <td class="search-field-label"><%= _("Last topics") %></td> | ||
9 | - | ||
10 | - <% r = forum.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %> | ||
11 | - <td class="<%= "search-field-none" if r.empty? %>"> | ||
12 | - <% r.each do |a| %> | ||
13 | - <%= link_to a.title, a.view_url, :class => 'search-forum-sample-item '+icon_for_article(a) %> | ||
14 | - <% end %> | ||
15 | - <%= _('None') if r.empty? %> | ||
16 | - </td> | ||
17 | - </tr> | ||
18 | - | ||
19 | - <%= render :partial => 'article_common', :object => forum %> | ||
20 | - </table> | ||
21 | - <%= render :partial => 'article_last_change', :object => forum %> | ||
22 | - | ||
23 | - <div style="clear:both"></div> | ||
24 | -</li> |
@@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
1 | +<li class="search-article-item article-item"> | ||
2 | + <%= link_to(article.title, article.url, :class => "search-result-title") %> | ||
3 | + <div class="search-content-first-column"> | ||
4 | + <%= render :partial => 'image', :object => article %> | ||
5 | + </div> | ||
6 | + <table class="noborder search-content-second-column"> | ||
7 | + <%= render :partial => 'article_common', :object => article %> | ||
8 | + </table> | ||
9 | + <%= render :partial => 'article_last_change', :object => article %> | ||
10 | + | ||
11 | + <div style="clear:both"></div> | ||
12 | +</li> |
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +<li class="search-blog article-item"> | ||
2 | + <%= link_to blog.title, blog.view_url, :class => 'search-result-title' %> | ||
3 | + <div class="search-content-first-column"> | ||
4 | + <%= render :partial => 'image', :object => blog %> | ||
5 | + </div> | ||
6 | + <table class="noborder search-content-second-column"> | ||
7 | + <tr class="search-blog-items"> | ||
8 | + <td class="search-field-label"><%= _("Last posts") %></td> | ||
9 | + | ||
10 | + <% r = blog.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %> | ||
11 | + <td class="<%= "search-field-none" if r.empty? %>"> | ||
12 | + <% r.each do |a| %> | ||
13 | + <%= link_to a.title, a.view_url, :class => 'search-blog-sample-item '+icon_for_article(a) %> | ||
14 | + <% end %> | ||
15 | + <%= _('None') if r.empty? %> | ||
16 | + </td> | ||
17 | + </tr> | ||
18 | + | ||
19 | + <%= render :partial => 'article_common', :object => blog %> | ||
20 | + </table> | ||
21 | + <%= render :partial => 'article_last_change', :object => blog %> | ||
22 | + | ||
23 | + <div style="clear: both;"/></div> | ||
24 | +</li> |
@@ -0,0 +1,38 @@ | @@ -0,0 +1,38 @@ | ||
1 | +<li class="search-profile-item"> | ||
2 | + <div class="search-enterprise-item"> | ||
3 | + <div class="search-enterprise-item-column-left"> | ||
4 | + <%= profile_image_link enterprise, :portrait, 'div', | ||
5 | + @filter == 'more_recent' ? enterprise.send(@filter + '_label') + show_date(enterprise.created_at) : enterprise.send(@filter + '_label') %> | ||
6 | + </div> | ||
7 | + <div class="search-enterprise-item-column-right"> | ||
8 | + <%= link_to_homepage(enterprise.name, enterprise.identifier, :class => "search-result-title") %> | ||
9 | + <div class="search-enterprise-description"> | ||
10 | + <% if enterprise.description %> | ||
11 | + <% body_stripped = strip_tags(enterprise.description) %> | ||
12 | + <% elsif enterprise.home_page and enterprise.home_page.body %> | ||
13 | + <% body_stripped = strip_tags(enterprise.home_page.body) %> | ||
14 | + <% end %> | ||
15 | + <%= excerpt(body_stripped, body_stripped.first(3), 200) if body_stripped %> | ||
16 | + </div> | ||
17 | + <div class="search-enterprise-region"> | ||
18 | + <span class="search-enterprise-region-label"><%= _("City") %></span> | ||
19 | + <% if enterprise.region %> | ||
20 | + <span class="search-enterprise-region-name"><%= city_with_state(enterprise.region) %></span> | ||
21 | + <% end %> | ||
22 | + </div> | ||
23 | + | ||
24 | + <div class="search-enterprise-categorization"> | ||
25 | + <% enterprise.top_level_categorization.each do |parent, children| %> | ||
26 | + <div class="search-enterprise-category-<%=parent.id%> search-enterprise-category"> | ||
27 | + <span class="search-enterprise-categorization-parent"><%= parent.name %></span> | ||
28 | + <span class="search-enterprise-categorization-children"> | ||
29 | + <%= children.collect(&:name).join(', ') %> | ||
30 | + </span> | ||
31 | + </div> | ||
32 | + <% end %> | ||
33 | + </div> | ||
34 | + </div> | ||
35 | + | ||
36 | + <hr class="clearfix" /> | ||
37 | + </div> | ||
38 | +</li> |
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +<li class="search-event-item article-item"> | ||
2 | +<%= link_to(event.title, event.url, :class => "search-result-title") %> | ||
3 | +<div class="search-content-first-column"> | ||
4 | + <%= render :partial => 'image', :object => event %> | ||
5 | +</div> | ||
6 | +<table class="noborder search-content-second-column"> | ||
7 | + <% if event.start_date %> | ||
8 | + <tr class="search-article-event-date"> | ||
9 | + <td class="search-field-label"><%= _('Start date') %></td> | ||
10 | + <td class="article-item-date"><%= event.start_date %></td> | ||
11 | + </tr> | ||
12 | + <% end %> | ||
13 | + <% if event.end_date %> | ||
14 | + <tr class="search-article-event-date"> | ||
15 | + <td class="search-field-label"><%= _('End date') %></td> | ||
16 | + <td class="article-item-date"><%= event.end_date %></td> | ||
17 | + </tr> | ||
18 | + <% end %> | ||
19 | + | ||
20 | + <%= render :partial => 'article_common', :object => event %> | ||
21 | +</table> | ||
22 | +<%= render :partial => 'article_last_change', :object => event %> | ||
23 | + | ||
24 | +<div style="clear: both"></div> | ||
25 | +</li> |
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +<li class="search-folder-item article-item"> | ||
2 | + <%= link_to folder.title, folder.view_url, :class => 'search-result-title' %> | ||
3 | + <div class="search-content-first-column"> | ||
4 | + <%= render :partial => 'image', :object => folder %> | ||
5 | + </div> | ||
6 | + <table class="noborder search-content-second-column"> | ||
7 | + <tr class="search-folder-items"> | ||
8 | + <td class="search-field-label"><%= _("Last items") %></td> | ||
9 | + | ||
10 | + <% r = folder.children.last(3) %> | ||
11 | + <td class="<%= "search-field-none" if r.empty? %>"> | ||
12 | + <% r.each do |a| %> | ||
13 | + <%= link_to a.title, a.view_url, :class => 'search-folder-sample-item '+icon_for_article(a) %> | ||
14 | + <% end %> | ||
15 | + <%= _('None') if r.empty? %> | ||
16 | + </td> | ||
17 | + </tr> | ||
18 | + | ||
19 | + <%= render :partial => 'article_common', :object => folder %> | ||
20 | + </table> | ||
21 | + <%= render :partial => 'article_last_change', :object => folder %> | ||
22 | + | ||
23 | + <div style="clear:both"></div> | ||
24 | +</li> |
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +<li class="search-forum-item article-item"> | ||
2 | + <%= link_to forum.title, forum.view_url, :class => 'search-result-title' %> | ||
3 | + <div class="search-content-first-column"> | ||
4 | + <%= render :partial => 'image', :object => forum %> | ||
5 | + </div> | ||
6 | + <table class="noborder search-content-second-column"> | ||
7 | + <tr class="search-forum-items"> | ||
8 | + <td class="search-field-label"><%= _("Last topics") %></td> | ||
9 | + | ||
10 | + <% r = forum.children.find(:all, :order => :updated_at, :conditions => ['type != ?', 'RssFeed']).last(3) %> | ||
11 | + <td class="<%= "search-field-none" if r.empty? %>"> | ||
12 | + <% r.each do |a| %> | ||
13 | + <%= link_to a.title, a.view_url, :class => 'search-forum-sample-item '+icon_for_article(a) %> | ||
14 | + <% end %> | ||
15 | + <%= _('None') if r.empty? %> | ||
16 | + </td> | ||
17 | + </tr> | ||
18 | + | ||
19 | + <%= render :partial => 'article_common', :object => forum %> | ||
20 | + </table> | ||
21 | + <%= render :partial => 'article_last_change', :object => forum %> | ||
22 | + | ||
23 | + <div style="clear:both"></div> | ||
24 | +</li> |
@@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
1 | +<li class="search-gallery article-item"> | ||
2 | + <%= link_to gallery.title, gallery.view_url, :class => 'search-result-title' %> | ||
3 | + <div class="search-content-first-column"> | ||
4 | + <%= render :partial => 'image', :object => gallery %> | ||
5 | + </div> | ||
6 | + <table class="noborder search-content-second-column"> | ||
7 | + <%= render :partial => 'article_common', :object => gallery %> | ||
8 | + </table> | ||
9 | + <%= render :partial => 'article_last_change', :object => gallery %> | ||
10 | + | ||
11 | + <div style="clear: both"></div> | ||
12 | +</li> | ||
13 | + |
@@ -0,0 +1,85 @@ | @@ -0,0 +1,85 @@ | ||
1 | +<% extra_content = @plugins.dispatch(:asset_product_extras, product).collect { |content| instance_eval(&content) } %> | ||
2 | +<% extra_properties = @plugins.dispatch(:asset_product_properties, product)%> | ||
3 | + | ||
4 | +<li class="search-product-item <%= 'highlighted' if product.highlighted? %>"> | ||
5 | + | ||
6 | + <div class="search-product-item-first-column"> | ||
7 | + <%= render :partial => 'search/image', :object => product %> | ||
8 | + | ||
9 | + <% if product.available %> | ||
10 | + <% if product.price && product.price > 0 %> | ||
11 | + <% has_discount = product.discount && product.discount > 0 %> | ||
12 | + <% if product.price %> | ||
13 | + <span class="search-product-price-textid"><%=_("from") if has_discount %></span><%= price_span(product.price, :class => "search-product-price " + (has_discount ? 'with-discount' : '')) %> | ||
14 | + <% if has_discount %> | ||
15 | + <span class="search-product-price-textid"><%=_("by")%></span><%= price_span(product.price_with_discount, :class => "search-product-price") %> | ||
16 | + <% end %> | ||
17 | + <% if product.unit %> | ||
18 | + <span class="search-product-unit"> <%= _('/') %> <%= product.unit.name %></span> | ||
19 | + <% end %> | ||
20 | + <% end %> | ||
21 | + <div class="search-product-inputs-info"> | ||
22 | + <% if p = product.percentage_from_solidarity_economy %> | ||
23 | + <div class="search-product-percentage-from-solidarity-economy search-product-ecosol-percentage-icon-<%= p[0].to_s %>" | ||
24 | + title="<%=_('Percentage of inputs from solidarity economy')%>"> | ||
25 | + <%= p[1] %> | ||
26 | + </div> | ||
27 | + <% end %> | ||
28 | + | ||
29 | + <% if product.price_described? %> | ||
30 | + <% title = (product.inputs.relevant_to_price + product.price_details).map{ |i| | ||
31 | + '<div class="search-product-input-dots-to-price">' + | ||
32 | + '<div class="search-product-input-name">' + i.name + '</div>' + | ||
33 | + price_span(i.price, :class => 'search-product-input-price') + | ||
34 | + '</div>' }.join('') %> | ||
35 | + <%= link_to_function _("Open Price"), '', :title => title, :class => "search-product-price-details" %> | ||
36 | + <% end %> | ||
37 | + </div> | ||
38 | + <% end %> | ||
39 | + <% else %> | ||
40 | + <span class="product-not-available"><%= _('Not available') %></div> | ||
41 | + <% end %> | ||
42 | + | ||
43 | + </div> | ||
44 | + <div class="search-product-item-second-column"> | ||
45 | + <%= link_to_product product, :class => 'search-result-title' %> | ||
46 | + <div class="search-product-supplier"> | ||
47 | + <span class="search-field-label"><%= _('Supplier') %> </span><%= link_to_homepage(product.enterprise.name, product.enterprise.identifier) %> | ||
48 | + </div> | ||
49 | + <div class="search-product-description"> | ||
50 | + <% if product.description %> | ||
51 | + <% desc_stripped = strip_tags(product.description) %> | ||
52 | + <span class="search-field-label"><%= _('Description') %> </span><%= excerpt(desc_stripped, desc_stripped.first(3), 300) %> | ||
53 | + <% end %> | ||
54 | + </div> | ||
55 | + </div> | ||
56 | + <div class="search-product-item-third-column"> | ||
57 | + <div class="search-product-region"> | ||
58 | + <% if product.enterprise.region %> | ||
59 | + <span class="search-field-label"><%= _('City') %></span> | ||
60 | + <br /><%= city_with_state(product.enterprise.region) %> | ||
61 | + <% end %> | ||
62 | + </div> | ||
63 | + <div class="search-product-qualifiers"> | ||
64 | + <% if product.product_qualifiers.count > 0 %> | ||
65 | + <span class="search-field-label"><%= _('Qualifiers') %></span> | ||
66 | + <% product.product_qualifiers.each do |pq| %> | ||
67 | + <% if pq.qualifier %> | ||
68 | + <span class="search-product-qualifier"><%= pq.qualifier.name + (pq.certifier.nil? ? _(";") : '') %></span> | ||
69 | + <% end %> | ||
70 | + <% if pq.certifier %> | ||
71 | + <span class="search-product-certifier"> <%= _('cert. ') + pq.certifier.name + _(";") %></span> | ||
72 | + <% end %> | ||
73 | + <% end %> | ||
74 | + <% end %> | ||
75 | + </div> | ||
76 | + </div> | ||
77 | + | ||
78 | + <div style="clear: both"></div> | ||
79 | + | ||
80 | + <%= extra_content.join('\n') %> | ||
81 | + <% extra_properties.each do |property| %> | ||
82 | + <div><%= property[:name] + ': ' + instance_eval(&property[:content]) %></div> | ||
83 | + <% end %> | ||
84 | + | ||
85 | +</li> |
@@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
1 | +<li class="search-text-article-item article-item"> | ||
2 | + <%= link_to(text_article.title, text_article.url, :class => "search-result-title") %> | ||
3 | + | ||
4 | + <div class="search-content-first-column"> | ||
5 | + <%= render :partial => 'image', :object => text_article %> | ||
6 | + </div> | ||
7 | + <table class="noborder search-content-second-column"> | ||
8 | + <%= render :partial => 'article_common', :object => text_article %> | ||
9 | + </table> | ||
10 | + <%= render :partial => 'article_last_change', :object => text_article %> | ||
11 | + | ||
12 | + <div style="clear: both"></div> | ||
13 | +</li> |
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +<li class="search-uploaded-file-item article-item"> | ||
2 | + <%= link_to uploaded_file.filename, uploaded_file.view_url, :class => 'search-result-title' %> | ||
3 | + | ||
4 | + <div class="search-content-first-column"> | ||
5 | + <%= render :partial => 'image', :object => uploaded_file %> | ||
6 | + </div> | ||
7 | + | ||
8 | + <table class="noborder search-content-second-column"> | ||
9 | + <%= render :partial => 'article_author', :object => uploaded_file %> | ||
10 | + <%= render :partial => 'article_description', :object => uploaded_file %> | ||
11 | + | ||
12 | + <% if uploaded_file.parent and uploaded_file.parent.published? %> | ||
13 | + <tr class="search-uploaded-file-parent"> | ||
14 | + <td class="search-field-label"><%= uploaded_file.parent.gallery? ? _("Gallery") : _("Folder") %></td> | ||
15 | + <td><%= link_to uploaded_file.parent.name, uploaded_file.parent.url %></td> | ||
16 | + </tr> | ||
17 | + <% end %> | ||
18 | + | ||
19 | + <%= render :partial => 'article_tags', :object => uploaded_file.tags %> | ||
20 | + <%= render :partial => 'article_categories', :object => uploaded_file.categories %> | ||
21 | + </table> | ||
22 | + <%= render :partial => 'article_last_change', :object => uploaded_file %> | ||
23 | + | ||
24 | + <div style="clear:both"></div> | ||
25 | +</li> |
app/views/search/_gallery.rhtml
@@ -1,13 +0,0 @@ | @@ -1,13 +0,0 @@ | ||
1 | -<li class="search-gallery article-item"> | ||
2 | - <%= link_to gallery.title, gallery.view_url, :class => 'search-result-title' %> | ||
3 | - <div class="search-content-first-column"> | ||
4 | - <%= render :partial => 'image', :object => gallery %> | ||
5 | - </div> | ||
6 | - <table class="noborder search-content-second-column"> | ||
7 | - <%= render :partial => 'article_common', :object => gallery %> | ||
8 | - </table> | ||
9 | - <%= render :partial => 'article_last_change', :object => gallery %> | ||
10 | - | ||
11 | - <div style="clear: both"></div> | ||
12 | -</li> | ||
13 | - |
app/views/search/_google_maps.rhtml
@@ -13,8 +13,8 @@ | @@ -13,8 +13,8 @@ | ||
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| %> | ||
17 | - <% results.each do |item| %> | 16 | + <% @searches.each do |name,search| %> |
17 | + <% search[: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 %>', |
20 | '<%= url_for(:controller => :map_balloon, :action => name.to_s.singularize, :id => item.id) %>'); | 20 | '<%= url_for(:controller => :map_balloon, :action => name.to_s.singularize, :id => item.id) %>'); |
@@ -0,0 +1,53 @@ | @@ -0,0 +1,53 @@ | ||
1 | +<div class="search-image-container"> | ||
2 | + | ||
3 | + <% if image.is_a? UploadedFile and image.filename %> | ||
4 | + <% extension = image.extension %> | ||
5 | + <% if ['jpg', 'jpeg', 'gif', 'png', 'tiff', 'svg'].include? extension %> | ||
6 | + <%= link_to '', image.view_url, :class => "search-image-pic", :style => 'background-image: url(%s)'% image.public_filename(:thumb) %> | ||
7 | + <% if image.width && image.height %> | ||
8 | + <% javascript_tag do %> | ||
9 | + image = jQuery('script').last().parent().find('.search-image-pic'); | ||
10 | + des_width = parseInt(image.css('width')); | ||
11 | + des_height = parseInt(image.css('height')); | ||
12 | + | ||
13 | + width = <%= image.width %>; | ||
14 | + height = <%= image.height %>; | ||
15 | + scale_factor = width > height ? des_width/width : des_height/height; | ||
16 | + | ||
17 | + image.css({'width' : scale_factor*width +'px', 'height' : scale_factor*height+'px'}); | ||
18 | + <% end %> | ||
19 | + <% end %> | ||
20 | + <% elsif ['pdf'].include? extension %> | ||
21 | + <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-pdf' %> | ||
22 | + <% elsif ['doc', 'docx', 'odt', 'rtf', 'txt', 'html', 'htm'].include? extension %> | ||
23 | + <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-vnd-oasis-opendocument-text' %> | ||
24 | + <% elsif ['xls', 'xlsx', 'ods', 'csv', 'tsv', 'tab'].include? extension %> | ||
25 | + <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-vnd-oasis-opendocument-spreadsheet' %> | ||
26 | + <% end %> | ||
27 | + <% elsif image.is_a? Gallery %> | ||
28 | + <div class="search-gallery-items"> | ||
29 | + <% r = image.children.find(:all, :order => :updated_at, :conditions => ['type = ?', 'UploadedFile']).last(3) %> | ||
30 | + <% if r.length > 0 %> | ||
31 | + <% r.each_index do |i| img = r[i] %> | ||
32 | + <%= link_to '', img.view_url, :class => "search-image-pic pic-num#{i+1}", | ||
33 | + :style => 'background-image: url(%s)'% img.public_filename(:thumb) %> | ||
34 | + <% end %> | ||
35 | + <% else %> | ||
36 | + <div class="search-no-image"><span><%= _('No image') %></span></div> | ||
37 | + <% end %> | ||
38 | + </div> | ||
39 | + <% elsif image.is_a? Product %> | ||
40 | + <% if image.image %> | ||
41 | + <div class="zoomable-image"> | ||
42 | + <%= link_to '', product_path(image), :class => "search-image-pic", | ||
43 | + :style => 'background-image: url(%s)'% image.default_image(:thumb) %> | ||
44 | + <%= link_to content_tag(:span, _('Zoom in')), image.image.public_filename, | ||
45 | + :class => 'zoomify-image' %> | ||
46 | + </div> | ||
47 | + <% else %> | ||
48 | + <div class="search-no-image"><span><%= _('No image') %></span></div> | ||
49 | + <% end %> | ||
50 | + <% else %> | ||
51 | + <div class="search-content-type-icon icon-content-<%=image.class.to_s.underscore.dasherize%>"></div> | ||
52 | + <% end %> | ||
53 | +</div> |
app/views/search/_image.rhtml
@@ -1,53 +0,0 @@ | @@ -1,53 +0,0 @@ | ||
1 | -<div class="search-image-container"> | ||
2 | - | ||
3 | - <% if image.is_a? UploadedFile and image.filename %> | ||
4 | - <% extension = image.extension %> | ||
5 | - <% if ['jpg', 'jpeg', 'gif', 'png', 'tiff', 'svg'].include? extension %> | ||
6 | - <%= link_to '', image.view_url, :class => "search-image-pic", :style => 'background-image: url(%s)'% image.public_filename(:thumb) %> | ||
7 | - <% if image.width && image.height %> | ||
8 | - <% javascript_tag do %> | ||
9 | - image = jQuery('script').last().parent().find('.search-image-pic'); | ||
10 | - des_width = parseInt(image.css('width')); | ||
11 | - des_height = parseInt(image.css('height')); | ||
12 | - | ||
13 | - width = <%= image.width %>; | ||
14 | - height = <%= image.height %>; | ||
15 | - scale_factor = width > height ? des_width/width : des_height/height; | ||
16 | - | ||
17 | - image.css({'width' : scale_factor*width +'px', 'height' : scale_factor*height+'px'}); | ||
18 | - <% end %> | ||
19 | - <% end %> | ||
20 | - <% elsif ['pdf'].include? extension %> | ||
21 | - <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-pdf' %> | ||
22 | - <% elsif ['doc', 'docx', 'odt', 'rtf', 'txt', 'html', 'htm'].include? extension %> | ||
23 | - <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-vnd-oasis-opendocument-text' %> | ||
24 | - <% elsif ['xls', 'xlsx', 'ods', 'csv', 'tsv', 'tab'].include? extension %> | ||
25 | - <%= link_to '', image.view_url, :class => 'search-image-pic icon-application-vnd-oasis-opendocument-spreadsheet' %> | ||
26 | - <% end %> | ||
27 | - <% elsif image.is_a? Gallery %> | ||
28 | - <div class="search-gallery-items"> | ||
29 | - <% r = image.children.find(:all, :order => :updated_at, :conditions => ['type = ?', 'UploadedFile']).last(3) %> | ||
30 | - <% if r.length > 0 %> | ||
31 | - <% r.each_index do |i| img = r[i] %> | ||
32 | - <%= link_to '', img.view_url, :class => "search-image-pic pic-num#{i+1}", | ||
33 | - :style => 'background-image: url(%s)'% img.public_filename(:thumb) %> | ||
34 | - <% end %> | ||
35 | - <% else %> | ||
36 | - <div class="search-no-image"><span><%= _('No image') %></span></div> | ||
37 | - <% end %> | ||
38 | - </div> | ||
39 | - <% elsif image.is_a? Product %> | ||
40 | - <% if image.image %> | ||
41 | - <div class="zoomable-image"> | ||
42 | - <%= link_to '', product_path(image), :class => "search-image-pic", | ||
43 | - :style => 'background-image: url(%s)'% image.default_image(:thumb) %> | ||
44 | - <%= link_to content_tag(:span, _('Zoom in')), image.image.public_filename, | ||
45 | - :class => 'zoomify-image' %> | ||
46 | - </div> | ||
47 | - <% else %> | ||
48 | - <div class="search-no-image"><span><%= _('No image') %></span></div> | ||
49 | - <% end %> | ||
50 | - <% else %> | ||
51 | - <div class="search-content-type-icon icon-content-<%=image.class.to_s.underscore.dasherize%>"></div> | ||
52 | - <% end %> | ||
53 | -</div> |
app/views/search/_product.rhtml
@@ -1,85 +0,0 @@ | @@ -1,85 +0,0 @@ | ||
1 | -<% extra_content = @plugins.dispatch(:asset_product_extras, product).collect { |content| instance_eval(&content) } %> | ||
2 | -<% extra_properties = @plugins.dispatch(:asset_product_properties, product)%> | ||
3 | - | ||
4 | -<li class="search-product-item <%= 'highlighted' if product.highlighted? %>"> | ||
5 | - | ||
6 | - <div class="search-product-item-first-column"> | ||
7 | - <%= render :partial => 'search/image', :object => product %> | ||
8 | - | ||
9 | - <% if product.available %> | ||
10 | - <% if product.price && product.price > 0 %> | ||
11 | - <% has_discount = product.discount && product.discount > 0 %> | ||
12 | - <% if product.price %> | ||
13 | - <span class="search-product-price-textid"><%=_("from") if has_discount %></span><%= price_span(product.price, :class => "search-product-price " + (has_discount ? 'with-discount' : '')) %> | ||
14 | - <% if has_discount %> | ||
15 | - <span class="search-product-price-textid"><%=_("by")%></span><%= price_span(product.price_with_discount, :class => "search-product-price") %> | ||
16 | - <% end %> | ||
17 | - <% if product.unit %> | ||
18 | - <span class="search-product-unit"> <%= _('/') %> <%= product.unit.name %></span> | ||
19 | - <% end %> | ||
20 | - <% end %> | ||
21 | - <div class="search-product-inputs-info"> | ||
22 | - <% if p = product.percentage_from_solidarity_economy %> | ||
23 | - <div class="search-product-percentage-from-solidarity-economy search-product-ecosol-percentage-icon-<%= p[0].to_s %>" | ||
24 | - title="<%=_('Percentage of inputs from solidarity economy')%>"> | ||
25 | - <%= p[1] %> | ||
26 | - </div> | ||
27 | - <% end %> | ||
28 | - | ||
29 | - <% if product.price_described? %> | ||
30 | - <% title = (product.inputs.relevant_to_price + product.price_details).map{ |i| | ||
31 | - '<div class="search-product-input-dots-to-price">' + | ||
32 | - '<div class="search-product-input-name">' + i.name + '</div>' + | ||
33 | - price_span(i.price, :class => 'search-product-input-price') + | ||
34 | - '</div>' }.join('') %> | ||
35 | - <%= link_to_function _("Open Price"), '', :title => title, :class => "search-product-price-details" %> | ||
36 | - <% end %> | ||
37 | - </div> | ||
38 | - <% end %> | ||
39 | - <% else %> | ||
40 | - <span class="product-not-available"><%= _('Not available') %></div> | ||
41 | - <% end %> | ||
42 | - | ||
43 | - </div> | ||
44 | - <div class="search-product-item-second-column"> | ||
45 | - <%= link_to_product product, :class => 'search-result-title' %> | ||
46 | - <div class="search-product-supplier"> | ||
47 | - <span class="search-field-label"><%= _('Supplier') %> </span><%= link_to_homepage(product.enterprise.name, product.enterprise.identifier) %> | ||
48 | - </div> | ||
49 | - <div class="search-product-description"> | ||
50 | - <% if product.description %> | ||
51 | - <% desc_stripped = strip_tags(product.description) %> | ||
52 | - <span class="search-field-label"><%= _('Description') %> </span><%= excerpt(desc_stripped, desc_stripped.first(3), 300) %> | ||
53 | - <% end %> | ||
54 | - </div> | ||
55 | - </div> | ||
56 | - <div class="search-product-item-third-column"> | ||
57 | - <div class="search-product-region"> | ||
58 | - <% if product.enterprise.region %> | ||
59 | - <span class="search-field-label"><%= _('City') %></span> | ||
60 | - <br /><%= city_with_state(product.enterprise.region) %> | ||
61 | - <% end %> | ||
62 | - </div> | ||
63 | - <div class="search-product-qualifiers"> | ||
64 | - <% if product.product_qualifiers.count > 0 %> | ||
65 | - <span class="search-field-label"><%= _('Qualifiers') %></span> | ||
66 | - <% product.product_qualifiers.each do |pq| %> | ||
67 | - <% if pq.qualifier %> | ||
68 | - <span class="search-product-qualifier"><%= pq.qualifier.name + (pq.certifier.nil? ? _(";") : '') %></span> | ||
69 | - <% end %> | ||
70 | - <% if pq.certifier %> | ||
71 | - <span class="search-product-certifier"> <%= _('cert. ') + pq.certifier.name + _(";") %></span> | ||
72 | - <% end %> | ||
73 | - <% end %> | ||
74 | - <% end %> | ||
75 | - </div> | ||
76 | - </div> | ||
77 | - | ||
78 | - <div style="clear: both"></div> | ||
79 | - | ||
80 | - <%= extra_content.join('\n') %> | ||
81 | - <% extra_properties.each do |property| %> | ||
82 | - <div><%= property[:name] + ': ' + instance_eval(&property[:content]) %></div> | ||
83 | - <% end %> | ||
84 | - | ||
85 | -</li> |
app/views/search/_profile.rhtml
@@ -1,42 +0,0 @@ | @@ -1,42 +0,0 @@ | ||
1 | -<li class="search-profile-item"> | ||
2 | -<% if @empty_query or multiple_search? or !profile.enterprise? %> | ||
3 | - <%= profile_image_link profile, :portrait, 'div', | ||
4 | - @filter == 'more_recent' ? profile.send(@filter + '_label') + show_date(profile.created_at) : profile.send(@filter + '_label') %> | ||
5 | -<% else %> | ||
6 | - <div class="search-enterprise-item"> | ||
7 | - <div class="search-enterprise-item-column-left"> | ||
8 | - <%= profile_image_link profile, :portrait, 'div' %> | ||
9 | - </div> | ||
10 | - <div class="search-enterprise-item-column-right"> | ||
11 | - <%= link_to_homepage(profile.name, profile.identifier, :class => "search-result-title") %> | ||
12 | - <div class="search-enterprise-description"> | ||
13 | - <% if profile.description %> | ||
14 | - <% body_stripped = strip_tags(profile.description) %> | ||
15 | - <% elsif profile.home_page and profile.home_page.body %> | ||
16 | - <% body_stripped = strip_tags(profile.home_page.body) %> | ||
17 | - <% end %> | ||
18 | - <%= excerpt(body_stripped, body_stripped.first(3), 200) if body_stripped %> | ||
19 | - </div> | ||
20 | - <div class="search-enterprise-region"> | ||
21 | - <span class="search-enterprise-region-label"><%= _("City") %></span> | ||
22 | - <% if profile.region %> | ||
23 | - <span class="search-enterprise-region-name"><%= city_with_state(profile.region) %></span> | ||
24 | - <% end %> | ||
25 | - </div> | ||
26 | - | ||
27 | - <div class="search-enterprise-categorization"> | ||
28 | - <% profile.top_level_categorization.each do |parent, children| %> | ||
29 | - <div class="search-enterprise-category-<%=parent.id%> search-enterprise-category"> | ||
30 | - <span class="search-enterprise-categorization-parent"><%= parent.name %></span> | ||
31 | - <span class="search-enterprise-categorization-children"> | ||
32 | - <%= children.collect(&:name).join(', ') %> | ||
33 | - </span> | ||
34 | - </div> | ||
35 | - <% end %> | ||
36 | - </div> | ||
37 | - </div> | ||
38 | - | ||
39 | - <hr class="clearfix" /> | ||
40 | - </div> | ||
41 | -<% end %> | ||
42 | -</li> |
app/views/search/_results_header.rhtml
1 | -<div class="search-results-header <%= "search-no-results" if @results[@asset].nil? or @results[@asset].length == 0 %>"> | ||
2 | - <% if !@empty_query %> | ||
3 | - <div class="search-results-header-information"> | ||
4 | - <% if @results[@asset].total_entries > 0 %> | ||
5 | - <%= label_total_found(@asset, @results[@asset].total_entries) %> | ||
6 | - <% if params[:display] != 'map' %> | ||
7 | - <span class="current-page"><%= _("Showing page %s of %s") % [@results[@asset].current_page, @results[@asset].total_pages] %></span> | ||
8 | - <% end %> | ||
9 | - <% end %> | ||
10 | - </div> | ||
11 | - | ||
12 | - <div class="search-results-header-facets-order-by"> | ||
13 | - <%= facets_unselect_menu(@asset) %> | ||
14 | - <%= order_by(@asset) if params[:display] != 'map' %> | ||
15 | - </div> | ||
16 | - <% else %> | ||
17 | - <div id='search-filter-title'><%= @filter_title if @filter_title %></div> | ||
18 | - <% end %> | ||
19 | - | 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(@asset, @filter) %></div> | ||
3 | + <%= display_selector(@asset, params[:display]) %> | ||
4 | + <%= filter_selector(@asset, @filter) %> | ||
20 | <div style="clear: both"></div> | 5 | <div style="clear: both"></div> |
21 | </div> | 6 | </div> |
app/views/search/_search_form.rhtml
@@ -4,16 +4,7 @@ | @@ -4,16 +4,7 @@ | ||
4 | :method => 'get', :class => 'search_form' ) do %> | 4 | :method => 'get', :class => 'search_form' ) do %> |
5 | 5 | ||
6 | <%= hidden_field_tag :display, params[:display] %> | 6 | <%= hidden_field_tag :display, params[:display] %> |
7 | - | ||
8 | - <% params_uri = CGI::unescape(request.request_uri) %> | ||
9 | - <% if params_uri.index('?') %> | ||
10 | - <% params_uri[(params_uri.index('?')+1)..-1].to_s.split("&").each do |part| %> | ||
11 | - <% if part.start_with? "facet" %> | ||
12 | - <% name_value = part.split("=") %> | ||
13 | - <%= hidden_field_tag name_value[0], name_value[1] %> | ||
14 | - <% end %> | ||
15 | - <% end %> | ||
16 | - <% end %> | 7 | + <%= hidden_field_tag :filter, params[:filter] %> |
17 | 8 | ||
18 | <div class="search-field"> | 9 | <div class="search-field"> |
19 | <span class="formfield"> | 10 | <span class="formfield"> |
@@ -24,6 +15,8 @@ | @@ -24,6 +15,8 @@ | ||
24 | <%= submit_button(:search, _('Search')) %> | 15 | <%= submit_button(:search, _('Search')) %> |
25 | </div> | 16 | </div> |
26 | 17 | ||
18 | + <%= render :partial => 'search_form_extra_fields' %> | ||
19 | + | ||
27 | <% end %> | 20 | <% end %> |
28 | 21 | ||
29 | <% if @empty_query %> | 22 | <% if @empty_query %> |
@@ -0,0 +1,6 @@ | @@ -0,0 +1,6 @@ | ||
1 | +<%# | ||
2 | + This partial serves the search engine plugins to fill in any extra | ||
3 | + fields they need in the search form. The search engine plugin must define a | ||
4 | + partial named like this one and the plugin's view path will override the | ||
5 | + default view path which will render the plugin file instead of this one. | ||
6 | +%> |
app/views/search/_text_article.rhtml
@@ -1,13 +0,0 @@ | @@ -1,13 +0,0 @@ | ||
1 | -<li class="search-text-article-item article-item"> | ||
2 | - <%= link_to(text_article.title, text_article.url, :class => "search-result-title") %> | ||
3 | - | ||
4 | - <div class="search-content-first-column"> | ||
5 | - <%= render :partial => 'image', :object => text_article %> | ||
6 | - </div> | ||
7 | - <table class="noborder search-content-second-column"> | ||
8 | - <%= render :partial => 'article_common', :object => text_article %> | ||
9 | - </table> | ||
10 | - <%= render :partial => 'article_last_change', :object => text_article %> | ||
11 | - | ||
12 | - <div style="clear: both"></div> | ||
13 | -</li> |
app/views/search/_uploaded_file.rhtml
@@ -1,25 +0,0 @@ | @@ -1,25 +0,0 @@ | ||
1 | -<li class="search-uploaded-file-item article-item"> | ||
2 | - <%= link_to uploaded_file.filename, uploaded_file.view_url, :class => 'search-result-title' %> | ||
3 | - | ||
4 | - <div class="search-content-first-column"> | ||
5 | - <%= render :partial => 'image', :object => uploaded_file %> | ||
6 | - </div> | ||
7 | - | ||
8 | - <table class="noborder search-content-second-column"> | ||
9 | - <%= render :partial => 'article_author', :object => uploaded_file %> | ||
10 | - <%= render :partial => 'article_description', :object => uploaded_file %> | ||
11 | - | ||
12 | - <% if uploaded_file.parent and uploaded_file.parent.published? %> | ||
13 | - <tr class="search-uploaded-file-parent"> | ||
14 | - <td class="search-field-label"><%= uploaded_file.parent.gallery? ? _("Gallery") : _("Folder") %></td> | ||
15 | - <td><%= link_to uploaded_file.parent.name, uploaded_file.parent.url %></td> | ||
16 | - </tr> | ||
17 | - <% end %> | ||
18 | - | ||
19 | - <%= render :partial => 'article_tags', :object => uploaded_file.tags %> | ||
20 | - <%= render :partial => 'article_categories', :object => uploaded_file.categories %> | ||
21 | - </table> | ||
22 | - <%= render :partial => 'article_last_change', :object => uploaded_file %> | ||
23 | - | ||
24 | - <div style="clear:both"></div> | ||
25 | -</li> |
app/views/search/articles.rhtml
@@ -1,17 +0,0 @@ | @@ -1,17 +0,0 @@ | ||
1 | -<%= search_page_title( @titles[:articles], @category ) %> | ||
2 | - | ||
3 | -<div id="search-column-left"> | ||
4 | - <% if !@empty_query %> | ||
5 | - <%= facets_menu(:articles, @facets) %> | ||
6 | - <% end %> | ||
7 | -</div> | ||
8 | - | ||
9 | -<div id="search-column-right"> | ||
10 | - <%= render :partial => 'search_form', :locals => { :hint => _('Type the title, author or content desired') } %> | ||
11 | - <%= render :partial => 'results_header' %> | ||
12 | - | ||
13 | - <%= display_results %> | ||
14 | - <%= pagination_links @results[:articles] %> | ||
15 | -</div> | ||
16 | - | ||
17 | -<div style="clear: both"></div> |
app/views/search/category_index.rhtml
@@ -0,0 +1,28 @@ | @@ -0,0 +1,28 @@ | ||
1 | +<div id="search-page" class="<%= "view-category" if @category %>"> | ||
2 | + | ||
3 | + <% if @category %> | ||
4 | + <div id="category-image"><%= image_tag(@category.image.public_filename(:thumb), :id => 'category-image') if @category.image %></div> | ||
5 | + <% end %> | ||
6 | + | ||
7 | + <h1><%= _("Category Index") %></h1> | ||
8 | + <%= category_context(@category, params) %> | ||
9 | + <%= display_results @searches %> | ||
10 | + | ||
11 | + <div id="category-childs"> | ||
12 | + <% if @category %> | ||
13 | + <h2> <%= _('Sub-categories') %> </h2> | ||
14 | + <% if @category.children.empty? %> | ||
15 | + <strong id="cat-no-child"><%= _('No sub-categories') %></strong> | ||
16 | + <% else %> | ||
17 | + <ul> | ||
18 | + <% @category.children.each do |c| %> | ||
19 | + <li> <%= link_to_category c, false %> </li> | ||
20 | + <% end %> | ||
21 | + </ul> | ||
22 | + <% end %> | ||
23 | + <% end %> | ||
24 | + </div> | ||
25 | + | ||
26 | +</div> | ||
27 | + | ||
28 | +<div style="clear: both"></div> |
app/views/search/communities.rhtml
@@ -1,25 +0,0 @@ | @@ -1,25 +0,0 @@ | ||
1 | -<%= search_page_title( @titles[:communities], @category ) %> | ||
2 | - | ||
3 | -<div id='search-column-left'> | ||
4 | - <% if logged_in? %> | ||
5 | - <% button_bar do %> | ||
6 | - <%# FIXME shouldn't the user create the community in the current environment instead of going to its home environment? %> | ||
7 | - <%= button(:add, __('New community'), user.url.merge(:controller => 'memberships', :action => 'new_community', :profile => user.identifier)) %> | ||
8 | - <% end %> | ||
9 | - <% end %> | ||
10 | - | ||
11 | - <% if !@empty_query %> | ||
12 | - <%= facets_menu(:communities, @facets) %> | ||
13 | - <% end %> | ||
14 | -</div> | ||
15 | - | ||
16 | -<div id='search-column-right'> | ||
17 | - <%= render :partial => 'search_form', :locals => { :hint => _("Type words about the community you're looking for") } %> | ||
18 | - <%= render :partial => 'results_header' %> | ||
19 | - | ||
20 | - <%= display_results %> | ||
21 | - <%= pagination_links @results.values.first %> | ||
22 | -</div> | ||
23 | - | ||
24 | -<div style="clear: both"></div> | ||
25 | - |
app/views/search/contents.rhtml
app/views/search/enterprises.rhtml
@@ -1,28 +0,0 @@ | @@ -1,28 +0,0 @@ | ||
1 | -<%= search_page_title( @titles[:enterprises], @category ) %> | ||
2 | - | ||
3 | -<div id="search-column-left"> | ||
4 | - <% if logged_in? && environment.enabled?('enterprise_registration') %> | ||
5 | - <% button_bar do %> | ||
6 | - <%= button(:add, __('New enterprise'), {:controller => 'enterprise_registration'}) %> | ||
7 | - <% end %> | ||
8 | - <% end %> | ||
9 | - | ||
10 | - <% if !@empty_query %> | ||
11 | - <% button_bar do %> | ||
12 | - <%= display_map_list_button %> | ||
13 | - <% end %> | ||
14 | - <%= facets_menu(:enterprises, @facets) %> | ||
15 | - <% end %> | ||
16 | -</div> | ||
17 | - | ||
18 | -<div id="search-column-right"> | ||
19 | - <%= render :partial => 'search_form', :locals => { :hint => _("Type words about the enterprise you're looking for") } %> | ||
20 | - <%= render :partial => 'results_header' %> | ||
21 | - | ||
22 | - <%= display_results(true) %> | ||
23 | - <% if params[:display] != 'map' %> | ||
24 | - <%= pagination_links @results[:enterprises] %> | ||
25 | - <% end %> | ||
26 | -</div> | ||
27 | - | ||
28 | -<div style="clear: both"></div> |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +<%= render :partial => 'events/agenda' %> |
app/views/search/events.rhtml
app/views/search/facets_browse.rhtml
@@ -1,8 +0,0 @@ | @@ -1,8 +0,0 @@ | ||
1 | -<% results = @asset_class.map_facet_results(@facet, params[:facet], @facets, @all_facets) %> | ||
2 | - | ||
3 | -<% array = [] %> | ||
4 | -<% @asset_class.facet_result_sort(@facet, results, :alphabetically).each do |id, label, count| %> | ||
5 | - <% array << {:id => id, :name => facet_link_html(@facet, params.merge(:controller => 'search', :action => @asset), id, label, count)} %> | ||
6 | -<% end %> | ||
7 | - | ||
8 | -<%= facet_javascript('facet-input-'+@facet[:id].to_s, @facet, array) %> |
app/views/search/index.rhtml
@@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
7 | <%= search_page_title(_('Search Results'), @category) %> | 7 | <%= search_page_title(_('Search Results'), @category) %> |
8 | <%= render :partial => 'search_form', :locals => { :hint => '' } %> | 8 | <%= render :partial => 'search_form', :locals => { :hint => '' } %> |
9 | <%= category_context(@category, params) %> | 9 | <%= category_context(@category, params) %> |
10 | - <%= display_results %> | 10 | + <%= display_results(@searches, @asset) %> |
11 | 11 | ||
12 | <div id="category-childs"> | 12 | <div id="category-childs"> |
13 | <% if @category %> | 13 | <% if @category %> |
app/views/search/people.rhtml
@@ -1,19 +0,0 @@ | @@ -1,19 +0,0 @@ | ||
1 | -<%= search_page_title( @titles[:people], @category ) %> | ||
2 | - | ||
3 | -<div id='search-column-left'> | ||
4 | - <% if !@empty_query %> | ||
5 | - <%= facets_menu(:people, @facets) %> | ||
6 | - <% end %> | ||
7 | -</div> | ||
8 | - | ||
9 | -<div id='search-column-right'> | ||
10 | - <%= render :partial => 'search_form', :locals => { :hint => _("Type words about the person you're looking for") } %> | ||
11 | - <%= render :partial => 'results_header' %> | ||
12 | - | ||
13 | - <%= display_results %> | ||
14 | - <% if params[:display] != 'map' %> | ||
15 | - <%= pagination_links @results.values.first %> | ||
16 | - <% end %> | ||
17 | -</div> | ||
18 | - | ||
19 | -<div style="clear: both"></div> |
app/views/search/products.rhtml
@@ -1,26 +0,0 @@ | @@ -1,26 +0,0 @@ | ||
1 | -<%= search_page_title( @titles[:products], @category ) %> | ||
2 | - | ||
3 | -<div id="search-column-left"> | ||
4 | - <% if !@empty_query %> | ||
5 | - <% button_bar do %> | ||
6 | - <%= display_map_list_button %> | ||
7 | -<% end %> | ||
8 | - <%= facets_menu(:products, @facets) %> | ||
9 | -<% end %> | ||
10 | -</div> | ||
11 | - | ||
12 | -<div id="search-column-right"> | ||
13 | - <%= render :partial => 'search_form', :locals => { :hint => _('Type the product, service, city or qualifier desired') } %> | ||
14 | - <%= render :partial => 'results_header' %> | ||
15 | - | ||
16 | - <%= display_results(true) %> | ||
17 | - <% if !@one_page and params[:display] != 'map' %> | ||
18 | - <%= pagination_links @results[:products] %> | ||
19 | -<% end %> | ||
20 | -</div> | ||
21 | - | ||
22 | -<% javascript_tag do %> | ||
23 | - jQuery('.search-product-price-details').altBeautify(); | ||
24 | -<% end %> | ||
25 | - | ||
26 | -<div style="clear: both"></div> |
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +<%= search_page_title( @titles[@asset], @category ) %> | ||
2 | + | ||
3 | +<%= render :partial => 'search_form', :locals => { :hint => _("Type words about the %s you're looking for") % @asset.to_s.singularize } %> | ||
4 | +<%= render :partial => 'results_header' %> | ||
5 | + | ||
6 | +<%= display_results(@searches, @asset) %> | ||
7 | +<% if params[:display] != 'map' %> | ||
8 | + <%= pagination_links @searches[@asset][:results] %> | ||
9 | +<% end %> | ||
10 | + | ||
11 | +<div style="clear: both"></div> | ||
12 | + | ||
13 | +<% if @asset == :product %> | ||
14 | + <% javascript_tag do %> | ||
15 | + jQuery('.search-product-price-details').altBeautify(); | ||
16 | + <% end %> | ||
17 | +<% end %> |
app/views/search/tag.rhtml
@@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
7 | <% end %> | 7 | <% end %> |
8 | 8 | ||
9 | <% cache_timeout(@tag_cache_key, 4.hour) do %> | 9 | <% cache_timeout(@tag_cache_key, 4.hour) do %> |
10 | - <%= display_results %> | 10 | + <%= display_results @searches %> |
11 | 11 | ||
12 | <div style="clear: both"></div> | 12 | <div style="clear: both"></div> |
13 | <% end %> | 13 | <% end %> |
app/views/tasks/_task.rhtml
@@ -50,13 +50,13 @@ | @@ -50,13 +50,13 @@ | ||
50 | <% fields_for "tasks[#{task.id}][task]", task do |f| %> | 50 | <% fields_for "tasks[#{task.id}][task]", task do |f| %> |
51 | <% if task.accept_details %> | 51 | <% if task.accept_details %> |
52 | <div id="on-accept-information-<%=task.id%>" style="display: none"> | 52 | <div id="on-accept-information-<%=task.id%>" style="display: none"> |
53 | - <%= render :partial => partial_for_class(task.class, :accept_details), :locals => {:task => task, :f => f} %> | 53 | + <%= render :partial => partial_for_class(task.class, nil, :accept_details), :locals => {:task => task, :f => f} %> |
54 | </div> | 54 | </div> |
55 | <% end %> | 55 | <% end %> |
56 | 56 | ||
57 | <% if task.reject_details %> | 57 | <% if task.reject_details %> |
58 | <div id="on-reject-information-<%=task.id%>" style="display: none"> | 58 | <div id="on-reject-information-<%=task.id%>" style="display: none"> |
59 | - <%= render :partial => partial_for_class(task.class, :reject_details), :locals => {:task => task, :f => f} %> | 59 | + <%= render :partial => partial_for_class(task.class, nil, :reject_details), :locals => {:task => task, :f => f} %> |
60 | </div> | 60 | </div> |
61 | <% end %> | 61 | <% end %> |
62 | <% end %> | 62 | <% end %> |
config/initializers/dependencies.rb
1 | # locally-developed modules | 1 | # locally-developed modules |
2 | -require 'acts_as_faceted' | ||
3 | require 'acts_as_filesystem' | 2 | require 'acts_as_filesystem' |
4 | require 'acts_as_having_settings' | 3 | require 'acts_as_having_settings' |
5 | -require 'acts_as_searchable' | ||
6 | require 'acts_as_having_boxes' | 4 | require 'acts_as_having_boxes' |
7 | require 'acts_as_having_image' | 5 | require 'acts_as_having_image' |
8 | require 'acts_as_having_posts' | 6 | require 'acts_as_having_posts' |
config/solr.yml.dist
@@ -1,25 +0,0 @@ | @@ -1,25 +0,0 @@ | ||
1 | -# Config file for the acts_as_solr plugin. | ||
2 | -# | ||
3 | -# If you change the host or port number here, make sure you update | ||
4 | -# them in your Solr config file | ||
5 | - | ||
6 | -# No change is needed to support multitenancy. Only one solr environment will be used. | ||
7 | -# Just remember to use 'rake multitenancy:reindex' for reindexation. | ||
8 | - | ||
9 | -production: | ||
10 | - url: http://127.0.0.1:8983/solr | ||
11 | - jvm_options: -server -Xmx192M -Xms64M | ||
12 | - timeout: 0 | ||
13 | - | ||
14 | -development: | ||
15 | - url: http://0.0.0.0:8982/solr | ||
16 | - jvm_options: -server -Xmx128M -Xms16M | ||
17 | - timeout: 0 | ||
18 | - | ||
19 | -test: &TEST | ||
20 | - url: http://0.0.0.0:8981/solr | ||
21 | - jvm_options: -server -Xmx128M -Xms16M | ||
22 | - timeout: 0 | ||
23 | - | ||
24 | -cucumber: | ||
25 | - <<: *TEST |
debian/noosfero.install
@@ -28,7 +28,6 @@ public usr/share/noosfero | @@ -28,7 +28,6 @@ public usr/share/noosfero | ||
28 | 28 | ||
29 | debian/default/noosfero etc/default | 29 | debian/default/noosfero etc/default |
30 | etc/init.d/noosfero etc/init.d | 30 | etc/init.d/noosfero etc/init.d |
31 | -debian/solr.yml etc/noosfero | ||
32 | debian/thin.yml etc/noosfero | 31 | debian/thin.yml etc/noosfero |
33 | etc/logrotate.d/noosfero etc/logrotate.d | 32 | etc/logrotate.d/noosfero etc/logrotate.d |
34 | debian/noosfero.yml etc/noosfero | 33 | debian/noosfero.yml etc/noosfero |
debian/noosfero.links
@@ -2,7 +2,6 @@ usr/share/rails-ruby1.8 usr/share/noosfero/vendor/ra | @@ -2,7 +2,6 @@ usr/share/rails-ruby1.8 usr/share/noosfero/vendor/ra | ||
2 | var/tmp/noosfero usr/share/noosfero/tmp | 2 | var/tmp/noosfero usr/share/noosfero/tmp |
3 | var/log/noosfero usr/share/noosfero/log | 3 | var/log/noosfero usr/share/noosfero/log |
4 | etc/noosfero/database.yml usr/share/noosfero/config/database.yml | 4 | etc/noosfero/database.yml usr/share/noosfero/config/database.yml |
5 | -etc/noosfero/solr.yml usr/share/noosfero/config/solr.yml | ||
6 | etc/noosfero/thin.yml usr/share/noosfero/config/thin.yml | 5 | etc/noosfero/thin.yml usr/share/noosfero/config/thin.yml |
7 | etc/noosfero/plugins usr/share/noosfero/config/plugins | 6 | etc/noosfero/plugins usr/share/noosfero/config/plugins |
8 | etc/noosfero/noosfero.yml usr/share/noosfero/config/noosfero.yml | 7 | etc/noosfero/noosfero.yml usr/share/noosfero/config/noosfero.yml |
debian/solr.yml
@@ -1,22 +0,0 @@ | @@ -1,22 +0,0 @@ | ||
1 | -# Config file for the acts_as_solr plugin. | ||
2 | -# | ||
3 | -# If you change the host or port number here, make sure you update | ||
4 | -# them in your Solr config file | ||
5 | - | ||
6 | -development: | ||
7 | - url: http://0.0.0.0:8982/solr | ||
8 | - jvm_options: -server -Xmx128M -Xms16M | ||
9 | - timeout: 0 | ||
10 | - | ||
11 | -production: | ||
12 | - url: http://127.0.0.1:8983/solr | ||
13 | - jvm_options: -server -Xmx192M -Xms64M | ||
14 | - timeout: 0 | ||
15 | - | ||
16 | -test: &TEST | ||
17 | - url: http://0.0.0.0:8981/solr | ||
18 | - jvm_options: -server -Xmx128M -Xms16M | ||
19 | - timeout: 0 | ||
20 | - | ||
21 | -cucumber: | ||
22 | - <<: *TEST |
etc/init.d/noosfero
@@ -45,14 +45,13 @@ if [ -z "$NOOSFERO_DIR" ] || [ -z "$NOOSFERO_USER" ]; then | @@ -45,14 +45,13 @@ if [ -z "$NOOSFERO_DIR" ] || [ -z "$NOOSFERO_USER" ]; then | ||
45 | fi | 45 | fi |
46 | 46 | ||
47 | ###################### | 47 | ###################### |
48 | -SOLR_PID_FILE=$NOOSFERO_DIR/tmp/pids/solr.production.pid | ||
49 | 48 | ||
50 | main_script() { | 49 | main_script() { |
51 | cd $NOOSFERO_DIR | 50 | cd $NOOSFERO_DIR |
52 | if [ "$NOOSFERO_USER" != "$USER" ]; then | 51 | if [ "$NOOSFERO_USER" != "$USER" ]; then |
53 | - su $NOOSFERO_USER -l -c "SOLR_DATA_PATH=/var/lib/noosfero-data/index ./script/production $1" | 52 | + su $NOOSFERO_USER -l -c "./script/production $1" |
54 | else | 53 | else |
55 | - SOLR_DATA_PATH=/var/lib/noosfero-data/index ./script/production $1 | 54 | + ./script/production $1 |
56 | fi | 55 | fi |
57 | } | 56 | } |
58 | 57 | ||
@@ -78,13 +77,6 @@ do_setup() { | @@ -78,13 +77,6 @@ do_setup() { | ||
78 | chmod 750 /var/tmp/noosfero | 77 | chmod 750 /var/tmp/noosfero |
79 | fi | 78 | fi |
80 | 79 | ||
81 | - # Solr directory | ||
82 | - if [ ! -d /var/tmp/noosfero/solr ]; then | ||
83 | - mkdir -p /var/tmp/noosfero/solr | ||
84 | - chown $NOOSFERO_USER:root /var/tmp/noosfero/solr | ||
85 | - chmod 750 /var/tmp/noosfero/solr | ||
86 | - fi | ||
87 | - | ||
88 | # symlink the directories into Noosfero directory | 80 | # symlink the directories into Noosfero directory |
89 | if [ ! -e $NOOSFERO_DIR/tmp ]; then | 81 | if [ ! -e $NOOSFERO_DIR/tmp ]; then |
90 | ln -s /var/tmp/noosfero $NOOSFERO_DIR/tmp | 82 | ln -s /var/tmp/noosfero $NOOSFERO_DIR/tmp |
@@ -98,28 +90,21 @@ do_setup() { | @@ -98,28 +90,21 @@ do_setup() { | ||
98 | } | 90 | } |
99 | 91 | ||
100 | do_start() { | 92 | do_start() { |
101 | - | ||
102 | - # FIXME should not test for solr only | ||
103 | - if [ -e $SOLR_PID_FILE ]; then | ||
104 | - echo 'noosfero already running, cannot start.' | ||
105 | - exit 2 | 93 | + if ! running; then |
94 | + do_setup | ||
95 | + # actually start the service | ||
96 | + main_script start | ||
97 | + else | ||
98 | + echo 'Noosfero is already running, nothing to do...' | ||
106 | fi | 99 | fi |
107 | - | ||
108 | - do_setup | ||
109 | - | ||
110 | - # actually start the service | ||
111 | - main_script start | ||
112 | } | 100 | } |
113 | 101 | ||
114 | do_stop() { | 102 | do_stop() { |
115 | - | ||
116 | - # FIXME should not test for solr only | ||
117 | - if [ ! -e $SOLR_PID_FILE ]; then | ||
118 | - echo 'noosfero not running, cannot stop' | ||
119 | - exit 2 | 103 | + if running; then |
104 | + main_script stop | ||
105 | + else | ||
106 | + echo 'Noosfero is already stopped, nothing to do...' | ||
120 | fi | 107 | fi |
121 | - | ||
122 | - main_script stop | ||
123 | } | 108 | } |
124 | 109 | ||
125 | do_restart() { | 110 | do_restart() { |
@@ -127,6 +112,10 @@ do_restart() { | @@ -127,6 +112,10 @@ do_restart() { | ||
127 | do_start | 112 | do_start |
128 | } | 113 | } |
129 | 114 | ||
115 | +running(){ | ||
116 | + pgrep -u noosfero -f server > /dev/null | ||
117 | +} | ||
118 | + | ||
130 | case "$1" in | 119 | case "$1" in |
131 | start|stop|restart|setup) | 120 | start|stop|restart|setup) |
132 | do_$1 | 121 | do_$1 |
features/support/env.rb
@@ -5,8 +5,6 @@ | @@ -5,8 +5,6 @@ | ||
5 | # files. | 5 | # files. |
6 | 6 | ||
7 | ENV["RAILS_ENV"] ||= "cucumber" | 7 | ENV["RAILS_ENV"] ||= "cucumber" |
8 | -abort unless system 'rake -s solr:start' | ||
9 | -at_exit { system 'rake -s solr:stop' } | ||
10 | 8 | ||
11 | require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') | 9 | require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') |
12 | 10 |
gitignore.example
@@ -8,7 +8,6 @@ config/database.yml | @@ -8,7 +8,6 @@ config/database.yml | ||
8 | config/session.secret | 8 | config/session.secret |
9 | config/noosfero.yml | 9 | config/noosfero.yml |
10 | config/mongrel_cluster.yml | 10 | config/mongrel_cluster.yml |
11 | -config/solr.yml | ||
12 | config/plugins | 11 | config/plugins |
13 | config/thin.yml | 12 | config/thin.yml |
14 | config/local.rb | 13 | config/local.rb |
@@ -32,7 +31,6 @@ doc/noosfero/*.xhtml | @@ -32,7 +31,6 @@ doc/noosfero/*.xhtml | ||
32 | doc/noosfero/*/*.xhtml | 31 | doc/noosfero/*/*.xhtml |
33 | tags | 32 | tags |
34 | pkg | 33 | pkg |
35 | -solr | ||
36 | *~ | 34 | *~ |
37 | *.swp | 35 | *.swp |
38 | debian/*.log | 36 | debian/*.log |
lib/acts_as_faceted.rb
@@ -1,222 +0,0 @@ | @@ -1,222 +0,0 @@ | ||
1 | -module ActsAsFaceted | ||
2 | - | ||
3 | - module ClassMethods | ||
4 | - end | ||
5 | - | ||
6 | - module ActsMethods | ||
7 | - # Example: | ||
8 | - # | ||
9 | - #acts_as_faceted :fields => { | ||
10 | - # :f_type => {:label => _('Type'), :proc => proc{|klass| f_type_proc(klass)}}, | ||
11 | - # :f_published_at => {:type => :date, :label => _('Published date'), :queries => {'[* TO NOW-1YEARS/DAY]' => _("Older than one year"), | ||
12 | - # '[NOW-1YEARS TO NOW/DAY]' => _("Last year"), '[NOW-1MONTHS TO NOW/DAY]' => _("Last month"), '[NOW-7DAYS TO NOW/DAY]' => _("Last week"), '[NOW-1DAYS TO NOW/DAY]' => _("Last day")}}, | ||
13 | - # :f_profile_type => {:label => _('Author'), :proc => proc{|klass| f_profile_type_proc(klass)}}, | ||
14 | - # :f_category => {:label => _('Categories')}}, | ||
15 | - # :order => [:f_type, :f_published_at, :f_profile_type, :f_category] | ||
16 | - # | ||
17 | - #acts_as_searchable :additional_fields => [ {:name => {:type => :string, :as => :name_sort, :boost => 5.0}} ] + facets_fields_for_solr, | ||
18 | - # :exclude_fields => [:setting], | ||
19 | - # :include => [:profile], | ||
20 | - # :facets => facets_option_for_solr, | ||
21 | - # :if => proc{|a| ! ['RssFeed'].include?(a.class.name)} | ||
22 | - def acts_as_faceted(options) | ||
23 | - extend ClassMethods | ||
24 | - extend ActsAsSolr::CommonMethods | ||
25 | - | ||
26 | - cattr_accessor :facets | ||
27 | - cattr_accessor :facets_order | ||
28 | - cattr_accessor :to_solr_fields_names | ||
29 | - cattr_accessor :facets_results_containers | ||
30 | - cattr_accessor :solr_fields_names | ||
31 | - cattr_accessor :facets_option_for_solr | ||
32 | - cattr_accessor :facets_fields_for_solr | ||
33 | - cattr_accessor :facet_category_query | ||
34 | - | ||
35 | - self.facets = options[:fields] | ||
36 | - self.facets_order = options[:order] || self.facets.keys | ||
37 | - self.facets_results_containers = {:fields => 'facet_fields', :queries => 'facet_queries', :ranges => 'facet_ranges'} | ||
38 | - self.facets_option_for_solr = Hash[facets.select{ |id,data| ! data.has_key?(:queries) }].keys | ||
39 | - self.facets_fields_for_solr = facets.map{ |id,data| {id => data[:type] || :facet} } | ||
40 | - self.solr_fields_names = facets.map{ |id,data| id.to_s + '_' + get_solr_field_type(data[:type] || :facet) } | ||
41 | - self.facet_category_query = options[:category_query] | ||
42 | - | ||
43 | - # A hash to retrieve the field key for the solr facet string returned | ||
44 | - # :field_name => "field_name_facet" | ||
45 | - self.to_solr_fields_names = Hash[facets.keys.zip(solr_fields_names)] | ||
46 | - | ||
47 | - def facet_by_id(id) | ||
48 | - {:id => id}.merge(facets[id]) if facets[id] | ||
49 | - end | ||
50 | - | ||
51 | - def map_facets_for(environment) | ||
52 | - facets_order.map do |id| | ||
53 | - facet = facet_by_id(id) | ||
54 | - next if facet[:type_if] and !facet[:type_if].call(self.new) | ||
55 | - | ||
56 | - if facet[:multi] | ||
57 | - facet[:label].call(environment).map do |label_id, label| | ||
58 | - facet.merge({:id => facet[:id].to_s+'_'+label_id.to_s, :solr_field => facet[:id], :label_id => label_id, :label => label}) | ||
59 | - end | ||
60 | - else | ||
61 | - facet.merge(:id => facet[:id].to_s, :solr_field => facet[:id]) | ||
62 | - end | ||
63 | - end.compact.flatten | ||
64 | - end | ||
65 | - | ||
66 | - def map_facet_results(facet, facet_params, facets_data, unfiltered_facets_data = {}, options = {}) | ||
67 | - raise 'Use map_facets_for before this method' if facet[:solr_field].nil? | ||
68 | - facets_data = {} if facets_data.blank? # could be empty array | ||
69 | - solr_facet = to_solr_fields_names[facet[:solr_field]] | ||
70 | - unfiltered_facets_data ||= {} | ||
71 | - | ||
72 | - if facet[:queries] | ||
73 | - container = facets_data[facets_results_containers[:queries]] | ||
74 | - facet_data = (container.nil? or container.empty?) ? [] : container.select{ |k,v| k.starts_with? solr_facet } | ||
75 | - container = unfiltered_facets_data[facets_results_containers[:queries]] | ||
76 | - unfiltered_facet_data = (container.nil? or container.empty?) ? [] : container.select{ |k,v| k.starts_with? solr_facet } | ||
77 | - else | ||
78 | - container = facets_data[facets_results_containers[:fields]] | ||
79 | - facet_data = (container.nil? or container.empty?) ? [] : container[solr_facet] || [] | ||
80 | - container = unfiltered_facets_data[facets_results_containers[:fields]] | ||
81 | - unfiltered_facet_data = (container.nil? or container.empty?) ? [] : container[solr_facet] || [] | ||
82 | - end | ||
83 | - | ||
84 | - if !unfiltered_facets_data.blank? and !facet_params.blank? | ||
85 | - f = Hash[Array(facet_data)] | ||
86 | - zeros = [] | ||
87 | - facet_data = unfiltered_facet_data.map do |id, count| | ||
88 | - count = f[id] | ||
89 | - if count.nil? | ||
90 | - zeros.push [id, 0] | ||
91 | - nil | ||
92 | - else | ||
93 | - [id, count] | ||
94 | - end | ||
95 | - end.compact + zeros | ||
96 | - end | ||
97 | - | ||
98 | - facet_count = facet_data.length | ||
99 | - | ||
100 | - if facet[:queries] | ||
101 | - result = facet_data.map do |id, count| | ||
102 | - q = id[id.index(':')+1,id.length] | ||
103 | - label = facet_result_name(facet, q) | ||
104 | - [q, label, count] if count > 0 | ||
105 | - end.compact | ||
106 | - result = facet[:queries_order].map{ |id| result.detect{ |rid, label, count| rid == id } }.compact if facet[:queries_order] | ||
107 | - elsif facet[:proc] | ||
108 | - if facet[:label_id] | ||
109 | - result = facet_data.map do |id, count| | ||
110 | - name = facet_result_name(facet, id) | ||
111 | - [id, name, count] if name | ||
112 | - end.compact | ||
113 | - # FIXME limit is NOT improving performance in this case :( | ||
114 | - facet_count = result.length | ||
115 | - result = result.first(options[:limit]) if options[:limit] | ||
116 | - else | ||
117 | - facet_data = facet_data.first(options[:limit]) if options[:limit] | ||
118 | - result = facet_data.map { |id, count| [id, facet_result_name(facet, id), count] } | ||
119 | - end | ||
120 | - else | ||
121 | - facet_data = facet_data.first(options[:limit]) if options[:limit] | ||
122 | - result = facet_data.map { |id, count| [id, facet_result_name(facet, id), count] } | ||
123 | - end | ||
124 | - | ||
125 | - sorted = facet_result_sort(facet, result, options[:sort]) | ||
126 | - | ||
127 | - # length can't be used if limit option is given; | ||
128 | - # total_entries comes to help | ||
129 | - sorted.class.send(:define_method, :total_entries, proc { facet_count }) | ||
130 | - | ||
131 | - sorted | ||
132 | - end | ||
133 | - | ||
134 | - def facet_result_sort(facet, facets_data, sort_by = nil) | ||
135 | - if facet[:queries_order] | ||
136 | - facets_data | ||
137 | - elsif sort_by == :alphabetically | ||
138 | - facets_data.sort{ |a,b| Array(a[1])[0] <=> Array(b[1])[0] } | ||
139 | - elsif sort_by == :count | ||
140 | - facets_data.sort{ |a,b| -1*(a[2] <=> b[2]) } | ||
141 | - else | ||
142 | - facets_data | ||
143 | - end | ||
144 | - end | ||
145 | - | ||
146 | - def facet_result_name(facet, data) | ||
147 | - if facet[:queries] | ||
148 | - gettext(facet[:queries][data]) | ||
149 | - elsif facet[:proc] | ||
150 | - if facet[:multi] | ||
151 | - facet[:label_id] ||= 0 | ||
152 | - facet[:proc].call(facet, data) | ||
153 | - else | ||
154 | - gettext(facet[:proc].call(data)) | ||
155 | - end | ||
156 | - else | ||
157 | - data | ||
158 | - end | ||
159 | - end | ||
160 | - | ||
161 | - def facet_label(facet) | ||
162 | - return nil unless facet | ||
163 | - _(facet[:label]) | ||
164 | - end | ||
165 | - | ||
166 | - def facets_find_options(facets_selected = {}, options = {}) | ||
167 | - browses = [] | ||
168 | - facets_selected ||= {} | ||
169 | - facets_selected.map do |id, value| | ||
170 | - next unless facets[id.to_sym] | ||
171 | - if value.kind_of?(Hash) | ||
172 | - value.map do |label_id, value| | ||
173 | - value.to_a.each do |value| | ||
174 | - browses << id.to_s + ':' + (facets[id.to_sym][:queries] ? value : '"'+value.to_s+'"') | ||
175 | - end | ||
176 | - end | ||
177 | - else | ||
178 | - browses << id.to_s + ':' + (facets[id.to_sym][:queries] ? value : '"'+value.to_s+'"') | ||
179 | - end | ||
180 | - end.flatten | ||
181 | - | ||
182 | - {:facets => {:zeros => false, :sort => :count, | ||
183 | - :fields => facets_option_for_solr, | ||
184 | - :browse => browses, | ||
185 | - :query => facets.map { |f, options| options[:queries].keys.map { |q| f.to_s + ':' + q } if options[:queries] }.compact.flatten, | ||
186 | - } | ||
187 | - } | ||
188 | - end | ||
189 | - end | ||
190 | - end | ||
191 | - | ||
192 | -end | ||
193 | - | ||
194 | -ActiveRecord::Base.extend ActsAsFaceted::ActsMethods | ||
195 | - | ||
196 | -# from https://github.com/rubyworks/facets/blob/master/lib/core/facets/enumerable/graph.rb | ||
197 | -module Enumerable | ||
198 | - def graph(&yld) | ||
199 | - if yld | ||
200 | - h = {} | ||
201 | - each do |*kv| | ||
202 | - r = yld[*kv] | ||
203 | - case r | ||
204 | - when Hash | ||
205 | - nk, nv = *r.to_a[0] | ||
206 | - when Range | ||
207 | - nk, nv = r.first, r.last | ||
208 | - else | ||
209 | - nk, nv = *r | ||
210 | - end | ||
211 | - h[nk] = nv | ||
212 | - end | ||
213 | - h | ||
214 | - else | ||
215 | - Enumerator.new(self,:graph) | ||
216 | - end | ||
217 | - end | ||
218 | - | ||
219 | - # Alias for #graph, which stands for "map hash". | ||
220 | - alias_method :mash, :graph | ||
221 | -end | ||
222 | - |
lib/acts_as_searchable.rb
@@ -1,87 +0,0 @@ | @@ -1,87 +0,0 @@ | ||
1 | -module ActsAsSearchable | ||
2 | - | ||
3 | - module ClassMethods | ||
4 | - ACTS_AS_SEARCHABLE_ENABLED = true unless defined? ACTS_AS_SEARCHABLE_ENABLED | ||
5 | - | ||
6 | - def acts_as_searchable(options = {}) | ||
7 | - return if !ACTS_AS_SEARCHABLE_ENABLED | ||
8 | - | ||
9 | - if options[:fields] | ||
10 | - options[:fields] << {:schema_name => :string} | ||
11 | - else | ||
12 | - options[:additional_fields] ||= [] | ||
13 | - options[:additional_fields] << {:schema_name => :string} | ||
14 | - end | ||
15 | - | ||
16 | - acts_as_solr options | ||
17 | - extend FindByContents | ||
18 | - send :include, InstanceMethods | ||
19 | - end | ||
20 | - | ||
21 | - module InstanceMethods | ||
22 | - def schema_name | ||
23 | - self.class.schema_name | ||
24 | - end | ||
25 | - | ||
26 | - # replace solr_id from vendor/plugins/acts_as_solr_reloaded/lib/acts_as_solr/instance_methods.rb | ||
27 | - # to include schema_name | ||
28 | - def solr_id | ||
29 | - id = "#{self.class.name}:#{record_id(self)}" | ||
30 | - id.insert(0, "#{schema_name}:") unless schema_name.blank? | ||
31 | - id | ||
32 | - end | ||
33 | - end | ||
34 | - | ||
35 | - module FindByContents | ||
36 | - | ||
37 | - def schema_name | ||
38 | - (Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql?) ? ActiveRecord::Base.connection.schema_search_path : '' | ||
39 | - end | ||
40 | - | ||
41 | - def find_by_contents(query, pg_options = {}, options = {}, db_options = {}) | ||
42 | - pg_options[:page] ||= 1 | ||
43 | - pg_options[:per_page] ||= 20 | ||
44 | - options[:page] = pg_options[:page].to_i | ||
45 | - options[:per_page] = pg_options[:per_page].to_i | ||
46 | - options[:scores] ||= true | ||
47 | - options[:filter_queries] ||= [] | ||
48 | - options[:filter_queries] << "schema_name:\"#{schema_name}\"" unless schema_name.blank? | ||
49 | - all_facets_enabled = options.delete(:all_facets) | ||
50 | - options[:per_page] = options.delete(:extra_limit) if options[:extra_limit] | ||
51 | - results = [] | ||
52 | - facets = all_facets = {} | ||
53 | - | ||
54 | - solr_result = find_by_solr(query, options) | ||
55 | - if all_facets_enabled | ||
56 | - options[:facets][:browse] = nil | ||
57 | - all_facets = find_by_solr(query, options.merge(:per_page => 0)).facets | ||
58 | - end | ||
59 | - | ||
60 | - if !solr_result.nil? | ||
61 | - facets = options.include?(:facets) ? solr_result.facets : [] | ||
62 | - | ||
63 | - if db_options.empty? | ||
64 | - results = solr_result | ||
65 | - else | ||
66 | - ids = solr_result.results.map{ |r| r[:id].to_i } | ||
67 | - if ids.empty? | ||
68 | - ids << -1 | ||
69 | - end | ||
70 | - | ||
71 | - if db_options[:conditions] | ||
72 | - db_options[:conditions] = sanitize_sql_for_conditions(db_options[:conditions]) + " and #{table_name}.id in (#{ids.join(', ')})" | ||
73 | - else | ||
74 | - db_options[:conditions] = "#{table_name}.id in (#{ids.join(', ')})" | ||
75 | - end | ||
76 | - | ||
77 | - results = find(:all, db_options) | ||
78 | - end | ||
79 | - end | ||
80 | - | ||
81 | - {:results => results, :facets => facets, :all_facets => all_facets} | ||
82 | - end | ||
83 | - end | ||
84 | - end | ||
85 | -end | ||
86 | - | ||
87 | -ActiveRecord::Base.send(:extend, ActsAsSearchable::ClassMethods) |
lib/noosfero/core_ext/active_record.rb
@@ -13,4 +13,17 @@ class ActiveRecord::Base | @@ -13,4 +13,17 @@ class ActiveRecord::Base | ||
13 | key.join('/') | 13 | key.join('/') |
14 | end | 14 | end |
15 | 15 | ||
16 | + def self.like_search(query) | ||
17 | + if defined?(self::SEARCHABLE_FIELDS) | ||
18 | + fields = self::SEARCHABLE_FIELDS.keys.map(&:to_s) & column_names | ||
19 | + query = query.downcase.strip | ||
20 | + conditions = fields.map do |field| | ||
21 | + "lower(#{table_name}.#{field}) LIKE '%#{query}%'" | ||
22 | + end.join(' OR ') | ||
23 | + where(conditions) | ||
24 | + else | ||
25 | + raise "No searchable fields defined for #{self.name}" | ||
26 | + end | ||
27 | + end | ||
28 | + | ||
16 | end | 29 | end |
lib/noosfero/plugin.rb
@@ -16,38 +16,52 @@ class Noosfero::Plugin | @@ -16,38 +16,52 @@ class Noosfero::Plugin | ||
16 | if Rails.env.test? && !enabled_plugins.include?(File.join(Rails.root, 'config', 'plugins', 'foo')) | 16 | if Rails.env.test? && !enabled_plugins.include?(File.join(Rails.root, 'config', 'plugins', 'foo')) |
17 | enabled_plugins << File.join(Rails.root, 'plugins', 'foo') | 17 | enabled_plugins << File.join(Rails.root, 'plugins', 'foo') |
18 | end | 18 | end |
19 | + | ||
19 | enabled_plugins.select do |entry| | 20 | enabled_plugins.select do |entry| |
20 | File.directory?(entry) | 21 | File.directory?(entry) |
21 | end.each do |dir| | 22 | end.each do |dir| |
22 | - plugin_name = File.basename(dir) | ||
23 | - | ||
24 | - plugin_dependencies_ok = true | ||
25 | - plugin_dependencies_file = File.join(dir, 'dependencies.rb') | ||
26 | - if File.exists?(plugin_dependencies_file) | ||
27 | - begin | ||
28 | - require plugin_dependencies_file | ||
29 | - rescue LoadError => ex | ||
30 | - plugin_dependencies_ok = false | ||
31 | - $stderr.puts "W: Noosfero plugin #{plugin_name} failed to load (#{ex})" | ||
32 | - end | ||
33 | - end | 23 | + load_plugin dir |
24 | + end | ||
25 | + end | ||
34 | 26 | ||
35 | - if plugin_dependencies_ok | ||
36 | - Rails.configuration.controller_paths << File.join(dir, 'controllers') | ||
37 | - ActiveSupport::Dependencies.load_paths << File.join(dir, 'controllers') | ||
38 | - controllers_folders = %w[public profile myprofile admin] | ||
39 | - controllers_folders.each do |folder| | ||
40 | - Rails.configuration.controller_paths << File.join(dir, 'controllers', folder) | ||
41 | - ActiveSupport::Dependencies.load_paths << File.join(dir, 'controllers', folder) | ||
42 | - end | ||
43 | - [ ActiveSupport::Dependencies.load_paths, $:].each do |path| | ||
44 | - path << File.join(dir, 'models') | ||
45 | - path << File.join(dir, 'lib') | ||
46 | - end | ||
47 | - | ||
48 | - klass(plugin_name) | 27 | + def load_plugin dir |
28 | + plugin_name = File.basename(dir) | ||
29 | + | ||
30 | + plugin_dependencies_ok = true | ||
31 | + plugin_dependencies_file = File.join(dir, 'dependencies.rb') | ||
32 | + if File.exists?(plugin_dependencies_file) | ||
33 | + begin | ||
34 | + require plugin_dependencies_file | ||
35 | + rescue LoadError => ex | ||
36 | + plugin_dependencies_ok = false | ||
37 | + $stderr.puts "W: Noosfero plugin #{plugin_name} failed to load (#{ex})" | ||
49 | end | 38 | end |
50 | end | 39 | end |
40 | + | ||
41 | + return unless plugin_dependencies_ok | ||
42 | + | ||
43 | + # add load paths | ||
44 | + Rails.configuration.controller_paths << File.join(dir, 'controllers') | ||
45 | + ActiveSupport::Dependencies.load_paths << File.join(dir, 'controllers') | ||
46 | + controllers_folders = %w[public profile myprofile admin] | ||
47 | + controllers_folders.each do |folder| | ||
48 | + Rails.configuration.controller_paths << File.join(dir, 'controllers', folder) | ||
49 | + ActiveSupport::Dependencies.load_paths << File.join(dir, 'controllers', folder) | ||
50 | + end | ||
51 | + [ ActiveSupport::Dependencies.load_paths, $:].each do |path| | ||
52 | + path << File.join(dir, 'models') | ||
53 | + path << File.join(dir, 'lib') | ||
54 | + end | ||
55 | + | ||
56 | + # load vendor/plugins | ||
57 | + Dir.glob(File.join(dir, '/vendor/plugins/*')).each do |vendor_plugin| | ||
58 | + [ ActiveSupport::Dependencies.load_paths, $:].each{ |path| path << "#{vendor_plugin}/lib" } | ||
59 | + init = "#{vendor_plugin}/init.rb" | ||
60 | + require init.gsub(/.rb$/, '') if File.file? init | ||
61 | + end | ||
62 | + | ||
63 | + # load class | ||
64 | + klass(plugin_name) | ||
51 | end | 65 | end |
52 | 66 | ||
53 | def all | 67 | def all |
@@ -380,6 +394,13 @@ class Noosfero::Plugin | @@ -380,6 +394,13 @@ class Noosfero::Plugin | ||
380 | nil | 394 | nil |
381 | end | 395 | end |
382 | 396 | ||
397 | + # -> Finds objects by their contents | ||
398 | + # returns = {:results => [a, b, c, ...], ...} | ||
399 | + # P.S.: The plugin might add other informations on the return hash for its | ||
400 | + # own use in specific views | ||
401 | + def find_by_contents(asset, scope, query, paginate_options={}, options={}) | ||
402 | + end | ||
403 | + | ||
383 | # -> Adds additional blocks to profiles and environments. | 404 | # -> Adds additional blocks to profiles and environments. |
384 | # Your plugin must implements a class method called 'extra_blocks' | 405 | # Your plugin must implements a class method called 'extra_blocks' |
385 | # that returns a hash with the following syntax. | 406 | # that returns a hash with the following syntax. |
lib/noosfero/plugin/manager.rb
@@ -23,12 +23,36 @@ class Noosfero::Plugin::Manager | @@ -23,12 +23,36 @@ class Noosfero::Plugin::Manager | ||
23 | dispatch_without_flatten(event, *args).flatten | 23 | dispatch_without_flatten(event, *args).flatten |
24 | end | 24 | end |
25 | 25 | ||
26 | + def dispatch_plugins(event, *args) | ||
27 | + map { |plugin| plugin.class if plugin.send(event, *args) }.compact.flatten | ||
28 | + end | ||
29 | + | ||
26 | def dispatch_without_flatten(event, *args) | 30 | def dispatch_without_flatten(event, *args) |
27 | map { |plugin| plugin.send(event, *args) }.compact | 31 | map { |plugin| plugin.send(event, *args) }.compact |
28 | end | 32 | end |
29 | 33 | ||
30 | alias :dispatch_scopes :dispatch_without_flatten | 34 | alias :dispatch_scopes :dispatch_without_flatten |
31 | 35 | ||
36 | + def first(event, *args) | ||
37 | + result = nil | ||
38 | + each do |plugin| | ||
39 | + result = plugin.send(event, *args) | ||
40 | + break if result.present? | ||
41 | + end | ||
42 | + result | ||
43 | + end | ||
44 | + | ||
45 | + def first_plugin(event, *args) | ||
46 | + result = nil | ||
47 | + each do |plugin| | ||
48 | + if plugin.send(event, *args) | ||
49 | + result = plugin.class | ||
50 | + break | ||
51 | + end | ||
52 | + end | ||
53 | + result | ||
54 | + end | ||
55 | + | ||
32 | def enabled_plugins | 56 | def enabled_plugins |
33 | @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin| | 57 | @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin| |
34 | p = plugin.constantize.new | 58 | p = plugin.constantize.new |
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,16 +25,20 @@ module SetProfileRegionFromCityState | @@ -24,16 +25,20 @@ 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 | - if s | ||
29 | - c = City.find_by_contents(self.city, {}, :filter_queries => ["parent_id:#{s.id}"])[:results].first | ||
30 | - self.region = c | ||
31 | - else | ||
32 | - self.region = nil | ||
33 | - end | 28 | + self.region = nil |
29 | + state = search_region(State, self.state) | ||
30 | + self.region = search_region(City.where(:parent_id => state.id), self.city) if state | ||
34 | end | 31 | end |
35 | end | 32 | end |
36 | 33 | ||
34 | + private | ||
35 | + | ||
36 | + def search_region(scope, query) | ||
37 | + return nil if !query | ||
38 | + query = query.downcase.strip | ||
39 | + scope.where(['lower(name)=? OR lower(abbreviation)=? OR lower(acronym)=?', query, query, query]).first | ||
40 | + end | ||
41 | + | ||
37 | end | 42 | end |
38 | 43 | ||
39 | end | 44 | end |
lib/tasks/multitenancy.rake
@@ -14,22 +14,6 @@ namespace :multitenancy do | @@ -14,22 +14,6 @@ namespace :multitenancy do | ||
14 | (file_envs - db_envs.map{ |e| e + '.rb' }).each { |env| safe_unlink env } | 14 | (file_envs - db_envs.map{ |e| e + '.rb' }).each { |env| safe_unlink env } |
15 | end | 15 | end |
16 | 16 | ||
17 | - task :reindex => :environment do | ||
18 | - # enable output from rebuild_index | ||
19 | - logger = ActiveRecord::Base.logger = Logger.new(STDOUT) | ||
20 | - logger.level = ActiveSupport::BufferedLogger::INFO | ||
21 | - | ||
22 | - db_envs = ActiveRecord::Base.configurations.keys.select{ |k| k.match(/_#{RAILS_ENV}$/) } | ||
23 | - db_envs.each do |e| | ||
24 | - puts "Rebuilding index for environment #{e}" | ||
25 | - ActiveRecord::Base.connection.schema_search_path = ActiveRecord::Base.configurations[e]['schema_search_path'] | ||
26 | - $solr_indexed_models.each do |m| | ||
27 | - puts "Rebuilding index for model #{m}" | ||
28 | - m.rebuild_index | ||
29 | - end | ||
30 | - end | ||
31 | - end | ||
32 | - | ||
33 | end | 17 | end |
34 | 18 | ||
35 | namespace :db do | 19 | namespace :db do |
lib/tasks/release.rake
1 | namespace :noosfero do | 1 | namespace :noosfero do |
2 | 2 | ||
3 | + def pendencies_on_authors | ||
4 | + sh "git status | grep 'AUTHORS'" do |ok, res| | ||
5 | + return {:ok => ok, :res => res} | ||
6 | + end | ||
7 | + end | ||
8 | + | ||
9 | + def pendencies_on_repo | ||
10 | + sh "git status | grep 'nothing.*commit'" do |ok, res| | ||
11 | + return {:ok => ok, :res => res} | ||
12 | + end | ||
13 | + end | ||
14 | + | ||
3 | desc 'checks if there are uncommitted changes in the repo' | 15 | desc 'checks if there are uncommitted changes in the repo' |
4 | task :check_repo do | 16 | task :check_repo do |
5 | - sh "git status | grep 'nothing.*commit'" do |ok, res| | ||
6 | - if !ok | ||
7 | - raise "******** There are uncommited changes in the repository, cannot continue" | ||
8 | - end | 17 | + if !pendencies_on_repo[:ok] |
18 | + raise "******** There are uncommited changes in the repository, cannot continue" | ||
9 | end | 19 | end |
10 | end | 20 | end |
11 | 21 | ||
@@ -85,6 +95,80 @@ EOF | @@ -85,6 +95,80 @@ EOF | ||
85 | rm_f 'AUTHORS' | 95 | rm_f 'AUTHORS' |
86 | raise e | 96 | raise e |
87 | end | 97 | end |
98 | + if pendencies_on_authors[:res] | ||
99 | + puts 'The AUTHORS file was updated!' | ||
100 | + sh 'git diff AUTHORS' | ||
101 | + if confirm('Do you want to commit this changes to the author file') | ||
102 | + default_message = 'Updating AUTHORS file' | ||
103 | + message = ask("Commit message [#{default_message}]:") | ||
104 | + message = message.present? ? message : default_message | ||
105 | + sh 'git add AUTHORS' | ||
106 | + sh "git commit -m '#{message}'" | ||
107 | + end | ||
108 | + end | ||
109 | + end | ||
110 | + | ||
111 | + def ask(message) | ||
112 | + print message | ||
113 | + STDIN.gets.chomp | ||
114 | + end | ||
115 | + | ||
116 | + def confirm(message, default=true) | ||
117 | + choice_message = default ? ' [Y/n]? ' : ' [y/N]? ' | ||
118 | + choice = nil | ||
119 | + while choice.nil? | ||
120 | + answer = ask(message + choice_message) | ||
121 | + if answer.blank? | ||
122 | + choice = default | ||
123 | + elsif ['y', 'yes'].include?(answer.downcase) | ||
124 | + choice = true | ||
125 | + elsif ['n', 'no'].include?(answer.downcase) | ||
126 | + choice = false | ||
127 | + end | ||
128 | + end | ||
129 | + choice | ||
130 | + end | ||
131 | + | ||
132 | + desc 'sets the new version on apropriate files' | ||
133 | + task :set_version, :release_kind do |t, args| | ||
134 | + next if File.exist?("tmp/pending-release") | ||
135 | + release_kind = args[:release_kind] || 'stable' | ||
136 | + | ||
137 | + if release_kind == 'test' | ||
138 | + version_question = "Release candidate of which version: " | ||
139 | + distribution = 'squeeze-test' | ||
140 | + else | ||
141 | + version_question = "Version that is being released: " | ||
142 | + distribution = 'unstable' | ||
143 | + end | ||
144 | + | ||
145 | + version_name = new_version = ask(version_question) | ||
146 | + | ||
147 | + if release_kind == 'test' | ||
148 | + timestamp = Time.now.strftime('%Y%m%d%H%M%S') | ||
149 | + version_name += "~rc#{timestamp}" | ||
150 | + end | ||
151 | + release_message = ask("Release message: ") | ||
152 | + | ||
153 | + sh 'git checkout debian/changelog lib/noosfero.rb' | ||
154 | + sh "sed -i \"s/VERSION = '[^']*'/VERSION = '#{version_name}'/\" lib/noosfero.rb" | ||
155 | + sh "dch --newversion #{version_name} --distribution #{distribution} --force-distribution '#{release_message}'" | ||
156 | + | ||
157 | + puts | ||
158 | + if confirm("Commit version bump to #{version_name} on #{distribution} distribution") | ||
159 | + sh 'git add debian/changelog lib/noosfero.rb' | ||
160 | + sh "git commit -m 'Bumping version #{version_name}'" | ||
161 | + sh "touch tmp/pending-release" | ||
162 | + else | ||
163 | + sh 'git checkout debian/changelog lib/noosfero.rb' | ||
164 | + abort 'Version update not confirmed. Reverting changes and exiting...' | ||
165 | + end | ||
166 | + end | ||
167 | + | ||
168 | + desc "uploads the packages to the repository" | ||
169 | + task :upload_packages, :release_kind do |t, args| | ||
170 | + release_kind = args[:release_kind] || 'stable' | ||
171 | + sh "dput --unchecked #{release_kind} #{Dir['pkg/*.changes'].first}" | ||
88 | end | 172 | end |
89 | 173 | ||
90 | def ask(message) | 174 | def ask(message) |
@@ -179,8 +263,6 @@ EOF | @@ -179,8 +263,6 @@ EOF | ||
179 | mkdir "#{target}/tmp" | 263 | mkdir "#{target}/tmp" |
180 | ln_s '../../../vendor/rails', "#{target}/vendor/rails" | 264 | ln_s '../../../vendor/rails', "#{target}/vendor/rails" |
181 | cp "#{target}/config/database.yml.sqlite3", "#{target}/config/database.yml" | 265 | cp "#{target}/config/database.yml.sqlite3", "#{target}/config/database.yml" |
182 | - # solr inclusion | ||
183 | - Dir.chdir(target) { sh "rake solr:download" } | ||
184 | 266 | ||
185 | sh "cd #{target} && dpkg-buildpackage -us -uc -b" | 267 | sh "cd #{target} && dpkg-buildpackage -us -uc -b" |
186 | end | 268 | end |
plugins/mezuro/script/install/install-rvm.sh
@@ -100,7 +100,6 @@ cd mezuro | @@ -100,7 +100,6 @@ cd mezuro | ||
100 | git checkout mezuro-dev | 100 | git checkout mezuro-dev |
101 | rvm use ruby-1.8.7-p302@mezuro | 101 | rvm use ruby-1.8.7-p302@mezuro |
102 | cp config/database.yml.sqlite3 config/database.yml | 102 | cp config/database.yml.sqlite3 config/database.yml |
103 | -cp config/solr.yml.dist config/solr.yml | ||
104 | cp plugins/mezuro/service.yml.example plugins/mezuro/service.yml | 103 | cp plugins/mezuro/service.yml.example plugins/mezuro/service.yml |
105 | cp plugins/mezuro/licenses.yml.example plugins/mezuro/licenses.yml | 104 | cp plugins/mezuro/licenses.yml.example plugins/mezuro/licenses.yml |
106 | mkdir tmp | 105 | mkdir tmp |
@@ -116,5 +115,4 @@ ln -s mezuro-theme/ default | @@ -116,5 +115,4 @@ ln -s mezuro-theme/ default | ||
116 | cd ../../../ | 115 | cd ../../../ |
117 | 116 | ||
118 | #Prepare Mezuro for running functional and unit tests | 117 | #Prepare Mezuro for running functional and unit tests |
119 | -rake solr:download | ||
120 | -rake db:test:prepare | ||
121 | \ No newline at end of file | 118 | \ No newline at end of file |
119 | +rake db:test:prepare |
plugins/mezuro/test/functional/myprofile/mezuro_plugin_metric_configuration_controller_test.rb
@@ -23,7 +23,6 @@ class MezuroPluginMetricConfigurationControllerTest < ActionController::TestCase | @@ -23,7 +23,6 @@ class MezuroPluginMetricConfigurationControllerTest < ActionController::TestCase | ||
23 | @configuration_content = MezuroPlugin::ConfigurationContent.new(:profile => @profile, :name => @configuration.name, :configuration_id => 42) | 23 | @configuration_content = MezuroPlugin::ConfigurationContent.new(:profile => @profile, :name => @configuration.name, :configuration_id => 42) |
24 | @configuration_content.expects(:send_configuration_to_service).returns(nil) | 24 | @configuration_content.expects(:send_configuration_to_service).returns(nil) |
25 | @configuration_content.expects(:validate_configuration_name).returns(true) | 25 | @configuration_content.expects(:validate_configuration_name).returns(true) |
26 | - @configuration_content.stubs(:solr_save) | ||
27 | @configuration_content.save | 26 | @configuration_content.save |
28 | 27 | ||
29 | @base_tool = BaseToolFixtures.base_tool | 28 | @base_tool = BaseToolFixtures.base_tool |
plugins/mezuro/test/functional/myprofile/mezuro_plugin_range_controller_test.rb
@@ -21,7 +21,6 @@ class MezuroPluginRangeControllerTest < ActionController::TestCase | @@ -21,7 +21,6 @@ class MezuroPluginRangeControllerTest < ActionController::TestCase | ||
21 | @content = MezuroPlugin::ConfigurationContent.new(:profile => @profile, :name => @configuration.name, :configuration_id => 42) | 21 | @content = MezuroPlugin::ConfigurationContent.new(:profile => @profile, :name => @configuration.name, :configuration_id => 42) |
22 | @content.expects(:send_configuration_to_service).returns(nil) | 22 | @content.expects(:send_configuration_to_service).returns(nil) |
23 | @content.expects(:validate_configuration_name).returns(true) | 23 | @content.expects(:validate_configuration_name).returns(true) |
24 | - @content.stubs(:solr_save) | ||
25 | @content.save | 24 | @content.save |
26 | 25 | ||
27 | @created_range = RangeFixtures.created_range | 26 | @created_range = RangeFixtures.created_range |
plugins/mezuro/test/functional/myprofile/mezuro_plugin_reading_controller_test.rb
@@ -16,7 +16,6 @@ class MezuroPluginReadingControllerTest < ActionController::TestCase | @@ -16,7 +16,6 @@ class MezuroPluginReadingControllerTest < ActionController::TestCase | ||
16 | @reading_hash = ReadingFixtures.hash | 16 | @reading_hash = ReadingFixtures.hash |
17 | @content = MezuroPlugin::ReadingGroupContent.new(:profile => @profile, :name => name) | 17 | @content = MezuroPlugin::ReadingGroupContent.new(:profile => @profile, :name => name) |
18 | @content.expects(:send_reading_group_to_service).returns(nil) | 18 | @content.expects(:send_reading_group_to_service).returns(nil) |
19 | - @content.stubs(:solr_save) | ||
20 | @content.save | 19 | @content.save |
21 | end | 20 | end |
22 | 21 |
plugins/mezuro/test/functional/profile/mezuro_plugin_repository_controller_test.rb
@@ -21,7 +21,6 @@ class MezuroPluginRepositoryControllerTest < ActionController::TestCase | @@ -21,7 +21,6 @@ class MezuroPluginRepositoryControllerTest < ActionController::TestCase | ||
21 | @repository_hash = RepositoryFixtures.hash | 21 | @repository_hash = RepositoryFixtures.hash |
22 | @content = MezuroPlugin::ProjectContent.new(:profile => @profile, :name => name) | 22 | @content = MezuroPlugin::ProjectContent.new(:profile => @profile, :name => name) |
23 | @content.expects(:send_project_to_service).returns(nil) | 23 | @content.expects(:send_project_to_service).returns(nil) |
24 | - @content.stubs(:solr_save) | ||
25 | @content.save | 24 | @content.save |
26 | end | 25 | end |
27 | 26 |
plugins/mezuro/test/unit/mezuro_plugin/configuration_content_test.rb
@@ -48,7 +48,6 @@ class ConfigurationContentTest < ActiveSupport::TestCase | @@ -48,7 +48,6 @@ class ConfigurationContentTest < ActiveSupport::TestCase | ||
48 | 48 | ||
49 | should 'send configuration to service after saving' do | 49 | should 'send configuration to service after saving' do |
50 | @content.expects :send_configuration_to_service | 50 | @content.expects :send_configuration_to_service |
51 | - @content.stubs(:solr_save) | ||
52 | @content.run_callbacks :before_save | 51 | @content.run_callbacks :before_save |
53 | end | 52 | end |
54 | 53 |