Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'add-elasticsearch-indexing'

Conflicts:
	Gemfile.lock
	app/views/shared/_navigation.html.haml
  • Loading branch information...
commit 15d998abdb2db7be3ff1b6ba51773085de6f791e 2 parents af65165 + d44b887
Paul Smith elandesign authored
1  Gemfile
@@ -4,6 +4,7 @@ gem 'rails', '3.2.6'
4 4
5 5 gem 'nokogiri'
6 6 gem 'mongoid', '~> 2.4.10'
  7 +gem 'tire'
7 8
8 9 gem 'haml'
9 10 gem 'htmlentities', "~> 4.3.0"
8 Gemfile.lock
@@ -86,6 +86,7 @@ GEM
86 86 libxml-ruby (~> 2.0)
87 87 has_scope (0.5.1)
88 88 hashie (1.2.0)
  89 + hashr (0.0.21)
89 90 hike (1.2.1)
90 91 hoptoad_notifier (2.4.11)
91 92 activesupport
@@ -246,6 +247,12 @@ GEM
246 247 rack (>= 1.0.0)
247 248 thor (0.15.2)
248 249 tilt (1.3.3)
  250 + tire (0.4.2)
  251 + activemodel (>= 3.0)
  252 + hashr (~> 0.0.19)
  253 + multi_json (~> 1.0)
  254 + rake
  255 + rest-client (~> 1.6)
249 256 treetop (1.4.10)
250 257 polyglot
251 258 polyglot (>= 0.3.1)
@@ -313,6 +320,7 @@ DEPENDENCIES
313 320 ruby-fogbugz
314 321 therubyracer
315 322 thin
  323 + tire
316 324 twitter-bootstrap-rails
317 325 uglifier (>= 1.0.3)
318 326 unicorn
20 app/assets/stylesheets/errbit.css
@@ -122,6 +122,26 @@ a.action { float: right; font-size: 0.9em;}
122 122 -webkit-border-top-right-radius: 12px;
123 123 border: 1px solid #bbb;
124 124 }
  125 +#nav-bar li.search {
  126 + background-color: transparent;
  127 + border: none;
  128 + border-top-left-radius: 0;
  129 + border-top-right-radius: 0;
  130 + -moz-border-top-left-radius: 0;
  131 + -moz-border-top-right-radius: 0;
  132 + -webkit-border-top-left-radius: 0;
  133 + -webkit-border-top-right-radius: 0;
  134 +}
  135 +#nav-bar li.search input {
  136 + padding: 0 5px;
  137 + margin: 0;
  138 + width: auto;
  139 + border: none;
  140 + line-height: 34px;
  141 + position: relative;
  142 + top: -15px;
  143 + left: 15px;
  144 +}
125 145 #nav-bar li.active {
126 146 border-color: #fff;
127 147 background: #FFF url(images/button-bg.png) 0 -2px repeat-x;
15 app/controllers/errs_controller.rb
... ... @@ -1,8 +1,8 @@
1 1 class ErrsController < ApplicationController
2 2 include ActionView::Helpers::TextHelper
3 3
4   - before_filter :find_app, :except => [:index, :all, :destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several]
5   - before_filter :find_problem, :except => [:index, :all, :destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several]
  4 + before_filter :find_app, :except => [:index, :all, :destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several, :search]
  5 + before_filter :find_problem, :except => [:index, :all, :destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several, :search]
6 6 before_filter :find_selected_problems, :only => [:destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several]
7 7 before_filter :set_sorting_params, :only => [:index, :all]
8 8 before_filter :set_tracker_params, :only => [:create_issue]
@@ -20,6 +20,17 @@ def index
20 20 end
21 21 end
22 22
  23 + def search
  24 + raise "Elastic Search is not enabled" unless Errbit::Config.elasticsearch_enabled
  25 + visible_apps = current_user.admin? ? App.all : current_user.apps
  26 + if params[:app_id]
  27 + visible_apps = visible_apps.where(:_id => params[:app_id])
  28 + end
  29 + @search = Search.new(params, :apps => visible_apps.map(&:id))
  30 + @problems = @search.results
  31 + @selected_problems = params[:problems] || []
  32 + end
  33 +
23 34 def all
24 35 app_scope = current_user.admin? ? App.all : current_user.apps
25 36 @problems = Problem.for_apps(app_scope).ordered_by(@sort, @order).page(params[:page]).per(current_user.per_page)
10 app/helpers/application_helper.rb
@@ -82,6 +82,16 @@ def create_percentage_table_from_tallies(tallies, options={})
82 82 render "errs/tally_table", :rows => rows
83 83 end
84 84
  85 + def search_path
  86 + if params[:controller] == 'apps' && params[:action] == 'show'
  87 + search_app_errs_path(:app_id => params[:id])
  88 + elsif params[:app_id]
  89 + search_app_errs_path(:app_id => params[:app_id])
  90 + else
  91 + search_errs_path
  92 + end
  93 + end
  94 +
85 95 private
86 96 def total_from_tallies(tallies)
87 97 tallies.values.inject(0) {|sum, n| sum + n}
1  app/helpers/sort_helper.rb
@@ -2,6 +2,7 @@
2 2 module SortHelper
3 3
4 4 def link_for_sort(name, field=nil)
  5 + return name if params[:action] == 'search'
