redis_monitor 0.0.6 → 0.1

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.
@@ -4,19 +4,20 @@ require 'errors/errors'
4
4
  module RedisMonitor
5
5
  module Controllers
6
6
  class BaseController
7
- attr_accessor :context, :params
7
+ attr_accessor :context, :session, :params
8
8
 
9
9
  include RedisMonitor::Helpers::BaseHelper
10
10
  include RedisMonitor::Helpers::LayoutsHelper
11
11
 
12
12
  def initialize(opts = {})
13
13
  @context = opts.delete(:context)
14
- @params = opts
14
+ @session = opts.delete(:session)
15
+ @params = opts.delete(:params)
15
16
  end
16
17
 
17
- def execute(action, params = {})
18
+ def execute(action)
18
19
  begin
19
- send(action, params)
20
+ send(action)
20
21
  rescue RedisMonitor::Errors::RedisNotAvailable
21
22
  redis_not_available
22
23
  end
@@ -30,6 +31,23 @@ module RedisMonitor
30
31
  def http_referer
31
32
  context.env['HTTP_REFERER']
32
33
  end
34
+
35
+ def context
36
+ @context
37
+ end
38
+
39
+ def params
40
+ @params
41
+ end
42
+
43
+ def session
44
+ @session
45
+ end
46
+
47
+ def set_database(database)
48
+ session[:database] = database
49
+ Backend.change_database(database)
50
+ end
33
51
  end
34
52
  end
35
53
  end
@@ -2,22 +2,29 @@
2
2
  module RedisMonitor
3
3
  module Controllers
4
4
  class ContentController < BaseController
5
- include RedisMonitor::Helpers::LayoutsHelper
6
-
7
5
  SECTION = 'content'
8
6
 
9
- def index(params = {})
7
+ def index
10
8
  haml 'content/index'.to_sym, layout: main_layout, locals: {section: SECTION}
11
9
  end
12
10
 
13
- def search(params = {})
11
+ def search
14
12
  results = Backend.search(params[:key]).paginate(:page => params[:page], :per_page => 20)
15
13
  haml 'content/search'.to_sym, layout: main_layout, locals: {results: results, section: SECTION, object: self}
16
14
  end
17
15
 
18
- def delete(params = {})
16
+ def delete
19
17
  Backend.del(params[:key])
18
+ redirect_back
19
+ end
20
+
21
+ def change_database
22
+ set_database(params[:database])
23
+ redirect_back
24
+ end
20
25
 
26
+ private
27
+ def redirect_back
21
28
  if http_referer
22
29
  context.redirect http_referer
23
30
  else
@@ -6,7 +6,7 @@ module RedisMonitor
6
6
 
7
7
  SECTION = 'info'
8
8
 
9
- def index(params={})
9
+ def index
10
10
  haml 'info/info'.to_sym, layout: main_layout, locals: {info: Backend.info, section: SECTION}
11
11
  end
12
12
  end
@@ -2,7 +2,6 @@
2
2
  module RedisMonitor
3
3
  module Controllers
4
4
  class PerformanceController < BaseController
5
- include RedisMonitor::Helpers::LayoutsHelper
6
5
 
7
6
  SECTION = 'performance'
8
7
 
@@ -0,0 +1,40 @@
1
+ module RedisMonitor
2
+ module Helpers
3
+ module DatabaseHelper
4
+ def current_database
5
+ session[:database].to_i
6
+ end
7
+
8
+ def databases
9
+ Backend.databases.each do |database|
10
+ database_option(database)
11
+ end
12
+ end
13
+
14
+ def database_option(database)
15
+ haml_tag :option, {selected: (database.to_i == current_database.to_i)} do
16
+ haml_concat database
17
+ end
18
+ end
19
+
20
+ def choose_database_select
21
+ capture_haml do
22
+ haml_tag :form, action: '/content/change_database', method: 'post' do
23
+ haml_tag :div, class: 'form-group' do
24
+ haml_tag :label, for: 'database_select' do
25
+ haml_concat 'Select database'
26
+ end
27
+
28
+ haml_tag :select, id: 'database_select', name: 'database', class: 'selectpicker form-control', data: {style: 'btn-info'} do
29
+ databases
30
+ end
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+
@@ -24,10 +24,6 @@ module RedisMonitor
24
24
  end
25
25
  end
26
26
  end
27
-
28
- def authorized_for?(action)
29
- Authorization.authorized_for?(action)
30
- end
31
27
  end
32
28
  end
33
29
  end
@@ -1,5 +1,10 @@
1
- module PaginationHelper
2
- def bootstrap_paginate(results)
3
- will_paginate results, renderer: BootstrapPagination::Sinatra
1
+ module RedisMonitor
2
+ module Helpers
3
+ module PaginationHelper
4
+ def bootstrap_paginate(results)
5
+ will_paginate results, renderer: BootstrapPagination::Sinatra
6
+ end
7
+ end
4
8
  end
5
- end
9
+ end
10
+
@@ -7,7 +7,7 @@ module RedisMonitor
7
7
  class Backend
8
8
  extend SingleForwardable
9
9
 
