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 | 33 | Debian-based systems, all of these packages are available through the Debian |
34 | 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 | 38 | On other systems, they may or may not be available through your regular package |
39 | 39 | management system. Below are the links to their homepages. |
... | ... | @@ -43,7 +43,6 @@ management system. Below are the links to their homepages. |
43 | 43 | * po4a: http://po4a.alioth.debian.org/ |
44 | 44 | * Ruby-sqlite3: http://rubyforge.org/projects/sqlite-ruby |
45 | 45 | * rcov: http://eigenclass.org/hiki/rcov |
46 | -* Solr: http://lucene.apache.org/solr | |
47 | 46 | * RMagick: http://rmagick.rubyforge.org/ |
48 | 47 | * RedCloth: http://redcloth.org/ |
49 | 48 | * will_paginate: http://github.com/mislav/will_paginate/wikis |
... | ... | @@ -111,9 +110,6 @@ $ tar -zxvf noosfero-0.39.0.tar.gz |
111 | 110 | $ ln -s noosfero-0.39.0 current |
112 | 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 | 113 | Create the thin configuration file: |
118 | 114 | |
119 | 115 | $ thin -C config/thin.yml -e production config |
... | ... | @@ -195,10 +191,6 @@ Compile the translations: |
195 | 191 | |
196 | 192 | $ RAILS_ENV=production rake noosfero:translations:compile |
197 | 193 | |
198 | -Run Solr: | |
199 | - | |
200 | -$ rake solr:start | |
201 | - | |
202 | 194 | Now we must create some initial data. To create your default environment |
203 | 195 | (the first one), run the command below: |
204 | 196 | ... | ... |
Rakefile
... | ... | @@ -7,6 +7,10 @@ require 'rake' |
7 | 7 | require 'rake/testtask' |
8 | 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 | 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 | 33 | def load_region_and_search |
34 | 34 | @region = environment.regions.find(params[:id]) |
35 | 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 | 37 | end |
38 | 38 | end |
39 | 39 | ... | ... |
app/controllers/application_controller.rb
... | ... | @@ -154,4 +154,18 @@ class ApplicationController < ActionController::Base |
154 | 154 | end |
155 | 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 | 171 | end | ... | ... |
app/controllers/my_profile/cms_controller.rb
... | ... | @@ -270,7 +270,7 @@ class CmsController < MyProfileController |
270 | 270 | |
271 | 271 | def search |
272 | 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 | 274 | render :text => article_list_to_json(results), :content_type => 'application/json' |
275 | 275 | end |
276 | 276 | ... | ... |
app/controllers/public/profile_search_controller.rb
... | ... | @@ -11,7 +11,7 @@ class ProfileSearchController < PublicController |
11 | 11 | if params[:where] == 'environment' |
12 | 12 | redirect_to :controller => 'search', :query => @q |
13 | 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 | 15 | end |
16 | 16 | end |
17 | 17 | end | ... | ... |
app/controllers/public/search_controller.rb
... | ... | @@ -4,10 +4,11 @@ class SearchController < PublicController |
4 | 4 | include SearchHelper |
5 | 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 | 8 | before_filter :load_category |
9 | 9 | before_filter :load_search_assets |
10 | 10 | before_filter :load_query |
11 | + before_filter :load_filter | |
11 | 12 | |
12 | 13 | # Backwards compatibility with old URLs |
13 | 14 | def redirect_asset_param |
... | ... | @@ -17,25 +18,51 @@ class SearchController < PublicController |
17 | 18 | |
18 | 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 | 61 | end |
32 | 62 | |
33 | 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 | 66 | end |
40 | 67 | |
41 | 68 | def contents |
... | ... | @@ -43,49 +70,23 @@ class SearchController < PublicController |
43 | 70 | end |
44 | 71 | |
45 | 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 | 75 | end |
52 | 76 | |
53 | 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 | 80 | end |
73 | 81 | |
74 | 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 | 85 | end |
82 | 86 | |
83 | 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 | 90 | end |
90 | 91 | |
91 | 92 | def events |
... | ... | @@ -93,7 +94,7 @@ class SearchController < PublicController |
93 | 94 | month = (params[:month] ? params[:month].to_i : Date.today.month) |
94 | 95 | day = (params[:day] ? params[:day].to_i : Date.today.day) |
95 | 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 | 99 | @selected_day = nil |
99 | 100 | @events_of_the_day = [] |
... | ... | @@ -104,64 +105,21 @@ class SearchController < PublicController |
104 | 105 | environment.events.by_day(@selected_day) |
105 | 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 | 112 | @calendar = populate_calendar(date, events) |
115 | 113 | @previous_calendar = populate_calendar(date - 1.month, events) |
116 | 114 | @next_calendar = populate_calendar(date + 1.month, events) |
117 | 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 | 117 | # keep old URLs workings |
139 | 118 | def assets |
140 | 119 | params[:action] = params[:asset].is_a?(Array) ? :index : params.delete(:asset) |
141 | 120 | redirect_to params |
142 | 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 | 123 | def tags |
166 | 124 | @tags_cache_key = "tags_env_#{environment.id.to_s}" |
167 | 125 | if is_cache_expired?(@tags_cache_key) |
... | ... | @@ -173,7 +131,7 @@ class SearchController < PublicController |
173 | 131 | @tag = params[:tag] |
174 | 132 | @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}" |
175 | 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 | 135 | end |
178 | 136 | end |
179 | 137 | |
... | ... | @@ -187,11 +145,9 @@ class SearchController < PublicController |
187 | 145 | protected |
188 | 146 | |
189 | 147 | def load_query |
190 | - @asset = params[:action].to_sym | |
148 | + @asset = (params[:asset] || params[:action]).to_sym | |
191 | 149 | @order ||= [@asset] |
192 | - @results ||= {} | |
193 | - @filter = filter | |
194 | - @filter_title = filter_description(@asset, @filter) | |
150 | + @searches ||= {} | |
195 | 151 | |
196 | 152 | @query = params[:query] || '' |
197 | 153 | @empty_query = @category.nil? && @query.blank? |
... | ... | @@ -211,42 +167,13 @@ class SearchController < PublicController |
211 | 167 | end |
212 | 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 | 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 | 172 | render_not_found |
246 | 173 | return |
247 | 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 | 177 | @searching = {} |
251 | 178 | @titles = {} |
252 | 179 | @enabled_searches.each do |key, name| |
... | ... | @@ -256,13 +183,19 @@ class SearchController < PublicController |
256 | 183 | @names = @titles if @names.nil? |
257 | 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 | 194 | def limit |
260 | - if map_search? | |
195 | + if map_search?(@searches) | |
261 | 196 | MAP_SEARCH_LIMIT |
262 | 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 | 199 | BLOCKS_SEARCH_LIMIT |
267 | 200 | else |
268 | 201 | LIST_SEARCH_LIMIT |
... | ... | @@ -273,41 +206,12 @@ class SearchController < PublicController |
273 | 206 | end |
274 | 207 | |
275 | 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 | 210 | { :per_page => limit, :page => page } |
278 | 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 | 215 | end |
312 | 216 | |
313 | 217 | private | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -274,9 +274,9 @@ module ApplicationHelper |
274 | 274 | |
275 | 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 | 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 | 281 | search_name = String.new(name) |
282 | 282 | if search_name.include?("/") |
... | ... | @@ -291,14 +291,14 @@ module ApplicationHelper |
291 | 291 | return name if File.exists?(File.join(path)) |
292 | 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 | 295 | end |
296 | 296 | |
297 | - def partial_for_class(klass, suffix=nil) | |
297 | + def partial_for_class(klass, prefix=nil, suffix=nil) | |
298 | 298 | raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' if klass.nil? |
299 | 299 | name = klass.name.underscore |
300 | 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 | 302 | return partial if partial |
303 | 303 | end |
304 | 304 | ... | ... |
app/helpers/search_helper.rb
... | ... | @@ -2,12 +2,10 @@ module SearchHelper |
2 | 2 | |
3 | 3 | MAP_SEARCH_LIMIT = 2000 |
4 | 4 | LIST_SEARCH_LIMIT = 20 |
5 | - BLOCKS_SEARCH_LIMIT = 18 | |
5 | + BLOCKS_SEARCH_LIMIT = 24 | |
6 | 6 | MULTIPLE_SEARCH_LIMIT = 8 |
7 | - DistFilt = 200 | |
8 | - DistBoost = 50 | |
9 | 7 | |
10 | - Searches = ActiveSupport::OrderedHash[ | |
8 | + SEARCHES = ActiveSupport::OrderedHash[ | |
11 | 9 | :articles, _('Contents'), |
12 | 10 | :enterprises, _('Enterprises'), |
13 | 11 | :people, _('People'), |
... | ... | @@ -16,46 +14,31 @@ module SearchHelper |
16 | 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 | 24 | # FIXME remove it after search_controler refactored |
46 | 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 | 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 | 37 | end |
55 | 38 | |
56 | 39 | def search_page_title(title, category = nil) |
57 | 40 | title = "<h1>" + title |
58 | - title += '<small>' + category.name + '</small>' if category | |
41 | + title += ' - <small>' + category.name + '</small>' if category | |
59 | 42 | title + "</h1>" |
60 | 43 | end |
61 | 44 | |
... | ... | @@ -66,8 +49,12 @@ module SearchHelper |
66 | 49 | :align => 'center', :class => 'search-category-context') if category |
67 | 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 | 58 | partial = 'google_maps' |
72 | 59 | klass = 'map' |
73 | 60 | else |
... | ... | @@ -78,10 +65,13 @@ module SearchHelper |
78 | 65 | content_tag('div', render(:partial => partial), :class => "map-or-list-search-results #{klass}") |
79 | 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 | 75 | end |
86 | 76 | |
87 | 77 | def city_with_state(city) |
... | ... | @@ -97,120 +87,50 @@ module SearchHelper |
97 | 87 | end |
98 | 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 | 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 | 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 | 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 | 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 | 134 | end |
215 | 135 | |
216 | 136 | end | ... | ... |
app/models/article.rb
... | ... | @@ -2,6 +2,26 @@ require 'hpricot' |
2 | 2 | |
3 | 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 | 25 | #FIXME This is necessary because html is being generated on the model... |
6 | 26 | include ActionView::Helpers::TagHelper |
7 | 27 | |
... | ... | @@ -147,7 +167,6 @@ class Article < ActiveRecord::Base |
147 | 167 | else |
148 | 168 | ArticleCategorization.add_category_to_article(c, self) |
149 | 169 | self.categories(reload) |
150 | - self.solr_save | |
151 | 170 | end |
152 | 171 | end |
153 | 172 | |
... | ... | @@ -165,7 +184,6 @@ class Article < ActiveRecord::Base |
165 | 184 | ArticleCategorization.add_category_to_article(item, self) |
166 | 185 | end |
167 | 186 | self.categories(true) |
168 | - self.solr_save | |
169 | 187 | pending_categorizations.clear |
170 | 188 | end |
171 | 189 | |
... | ... | @@ -201,20 +219,12 @@ class Article < ActiveRecord::Base |
201 | 219 | named_scope :public, |
202 | 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 | 222 | # retrives the most commented articles, sorted by the comment count (largest |
212 | 223 | # first) |
213 | 224 | def self.most_commented(limit) |
214 | 225 | paginate(:order => 'comments_count DESC', :page => 1, :per_page => limit) |
215 | 226 | end |
216 | 227 | |
217 | - named_scope :more_popular, :order => 'hits DESC' | |
218 | 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 | 230 | def self.recent(limit = nil, extra_conditions = {}, pagination = true) |
... | ... | @@ -426,8 +436,8 @@ class Article < ActiveRecord::Base |
426 | 436 | named_scope :images, :conditions => { :is_image => true } |
427 | 437 | named_scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ] |
428 | 438 | |
439 | + named_scope :more_popular, :order => 'hits DESC' | |
429 | 440 | named_scope :more_comments, :order => "comments_count DESC" |
430 | - named_scope :more_views, :order => "hits DESC" | |
431 | 441 | named_scope :more_recent, :order => "created_at DESC" |
432 | 442 | |
433 | 443 | def self.display_filter(user, profile) |
... | ... | @@ -479,10 +489,6 @@ class Article < ActiveRecord::Base |
479 | 489 | allow_post_content?(user) || user && allow_members_to_edit && user.is_member_of?(profile) |
480 | 490 | end |
481 | 491 | |
482 | - def comments_updated | |
483 | - solr_save | |
484 | - end | |
485 | - | |
486 | 492 | def accept_category?(cat) |
487 | 493 | !cat.is_a?(ProductCategory) |
488 | 494 | end |
... | ... | @@ -620,7 +626,7 @@ class Article < ActiveRecord::Base |
620 | 626 | |
621 | 627 | end |
622 | 628 | |
623 | - def more_views_label | |
629 | + def more_popular_label | |
624 | 630 | amount = self.hits |
625 | 631 | { |
626 | 632 | 0 => _('no views'), |
... | ... | @@ -648,98 +654,7 @@ class Article < ActiveRecord::Base |
648 | 654 | img.nil? ? '' : img.attributes['src'] |
649 | 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 | 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 | 659 | private |
745 | 660 | ... | ... |
app/models/category.rb
1 | 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 | 10 | validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('%{fn} cannot be like that.').fix_i18n |
4 | 11 | validates_presence_of :name, :environment_id |
5 | 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 | 107 | self.children.find(:all, :conditions => {:display_in_menu => true}).empty? |
101 | 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 | 110 | end | ... | ... |
app/models/certifier.rb
1 | 1 | class Certifier < ActiveRecord::Base |
2 | 2 | |
3 | + SEARCHABLE_FIELDS = { | |
4 | + :name => 10, | |
5 | + :description => 3, | |
6 | + :link => 1, | |
7 | + } | |
8 | + | |
3 | 9 | belongs_to :environment |
4 | 10 | |
5 | 11 | has_many :qualifier_certifiers, :dependent => :destroy |
... | ... | @@ -24,6 +30,4 @@ class Certifier < ActiveRecord::Base |
24 | 30 | self.name.downcase.transliterate <=> b.name.downcase.transliterate |
25 | 31 | end |
26 | 32 | |
27 | - after_save_reindex [:products], :with => :delayed_job | |
28 | - | |
29 | 33 | end | ... | ... |
app/models/comment.rb
1 | 1 | class Comment < ActiveRecord::Base |
2 | 2 | |
3 | + SEARCHABLE_FIELDS = { | |
4 | + :title => 10, | |
5 | + :name => 4, | |
6 | + :body => 2, | |
7 | + } | |
8 | + | |
3 | 9 | validates_presence_of :body |
4 | 10 | |
5 | 11 | belongs_to :source, :counter_cache => true, :polymorphic => true |
... | ... | @@ -78,12 +84,6 @@ class Comment < ActiveRecord::Base |
78 | 84 | self.article.profile.notification_emails - [self.author_email || self.email] |
79 | 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 | 87 | after_create :new_follower |
88 | 88 | def new_follower |
89 | 89 | if source.kind_of?(Article) | ... | ... |
app/models/enterprise.rb
... | ... | @@ -2,6 +2,8 @@ |
2 | 2 | # only enterprises can offer products and services. |
3 | 3 | class Enterprise < Organization |
4 | 4 | |
5 | + SEARCH_DISPLAYS += %w[map full] | |
6 | + | |
5 | 7 | def self.type_name |
6 | 8 | _('Enterprise') |
7 | 9 | end |
... | ... | @@ -14,8 +16,6 @@ class Enterprise < Organization |
14 | 16 | |
15 | 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 | 19 | def product_categories |
20 | 20 | products.includes(:product_category).map{|p| p.category_full_name}.compact |
21 | 21 | end |
... | ... | @@ -189,4 +189,8 @@ class Enterprise < Organization |
189 | 189 | { :profile => identifier, :controller => 'catalog'} |
190 | 190 | end |
191 | 191 | |
192 | + def more_recent_label | |
193 | + '' | |
194 | + end | |
195 | + | |
192 | 196 | end | ... | ... |
app/models/environment.rb
... | ... | @@ -268,8 +268,6 @@ class Environment < ActiveRecord::Base |
268 | 268 | |
269 | 269 | settings_items :search_hints, :type => Hash, :default => {} |
270 | 270 | |
271 | - settings_items :top_level_category_as_facet_ids, :type => Array, :default => [] | |
272 | - | |
273 | 271 | def news_amount_by_folder=(amount) |
274 | 272 | settings[:news_amount_by_folder] = amount.to_i |
275 | 273 | end | ... | ... |
app/models/license.rb
app/models/national_region.rb
app/models/organization.rb
app/models/person.rb
app/models/product.rb
1 | 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 | 18 | belongs_to :enterprise |
4 | 19 | has_one :region, :through => :enterprise |
5 | 20 | validates_presence_of :enterprise |
... | ... | @@ -173,7 +188,7 @@ class Product < ActiveRecord::Base |
173 | 188 | |
174 | 189 | def price_described? |
175 | 190 | return false if price.blank? or price == 0 |
176 | - (price - total_production_cost).zero? | |
191 | + (price - total_production_cost.to_f).zero? | |
177 | 192 | end |
178 | 193 | |
179 | 194 | def update_price_details(price_details) |
... | ... | @@ -215,89 +230,6 @@ class Product < ActiveRecord::Base |
215 | 230 | end |
216 | 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 | 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 | 235 | end | ... | ... |
app/models/product_category.rb
app/models/profile.rb
... | ... | @@ -3,10 +3,20 @@ |
3 | 3 | # which by default is the one returned by Environment:default. |
4 | 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 | 20 | end |
11 | 21 | |
12 | 22 | module Roles |
... | ... | @@ -127,18 +137,6 @@ class Profile < ActiveRecord::Base |
127 | 137 | scrap.nil? ? Scrap.all_scraps(self) : Scrap.all_scraps(self).find(scrap) |
128 | 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 | 140 | acts_as_having_settings :field => :data |
143 | 141 | |
144 | 142 | def settings |
... | ... | @@ -262,7 +260,6 @@ class Profile < ActiveRecord::Base |
262 | 260 | else |
263 | 261 | ProfileCategorization.add_category_to_profile(c, self) |
264 | 262 | self.categories(true) |
265 | - self.solr_save | |
266 | 263 | end |
267 | 264 | self.categories(reload) |
268 | 265 | end |
... | ... | @@ -894,86 +891,6 @@ private :generate_url, :url_options |
894 | 891 | self.active_fields |
895 | 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 | 894 | def control_panel_settings_button |
978 | 895 | {:title => _('Profile Info and settings'), :icon => 'edit-profile'} |
979 | 896 | end | ... | ... |
app/models/qualifier.rb
1 | 1 | class Qualifier < ActiveRecord::Base |
2 | 2 | |
3 | + SEARCHABLE_FIELDS = { | |
4 | + :name => 1, | |
5 | + } | |
6 | + | |
3 | 7 | belongs_to :environment |
4 | 8 | |
5 | 9 | has_many :qualifier_certifiers, :dependent => :destroy |
... | ... | @@ -15,6 +19,4 @@ class Qualifier < ActiveRecord::Base |
15 | 19 | self.name.downcase.transliterate <=> b.name.downcase.transliterate |
16 | 20 | end |
17 | 21 | |
18 | - after_save_reindex [:products], :with => :delayed_job | |
19 | - | |
20 | 22 | end | ... | ... |
app/models/region.rb
... | ... | @@ -4,12 +4,6 @@ class Region < Category |
4 | 4 | |
5 | 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 | 7 | def has_validator? |
14 | 8 | validators.count > 0 |
15 | 9 | end | ... | ... |
app/models/scrap.rb
app/views/layouts/application-ng.rhtml
app/views/map_balloon/product.rhtml
app/views/search/_article.rhtml
... | ... | @@ -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 | -<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 | 1 | <div id="search-results" class="<%= !multiple_search? ? 'only-one-result-box' : 'multiple-results-boxes' %>"> |
2 | 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 | 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 | 12 | <% end %> |
15 | 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 | 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 | 24 | </ul> |
23 | 25 | </div> |
24 | 26 | <% else %> | ... | ... |
app/views/search/_event.rhtml
... | ... | @@ -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 | -<% 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 | -<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 | -<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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 | -<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 | 13 | <script type='text/javascript'> |
14 | 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 | 18 | <% if item.lat && item.lng %> |
19 | 19 | mapPutMarker(<%= item.lat.to_json %>, <%= item.lng.to_json %>, <%= item.name.to_json %>, '<%= icon %>', |
20 | 20 | '<%= url_for(:controller => :map_balloon, :action => name.to_s.singularize, :id => item.id) %>'); | ... | ... |
... | ... | @@ -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 | -<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 | -<% 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 | -<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 | 5 | <div style="clear: both"></div> |
21 | 6 | </div> | ... | ... |
app/views/search/_search_form.rhtml
... | ... | @@ -4,16 +4,7 @@ |
4 | 4 | :method => 'get', :class => 'search_form' ) do %> |
5 | 5 | |
6 | 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 | 9 | <div class="search-field"> |
19 | 10 | <span class="formfield"> |
... | ... | @@ -24,6 +15,8 @@ |
24 | 15 | <%= submit_button(:search, _('Search')) %> |
25 | 16 | </div> |
26 | 17 | |
18 | + <%= render :partial => 'search_form_extra_fields' %> | |
19 | + | |
27 | 20 | <% end %> |
28 | 21 | |
29 | 22 | <% if @empty_query %> | ... | ... |
... | ... | @@ -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 | -<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 | -<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 | -<%= 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 @@ |
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 | -<%= 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 | -<%= 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 @@ |
1 | +<%= render :partial => 'events/agenda' %> | ... | ... |
app/views/search/events.rhtml
app/views/search/facets_browse.rhtml
... | ... | @@ -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 | <%= search_page_title(_('Search Results'), @category) %> |
8 | 8 | <%= render :partial => 'search_form', :locals => { :hint => '' } %> |
9 | 9 | <%= category_context(@category, params) %> |
10 | - <%= display_results %> | |
10 | + <%= display_results(@searches, @asset) %> | |
11 | 11 | |
12 | 12 | <div id="category-childs"> |
13 | 13 | <% if @category %> | ... | ... |
app/views/search/people.rhtml
... | ... | @@ -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 | -<%= 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 @@ |
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
app/views/tasks/_task.rhtml
... | ... | @@ -50,13 +50,13 @@ |
50 | 50 | <% fields_for "tasks[#{task.id}][task]", task do |f| %> |
51 | 51 | <% if task.accept_details %> |
52 | 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 | 54 | </div> |
55 | 55 | <% end %> |
56 | 56 | |
57 | 57 | <% if task.reject_details %> |
58 | 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 | 60 | </div> |
61 | 61 | <% end %> |
62 | 62 | <% end %> | ... | ... |
config/initializers/dependencies.rb
config/solr.yml.dist
... | ... | @@ -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
debian/noosfero.links
... | ... | @@ -2,7 +2,6 @@ usr/share/rails-ruby1.8 usr/share/noosfero/vendor/ra |
2 | 2 | var/tmp/noosfero usr/share/noosfero/tmp |
3 | 3 | var/log/noosfero usr/share/noosfero/log |
4 | 4 | etc/noosfero/database.yml usr/share/noosfero/config/database.yml |
5 | -etc/noosfero/solr.yml usr/share/noosfero/config/solr.yml | |
6 | 5 | etc/noosfero/thin.yml usr/share/noosfero/config/thin.yml |
7 | 6 | etc/noosfero/plugins usr/share/noosfero/config/plugins |
8 | 7 | etc/noosfero/noosfero.yml usr/share/noosfero/config/noosfero.yml | ... | ... |
debian/solr.yml
... | ... | @@ -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 | 45 | fi |
46 | 46 | |
47 | 47 | ###################### |
48 | -SOLR_PID_FILE=$NOOSFERO_DIR/tmp/pids/solr.production.pid | |
49 | 48 | |
50 | 49 | main_script() { |
51 | 50 | cd $NOOSFERO_DIR |
52 | 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 | 53 | else |
55 | - SOLR_DATA_PATH=/var/lib/noosfero-data/index ./script/production $1 | |
54 | + ./script/production $1 | |
56 | 55 | fi |
57 | 56 | } |
58 | 57 | |
... | ... | @@ -78,13 +77,6 @@ do_setup() { |
78 | 77 | chmod 750 /var/tmp/noosfero |
79 | 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 | 80 | # symlink the directories into Noosfero directory |
89 | 81 | if [ ! -e $NOOSFERO_DIR/tmp ]; then |
90 | 82 | ln -s /var/tmp/noosfero $NOOSFERO_DIR/tmp |
... | ... | @@ -98,28 +90,21 @@ do_setup() { |
98 | 90 | } |
99 | 91 | |
100 | 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 | 99 | fi |
107 | - | |
108 | - do_setup | |
109 | - | |
110 | - # actually start the service | |
111 | - main_script start | |
112 | 100 | } |
113 | 101 | |
114 | 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 | 107 | fi |
121 | - | |
122 | - main_script stop | |
123 | 108 | } |
124 | 109 | |
125 | 110 | do_restart() { |
... | ... | @@ -127,6 +112,10 @@ do_restart() { |
127 | 112 | do_start |
128 | 113 | } |
129 | 114 | |
115 | +running(){ | |
116 | + pgrep -u noosfero -f server > /dev/null | |
117 | +} | |
118 | + | |
130 | 119 | case "$1" in |
131 | 120 | start|stop|restart|setup) |
132 | 121 | do_$1 | ... | ... |
features/support/env.rb
gitignore.example
... | ... | @@ -8,7 +8,6 @@ config/database.yml |
8 | 8 | config/session.secret |
9 | 9 | config/noosfero.yml |
10 | 10 | config/mongrel_cluster.yml |
11 | -config/solr.yml | |
12 | 11 | config/plugins |
13 | 12 | config/thin.yml |
14 | 13 | config/local.rb |
... | ... | @@ -32,7 +31,6 @@ doc/noosfero/*.xhtml |
32 | 31 | doc/noosfero/*/*.xhtml |
33 | 32 | tags |
34 | 33 | pkg |
35 | -solr | |
36 | 34 | *~ |
37 | 35 | *.swp |
38 | 36 | debian/*.log | ... | ... |
lib/acts_as_faceted.rb
... | ... | @@ -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 | -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 | 13 | key.join('/') |
14 | 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 | 29 | end | ... | ... |
lib/noosfero/plugin.rb
... | ... | @@ -16,38 +16,52 @@ class Noosfero::Plugin |
16 | 16 | if Rails.env.test? && !enabled_plugins.include?(File.join(Rails.root, 'config', 'plugins', 'foo')) |
17 | 17 | enabled_plugins << File.join(Rails.root, 'plugins', 'foo') |
18 | 18 | end |
19 | + | |
19 | 20 | enabled_plugins.select do |entry| |
20 | 21 | File.directory?(entry) |
21 | 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 | 38 | end |
50 | 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 | 65 | end |
52 | 66 | |
53 | 67 | def all |
... | ... | @@ -380,6 +394,13 @@ class Noosfero::Plugin |
380 | 394 | nil |
381 | 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 | 404 | # -> Adds additional blocks to profiles and environments. |
384 | 405 | # Your plugin must implements a class method called 'extra_blocks' |
385 | 406 | # that returns a hash with the following syntax. | ... | ... |
lib/noosfero/plugin/manager.rb
... | ... | @@ -23,12 +23,36 @@ class Noosfero::Plugin::Manager |
23 | 23 | dispatch_without_flatten(event, *args).flatten |
24 | 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 | 30 | def dispatch_without_flatten(event, *args) |
27 | 31 | map { |plugin| plugin.send(event, *args) }.compact |
28 | 32 | end |
29 | 33 | |
30 | 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 | 56 | def enabled_plugins |
33 | 57 | @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin| |
34 | 58 | p = plugin.constantize.new | ... | ... |
lib/set_profile_region_from_city_state.rb
... | ... | @@ -11,6 +11,7 @@ module SetProfileRegionFromCityState |
11 | 11 | end |
12 | 12 | |
13 | 13 | module InstanceMethods |
14 | + include Noosfero::Plugin::HotSpot | |
14 | 15 | |
15 | 16 | def city_with_region=(value) |
16 | 17 | self.city_without_region = value |
... | ... | @@ -24,16 +25,20 @@ module SetProfileRegionFromCityState |
24 | 25 | |
25 | 26 | def region_from_city_and_state |
26 | 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 | 31 | end |
35 | 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 | 42 | end |
38 | 43 | |
39 | 44 | end | ... | ... |
lib/tasks/multitenancy.rake
... | ... | @@ -14,22 +14,6 @@ namespace :multitenancy do |
14 | 14 | (file_envs - db_envs.map{ |e| e + '.rb' }).each { |env| safe_unlink env } |
15 | 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 | 17 | end |
34 | 18 | |
35 | 19 | namespace :db do | ... | ... |
lib/tasks/release.rake
1 | 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 | 15 | desc 'checks if there are uncommitted changes in the repo' |
4 | 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 | 19 | end |
10 | 20 | end |
11 | 21 | |
... | ... | @@ -85,6 +95,80 @@ EOF |
85 | 95 | rm_f 'AUTHORS' |
86 | 96 | raise e |
87 | 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 | 172 | end |
89 | 173 | |
90 | 174 | def ask(message) |
... | ... | @@ -179,8 +263,6 @@ EOF |
179 | 263 | mkdir "#{target}/tmp" |
180 | 264 | ln_s '../../../vendor/rails', "#{target}/vendor/rails" |
181 | 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 | 267 | sh "cd #{target} && dpkg-buildpackage -us -uc -b" |
186 | 268 | end | ... | ... |
plugins/mezuro/script/install/install-rvm.sh
... | ... | @@ -100,7 +100,6 @@ cd mezuro |
100 | 100 | git checkout mezuro-dev |
101 | 101 | rvm use ruby-1.8.7-p302@mezuro |
102 | 102 | cp config/database.yml.sqlite3 config/database.yml |
103 | -cp config/solr.yml.dist config/solr.yml | |
104 | 103 | cp plugins/mezuro/service.yml.example plugins/mezuro/service.yml |
105 | 104 | cp plugins/mezuro/licenses.yml.example plugins/mezuro/licenses.yml |
106 | 105 | mkdir tmp |
... | ... | @@ -116,5 +115,4 @@ ln -s mezuro-theme/ default |
116 | 115 | cd ../../../ |
117 | 116 | |
118 | 117 | #Prepare Mezuro for running functional and unit tests |
119 | -rake solr:download | |
120 | -rake db:test:prepare | |
121 | 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 | 23 | @configuration_content = MezuroPlugin::ConfigurationContent.new(:profile => @profile, :name => @configuration.name, :configuration_id => 42) |
24 | 24 | @configuration_content.expects(:send_configuration_to_service).returns(nil) |
25 | 25 | @configuration_content.expects(:validate_configuration_name).returns(true) |
26 | - @configuration_content.stubs(:solr_save) | |
27 | 26 | @configuration_content.save |
28 | 27 | |
29 | 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 | 21 | @content = MezuroPlugin::ConfigurationContent.new(:profile => @profile, :name => @configuration.name, :configuration_id => 42) |
22 | 22 | @content.expects(:send_configuration_to_service).returns(nil) |
23 | 23 | @content.expects(:validate_configuration_name).returns(true) |
24 | - @content.stubs(:solr_save) | |
25 | 24 | @content.save |
26 | 25 | |
27 | 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 | 16 | @reading_hash = ReadingFixtures.hash |
17 | 17 | @content = MezuroPlugin::ReadingGroupContent.new(:profile => @profile, :name => name) |
18 | 18 | @content.expects(:send_reading_group_to_service).returns(nil) |
19 | - @content.stubs(:solr_save) | |
20 | 19 | @content.save |
21 | 20 | end |
22 | 21 | ... | ... |
plugins/mezuro/test/functional/profile/mezuro_plugin_repository_controller_test.rb
... | ... | @@ -21,7 +21,6 @@ class MezuroPluginRepositoryControllerTest < ActionController::TestCase |
21 | 21 | @repository_hash = RepositoryFixtures.hash |
22 | 22 | @content = MezuroPlugin::ProjectContent.new(:profile => @profile, :name => name) |
23 | 23 | @content.expects(:send_project_to_service).returns(nil) |
24 | - @content.stubs(:solr_save) | |
25 | 24 | @content.save |
26 | 25 | end |
27 | 26 | ... | ... |
plugins/mezuro/test/unit/mezuro_plugin/configuration_content_test.rb
... | ... | @@ -48,7 +48,6 @@ class ConfigurationContentTest < ActiveSupport::TestCase |
48 | 48 | |
49 | 49 | should 'send configuration to service after saving' do |
50 | 50 | @content.expects :send_configuration_to_service |
51 | - @content.stubs(:solr_save) | |
52 | 51 | @content.run_callbacks :before_save |
53 | 52 | end |
54 | 53 | ... | ... |