5 6 field ||= name.underscore
6 7 current = (@sort == field)
7 8 order = (current && (@order == "asc")) ? "desc" : "asc"
18 app/models/problem.rb
@@ -42,6 +42,24 @@ class Problem
42 42 scope :ordered, order_by(:last_notice_at.desc)
43 43 scope :for_apps, lambda {|apps| where(:app_id.in => apps.all.map(&:id))}
44 44
  45 + include Tire::Model::Search
  46 + mapping do
  47 + indexes :app_id, :index => :not_analyzed
  48 + indexes :app_name, :index => :not_analyzed
  49 + indexes :error_class, :analyzer => :snowball
  50 + indexes :where, :analyzer => :snowball
  51 + indexes :message, :analyzer => :snowball
  52 + indexes :environment, :index => :not_analyzed
  53 + indexes :resolved, :index => :not_analyzed
  54 + indexes :last_notice_at, :index => :not_analyzed
  55 + end
  56 +
  57 + after_save :update_index, :if => lambda { Errbit::Config.elasticsearch_enabled }
  58 + after_destroy :update_index, :if => lambda { Errbit::Config.elasticsearch_enabled }
  59 +
  60 + def update_index
  61 + tire.update_index
  62 + end
45 63
46 64 def self.in_env(env)
47 65 env.present? ? where(:environment => env) : scoped
30 app/models/search.rb
... ... @@ -0,0 +1,30 @@
  1 +class Search
  2 +
  3 + attr_reader :terms, :show_resolved
  4 +
  5 + def initialize(params, options = {})
  6 + @apps = options[:apps] || []
  7 + @terms = params[:terms]
  8 + @show_resolved = params[:resolved].present?
  9 + build_search
  10 + end
  11 +
  12 + def results
  13 + @search.results
  14 + end
  15 +
  16 + private
  17 +
  18 + def build_search
  19 + @search = Tire.search('problems', :load => true) do |search|
  20 + search.query do |query|
  21 + query.boolean do |it|
  22 + it.must { |have| have.terms :app_id, @apps }
  23 + it.must { |have| have.string "#{self.terms}*" }
  24 + it.must { |have| have.term :resolved, false } unless self.show_resolved
  25 + end
  26 + end
  27 + end
  28 + end
  29 +
  30 +end
7 app/views/errs/search.html.haml
... ... @@ -0,0 +1,7 @@
  1 +- content_for :title, 'Search Results'
  2 +- content_for :action_bar do
  3 + - if params[:resolved].present?
  4 + = link_to 'hide resolved', params.except(:resolved), {:class => 'button'}
  5 + - else
  6 + = link_to 'show resolved', params.merge({:resolved => true}), {:class => 'button'}
  7 += render 'table', :errs => @problems
5 app/views/shared/_navigation.html.haml
@@ -18,5 +18,6 @@
18 18 %li.divider-vertical
19 19 - if user_signed_in? && current_user.admin?
20 20 %li.users{:class => active_if_here(:users)}= link_to 'Users', users_path
21   - %form{:class => 'navbar-search pull-left'}
22   - %input{:type => 'text', :class => 'search-query span2', :placeholder => 'Search'}
  21 + - if Errbit::Config.elasticsearch_enabled
  22 + = form_tag search_path, {:method => :get, :class => 'navbar-search pull-left'} do
  23 + %input{:type => 'text', :class => 'search-query span2', :placeholder => 'Search', :name => 'terms', :value => @search.present? ? @search.terms : ''}
4 config/config.example.yml
@@ -39,6 +39,10 @@ user_has_username: false
39 39 # but you want to leave a short comment.
40 40 allow_comments_with_issue_tracker: true
41 41
  42 +# Index any problems in ElasticSearch
  43 +elasticsearch_enabled: true
  44 +elasticsearch_url: http://localhost:9200
  45 +
42 46 # Setup your deploy options for capistrano.
43 47 deployment:
44 48 hosts:
6 config/initializers/tire.rb
... ... @@ -0,0 +1,6 @@
  1 +if Errbit::Config.elasticsearch_enabled
  2 + Tire.configure do
  3 + url Errbit::Config.elasticsearch_url
  4 + logger Rails.root.join("log", "elasticsearch.#{Rails.env}.log") unless Rails.env.production?
  5 + end
  6 +end
5 config/routes.rb
@@ -21,6 +21,7 @@
21 21 post :merge_several
22 22 post :unmerge_several
23 23 get :all
  24 + get :search
24 25 end
25 26 end
26 27
@@ -35,6 +36,10 @@
35 36 post :create_issue
36 37 delete :unlink_issue
37 38 end
  39 +
  40 + collection do
  41 + get :search
  42 + end
38 43 end
39 44
40 45 resources :deploys, :only => [:index]
5 spec/spec_helper.rb
@@ -21,6 +21,10 @@
21 21 config.run_all_when_everything_filtered = true
22 22 config.alias_example_to :fit, :focused => true
23 23
  24 + config.before(:all) do
  25 + Problem.index_name('test_' + Problem.model_name.plural)
  26 + end
  27 +
24 28 config.before(:each) do
25 29 DatabaseCleaner[:mongoid].strategy = :truncation
26 30 DatabaseCleaner.clean
@@ -28,4 +32,5 @@
28 32 config.include WebMock::API
29 33 end
30 34
  35 +Errbit::Config.elasticsearch_enabled = false
31 36 OmniAuth.config.test_mode = true

0 comments on commit 15d998a

Please sign in to comment.
Something went wrong with that request. Please try again.