10
- def_delegators :redis, :get, :set, :info, :keys, :dbsize, :monitor
10
+ def_delegators :redis, :get, :set, :info, :keys, :dbsize, :select
11
11
 
12
12
  def self.config(arguments)
13
13
  @@host = arguments[:redis_host]
@@ -34,8 +34,16 @@ module RedisMonitor
34
34
  keys(key).map{|found| {key: found, value: get(found)} }
35
35
  end
36
36
 
37
+ def self.change_database(*args)
38
+ select(*args)
39
+ end
40
+
37
41
  def self.del(key)
38
42
  redis.del(key) if Authorization.authorized_for?(:remove_content)
39
43
  end
44
+
45
+ def self.databases
46
+ info.keys.map{|d| d.match(/db(\d+)/);$1}.compact
47
+ end
40
48
  end
41
49
  end
@@ -1,12 +1,15 @@
1
1
  require 'helpers/base_helper'
2
2
  require 'helpers/layouts_helper'
3
3
  require 'helpers/pagination_helper'
4
+ require 'helpers/database_helper'
4
5
 
5
6
  module RedisMonitor
6
7
  module Helpers
7
8
  module AllHelpers
8
9
  include BaseHelper
9
10
  include LayoutsHelper
11
+ include PaginationHelper
12
+ include DatabaseHelper
10
13
  end
11
14
  end
12
15
  end
@@ -5,17 +5,22 @@ module RedisMonitor
5
5
  module Router
6
6
  include RedisMonitor::Controllers
7
7
 
8
+ def dependencies
9
+ {context: self, session: session, params: params}
10
+ end
11
+
8
12
  def self.included(server)
9
13
  server.get('/'){ redirect '/info' }
10
- server.get('/info'){ InfoController.new(context: self).execute(:index, params) }
14
+ server.get('/info'){ InfoController.new(dependencies).execute(:index) }
11
15
 
12
- server.get('/content'){ ContentController.new(context: self).execute(:index, params) }
13
- server.get('/content/search'){ ContentController.new(context: self).execute(:search, params) }
14
- server.post('/content/delete'){ ContentController.new(context: self).execute(:delete, params) }
16
+ server.get('/content'){ ContentController.new(dependencies).execute(:index) }
17
+ server.get('/content/search'){ ContentController.new(dependencies).execute(:search) }
18
+ server.post('/content/delete'){ ContentController.new(dependencies).execute(:delete) }
19
+ server.post('/content/change_database'){ ContentController.new(dependencies).execute(:change_database) }
15
20
 
16
21
  server.get('/performance'){ redirect '/performance/warning' }
17
- server.get('/performance/warning'){ PerformanceController.new(context: self).execute(:warning, params) }
18
- server.get('/performance/check'){ PerformanceController.new(context: self).execute(:check, params) }
22
+ server.get('/performance/warning'){ PerformanceController.new(dependencies).execute(:warning) }
23
+ server.get('/performance/check'){ PerformanceController.new(dependencies).execute(:check) }
19
24
  end
20
25
  end
21
26
  end
@@ -1,3 +1,3 @@
1
1
  module RedisMonitor
2
- VERSION = '0.0.6'
2
+ VERSION = '0.1'
3
3
  end
data/lib/server/server.rb CHANGED
@@ -10,10 +10,12 @@ module RedisMonitor
10
10
  include RedisMonitor::Router
11
11
  include RedisMonitor::Helpers::LayoutsHelper
12
12
  include WillPaginate::Sinatra::Helpers
13
- include PaginationHelper
13
+ include RedisMonitor::Helpers::PaginationHelper
14
+ include RedisMonitor::Helpers::DatabaseHelper
14
15
 
15
16
  set :public_folder, File.dirname(__FILE__) + '/../static'
16
17
  set :views, File.dirname(__FILE__) + '/../views'
18
+ enable :sessions
17
19
 
18
20
  def self.config(arguments)
19
21
  set :server, arguments[:http_server]
