whoops 0.3.5 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -0
- data/README.asciidoc +1 -1
- data/app/assets/javascripts/whoops.js +31 -3
- data/app/assets/stylesheets/whoops.css.scss +46 -14
- data/app/controllers/notification_subscriptions_controller.rb +33 -0
- data/app/helpers/event_groups_helper.rb +26 -19
- data/app/helpers/filters_helper.rb +5 -0
- data/app/mailers/whoops/notification_mailer.rb +6 -1
- data/app/models/whoops/event_group.rb +2 -2
- data/app/models/whoops/filter.rb +30 -4
- data/app/models/whoops/notification_subscription.rb +27 -0
- data/app/views/event_groups/index.html.haml +1 -8
- data/app/views/filters/_filters.html.haml +12 -0
- data/app/views/filters/_summary.html.haml +9 -0
- data/app/views/layouts/whoops.html.haml +2 -2
- data/app/views/notification_subscriptions/_form.html.haml +11 -0
- data/app/views/notification_subscriptions/edit.html.haml +8 -0
- data/app/views/notification_subscriptions/index.html.haml +19 -0
- data/config/routes.rb +1 -1
- metadata +14 -10
- data/app/assets/stylesheets/main.css.scss +0 -0
- data/app/controllers/notification_rules_controller.rb +0 -29
- data/app/views/notification_rules/_form.html.haml +0 -15
- data/app/views/notification_rules/edit.html.haml +0 -8
- data/app/views/notification_rules/index.html.haml +0 -21
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.asciidoc
    CHANGED
    
    | @@ -3,7 +3,7 @@ Whoops | |
| 3 3 | 
             
            Daniel Higginbotham <daniel@flyingmachinestudios.com>
         | 
| 4 4 | 
             
            2011-07-09
         | 
| 5 5 |  | 
| 6 | 
            -
            image::https://secure.travis-ci.org/driv3r/whoops.png?branch=master[]
         | 
| 6 | 
            +
            image::https://secure.travis-ci.org/driv3r/whoops.png?branch=master[link="https://secure.travis-ci.org/driv3r/whoops"]
         | 
| 7 7 |  | 
| 8 8 | 
             
            == What is Whoops?
         | 
