aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/mauve/web_interface.rb102
-rw-r--r--views/_alerts_table.haml31
-rw-r--r--views/_head.haml1
-rw-r--r--views/_navbar.haml15
-rw-r--r--views/alert.haml156
-rw-r--r--views/alerts.haml41
-rw-r--r--views/login.haml28
-rw-r--r--views/not_implemented.haml8
8 files changed, 218 insertions, 164 deletions
diff --git a/lib/mauve/web_interface.rb b/lib/mauve/web_interface.rb
index 721fc3f..d999554 100644
--- a/lib/mauve/web_interface.rb
+++ b/lib/mauve/web_interface.rb
@@ -44,7 +44,23 @@ module Mauve
set :dump_errors, true # ...will dump errors to the log
set :raise_errors, false # ...will not let exceptions out to main program
set :show_exceptions, false # ...will not show exceptions
-
+
+ #
+ # Default template.
+ #
+ template :layout do
+ <<EOF
+!!! 5
+%html
+ = partial('head')
+ %body
+ =partial("navbar")
+ =yield
+EOF
+ end
+
+
+
###########################################/alert#############################
before do
@@ -65,6 +81,11 @@ module Mauve
env['REMOTE_USER'] = @person.username
#
+ # Don't cache ajax requests
+ #
+ cache_control :no_cache if request.xhr?
+
+ #
# Set up some defaults.
#
@group_by = "subject"
@@ -147,33 +168,12 @@ module Mauve
end
get '/alerts/:alert_type/:group_by' do
- find_active_alerts
- if %w(raised cleared acknowledged).include?(params[:alert_type])
- @alert_type = params[:alert_type]
- else
- @alert_type = "raised"
- end
-
- if %w(subject source summary id alert_id level).include?(params[:group_by])
- @group_by = params[:group_by]
- else
- @group_by = "subject"
- end
-
- @title += " Alerts "
+ return haml(:not_implemented) unless %w(raised acknowledged).include?(params[:alert_type])
+ alerts_table(params)
- case @alert_type
- when "raised"
- @grouped_alerts = group_by(@alerts_raised, @group_by)
- haml(:alerts)
- when "acknowledged"
- @grouped_alerts = group_by(@alerts_ackd, @group_by)
- haml(:alerts)
- else
- haml(:not_implemented)
- end
+ haml(:alerts)
end
post '/alerts/acknowledge' do
@@ -216,7 +216,7 @@ module Mauve
redirect "/alerts/raised"
end
- #
+ ######################################################
# AJAX methods for returning snippets of stuff.
#
@@ -246,10 +246,30 @@ module Mauve
get '/ajax/time_to_s_human/:seconds' do
content_type :text
+
secs = params[:seconds].to_i
Time.at(secs).to_s_human
end
+ #
+ # This returns an array of 5 numbers.
+ #
+ get '/ajax/alert_counts' do
+ content_type :json
+
+ counts = Hash.new{|h,k| h[k] = 0}
+
+ Alert.all_raised.each{|a| counts[a.level] += 1}
+
+ (AlertGroup::LEVELS.reverse.collect{|l| counts[l]}+
+ [Alert.all_acknowledged.length, Alert.all_cleared.length]).to_json
+ end
+
+ get '/ajax/alerts_table/:alert_type/:group_by' do
+ alerts_table(params)
+ haml(:_alerts_table)
+ end
+
get '/ajax/alerts_table_alert/:alert_id' do
content_type "text/html"
alert = Alert.get(params[:alert_id].to_i)
@@ -361,7 +381,6 @@ module Mauve
results = Hash.new{|h,k| h[k] = Array.new}
things.sort.each do |thing|
- self.class._logger.debug [AlertGroup::LEVELS.index(thing.level), (thing.raised_at || thing.cleared_at) ].inspect
results[thing.__send__(meth)] << thing
end
@@ -369,6 +388,35 @@ module Mauve
[a[1].first, a[0]] <=> [b[1].first, b[0]]
end
end
+
+ def alerts_table(params)
+ find_active_alerts
+
+ if %w(raised cleared acknowledged).include?(params[:alert_type])
+ @alert_type = params[:alert_type]
+ else
+ @alert_type = "raised"
+ end
+
+ if %w(subject source summary id alert_id level).include?(params[:group_by])
+ @group_by = params[:group_by]
+ else
+ @group_by = "subject"
+ end
+
+ @title += " Alerts "
+
+
+ case @alert_type
+ when "raised"
+ @grouped_alerts = group_by(@alerts_raised, @group_by)
+ when "acknowledged"
+ @grouped_alerts = group_by(@alerts_ackd, @group_by)
+ haml(:alerts)
+ else
+ haml(:not_implemented)
+ end
+ end
def find_active_alerts
@alerts_raised = Alert.all_raised
diff --git a/views/_alerts_table.haml b/views/_alerts_table.haml
index f413c30..99a4e13 100644
--- a/views/_alerts_table.haml
+++ b/views/_alerts_table.haml
@@ -1,19 +1,14 @@
-%form#alerts{:method => :post, :action => '/alerts/acknowledge'}
- %table
- %tr
- %th#selector
- %input#toggle_all{ :type => "checkbox" }
- :javascript
- // This just toggles all the checkboxes.
- $('#toggle_all').change( function() {
- $('input.alert').each( function(index) {
- this.checked = !this.checked;
- });
+%table#alerts_table
+ %tr
+ %th#selector
+ %input#toggle_all{ :type => "checkbox" }
+ :javascript
+ // This just toggles all the checkboxes.
+ $('#toggle_all').change( function() {
+ $('input.alert').each( function(index) {
+ this.checked = !this.checked;
});
- %th#summary Summary
- %th#time At
- = partial("alerts_table_group", :collection => @grouped_alerts)
- %tr
- %td &nbsp;
- %td{:colspan => 2}
- = partial("acknowledge_input")
+ });
+ %th#summary Summary
+ %th#time At
+ = partial("alerts_table_group", :collection => @grouped_alerts)
diff --git a/views/_head.haml b/views/_head.haml
index 981aaf1..642d408 100644
--- a/views/_head.haml
+++ b/views/_head.haml
@@ -5,4 +5,5 @@
%link{:rel => "stylesheet", :href => "/stylesheets/mauve.css", :media => "all", :type => "text/css"}/
%link{:rel => "stylesheet", :href => "/stylesheets/mauve-handheld.css", :media => "handheld, only screen and (max-width: 1000px), only screen and (max-device-width: 1000px)", :type => "text/css" }/
%script{:src => '/javascript/jquery/jquery.min.js', :type => 'text/javascript'}
+ %script{:src => '/javascript/jquery.periodicalupdater.js', :type => 'text/javascript'}
%script{:src => '/javascript/mauve_utils.js', :type => 'text/javascript'}
diff --git a/views/_navbar.haml b/views/_navbar.haml
index 4f81450..5df4991 100644
--- a/views/_navbar.haml
+++ b/views/_navbar.haml
@@ -4,11 +4,20 @@
%a{:href => "/"} Mauve
- if @person
%li{:class => [ @alert_type == "raised" && "nav_selected"]}
- %a{:href => '/alerts/raised/'+@group_by} Raised (#{@alerts_raised.length})
+ %a{:href => '/alerts/raised/'+@group_by}
+ Raised (
+ %span#count_raised><= @alerts_raised.length
+ )
%li{:class => [ @alert_type == "acknowledged" && "nav_selected"]}
- %a{:href => '/alerts/acknowledged/'+@group_by} Ack'd (#{@alerts_ackd.length})
+ %a{:href => '/alerts/acknowledged/'+@group_by}
+ Ack'd (
+ %span#count_ackd><= @alerts_ackd.length
+ )
%li{:class => [ @alert_type == "cleared" && "nav_selected"]}
- %a{:href => '/alerts/cleared/'+@group_by} Cleared (#{@alerts_cleared.length})
+ %a{:href => '/alerts/cleared/'+@group_by}
+ Cleared (
+ %span#count_cleared><= @alerts_cleared.length
+ )
%li
%a{:href => '/logout'} Log out
%br
diff --git a/views/alert.haml b/views/alert.haml
index 0486770..b752f35 100644
--- a/views/alert.haml
+++ b/views/alert.haml
@@ -1,82 +1,76 @@
-!!!5
-%html
- = partial('head')
- %body
- =partial("navbar")
- .container
- %h1 Alert detail
- %table
- %tr
- %th.summary{:title => "Text for humans describing the nature of the alert, first 100 characters are only ones guaranteed to make it to pagers, twitter, SMS etc."} Summary
- %td= @alert.summary
- %tr
- %th.summary{:title => "The server/entity that this alert concerns"} Subject
- %td= @alert.subject
- %tr
- %th{:title => "The server/entitiy that originated the alert"} Source
- %td= @alert.source
- %tr
- %th{:title => "HTML fragment describing the alert in more detail, no limit on length."} Detail
- %td
- :textile
- #{@alert.detail}
- %tr
- %th{:title => "ID set by the source of the alert."} Alert ID
- %td= @alert.alert_id
- %tr
- %th{:title => "The groups in the Mauve server configuration that match this alert"} Alert groups
- %td= Mauve::AlertGroup.matches(@alert).map{|g| g.name}.join("; ")
- %tr
- %th{:title => "The level of the first group in the Mauve server configuration that matched this alert"} Alert level
- %td= @alert.level.to_s.upcase
- -if @alert.raised?
- %tr
- %th{:title => "The time at which the alert was raised"} Raised at
- %td= @alert.raised_at.to_s_human
- -if @alert.acknowledged?
- %tr
- %th{:title => "The time at which the alert was acknowledged"} Acknowledged at
- %td= @alert.acknowledged_at.to_s_human + " by " + @alert.acknowledged_by + " until " + @alert.will_unacknowledge_at.to_s_human
- -if @alert.will_raise_at
- %tr
- %th{:title => "The time at which the alert will be automatically raised"} Will raise at
- %td= @alert.will_raise_at.to_s_human
- -if @alert.cleared_at
- %tr
- %th{:title => "The time at which the alert was last cleared"} Last cleared at
- %td= @alert.cleared_at.to_s_human
- -if @alert.will_clear_at
- %tr
- %th{:title => "The time at which the alert will be automatically cleared"} Will clear
- %td= @alert.will_raise_at.to_s_human
- %tr
- %th Notifications sent out
- %td
- %ul
- - @alert.changes.each do |change|
- - if change.was_relevant?
- %li
- %strong= change.level
- = change.update_type
- notification to
- = change.person
- at
- = change.at.to_s_human
-
- %h2 Actions
- - if !@alert.acknowledged?
- %form{:method => :post, :action => "/alert/#{@alert.id}/acknowledge"}
- =partial("acknowledge_input")
- - else
- %form.hidden{:method => :post, :action => "/alert/#{@alert.id}/unacknowledge"}
- %input{:type => :submit, :value => "Unacknowledge this alert"}
- %a#hide{:onclick => "$('form.hidden').toggle(); return false", :href=>"#"} Show other actions
- - if @alert.cleared?
- %form.hidden{:method => :post, :action => "/alert/#{@alert.id}/raise"}
- %input{:type => :submit, :value => "Raise this alert"}
- - if @alert.raised?
- %form.hidden{:method => :post, :action => "/alert/#{@alert.id}/clear"}
- %input{:type => :submit, :value => "Clear this alert"}
- %form.hidden{:method => :post, :action => "/alert/#{@alert.id}/destroy"}
- %input{:type => :submit, :value => "Destroy this alert"}
+%h1 Alert detail
+%table
+ %tr
+ %th.summary{:title => "Text for humans describing the nature of the alert, first 100 characters are only ones guaranteed to make it to pagers, twitter, SMS etc."} Summary
+ %td= @alert.summary
+ %tr
+ %th.summary{:title => "The server/entity that this alert concerns"} Subject
+ %td= @alert.subject
+ %tr
+ %th{:title => "The server/entitiy that originated the alert"} Source
+ %td= @alert.source
+ %tr
+ %th{:title => "HTML fragment describing the alert in more detail, no limit on length."} Detail
+ %td
+ :textile
+ #{@alert.detail}
+ %tr
+ %th{:title => "ID set by the source of the alert."} Alert ID
+ %td= @alert.alert_id
+ %tr
+ %th{:title => "The groups in the Mauve server configuration that match this alert"} Alert groups
+ %td= Mauve::AlertGroup.matches(@alert).map{|g| g.name}.join("; ")
+ %tr
+ %th{:title => "The level of the first group in the Mauve server configuration that matched this alert"} Alert level
+ %td= @alert.level.to_s.upcase
+ -if @alert.raised?
+ %tr
+ %th{:title => "The time at which the alert was raised"} Raised at
+ %td= @alert.raised_at.to_s_human
+ -if @alert.acknowledged?
+ %tr
+ %th{:title => "The time at which the alert was acknowledged"} Acknowledged at
+ %td= @alert.acknowledged_at.to_s_human + " by " + @alert.acknowledged_by + " until " + @alert.will_unacknowledge_at.to_s_human
+ -if @alert.will_raise_at
+ %tr
+ %th{:title => "The time at which the alert will be automatically raised"} Will raise at
+ %td= @alert.will_raise_at.to_s_human
+ -if @alert.cleared_at
+ %tr
+ %th{:title => "The time at which the alert was last cleared"} Last cleared at
+ %td= @alert.cleared_at.to_s_human
+ -if @alert.will_clear_at
+ %tr
+ %th{:title => "The time at which the alert will be automatically cleared"} Will clear
+ %td= @alert.will_raise_at.to_s_human
+ %tr
+ %th Notifications sent out
+ %td
+ %ul
+ - @alert.changes.each do |change|
+ - if change.was_relevant?
+ %li
+ %strong= change.level
+ = change.update_type
+ notification to
+ = change.person
+ at
+ = change.at.to_s_human
+
+%h2 Actions
+- if !@alert.acknowledged?
+ %form{:method => :post, :action => "/alert/#{@alert.id}/acknowledge"}
+ =partial("acknowledge_input")
+- else
+ %form.hidden{:method => :post, :action => "/alert/#{@alert.id}/unacknowledge"}
+ %input{:type => :submit, :value => "Unacknowledge this alert"}
+%a#hide{:onclick => "$('form.hidden').toggle(); return false", :href=>"#"} Show other actions
+- if @alert.cleared?
+ %form.hidden{:method => :post, :action => "/alert/#{@alert.id}/raise"}
+ %input{:type => :submit, :value => "Raise this alert"}
+- if @alert.raised?
+ %form.hidden{:method => :post, :action => "/alert/#{@alert.id}/clear"}
+ %input{:type => :submit, :value => "Clear this alert"}
+%form.hidden{:method => :post, :action => "/alert/#{@alert.id}/destroy"}
+ %input{:type => :submit, :value => "Destroy this alert"}
diff --git a/views/alerts.haml b/views/alerts.haml
index 2d871cc..aedbc72 100644
--- a/views/alerts.haml
+++ b/views/alerts.haml
@@ -1,12 +1,31 @@
-!!! 5
-%html
- = partial('head')
- %body
- =partial("navbar")
- .container
- - if @grouped_alerts.length > 0
- = partial('alerts_table')
- - else
- .notice
- %p No alerts to display.
+- if @grouped_alerts.length > 0
+ %form#alerts{:method => :post, :action => '/alerts/acknowledge'}
+ = partial('alerts_table')
+ %h2 Actions
+ %p= partial('acknowledge_input')
+- else
+ .notice#alerts_table
+ %p No alerts to display.
+:javascript
+ $(document).ready( function() {
+ $.PeriodicalUpdater({
+ url: '/ajax/alerts_table/#{@alert_type}/#{@group_by}',
+ minTimeout: 10000,
+ maxTimeout: 30000,
+ }, function(alerts_table, success, xhr, handle){
+ $('#alerts_table').replaceWith(alerts_table);
+ });
+ $.PeriodicalUpdater({
+ url: '/ajax/alert_counts',
+ minTimeout: 10000,
+ maxTimeout: 30000,
+ }, function(alert_counts, success, xhr, handle){
+ var counts = jQuery.parseJSON( alert_counts );
+ $('#count_raised').html(counts[0]+counts[1]+counts[2]);
+ $('#count_ackd').html(counts[3]);
+ $('#count_cleared').html(counts[4]);
+ return false;
+ });
+
+ });
diff --git a/views/login.haml b/views/login.haml
index 06e5320..3deee76 100644
--- a/views/login.haml
+++ b/views/login.haml
@@ -1,17 +1,11 @@
-!!! 5
-%html
- =partial("head")
- %body
- = partial('navbar')
- .container
- %form{:action => '/login', :method => :POST}
- %fieldset
- %legend Please log in
- %label{:for => "username"} Username
- %input{:name => 'username', :type => 'text', :autocorrect => "off", :autocapitalize => "off"}/
- %br
- %label{:for => "password", :title => "This is either your Single Sign On password or a PIN."} Password / PIN
- %input{:name => 'password', :type => 'password'}/
- %br
- %input{:type => 'hidden', :name => 'next_page', :value => @next_page}/
- %input{:type => 'submit', :value => 'Log in'}/
+%form{:action => '/login', :method => :POST}
+ %fieldset
+ %legend Please log in
+ %label{:for => "username"} Username
+ %input{:name => 'username', :type => 'text', :autocorrect => "off", :autocapitalize => "off"}/
+ %br
+ %label{:for => "password", :title => "This is either your Single Sign On password or a PIN."} Password / PIN
+ %input{:name => 'password', :type => 'password'}/
+ %br
+ %input{:type => 'hidden', :name => 'next_page', :value => @next_page}/
+ %input{:type => 'submit', :value => 'Log in'}/
diff --git a/views/not_implemented.haml b/views/not_implemented.haml
index a07b00d..dd3fe15 100644
--- a/views/not_implemented.haml
+++ b/views/not_implemented.haml
@@ -1,7 +1 @@
-!!! 5
-%html
- = partial('head')
- %body
- =partial("navbar")
- .container
- .error Not implemented
+.error Not implemented