@@ -0,0 +1,6 @@
1
+ $(document).ready(function(){
2
+ $('.selectpicker').selectpicker();
3
+ $('#database_select').change(function(){
4
+ $(this).closest('form').submit();
5
+ });
6
+ });
@@ -0,0 +1,8 @@
1
+ /*!
2
+ * bootstrap-select v1.4.2
3
+ * http://silviomoreto.github.io/bootstrap-select/
4
+ *
5
+ * Copyright 2013 bootstrap-select
6
+ * Licensed under the MIT license
7
+ */
8
+ ;!function(b){b.expr[":"].icontains=function(e,c,d){return b(e).text().toUpperCase().indexOf(d[3].toUpperCase())>=0};var a=function(d,c,f){if(f){f.stopPropagation();f.preventDefault()}this.$element=b(d);this.$newElement=null;this.$button=null;this.$menu=null;this.options=b.extend({},b.fn.selectpicker.defaults,this.$element.data(),typeof c=="object"&&c);if(this.options.title===null){this.options.title=this.$element.attr("title")}this.val=a.prototype.val;this.render=a.prototype.render;this.refresh=a.prototype.refresh;this.setStyle=a.prototype.setStyle;this.selectAll=a.prototype.selectAll;this.deselectAll=a.prototype.deselectAll;this.init()};a.prototype={constructor:a,init:function(){this.$element.hide();this.multiple=this.$element.prop("multiple");var d=this.$element.attr("id");this.$newElement=this.createView();this.$element.after(this.$newElement);this.$menu=this.$newElement.find("> .dropdown-menu");this.$button=this.$newElement.find("> button");this.$searchbox=this.$newElement.find("input");if(d!==undefined){var c=this;this.$button.attr("data-id",d);b('label[for="'+d+'"]').click(function(f){f.preventDefault();c.$button.focus()})}this.checkDisabled();this.clickListener();if(this.options.liveSearch){this.liveSearchListener()}this.render();this.liHeight();this.setStyle();this.setWidth();if(this.options.container){this.selectPosition()}this.$menu.data("this",this);this.$newElement.data("this",this)},createDropdown:function(){var c=this.multiple?" show-tick":"";var f=this.options.header?'<div class="popover-title"><button type="button" class="close" aria-hidden="true">&times;</button>'+this.options.header+"</div>":"";var e=this.options.liveSearch?'<div class="bootstrap-select-searchbox"><input type="text" class="input-block-level form-control" /></div>':"";var d='<div class="btn-group bootstrap-select'+c+'"><button type="button" class="btn dropdown-toggle selectpicker" data-toggle="dropdown"><span class="filter-option pull-left"></span>&nbsp;<span class="caret"></span></button><div class="dropdown-menu open">'+f+e+'<ul class="dropdown-menu inner selectpicker" role="menu"></ul></div></div>';return b(d)},createView:function(){var c=this.createDropdown();var d=this.createLi();c.find("ul").append(d);return c},reloadLi:function(){this.destroyLi();var c=this.createLi();this.$menu.find("ul").append(c)},destroyLi:function(){this.$menu.find("li").remove()},createLi:function(){var d=this,e=[],c="";this.$element.find("option").each(function(){var i=b(this);var g=i.attr("class")||"";var h=i.attr("style")||"";var m=i.data("content")?i.data("content"):i.html();var k=i.data("subtext")!==undefined?'<small class="muted text-muted">'+i.data("subtext")+"</small>":"";var j=i.data("icon")!==undefined?'<i class="'+d.options.iconBase+" "+i.data("icon")+'"></i> ':"";if(j!==""&&(i.is(":disabled")||i.parent().is(":disabled"))){j="<span>"+j+"</span>"}if(!i.data("content")){m=j+'<span class="text">'+m+k+"</span>"}if(d.options.hideDisabled&&(i.is(":disabled")||i.parent().is(":disabled"))){e.push('<a style="min-height: 0; padding: 0"></a>')}else{if(i.parent().is("optgroup")&&i.data("divider")!==true){if(i.index()===0){var l=i.parent().attr("label");var n=i.parent().data("subtext")!==undefined?'<small class="muted text-muted">'+i.parent().data("subtext")+"</small>":"";var f=i.parent().data("icon")?'<i class="'+i.parent().data("icon")+'"></i> ':"";l=f+'<span class="text">'+l+n+"</span>";if(i[0].index!==0){e.push('<div class="div-contain"><div class="divider"></div></div><dt>'+l+"</dt>"+d.createA(m,"opt "+g,h))}else{e.push("<dt>"+l+"</dt>"+d.createA(m,"opt "+g,h))}}else{e.push(d.createA(m,"opt "+g,h))}}else{if(i.data("divider")===true){e.push('<div class="div-contain"><div class="divider"></div></div>')}else{if(b(this).data("hidden")===true){e.push("")}else{e.push(d.createA(m,g,h))}}}}});b.each(e,function(f,g){c+="<li rel="+f+">"+g+"</li>"});if(!this.multiple&&this.$element.find("option:selected").length===0&&!this.options.title){this.$element.find("option").eq(0).prop("selected",true).attr("selected","selected")}return b(c)},createA:function(e,c,d){return'<a tabindex="0" class="'+c+'" style="'+d+'">'+e+'<i class="'+this.options.iconBase+" "+this.options.tickIcon+' icon-ok check-mark"></i></a>'},render:function(){var d=this;this.$element.find("option").each(function(h){d.setDisabled(h,b(this).is(":disabled")||b(this).parent().is(":disabled"));d.setSelected(h,b(this).is(":selected"))});this.tabIndex();var g=this.$element.find("option:selected").map(function(){var j=b(this);var i=j.data("icon")&&d.options.showIcon?'<i class="'+d.options.iconBase+" "+j.data("icon")+'"></i> ':"";var h;if(d.options.showSubtext&&j.attr("data-subtext")&&!d.multiple){h=' <small class="muted text-muted">'+j.data("subtext")+"</small>"}else{h=""}if(j.data("content")&&d.options.showContent){return j.data("content")}else{if(j.attr("title")!==undefined){return j.attr("title")}else{return i+j.html()+h}}}).toArray();var f=!this.multiple?g[0]:g.join(this.options.multipleSeparator);if(this.multiple&&this.options.selectedTextFormat.indexOf("count")>-1){var c=this.options.selectedTextFormat.split(">");var e=this.options.hideDisabled?":not([disabled])":"";if((c.length>1&&g.length>c[1])||(c.length==1&&g.length>=2)){f=this.options.countSelectedText.replace("{0}",g.length).replace("{1}",this.$element.find('option:not([data-divider="true"]):not([data-hidden="true"])'+e).length)}}if(!f){f=this.options.title!==undefined?this.options.title:this.options.noneSelectedText}this.$button.attr("title",b.trim(f));this.$newElement.find(".filter-option").html(f)},setStyle:function(e,d){if(this.$element.attr("class")){this.$newElement.addClass(this.$element.attr("class").replace(/selectpicker|mobile-device/gi,""))}var c=e?e:this.options.style;if(d=="add"){this.$button.addClass(c)}else{if(d=="remove"){this.$button.removeClass(c)}else{this.$button.removeClass(this.options.style);this.$button.addClass(c)}}},liHeight:function(){var e=this.$menu.parent().clone().appendTo("body"),f=e.addClass("open").find("> .dropdown-menu"),d=f.find("li > a").outerHeight(),c=this.options.header?f.find(".popover-title").outerHeight():0,g=this.options.liveSearch?f.find(".bootstrap-select-searchbox").outerHeight():0;e.remove();this.$newElement.data("liHeight",d).data("headerHeight",c).data("searchHeight",g)},setSize:function(){var h=this,d=this.$menu,i=d.find(".inner"),t=this.$newElement.outerHeight(),f=this.$newElement.data("liHeight"),r=this.$newElement.data("headerHeight"),l=this.$newElement.data("searchHeight"),k=d.find("li .divider").outerHeight(true),q=parseInt(d.css("padding-top"))+parseInt(d.css("padding-bottom"))+parseInt(d.css("border-top-width"))+parseInt(d.css("border-bottom-width")),o=this.options.hideDisabled?":not(.disabled)":"",n=b(window),g=q+parseInt(d.css("margin-top"))+parseInt(d.css("margin-bottom"))+2,p,u,s,j=function(){u=h.$newElement.offset().top-n.scrollTop();s=n.height()-u-t};j();if(this.options.header){d.css("padding-top",0)}if(this.options.size=="auto"){var e=function(){var v;j();p=s-g;if(h.options.dropupAuto){h.$newElement.toggleClass("dropup",(u>s)&&((p-g)<d.height()))}if(h.$newElement.hasClass("dropup")){p=u-g}if((d.find("li").length+d.find("dt").length)>3){v=f*3+g-2}else{v=0}d.css({"max-height":p+"px",overflow:"hidden","min-height":v+"px"});i.css({"max-height":p-r-l-q+"px","overflow-y":"auto","min-height":v-q+"px"})};e();b(window).resize(e);b(window).scroll(e)}else{if(this.options.size&&this.options.size!="auto"&&d.find("li"+o).length>this.options.size){var m=d.find("li"+o+" > *").filter(":not(.div-contain)").slice(0,this.options.size).last().parent().index();var c=d.find("li").slice(0,m+1).find(".div-contain").length;p=f*this.options.size+c*k+q;if(h.options.dropupAuto){this.$newElement.toggleClass("dropup",(u>s)&&(p<d.height()))}d.css({"max-height":p+r+l+"px",overflow:"hidden"});i.css({"max-height":p-q+"px","overflow-y":"auto"})}}},setWidth:function(){if(this.options.width=="auto"){this.$menu.css("min-width","0");var d=this.$newElement.clone().appendTo("body");var c=d.find("> .dropdown-menu").css("width");d.remove();this.$newElement.css("width",c)}else{if(this.options.width=="fit"){this.$menu.css("min-width","");this.$newElement.css("width","").addClass("fit-width")}else{if(this.options.width){this.$menu.css("min-width","");this.$newElement.css("width",this.options.width)}else{this.$menu.css("min-width","");this.$newElement.css("width","")}}}if(this.$newElement.hasClass("fit-width")&&this.options.width!=="fit"){this.$newElement.removeClass("fit-width")}},selectPosition:function(){var e=this,d="<div />",f=b(d),h,g,c=function(i){f.addClass(i.attr("class")).toggleClass("dropup",i.hasClass("dropup"));h=i.offset();g=i.hasClass("dropup")?0:i[0].offsetHeight;f.css({top:h.top+g,left:h.left,width:i[0].offsetWidth,position:"absolute"})};this.$newElement.on("click",function(){c(b(this));f.appendTo(e.options.container);f.toggleClass("open",!b(this).hasClass("open"));f.append(e.$menu)});b(window).resize(function(){c(e.$newElement)});b(window).on("scroll",function(){c(e.$newElement)});b("html").on("click",function(i){if(b(i.target).closest(e.$newElement).length<1){f.removeClass("open")}})},mobile:function(){this.$element.addClass("mobile-device").appendTo(this.$newElement);if(this.options.container){this.$menu.hide()}},refresh:function(){this.reloadLi();this.render();this.setWidth();this.setStyle();this.checkDisabled();this.liHeight()},update:function(){this.reloadLi();this.setWidth();this.setStyle();this.checkDisabled();this.liHeight()},setSelected:function(c,d){this.$menu.find("li").eq(c).toggleClass("selected",d)},setDisabled:function(c,d){if(d){this.$menu.find("li").eq(c).addClass("disabled").find("a").attr("href","#").attr("tabindex",-1)}else{this.$menu.find("li").eq(c).removeClass("disabled").find("a").removeAttr("href").attr("tabindex",0)}},isDisabled:function(){return this.$element.is(":disabled")},checkDisabled:function(){var c=this;if(this.isDisabled()){this.$button.addClass("disabled").attr("tabindex",-1)}else{if(this.$button.hasClass("disabled")){this.$button.removeClass("disabled")}if(this.$button.attr("tabindex")==-1){if(!this.$element.data("tabindex")){this.$button.removeAttr("tabindex")}}}this.$button.click(function(){return !c.isDisabled()})},tabIndex:function(){if(this.$element.is("[tabindex]")){this.$element.data("tabindex",this.$element.attr("tabindex"));this.$button.attr("tabindex",this.$element.data("tabindex"))}},clickListener:function(){var c=this;b("body").on("touchstart.dropdown",".dropdown-menu",function(d){d.stopPropagation()});this.$newElement.on("click",function(){c.setSize();if(!c.options.liveSearch&&!c.multiple){setTimeout(function(){c.$menu.find(".selected a").focus()},10)}});this.$menu.on("click","li a",function(k){var g=b(this).parent().index(),j=c.$element.val(),f=c.$element.prop("selectedIndex");if(c.multiple){k.stopPropagation()}k.preventDefault();if(!c.isDisabled()&&!b(this).parent().hasClass("disabled")){var d=c.$element.find("option");var i=d.eq(g);if(!c.multiple){d.prop("selected",false);i.prop("selected",true)}else{var h=i.prop("selected");i.prop("selected",!h)}if(!c.multiple){c.$button.focus()}else{if(c.options.liveSearch){c.$searchbox.focus()}}if((j!=c.$element.val()&&c.multiple)||(f!=c.$element.prop("selectedIndex")&&!c.multiple)){c.$element.change()}}});this.$menu.on("click","li.disabled a, li dt, li .div-contain, .popover-title, .popover-title :not(.close)",function(d){if(d.target==this){d.preventDefault();d.stopPropagation();if(!c.options.liveSearch){c.$button.focus()}else{c.$searchbox.focus()}}});this.$menu.on("click",".popover-title .close",function(){c.$button.focus()});this.$searchbox.on("click",function(d){d.stopPropagation()});this.$element.change(function(){c.render()})},liveSearchListener:function(){var d=this,c=b('<li class="no-results"></li>');this.$newElement.on("click.dropdown.data-api",function(){d.$menu.find(".active").removeClass("active");if(!!d.$searchbox.val()){d.$searchbox.val("");d.$menu.find("li").show();if(!!c.parent().length){c.remove()}}if(!d.multiple){d.$menu.find(".selected").addClass("active")}setTimeout(function(){d.$searchbox.focus()},10)});this.$searchbox.on("input propertychange",function(){if(d.$searchbox.val()){d.$menu.find("li").show().not(":icontains("+d.$searchbox.val()+")").hide();if(!d.$menu.find("li").filter(":visible:not(.no-results)").length){if(!!c.parent().length){c.remove()}c.html('No results match "'+d.$searchbox.val()+'"').show();d.$menu.find("li").last().after(c)}else{if(!!c.parent().length){c.remove()}}}else{d.$menu.find("li").show();if(!!c.parent().length){c.remove()}}d.$menu.find("li.active").removeClass("active");d.$menu.find("li").filter(":visible:not(.divider)").eq(0).addClass("active").find("a").focus();b(this).focus()});this.$menu.on("mouseenter","a",function(f){d.$menu.find(".active").removeClass("active");b(f.currentTarget).parent().not(".disabled").addClass("active")});this.$menu.on("mouseleave","a",function(){d.$menu.find(".active").removeClass("active")})},val:function(c){if(c!==undefined){this.$element.val(c);this.$element.change();return this.$element}else{return this.$element.val()}},selectAll:function(){this.$element.find("option").prop("selected",true).attr("selected","selected");this.render()},deselectAll:function(){this.$element.find("option").prop("selected",false).removeAttr("selected");this.render()},keydown:function(p){var q,o,i,n,k,j,r,f,h,m,d,s,g={32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"};q=b(this);i=q.parent();if(q.is("input")){i=q.parent().parent()}m=i.data("this");if(m.options.liveSearch){i=q.parent().parent()}if(m.options.container){i=m.$menu}o=b("[role=menu] li:not(.divider) a",i);s=m.$menu.parent().hasClass("open");if(m.options.liveSearch){if(/(^9$|27)/.test(p.keyCode)&&s&&m.$menu.find(".active").length===0){p.preventDefault();m.$menu.parent().removeClass("open");m.$button.focus()}o=b("[role=menu] li:not(.divider):visible",i);if(!q.val()&&!/(38|40)/.test(p.keyCode)){if(o.filter(".active").length===0){o=m.$newElement.find("li").filter(":icontains("+g[p.keyCode]+")")}}}if(!o.length){return}if(/(38|40)/.test(p.keyCode)){if(!s){m.$menu.parent().addClass("open")}n=o.index(o.filter(":focus"));j=o.parent(":not(.disabled):visible").first().index();r=o.parent(":not(.disabled):visible").last().index();k=o.eq(n).parent().nextAll(":not(.disabled):visible").eq(0).index();f=o.eq(n).parent().prevAll(":not(.disabled):visible").eq(0).index();h=o.eq(k).parent().prevAll(":not(.disabled):visible").eq(0).index();if(m.options.liveSearch){o.each(function(e){if(b(this).is(":not(.disabled)")){b(this).data("index",e)}});n=o.index(o.filter(".active"));j=o.filter(":not(.disabled):visible").first().data("index");r=o.filter(":not(.disabled):visible").last().data("index");k=o.eq(n).nextAll(":not(.disabled):visible").eq(0).data("index");f=o.eq(n).prevAll(":not(.disabled):visible").eq(0).data("index");h=o.eq(k).prevAll(":not(.disabled):visible").eq(0).data("index")}d=q.data("prevIndex");if(p.keyCode==38){if(m.options.liveSearch){n-=1}if(n!=h&&n>f){n=f}if(n<j){n=j}if(n==d){n=r}}if(p.keyCode==40){if(m.options.liveSearch){n+=1}if(n==-1){n=0}if(n!=h&&n<k){n=k}if(n>r){n=r}if(n==d){n=j}}q.data("prevIndex",n);if(!m.options.liveSearch){o.eq(n).focus()}else{p.preventDefault();if(!q.is(".dropdown-toggle")){o.removeClass("active");o.eq(n).addClass("active").find("a").focus();q.focus()}}}else{if(!q.is("input")){var c=[],l,t;o.each(function(){if(b(this).parent().is(":not(.disabled)")){if(b.trim(b(this).text().toLowerCase()).substring(0,1)==g[p.keyCode]){c.push(b(this).parent().index())}}});l=b(document).data("keycount");l++;b(document).data("keycount",l);t=b.trim(b(":focus").text().toLowerCase()).substring(0,1);if(t!=g[p.keyCode]){l=1;b(document).data("keycount",l)}else{if(l>=c.length){b(document).data("keycount",0);if(l>c.length){l=1}}}o.eq(c[l-1]).focus()}}if(/(13|32|^9$)/.test(p.keyCode)&&s){if(!/(32)/.test(p.keyCode)){p.preventDefault()}if(!m.options.liveSearch){b(":focus").click()}else{if(!/(32)/.test(p.keyCode)){m.$menu.find(".active a").click();q.focus()}}b(document).data("keycount",0)}if((/(^9$|27)/.test(p.keyCode)&&s&&(m.multiple||m.options.liveSearch))||(/(27)/.test(p.keyCode)&&!s)){m.$menu.parent().removeClass("open");m.$button.focus()}},hide:function(){this.$newElement.hide()},show:function(){this.$newElement.show()},destroy:function(){this.$newElement.remove();this.$element.remove()}};b.fn.selectpicker=function(e,f){var c=arguments;var g;var d=this.each(function(){if(b(this).is("select")){var m=b(this),l=m.data("selectpicker"),h=typeof e=="object"&&e;if(!l){m.data("selectpicker",(l=new a(this,h,f)))}else{if(h){for(var j in h){l.options[j]=h[j]}}}if(typeof e=="string"){var k=e;if(l[k] instanceof Function){[].shift.apply(c);g=l[k].apply(l,c)}else{g=l.options[k]}}}});if(g!==undefined){return g}else{return d}};b.fn.selectpicker.defaults={style:"btn-default",size:"auto",title:null,selectedTextFormat:"values",noneSelectedText:"Nothing selected",countSelectedText:"{0} of {1} selected",width:false,container:false,hideDisabled:false,showSubtext:false,showIcon:true,showContent:true,dropupAuto:true,header:false,liveSearch:false,multipleSeparator:", ",iconBase:"glyphicon",tickIcon:"glyphicon-ok"};b(document).data("keycount",0).on("keydown",".bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=menu], .bootstrap-select-searchbox input",a.prototype.keydown).on("focusin.modal",".bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=menu], .bootstrap-select-searchbox input",function(c){c.stopPropagation()})}(window.jQuery);
@@ -0,0 +1,7 @@
1
+ /*!
2
+ * bootstrap-select v1.4.2
3
+ * http://silviomoreto.github.io/bootstrap-select/
4
+ *
5
+ * Copyright 2013 bootstrap-select
6
+ * Licensed under the MIT license
7
+ */.bootstrap-select.btn-group,.bootstrap-select.btn-group[class*="span"]{float:none;display:inline-block;margin-bottom:10px;margin-left:0}.form-search .bootstrap-select.btn-group,.form-inline .bootstrap-select.btn-group,.form-horizontal .bootstrap-select.btn-group{margin-bottom:0}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:0}.bootstrap-select.btn-group.pull-right,.bootstrap-select.btn-group[class*="span"].pull-right,.row-fluid .bootstrap-select.btn-group[class*="span"].pull-right{float:right}.input-append .bootstrap-select.btn-group{margin-left:-1px}.input-prepend .bootstrap-select.btn-group{margin-right:-1px}.bootstrap-select:not([class*="span"]):not([class*="col-"]):not([class*="form-control"]){width:220px}.bootstrap-select{width:220px\0}.bootstrap-select.form-control:not([class*="span"]){width:100%}.bootstrap-select>.btn{width:100%}.error .bootstrap-select .btn{border:1px solid #b94a48}.dropdown-menu{z-index:2000}.bootstrap-select.show-menu-arrow.open>.btn{z-index:2051}.bootstrap-select .btn:focus{outline:thin dotted #333 !important;outline:5px auto -webkit-focus-ring-color !important;outline-offset:-2px}.bootstrap-select.btn-group .btn .filter-option{overflow:hidden;position:absolute;left:12px;right:25px;text-align:left}.bootstrap-select.btn-group .btn .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.bootstrap-select.btn-group>.disabled,.bootstrap-select.btn-group .dropdown-menu li.disabled>a{cursor:not-allowed}.bootstrap-select.btn-group>.disabled:focus{outline:none !important}.bootstrap-select.btn-group[class*="span"] .btn{width:100%}.bootstrap-select.btn-group .dropdown-menu{min-width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .dropdown-menu.inner{position:static;border:0;padding:0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.bootstrap-select.btn-group .dropdown-menu dt{display:block;padding:3px 20px;cursor:default}.bootstrap-select.btn-group .div-contain{overflow:hidden}.bootstrap-select.btn-group .dropdown-menu li{position:relative}.bootstrap-select.btn-group .dropdown-menu li>a.opt{position:relative;padding-left:35px}.bootstrap-select.btn-group .dropdown-menu li>a{cursor:pointer}.bootstrap-select.btn-group .dropdown-menu li>dt small{font-weight:normal}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a i.check-mark{display:inline-block;position:absolute;right:15px;margin-top:2.5px}.bootstrap-select.btn-group .dropdown-menu li a i.check-mark{display:none}.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select.btn-group .dropdown-menu li small{padding-left:.5em}.bootstrap-select.btn-group .dropdown-menu li:not(.disabled)>a:hover small,.bootstrap-select.btn-group .dropdown-menu li:not(.disabled)>a:focus small,.bootstrap-select.btn-group .dropdown-menu li.active:not(.disabled)>a small{color:#64b1d8;color:rgba(255,255,255,0.4)}.bootstrap-select.btn-group .dropdown-menu li>dt small{font-weight:normal}.bootstrap-select.show-menu-arrow .dropdown-toggle:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #CCC;border-bottom-color:rgba(0,0,0,0.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid white;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before{bottom:auto;top:-3px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after{bottom:auto;top:-3px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:before,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:after{display:block}.bootstrap-select.btn-group .no-results{padding:3px;background:#f5f5f5;margin:0 5px}.mobile-device{position:absolute;top:0;left:0;display:block !important;width:100%;height:100% !important;opacity:0}.bootstrap-select.fit-width{width:auto !important}.bootstrap-select.btn-group.fit-width .btn .filter-option{position:static}.bootstrap-select.btn-group.fit-width .btn .caret{position:static;top:auto;margin-top:-1px}.control-group.error .bootstrap-select .dropdown-toggle{border-color:#b94a48}.bootstrap-select-searchbox{padding:4px 8px}.bootstrap-select-searchbox input{margin-bottom:0}
@@ -1,5 +1,5 @@
1
1
  body {
2
- padding-top: 60px;
2
+ padding-top: 70px;
3
3
  }
4
4
 
5
5
  .message_centered {
@@ -1,5 +1,8 @@
1
1
  - search_term ||= nil
2
2
 
3
+ = choose_database_select
4
+ %hr
5
+
3
6
  %form{action: '/content/search', method: 'get', style: 'margin-top: 5px'}
4
7
  .form-group
5
8
  %label{for: 'input_key'}
@@ -7,7 +7,7 @@
7
7
  Key
8
8
  %th
9
9
  Value
10
- - if authorized_for?(:remove_content)
10
+ - if RedisMonitor::Authorization.authorized_for?(:remove_content)
11
11
  %th
12
12
  Actions
13
13
 
@@ -18,7 +18,7 @@
18
18
  = result[:key]
19
19
  %td
20
20
  = result[:value]
21
- - if authorized_for?(:remove_content)
21
+ - if RedisMonitor::Authorization.authorized_for?(:remove_content)
22
22
  %td
23
23
  %form{action: '/content/delete', method: 'post'}
24
24
  %input{type: 'hidden', name: 'key', value: result[:key]}
@@ -2,9 +2,12 @@
2
2
  %head
3
3
  %meta{name: 'viewport', content: 'width=device-width, initial-scale=1.0'}
4
4
  %link{rel: 'stylesheet', media: 'screen, projection', type: 'text/css', href: '/styles/bootstrap.min.css'}
5
+ %link{rel: 'stylesheet', media: 'screen, projection', type: 'text/css', href: '/styles/bootstrap-select.min.css'}
5
6
  %link{rel: 'stylesheet', media: 'screen, projection', type: 'text/css', href: '/styles/custom.css'}
6
7
  %script{src: '/scripts/jquery-2.0.3.min.js'}
7
8
  %script{src: '/scripts/bootstrap.min.js'}
9
+ %script{src: '/scripts/bootstrap-select.min.js'}
10
+ %script{src: '/scripts/app.js'}
8
11
  %body
9
12
  .navbar.navbar-inverse.navbar-fixed-top
10
13
  .container
@@ -4,6 +4,11 @@ describe BaseController do
4
4
  let(:context){ double() }
5
5
  let(:controller){ BaseController.new(context: context) }
6
6
 
7
+ before :each do
8
+ Backend.stub(:host)
9
+ Backend.stub(:port)
10
+ end
11
+
7
12
  describe 'execute method' do
8
13
  it 'should not raise error if the action executed raised RedisNotAvailable' do
9
14
  controller.stub(:action) { raise RedisNotAvailable }
@@ -14,10 +19,16 @@ describe BaseController do
14
19
 
15
20
  describe 'redis_not_available method' do
16
21
  it 'should render redis not available error page' do
17
- Backend.stub(:host)
18
- Backend.stub(:port)
19
22
  context.should_receive(:haml).with('errors/redis_not_available'.to_sym, anything)
20
23
  controller.redis_not_available
21
24
  end
22
25
  end
26
+
27
+ describe 'set_database' do
28
+ it 'should change the actual database' do
29
+ controller.stub(:session){ {} }
30
+ Backend.should_receive(:change_database)
31
+ controller.set_database(2)
32
+ end
33
+ end
23
34
  end
@@ -2,9 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  describe ContentController do
4
4
  let(:context){ double() }
5
- let(:controller){ ContentController.new(context: context) }
5
+ let(:params){ {key: ''} }
6
+ let(:controller){ ContentController.new(context: context, params: params) }
6
7
  let(:search_results){ double(paginate: []) }
7
8
 
9
+ before :each do
10
+ controller.stub(:redirect_back)
11
+ end
12
+
8
13
  describe 'index action' do
9
14
  it 'should render index template' do
10
15
  context.should_receive(:haml).with('content/index'.to_sym, anything)
@@ -21,20 +26,16 @@ describe ContentController do
21
26
  end
22
27
 
23
28
  describe 'delete action' do
24
- before :each do
25
- Backend.stub(:del)
26
- end
27
-
28
- it 'should redirect to the referer if exists' do
29
- controller.stub(:http_referer){ '/referer' }
30
- context.should_receive(:redirect).with('/referer')
29
+ it 'should call del on Backend' do
30
+ Backend.should_receive(:del)
31
31
  controller.delete
32
32
  end
33
+ end
33
34
 
34
- it 'should redirect to search page if referer does not exists' do
35
- controller.stub(:http_referer){ nil }
36
- context.should_receive(:redirect).with('/content/search')
37
- controller.delete
35
+ describe 'change_database' do
36
+ it 'should call set_database' do
37
+ controller.should_receive(:set_database)
38
+ controller.change_database
38
39
  end
39
40
  end
40
41
  end
@@ -51,4 +51,13 @@ describe Backend do
51
51
  Backend.del('key')
52
52
  end
53
53
  end
54
+
55
+ describe 'databases' do
56
+ it 'should retrieve databases' do
57
+ info_keys = {db0: '', db1: '', example: ''}
58
+ Backend.stub(:info){ info_keys }
59
+ Backend.databases.should include('0')
60
+ Backend.databases.should include('1')
61
+ end
62
+ end
54
63
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis_monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: '0.1'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-04 00:00:00.000000000 Z
12
+ date: 2014-01-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
@@ -178,6 +178,7 @@ files:
178
178
  - lib/errors/errors.rb
179
179
  - lib/errors/redis_not_available.rb
180
180
  - lib/helpers/base_helper.rb
181
+ - lib/helpers/database_helper.rb
181
182
  - lib/helpers/layouts_helper.rb
182
183
  - lib/helpers/pagination_helper.rb
183
184
  - lib/modules/backend.rb
@@ -191,8 +192,11 @@ files:
191
192
  - lib/redis_monitor.rb
192
193
  - lib/server/command_line_parser.rb
193
194
  - lib/server/server.rb
195
+ - lib/static/scripts/app.js
196
+ - lib/static/scripts/bootstrap-select.min.js
194
197
  - lib/static/scripts/bootstrap.min.js
195
198
  - lib/static/scripts/jquery-2.0.3.min.js
199
+ - lib/static/styles/bootstrap-select.min.css
196
200
  - lib/static/styles/bootstrap.min.css
197
201
  - lib/static/styles/custom.css
198
202
  - lib/views/content/_search_form.haml