| 9 9 |  | 
| @@ -1,8 +1,36 @@ | |
| 1 1 | 
             
            Whoops = {
         | 
| 2 2 | 
             
              setupFilters: function() {
         | 
| 3 | 
            -
                 | 
| 4 | 
            -
                   | 
| 5 | 
            -
             | 
| 3 | 
            +
                function checkboxBehavior(afterChecked) {
         | 
| 4 | 
            +
                  if (afterChecked === undefined) {
         | 
| 5 | 
            +
                    afterChecked = function(){}
         | 
| 6 | 
            +
                  }
         | 
| 7 | 
            +
                  
         | 
| 8 | 
            +
                  return function(i, list){
         | 
| 9 | 
            +
                    var all = $($(list).find("input").get(0));
         | 
| 10 | 
            +
                    var allowedValues = $(list).find("input").slice(1);
         | 
| 11 | 
            +
                    var form = $(this).parents("form");
         | 
| 12 | 
            +
                    
         | 
| 13 | 
            +
                    all.change(function(event){
         | 
| 14 | 
            +
                      if ($(this).attr("checked")) {
         | 
| 15 | 
            +
                        allowedValues.attr("checked", false);
         | 
| 16 | 
            +
                        afterChecked(form);
         | 
| 17 | 
            +
                      } else {
         | 
| 18 | 
            +
                        $(this).attr("checked", true);
         | 
| 19 | 
            +
                      }
         | 
| 20 | 
            +
                    })
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    $(allowedValues).change(function(event){
         | 
| 23 | 
            +
                      if ($(this).attr("checked")) {
         | 
| 24 | 
            +
                        all.attr("checked", false);
         | 
| 25 | 
            +
                      }
         | 
| 26 | 
            +
                      afterChecked(form);
         | 
| 27 | 
            +
                    })
         | 
| 28 | 
            +
                  }
         | 
| 29 | 
            +
                }
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                $("#new_whoops_filter ul").each(checkboxBehavior(function(form){form.submit()}));
         | 
| 32 | 
            +
                $("#new-notification-rule .filters ul").each(checkboxBehavior());
         | 
| 33 | 
            +
                
         | 
| 6 34 | 
             
                $("#reset").click(function(){
         | 
| 7 35 | 
             
                  window.location = window.location.pathname
         | 
| 8 36 | 
             
                  return false
         | 
| @@ -25,6 +25,10 @@ li { | |
| 25 25 | 
             
              }
         | 
| 26 26 | 
             
            }
         | 
| 27 27 |  | 
| 28 | 
            +
            #main {
         | 
| 29 | 
            +
              padding-bottom:1em;
         | 
| 30 | 
            +
            }
         | 
| 31 | 
            +
             | 
| 28 32 | 
             
            /* sidebar */
         | 
| 29 33 | 
             
            .container-fluid .sidebar {
         | 
| 30 34 | 
             
              margin-left:-20px;  
         | 
| @@ -37,24 +41,28 @@ li { | |
| 37 41 | 
             
              input[type=text] {
         | 
| 38 42 | 
             
                width:190px;
         | 
| 39 43 | 
             
              }
         | 
| 40 | 
            -
                
         | 
| 41 | 
            -
             | 
| 42 44 | 
             
            }
         | 
| 43 45 |  | 
| 44 46 | 
             
            /* for kaminari pagination */
         | 
| 45 | 
            -
            .sidebar  | 
| 46 | 
            -
               | 
| 47 | 
            +
            .sidebar {
         | 
| 48 | 
            +
              .pagination {
         | 
| 49 | 
            +
                margin:0;
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                a, .current {
         | 
| 52 | 
            +
                  line-height: ($baseline * 2) - 2;
         | 
| 53 | 
            +
                  padding:0;
         | 
| 54 | 
            +
                  border:none;
         | 
| 55 | 
            +
                  display:block;
         | 
| 56 | 
            +
                  float:left;
         | 
| 57 | 
            +
                  margin-right:2px;  
         | 
| 58 | 
            +
                }
         | 
| 47 59 |  | 
| 48 | 
            -
             | 
| 49 | 
            -
                line-height: ($baseline * 2) - 2;
         | 
| 50 | 
            -
                padding:0;
         | 
| 51 | 
            -
                border:none;
         | 
| 52 | 
            -
                display:block;
         | 
| 53 | 
            -
                float:left;
         | 
| 54 | 
            -
                margin-right:2px;  
         | 
| 60 | 
            +
                .next, .first, .prev, .last { display:none; }
         | 
| 55 61 | 
             
              }
         | 
| 62 | 
            +
            }
         | 
| 56 63 |  | 
| 57 | 
            -
             | 
| 64 | 
            +
            .nofloat {
         | 
| 65 | 
            +
              float:none;
         | 
| 58 66 | 
             
            }
         | 
| 59 67 |  | 
| 60 68 | 
             
            .content .pagination {
         | 
| @@ -122,8 +130,19 @@ li { | |
| 122 130 | 
             
              }
         | 
| 123 131 | 
             
            }
         | 
| 124 132 |  | 
| 125 | 
            -
            . | 
| 126 | 
            -
               | 
| 133 | 
            +
            .filter-selects {
         | 
| 134 | 
            +
              hr {
         | 
| 135 | 
            +
                margin:0;
         | 
| 136 | 
            +
                border-bottom: 1px dotted #ccc;
         | 
| 137 | 
            +
              }
         | 
| 138 | 
            +
             | 
| 139 | 
            +
              li.filter-option:hover {
         | 
| 140 | 
            +
                background:#e8e5cc;
         | 
| 141 | 
            +
              }
         | 
| 142 | 
            +
             | 
| 143 | 
            +
              label {
         | 
| 144 | 
            +
                cursor: pointer;
         | 
| 145 | 
            +
              }
         | 
| 127 146 | 
             
            }
         | 
| 128 147 |  | 
| 129 148 | 
             
            /* events for event group */
         | 
| @@ -163,4 +182,17 @@ ul.detail { | |
| 163 182 |  | 
| 164 183 | 
             
            header form {
         | 
| 165 184 | 
             
              float:right;
         | 
| 185 | 
            +
            }
         | 
| 186 | 
            +
             | 
| 187 | 
            +
            #notification-subscriptions {
         | 
| 188 | 
            +
              .email {
         | 
| 189 | 
            +
                width: 20%;
         | 
| 190 | 
            +
              }
         | 
| 191 | 
            +
             | 
| 192 | 
            +
              span {
         | 
| 193 | 
            +
                padding:0 3px;
         | 
| 194 | 
            +
                background: #cbdbe5;
         | 
| 195 | 
            +
                margin-right:4px;
         | 
| 196 | 
            +
                border-radius:3px;
         | 
| 197 | 
            +
              }
         | 
| 166 198 | 
             
            }
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            class NotificationSubscriptionsController < ApplicationController
         | 
| 2 | 
            +
              layout 'whoops'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              def index
         | 
| 5 | 
            +
                @notification_subscription = Whoops::NotificationSubscription.new
         | 
| 6 | 
            +
                @notification_subscription.build_filter
         | 
| 7 | 
            +
                @notification_subscriptions = Whoops::NotificationSubscription.asc(:email)
         | 
| 8 | 
            +
                @filter = Whoops::Filter.new
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def create
         | 
| 12 | 
            +
                ns = Whoops::NotificationSubscription.create(params[:notification_subscription])
         | 
| 13 | 
            +
                ns.filter = Whoops::Filter.new_from_params(params[:whoops_filter])
         | 
| 14 | 
            +
                ns.filter.save
         | 
| 15 | 
            +
                redirect_to whoops_notification_subscriptions_path
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def edit
         | 
| 19 | 
            +
                @notification_subscription = Whoops::NotificationSubscription.find(params[:id])
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def update
         | 
| 23 | 
            +
                @notification_subscription = Whoops::NotificationSubscription.find(params[:id])
         | 
| 24 | 
            +
                @notification_subscription.update_attributes(params[:notification_subscription])
         | 
| 25 | 
            +
                @notification_subscription.filter.update_from_params(params[:whoops_filter])
         | 
| 26 | 
            +
                redirect_to whoops_notification_subscriptions_path
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def destroy
         | 
| 30 | 
            +
                Whoops::NotificationSubscription.find(params[:id]).destroy
         | 
| 31 | 
            +
                redirect_to whoops_notification_subscriptions_path
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| @@ -3,29 +3,36 @@ module EventGroupsHelper | |
| 3 3 | 
             
                new_filter  = {:whoops_filter => event_group_filter.to_query_document.merge(scope => event_group.send(scope))}
         | 
| 4 4 | 
             
                link_to(event_group.send(scope), whoops_event_groups_path(new_filter))
         | 
| 5 5 | 
             
              end
         | 
| 6 | 
            -
              
         | 
| 7 | 
            -
              # meant for consumption by options_from_collection_for_select
         | 
| 8 | 
            -
              def filter_options
         | 
| 9 | 
            -
                all_event_groups = Whoops::EventGroup.all
         | 
| 10 | 
            -
                return @filter_options if @filter_options
         | 
| 11 6 |  | 
| 12 | 
            -
             | 
| 13 | 
            -
                
         | 
| 14 | 
            -
                @ | 
| 15 | 
            -
                @filter_options["environment"] = Whoops::EventGroup.all.distinct("environment")
         | 
| 16 | 
            -
                @filter_options["event_type"] = Whoops::EventGroup.all.distinct("event_type")
         | 
| 7 | 
            +
              def filter_field_allowed_values
         | 
| 8 | 
            +
                return @filter_field_allowed_values if @filter_field_allowed_values
         | 
| 9 | 
            +
                @filter_field_allowed_values = Hash.new{|h, k| h[k] = [["all"]]}
         | 
| 17 10 |  | 
| 18 | 
            -
                #  | 
| 19 | 
            -
                 | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 11 | 
            +
                # group services by root, eg "sv1.web" and "sv1.resque" are in the
         | 
| 12 | 
            +
                # same sub array
         | 
| 13 | 
            +
                previous_service_root = ""
         | 
| 14 | 
            +
                Whoops::EventGroup.services.to_a.sort.each { |service|
         | 
| 15 | 
            +
                  service_root = (/(.*?)\./ =~ service && $~[1]) || service
         | 
| 16 | 
            +
                  if service_root == previous_service_root
         | 
| 17 | 
            +
                    @filter_field_allowed_values["service"].last << service
         | 
| 18 | 
            +
                  else
         | 
| 19 | 
            +
                    @filter_field_allowed_values["service"] << ["#{service_root}.*", service]
         | 
| 20 | 
            +
                    previous_service_root = service_root
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                }
         | 
| 23 23 |  | 
| 24 | 
            -
                @ | 
| 24 | 
            +
                @filter_field_allowed_values["environment"] << Whoops::EventGroup.all.distinct("environment")
         | 
| 25 | 
            +
                @filter_field_allowed_values["event_type"] << Whoops::EventGroup.all.distinct("event_type")
         | 
| 26 | 
            +
                @filter_field_allowed_values
         | 
| 25 27 | 
             
              end
         | 
| 26 28 |  | 
| 27 | 
            -
              def  | 
| 28 | 
            -
                filtered_field =  | 
| 29 | 
            -
                 | 
| 29 | 
            +
              def allowed_value_checked?(field_name, allowed_value, filter)
         | 
| 30 | 
            +
                filtered_field = filter.send(field_name)
         | 
| 31 | 
            +
                (allowed_value == "all" && filtered_field_allows_all?(filtered_field)) ||
         | 
| 32 | 
            +
                  filtered_field.try(:include?, allowed_value)
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              def filtered_field_allows_all?(filtered_field)
         | 
| 36 | 
            +
                filtered_field.blank?
         | 
| 30 37 | 
             
              end
         | 
| 31 38 | 
             
            end
         | 
| @@ -2,11 +2,16 @@ class Whoops::NotificationMailer < ActionMailer::Base | |
| 2 2 | 
             
              def event_notification(event_group, addresses)
         | 
| 3 3 | 
             
                @event_group = event_group
         | 
| 4 4 | 
             
                @addresses = addresses
         | 
| 5 | 
            +
                body = <<-BODY
         | 
| 6 | 
            +
            #{whoops_event_group_events_url(event_group.id)}
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            #{event_group.service}: #{event_group.environment}: #{event_group.message}
         | 
| 9 | 
            +
                BODY
         | 
| 5 10 | 
             
                mail(
         | 
| 6 11 | 
             
                  :to      => addresses.join(", "),
         | 
| 7 12 | 
             
                  :from    => Rails.application.config.whoops_sender,
         | 
| 8 13 | 
             
                  :subject => "Whoops Notification | #{event_group.service}: #{event_group.environment}: #{event_group.message}",
         | 
| 9 | 
            -
                  :body    =>  | 
| 14 | 
            +
                  :body    => body
         | 
| 10 15 | 
             
                )
         | 
| 11 16 | 
             
              end
         | 
| 12 17 | 
             
            end
         | 
| @@ -59,7 +59,7 @@ class Whoops::EventGroup | |
| 59 59 |  | 
| 60 60 | 
             
              def send_notifications
         | 
| 61 61 | 
             
                return unless should_send_notifications?
         | 
| 62 | 
            -
                matcher = Whoops:: | 
| 63 | 
            -
                Whoops::NotificationMailer.event_notification(self, matcher. | 
| 62 | 
            +
                matcher = Whoops::NotificationSubscription::Matcher.new(self)
         | 
| 63 | 
            +
                Whoops::NotificationMailer.event_notification(self, matcher.matching_emails).deliver unless matcher.matching_emails.empty?
         | 
| 64 64 | 
             
              end
         | 
| 65 65 | 
             
            end
         | 
    
        data/app/models/whoops/filter.rb
    CHANGED
    
    | @@ -1,13 +1,17 @@ | |
| 1 1 | 
             
            class Whoops::Filter
         | 
| 2 2 | 
             
              include Mongoid::Document
         | 
| 3 3 | 
             
              include FieldNames
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              FILTERED_FIELDS = [:service, :environment, :event_type, :message, :details]
         | 
| 4 6 |  | 
| 5 | 
            -
               | 
| 7 | 
            +
              FILTERED_FIELDS.each do |document_field|
         | 
| 6 8 | 
             
                field document_field, :type => Array
         | 
| 7 9 | 
             
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              belongs_to :filterable, :polymorphic => true
         | 
| 8 12 |  | 
| 9 13 | 
             
              def to_query_document
         | 
| 10 | 
            -
                doc = attributes.except(:_id, "_id").delete_if{|k, v| v.blank?}
         | 
| 14 | 
            +
                doc = attributes.except(:_id, "_id", :_type, "_type").delete_if{|k, v| v.blank?}
         | 
| 11 15 | 
             
                # match all services under namespace. ie, if "app" given, match "app.web", "app.backend" etc
         | 
| 12 16 | 
             
                doc["service"] = doc["service"].collect{ |d| /^#{d}/ } if doc["service"]
         | 
| 13 17 | 
             
                doc.inject({}) do |hash, current|
         | 
| @@ -16,13 +20,35 @@ class Whoops::Filter | |
| 16 20 | 
             
                end
         | 
| 17 21 | 
             
              end
         | 
| 18 22 |  | 
| 23 | 
            +
              def matches_event_group?(event_group)
         | 
| 24 | 
            +
                FILTERED_FIELDS.all? do |field|
         | 
| 25 | 
            +
                  if self.send(field).blank?
         | 
| 26 | 
            +
                    true
         | 
| 27 | 
            +
                  else
         | 
| 28 | 
            +
                    /^(#{self.send(field).join("|")})$/ =~ event_group.send(field)
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              def update_from_params(params)
         | 
| 34 | 
            +
                update_attributes(self.class.clean_params(params))
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 19 37 | 
             
              class << self
         | 
| 20 38 | 
             
                def new_from_params(params)
         | 
| 21 39 | 
             
                  if params
         | 
| 22 | 
            -
                    new(params | 
| 40 | 
            +
                    f = new(clean_params(params))
         | 
| 23 41 | 
             
                  else
         | 
| 24 42 | 
             
                    new
         | 
| 25 43 | 
             
                  end
         | 
| 26 44 | 
             
                end
         | 
| 27 | 
            -
             | 
| 45 | 
            +
             | 
| 46 | 
            +
                def clean_params(params)
         | 
| 47 | 
            +
                  params.inject({}){ |hash, current|
         | 
| 48 | 
            +
                    allowed_values = current.last.keys
         | 
| 49 | 
            +
                    hash[current.first] = allowed_values.include?("all") ? [] : allowed_values
         | 
| 50 | 
            +
                    hash
         | 
| 51 | 
            +
                  }
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 28 54 | 
             
            end
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            class Whoops::NotificationSubscription
         | 
| 2 | 
            +
              include Mongoid::Document
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              has_one :filter, :as => :filterable, :class_name => "Whoops::Filter"
         | 
| 5 | 
            +
              validates_presence_of :email
         | 
| 6 | 
            +
              
         | 
| 7 | 
            +
              field :email, :type => String
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              before_save :downcase_email
         | 
| 10 | 
            +
              
         | 
| 11 | 
            +
              def downcase_email
         | 
| 12 | 
            +
                self.email.downcase!
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              class Matcher
         | 
| 16 | 
            +
                attr_accessor :event_group
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                # @param [ Whoops::EventGroup ]
         | 
| 19 | 
            +
                def initialize(event_group)
         | 
| 20 | 
            +
                  self.event_group = event_group
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
                
         | 
| 23 | 
            +
                def matching_emails
         | 
| 24 | 
            +
                  Whoops::NotificationSubscription.all.select{ |ns| ns.filter.matches_event_group?(self.event_group) }.collect(&:email)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
| @@ -3,14 +3,7 @@ | |
| 3 3 | 
             
                %h3 Filters
         | 
| 4 4 | 
             
                = form_for event_group_filter, :url => whoops_event_groups_path, :html => {:method => "get"} do |f|
         | 
| 5 5 | 
             
                  = hidden_field_tag 'updating_filters', true
         | 
| 6 | 
            -
                   | 
| 7 | 
            -
                    %h4= field_name
         | 
| 8 | 
            -
                    %ul.filter_selects.inputs-list
         | 
| 9 | 
            -
                      - options.each do |option|
         | 
| 10 | 
            -
                        %li
         | 
| 11 | 
            -
                          %label
         | 
| 12 | 
            -
                            %input{:type => 'checkbox', :name => "whoops_filter[#{field_name}][#{option}]", :checked => filter_checked?(field_name, option)}
         | 
| 13 | 
            -
                            = option
         | 
| 6 | 
            +
                  = render(:partial => "filters/filters", :locals => {:filter => session[:event_group_filter]} )
         | 
| 14 7 | 
             
              .space
         | 
| 15 8 | 
             
                %h3 Keyword Search
         | 
| 16 9 | 
             
                = form_tag whoops_event_groups_path, :method => "get" do |f|
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            - filter_field_allowed_values.each do |field_name, allowed_value_groups|
         | 
| 2 | 
            +
              %h4= field_name
         | 
| 3 | 
            +
              %ul.filter-selects.inputs-list
         | 
| 4 | 
            +
                - allowed_value_groups.each do |allowed_values|
         | 
| 5 | 
            +
                  - allowed_values.each do |allowed_value|
         | 
| 6 | 
            +
                    %li.filter-option
         | 
| 7 | 
            +
                      %label
         | 
| 8 | 
            +
                        %input{:type => 'checkbox', :name => "whoops_filter[#{field_name}][#{allowed_value}]", :checked => allowed_value_checked?(field_name, allowed_value, filter)}
         | 
| 9 | 
            +
                        = allowed_value
         | 
| 10 | 
            +
                  - unless allowed_values == allowed_value_groups.last
         | 
| 11 | 
            +
                    %li.divider
         | 
| 12 | 
            +
                      %hr
         | 
| @@ -15,9 +15,9 @@ | |
| 15 15 | 
             
                  .listfill
         | 
| 16 16 | 
             
                    .container-fluid
         | 
| 17 17 | 
             
                      = link_to "Event Groups", whoops_event_groups_path, :class => "brand"
         | 
| 18 | 
            -
                      = link_to "Notification  | 
| 18 | 
            +
                      = link_to "Notification Subscriptions", whoops_notification_subscriptions_path, :class => "brand"
         | 
| 19 19 | 
             
                      = link_to "Whoops Documentation", "http://www.whoopsapp.com/", :class => "documentation"
         | 
| 20 | 
            -
                .container-fluid
         | 
| 20 | 
            +
                .container-fluid#main
         | 
| 21 21 | 
             
                  .sidebar
         | 
| 22 22 | 
             
                    = yield :sidebar
         | 
| 23 23 | 
             
                  .content
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            - new_record = @notification_subscription.new_record?
         | 
| 2 | 
            +
            - options = new_record ? {:url => whoops_notification_subscriptions_path, :method => :post} : {:url => whoops_notification_subscription_path(@notification_subscription), :method => :put}
         | 
| 3 | 
            +
            = form_for :notification_subscription, options do |f|
         | 
| 4 | 
            +
              #new-notification-rule
         | 
| 5 | 
            +
                %label.nofloat
         | 
| 6 | 
            +
                  Email
         | 
| 7 | 
            +
                  %br
         | 
| 8 | 
            +
                  =f.text_field :email
         | 
| 9 | 
            +
                .filters
         | 
| 10 | 
            +
                  = render(:partial => "filters/filters", :locals => {:filter => @notification_subscription.filter} )
         | 
| 11 | 
            +
                = submit_tag (new_record ? "Create" : "Update"), :class => "btn primary"
         | 
| @@ -0,0 +1,8 @@ | |
| 1 | 
            +
            %h3 Edit Notification Subscription for #{@notification_subscription.email}
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            = render :partial => "form"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            %h4 Delete This Rule
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            = form_for :notification_subscription, :method => :delete, :url => whoops_notification_subscription_path(@notification_subscription) do |f|
         | 
| 8 | 
            +
              = f.submit :class => "btn", :value => "Delete it Forever! There's no going back!"
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            %h3 Notification Subscriptions
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            - content_for :sidebar do
         | 
| 4 | 
            +
              .space
         | 
| 5 | 
            +
                %h3 New Subscription
         | 
| 6 | 
            +
                = render :partial => "form"
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            %table#notification-subscriptions
         | 
| 10 | 
            +
              %tr
         | 
| 11 | 
            +
                %th.email Email Address
         | 
| 12 | 
            +
                %th.filter Filter
         | 
| 13 | 
            +
              - @notification_subscriptions.each do |ns|
         | 
| 14 | 
            +
                %tr
         | 
| 15 | 
            +
                  %td.email= ns.email
         | 
| 16 | 
            +
                  %td.filter= render :partial => "filters/summary", :locals => {:filter => ns.filter}
         | 
| 17 | 
            +
                  %td.update= link_to "update", edit_whoops_notification_subscription_path(ns)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  
         | 
    
        data/config/routes.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: whoops
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 4 | 
            +
              hash: 15
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 0
         | 
| 8 | 
            -
              -  | 
| 9 | 
            -
              -  | 
| 10 | 
            -
              version: 0. | 
| 8 | 
            +
              - 4
         | 
| 9 | 
            +
              - 0
         | 
| 10 | 
            +
              version: 0.4.0
         | 
| 11 11 | 
             
            platform: ruby
         | 
| 12 12 | 
             
            authors: 
         | 
| 13 13 | 
             
            - Daniel Higginbotham
         | 
| @@ -15,7 +15,7 @@ autorequire: | |
| 15 15 | 
             
            bindir: bin
         | 
| 16 16 | 
             
            cert_chain: []
         | 
| 17 17 |  | 
| 18 | 
            -
            date: 2012- | 
| 18 | 
            +
            date: 2012-11-28 00:00:00 Z
         | 
| 19 19 | 
             
            dependencies: 
         | 
| 20 20 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 21 21 | 
             
              name: rails
         | 
| @@ -175,7 +175,6 @@ files: | |
| 175 175 | 
             
            - app/assets/stylesheets/bootstrap.scss
         | 
| 176 176 | 
             
            - app/assets/stylesheets/forms.scss
         | 
| 177 177 | 
             
            - app/assets/stylesheets/ie.css
         | 
| 178 | 
            -
            - app/assets/stylesheets/main.css.scss
         | 
| 179 178 | 
             
            - app/assets/stylesheets/mixins.scss
         | 
| 180 179 | 
             
            - app/assets/stylesheets/patterns.scss
         | 
| 181 180 | 
             
            - app/assets/stylesheets/reset.scss
         | 
| @@ -187,9 +186,10 @@ files: | |
| 187 186 | 
             
            - app/assets/stylesheets/whoops.css.scss
         | 
| 188 187 | 
             
            - app/controllers/event_groups_controller.rb
         | 
| 189 188 | 
             
            - app/controllers/events_controller.rb
         | 
| 190 | 
            -
            - app/controllers/ | 
| 189 | 
            +
            - app/controllers/notification_subscriptions_controller.rb
         | 
| 191 190 | 
             
            - app/helpers/event_groups_helper.rb
         | 
| 192 191 | 
             
            - app/helpers/events_helper.rb
         | 
| 192 | 
            +
            - app/helpers/filters_helper.rb
         | 
| 193 193 | 
             
            - app/helpers/notifications_helper.rb
         | 
| 194 194 | 
             
            - app/lib/field_names.rb
         | 
| 195 195 | 
             
            - app/mailers/whoops/notification_mailer.rb
         | 
| @@ -198,15 +198,18 @@ files: | |
| 198 198 | 
             
            - app/models/whoops/filter.rb
         | 
| 199 199 | 
             
            - app/models/whoops/mongoid_search_parser.rb
         | 
| 200 200 | 
             
            - app/models/whoops/notification_rule.rb
         | 
| 201 | 
            +
            - app/models/whoops/notification_subscription.rb
         | 
| 201 202 | 
             
            - app/views/event_groups/_list.html.haml
         | 
| 202 203 | 
             
            - app/views/event_groups/index.html.haml
         | 
| 203 204 | 
             
            - app/views/events/_detail.html.haml
         | 
| 204 205 | 
             
            - app/views/events/_details.html.haml
         | 
| 205 206 | 
             
            - app/views/events/index.html.haml
         | 
| 207 | 
            +
            - app/views/filters/_filters.html.haml
         | 
| 208 | 
            +
            - app/views/filters/_summary.html.haml
         | 
| 206 209 | 
             
            - app/views/layouts/whoops.html.haml
         | 
| 207 | 
            -
            - app/views/ | 
| 208 | 
            -
            - app/views/ | 
| 209 | 
            -
            - app/views/ | 
| 210 | 
            +
            - app/views/notification_subscriptions/_form.html.haml
         | 
| 211 | 
            +
            - app/views/notification_subscriptions/edit.html.haml
         | 
| 212 | 
            +
            - app/views/notification_subscriptions/index.html.haml
         | 
| 210 213 | 
             
            - lib/tasks/whoops.rake
         | 
| 211 214 | 
             
            - lib/whoops/engine.rb
         | 
| 212 215 | 
             
            - lib/whoops.rb
         | 
| @@ -251,3 +254,4 @@ specification_version: 3 | |
| 251 254 | 
             
            summary: A Rails engine which receives logs and provides an interface for them
         | 
| 252 255 | 
             
            test_files: []
         | 
| 253 256 |  | 
| 257 | 
            +
            has_rdoc: 
         | 
| 
            File without changes
         | 
| @@ -1,29 +0,0 @@ | |
| 1 | 
            -
            class NotificationRulesController < ApplicationController
         | 
| 2 | 
            -
              layout 'whoops'
         | 
| 3 | 
            -
             | 
| 4 | 
            -
              def index
         | 
| 5 | 
            -
                @notification_rule = Whoops::NotificationRule.new
         | 
| 6 | 
            -
                @notification_rules = Whoops::NotificationRule.asc(:email)
         | 
| 7 | 
            -
              end
         | 
| 8 | 
            -
             | 
| 9 | 
            -
              def create
         | 
| 10 | 
            -
                Whoops::NotificationRule.add_rules(params[:notification_rule])
         | 
| 11 | 
            -
                redirect_to whoops_notification_rules_path
         | 
| 12 | 
            -
              end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
              def edit
         | 
| 15 | 
            -
                @notification_rule = Whoops::NotificationRule.find(params[:id])
         | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
              def update
         | 
| 19 | 
            -
                @notification_rule = Whoops::NotificationRule.find(params[:id])
         | 
| 20 | 
            -
                @notification_rule.update_attributes(params[:notification_rule])
         | 
| 21 | 
            -
                notification_rules = Whoops::NotificationRule.asc(:email)
         | 
| 22 | 
            -
                redirect_to whoops_notification_rules_path
         | 
| 23 | 
            -
              end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
              def destroy
         | 
| 26 | 
            -
                Whoops::NotificationRule.find(params[:id]).destroy
         | 
| 27 | 
            -
                redirect_to whoops_notification_rules_path
         | 
| 28 | 
            -
              end
         | 
| 29 | 
            -
            end
         | 
| @@ -1,15 +0,0 @@ | |
| 1 | 
            -
            %h3 New
         | 
| 2 | 
            -
            - options = @notification_rule.new_record? ? {:url => whoops_notification_rules_path, :method => :post} : {:url => whoops_notification_rule_path(@notification_rule), :method => :put}
         | 
| 3 | 
            -
            = form_for :notification_rule, options do |f|
         | 
| 4 | 
            -
              #new-notification-rule
         | 
| 5 | 
            -
                %p
         | 
| 6 | 
            -
                  Email
         | 
| 7 | 
            -
                  %br
         | 
| 8 | 
            -
                  =f.text_field :email
         | 
| 9 | 
            -
                %p
         | 
| 10 | 
            -
                  Matchers
         | 
| 11 | 
            -
                  %br
         | 
| 12 | 
            -
                  = f.text_area :matchers, :value => @notification_rule.matchers.to_a.join("\n")
         | 
| 13 | 
            -
                %p= f.submit(:class => "primary btn", :value => "Save Notification Rule")
         | 
| 14 | 
            -
             | 
| 15 | 
            -
            %p= link_to "Back to notification rules", whoops_notification_rules_path
         | 
| @@ -1,8 +0,0 @@ | |
| 1 | 
            -
            %h3 Edit Notification Rules for #{@notification_rule.email}
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            = render :partial => "form"
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            %h4 Delete This Rule
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            = form_for :notification_rule, :method => :delete, :url => whoops_notification_rule_path(@notification_rule) do |f|
         | 
| 8 | 
            -
              = f.submit :class => "btn", :value => "Delete it Forever! There's no going back!"
         | 
| @@ -1,21 +0,0 @@ | |
| 1 | 
            -
            %h3 Notification Rules
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            - content_for :sidebar do
         | 
| 4 | 
            -
              .space
         | 
| 5 | 
            -
                = render :partial => "form"
         | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
            %table
         | 
| 10 | 
            -
              %tr
         | 
| 11 | 
            -
                %th Email Address
         | 
| 12 | 
            -
                %th Services to Monitor
         | 
| 13 | 
            -
                %th
         | 
| 14 | 
            -
              
         | 
| 15 | 
            -
              - @notification_rules.each do |nr|
         | 
| 16 | 
            -
                %tr
         | 
| 17 | 
            -
                  %td= nr.email
         | 
| 18 | 
            -
                  %td= nr.matchers.sort.join(", ")
         | 
| 19 | 
            -
                  %td= link_to "update", edit_whoops_notification_rule_path(nr)
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                  
         |