beanstalkd_view 1.1.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/Gruntfile.js +41 -0
  2. data/README.md +13 -1
  3. data/Rakefile +0 -2
  4. data/lib/beanstalkd_view/beanstalkd_utils.rb +11 -16
  5. data/lib/beanstalkd_view/resources/css/beanstalkd_view.css +76 -0
  6. data/lib/beanstalkd_view/resources/js/beanstalkd_view.js +242 -0
  7. data/lib/beanstalkd_view/resources/js/beanstalkd_view.min.js +6 -0
  8. data/lib/beanstalkd_view/server.rb +0 -17
  9. data/lib/beanstalkd_view/version.rb +1 -1
  10. data/lib/beanstalkd_view/views/index.erb +30 -78
  11. data/lib/beanstalkd_view/views/job_info_popup.erb +67 -6
  12. data/lib/beanstalkd_view/views/layout.erb +2 -7
  13. data/lib/beanstalkd_view/views/peek_range.erb +1 -1
  14. data/lib/beanstalkd_view/views/tube_stats.erb +34 -35
  15. data/lib/beanstalkd_view.rb +0 -1
  16. data/package.json +10 -0
  17. data/spec/{integration → features}/rails_integration_spec.rb +1 -1
  18. data/spec/{integration → features}/sinatra_integration_spec.rb +1 -1
  19. data/spec/rails_app/log/test.log +990 -3
  20. data/spec/support/integration_test_shared_examples.rb +3 -3
  21. data/spec/support/queue_browser_shared_examples.rb +13 -13
  22. data/{lib/beanstalkd_view/resources → web}/css/app.css +0 -0
  23. data/{lib/beanstalkd_view/resources → web}/css/vendor/bootstrap.min.css +0 -0
  24. data/web/js/draw_chart.js +49 -0
  25. data/web/js/initialization.js +20 -0
  26. data/web/js/peek_jobs.js +135 -0
  27. data/web/js/peek_range.js +24 -0
  28. data/{lib/beanstalkd_view/resources → web}/js/vendor/bluff-0.3.6.2/bluff-min.js +0 -0
  29. data/{lib/beanstalkd_view/resources → web}/js/vendor/bluff-0.3.6.2/js-class.js +0 -0
  30. data/{lib/beanstalkd_view/resources → web}/js/vendor/bootstrap.min.js +0 -0
  31. data/{lib/beanstalkd_view/resources → web}/js/vendor/jquery-1.7.1.min.js +0 -0
  32. data/{lib/beanstalkd_view/resources → web}/js/vendor/json2.js +0 -0
  33. data/web/js/vendor/underscore-min.js +1 -0
  34. metadata +25 -34
  35. data/lib/beanstalkd_view/resources/js/app.js +0 -4
  36. data/lib/beanstalkd_view/resources/js/peek_jobs.js +0 -169
  37. data/lib/beanstalkd_view/resources/js/peek_range.js +0 -21
@@ -42,9 +42,9 @@ shared_examples 'integration_test' do
42
42
 
43
43
  it "should show the overview at: /", :requires_two_beanstalkd => true do
44
44
  visit site_root
45
- body.should have_content "Beanstalkd View"
46
- body.should have_content "Statistics"
47
- body.should have_content "Tubes"
45
+ page.should have_content "Beanstalkd View"
46
+ page.should have_content "Statistics"
47
+ page.should have_content "Tubes"
48
48
  end
49
49
 
50
50
  it_behaves_like "queue_browser", :requires_two_beanstalkd => true do
@@ -2,15 +2,15 @@ shared_examples 'queue_browser' do
2
2
 
3
3
  it "should show the overview at: /" do
4
4
  visit site_root
5
- body.should have_content "Beanstalkd View"
6
- body.should have_content "Statistics"
7
- body.should have_content "Tubes"
5
+ page.should have_content "Beanstalkd View"
6
+ page.should have_content "Statistics"
7
+ page.should have_content "Tubes"
8
8
  end
9
9
 
10
10
  it "should show the default tube stats at: tube/default" do
11
11
  visit "#{site_root}tube/default"
12
- body.should have_content "Beanstalkd View"
13
- body.should have_content "Statistics"
12
+ page.should have_content "Beanstalkd View"
13
+ page.should have_content "Statistics"
14
14
  end
15
15
 
16
16
  it "should be able to add a job on the overview page", :js => true do
@@ -19,15 +19,15 @@ shared_examples 'queue_browser' do
19
19
  form.fill_in 'form_tube_name', :with => tube_name
20
20
  form.fill_in 'form_job_body', :with => '{"id": 1, "name": "Bob"}'
21
21
  form.click_link('Add Job')
22
- body.should have_content "Add new job?"
22
+ page.should have_content "Add new job?"
23
23
  click_link "confirm_add_job_btn"
24
- body.should have_content "Added job:"
24
+ page.should have_content "Added job:"
25
25
  end
26
26
 
27
27
  it "should be able to click on the tube_name link (created by the last test)", :js => true do
28
28
  visit site_root
29
29
  click_link('test.tube')
30
- body.should have_content "test.tube"
30
+ page.should have_content "test.tube"
31
31
  end
32
32
 
33
33
  it "should be able to peek_range and see job (created by the last test)", :js => true do
@@ -36,7 +36,7 @@ shared_examples 'queue_browser' do
36
36
  form.fill_in 'min', :with => '0'
37
37
  form.fill_in 'max', :with => '0'
38
38
  click_button 'Peek'
39
- body.should have_content "Peek Range"
39
+ page.should have_content "Peek Range"
40
40
  end
41
41
 
42
42
  it "should be able to pause a tube", :js => true do
@@ -44,7 +44,7 @@ shared_examples 'queue_browser' do
44
44
  form = find('#pause_form')
45
45
  form.fill_in 'delay', :with => 1
46
46
  click_button "Pause"
47
- body.should have_content "Paused #{tube_name}"
47
+ page.should have_content "Paused #{tube_name}"
48
48
  end
49
49
 
50
50
  it "should be able to kick a tube", :js => true do
@@ -52,13 +52,13 @@ shared_examples 'queue_browser' do
52
52
  form = find('#kick_form')
53
53
  form.fill_in 'bound', :with => 1
54
54
  click_button "Kick"
55
- body.should have_content "Kicked #{tube_name}"
55
+ page.should have_content "Kicked #{tube_name}"
56
56
  end
57
57
 
58
58
  it "should be able to peek_ready a tube", :js => true do
59
59
  visit "#{site_root}tube/#{CGI::escape(tube_name)}"
60
60
  click_link('peek_ready_btn')
61
- body.should have_content "Job id:"
61
+ page.should have_content "Job id:"
62
62
  end
63
63
 
64
64
  it "should be able to clear a tube", :js => true do
@@ -66,7 +66,7 @@ shared_examples 'queue_browser' do
66
66
  form = find('#clear_form')
67
67
  form.select 'Buried', :from => 'state'
68
68
  click_button "Clear"
69
- body.should have_content "Cleared all buried jobs from #{tube_name}"
69
+ page.should have_content "Cleared all buried jobs from #{tube_name}"
70
70
  end
71
71
 
72
72
  end
File without changes
@@ -0,0 +1,49 @@
1
+ (function() {
2
+
3
+ $(document).ready(function() {
4
+ function draw_pie_chart(div, data) {
5
+ //Create pie charts
6
+ var chart = new Bluff.Bar(div, 460);
7
+ //Setup theme
8
+ var colors = ['#6886B4', '#FDD84E', '#72AE6E', '#D1695E', '#8A6EAF', '#EFAA43', 'white'];
9
+ chart.set_theme({
10
+ colors: colors,
11
+ marker_color: 'white',
12
+ font_color: 'white',
13
+ background_colors: ['#008000', '#008000']
14
+ });
15
+ chart.tooltips = true;
16
+ chart.hide_line_markers = false;
17
+ chart.minimum_value = 0;
18
+ var max_value = 0;
19
+ //Add each data item to chart
20
+ for (var i in data.items) {
21
+ var item = data.items[i];
22
+ chart.data(item.label, item.data);
23
+ if (item.data > max_value) {
24
+ max_value = item.data;
25
+ }
26
+ }
27
+ chart.maximum_value = max_value;
28
+ //Finally draw the chart
29
+ chart.draw();
30
+ }
31
+
32
+ if ($('#total_jobs_chart').length > 0) {
33
+ var total_jobs_data = $('#total_jobs_chart').data('set');
34
+ if (total_jobs_data !== null) {
35
+ draw_pie_chart('total_jobs_chart', total_jobs_data);
36
+ $("#total_jobs_container").css('visibility', 'visible');
37
+ }
38
+ }
39
+
40
+ if ($('#buried_jobs_chart').length > 0) {
41
+ var buried_jobs_data = $('#buried_jobs_chart').data('set');
42
+ if (buried_jobs_data !== null) {
43
+ draw_pie_chart('buried_jobs_chart', buried_jobs_data);
44
+ $("#buried_jobs_container").css('visibility', 'visible');
45
+ }
46
+ }
47
+ });
48
+
49
+ })();
@@ -0,0 +1,20 @@
1
+ (function() {
2
+
3
+ $(document).ready(function() {
4
+ //Enable Tooltips
5
+ $("[rel=tooltip]").tooltip();
6
+
7
+ if ($('#form_tube_name').length > 0) {
8
+ //Setup Typeahead For Tube Names on Add Job Form
9
+ var tubeNames = $('#form_tube_name').data('tubes');
10
+ $('#form_tube_name').typeahead({source: tubeNames});
11
+ }
12
+
13
+ //Update Underscore delimiters <% %> to Handlebar-style {{ }}
14
+ _.templateSettings = {
15
+ interpolate: /\{\{\=(.+?)\}\}/g,
16
+ evaluate: /\{\{(.+?)\}\}/g
17
+ };
18
+ });
19
+
20
+ })();
@@ -0,0 +1,135 @@
1
+ (function() {
2
+
3
+ $(document).ready(function() {
4
+ // Enable Peek Button Handlers
5
+ if ($("#peek_ready_btn").length > 0) {
6
+ $("#peek_ready_btn").click(function(event) {
7
+ event.preventDefault();
8
+ peek('ready');
9
+ });
10
+ }
11
+ if ($("#peek_delayed_btn").length > 0) {
12
+ $("#peek_delayed_btn").click(function(event) {
13
+ event.preventDefault();
14
+ peek('delayed');
15
+ });
16
+ }
17
+ if ($("#peek_buried_btn").length > 0) {
18
+ $("#peek_buried_btn").click(function(event) {
19
+ event.preventDefault();
20
+ peek('buried');
21
+ });
22
+ }
23
+ if ($("#add_job_btn").length > 0) {
24
+ $("#add_job_btn").click(function(event) {
25
+ event.preventDefault();
26
+ add_job();
27
+ });
28
+ }
29
+
30
+ function peek(queue) {
31
+ var tube = document.getElementById("form_tube_name").value;
32
+ var url_base = document.getElementById("form_url_base").value;
33
+ var jqxhr = $.getJSON(url_base+"peek/"+encodeURIComponent(tube)+"/"+queue, function(data) {
34
+ if (data.hasOwnProperty("error")) {
35
+ alert(data.error);
36
+ } else {
37
+ $("#job_info_popup_title").html(create_job_info_title(data));
38
+ $("#job_info_popup_body").html(create_job_info_table(data));
39
+ $("#job_info_popup_footer").html(create_job_info_buttons(tube, data, url_base));
40
+ $("[rel=tooltip]").tooltip(); //refresh tooltips
41
+ $("#job_info_popup").modal({});
42
+ }
43
+ }).error(function() { alert("An error occurred while trying to peek at the next job."); });
44
+ }
45
+
46
+ function add_job() {
47
+ var tube = document.getElementById("form_tube_name").value;
48
+ var priority = document.getElementById("form_job_priority").value;
49
+ var delay = document.getElementById("form_job_delay").value;
50
+ var ttr = document.getElementById("form_job_ttr").value;
51
+ var body = document.getElementById("form_job_body").value;
52
+ // Use defaults if empty
53
+ if (tube === "") {
54
+ tube = "default";
55
+ document.getElementById("form_tube_name").value = tube;
56
+ }
57
+ if (priority === "") {
58
+ priority = "65536";
59
+ document.getElementById("form_job_priority").value = priority;
60
+ }
61
+ if (delay === "") {
62
+ delay = "0";
63
+ document.getElementById("form_job_delay").value = delay;
64
+ }
65
+ if (ttr === "") {
66
+ ttr = "120";
67
+ document.getElementById("form_job_ttr").value = ttr;
68
+ }
69
+ if (body === "") {
70
+ body = "{}";
71
+ document.getElementById("form_job_body").value = body;
72
+ }
73
+ //Ensure valid body JSON
74
+ var parsed_body_json = null;
75
+ var body_parse_error = null;
76
+ try {
77
+ parsed_body_json = JSON.parse(body);
78
+ if (parsed_body_json.constructor == Array) {
79
+ throw "Job Body JSON must be a Hash";
80
+ }
81
+ } catch(e) {
82
+ body_parse_error = e;
83
+ }
84
+ if (body_parse_error !== null) {
85
+ alert("Job Body JSON parse error: "+body_parse_error);
86
+ } else {
87
+ // Build the confirmation popup
88
+ data = {};
89
+ data.tube = tube;
90
+ data.pri = priority;
91
+ data.delay = delay;
92
+ data.ttr = ttr;
93
+ data.body = JSON.stringify(parsed_body_json);
94
+ $("#job_info_popup_title").html(create_new_job_title());
95
+ $("#job_info_popup_body").html(create_job_info_table(data));
96
+ $("#job_info_popup_footer").html(create_new_job_buttons());
97
+ $("#confirm_add_job_btn").click(function() {
98
+ $("#add_job_form").submit();
99
+ });
100
+ $("[rel=tooltip]").tooltip(); //refresh tooltips
101
+ $("#job_info_popup").modal({});
102
+ }
103
+ }
104
+
105
+ function create_new_job_buttons() {
106
+ var job_info_buttons = "";
107
+ job_info_buttons += "<a id=\"confirm_add_job_btn\" href=\"#\" class=\"btn\">Add Job</a>";
108
+ return job_info_buttons;
109
+ }
110
+
111
+ function create_job_info_buttons(tube, data, url_base) {
112
+ var job_id = data.id;
113
+ var priority = data.pri;
114
+ var job_info_buttons = "";
115
+ job_info_buttons += "<a href=\""+url_base+"delete/"+encodeURIComponent(tube)+"/"+job_id+"\" class=\"btn\">Delete Job</a>";
116
+ return job_info_buttons;
117
+ }
118
+
119
+ function create_new_job_title() {
120
+ return "<h3>Add new job?</h3>";
121
+ }
122
+
123
+ function create_job_info_title(data) {
124
+ var id = data.id;
125
+ var state = data.state;
126
+ return "<h3>Job id: "+id+" ("+state+")</h3>";
127
+ }
128
+
129
+ function create_job_info_table(data) {
130
+ var compiled = _.template($('#job_modal_template').text());
131
+ return compiled({data: data});
132
+ }
133
+ });
134
+
135
+ })();
@@ -0,0 +1,24 @@
1
+ (function() {
2
+
3
+ $(document).ready(function() {
4
+ function filter_table_by_tube() {
5
+ var tube = $("#peek_range_tube_select").val();
6
+ if (tube === '') {
7
+ $('tr.datum[data-tube]').show();
8
+ } else {
9
+ $('tr.datum[data-tube!="'+tube+'"]').hide();
10
+ $('tr.datum[data-tube="'+tube+'"]').show();
11
+ }
12
+ }
13
+
14
+ if ($('#peek_range_table').length > 0) {
15
+ $("#peek_range_tube_select").change(function(event) {
16
+ filter_table_by_tube();
17
+ });
18
+
19
+ //Run Immediately on Page Load
20
+ filter_table_by_tube();
21
+ }
22
+ });
23
+
24
+ })();
@@ -0,0 +1 @@
1
+ (function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new w(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VERSION="1.4.4";var A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(r,n,u,i)}),e)};var O="Reduce of empty array with no initial value";w.reduce=w.foldl=w.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},w.reduceRight=w.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},w.find=w.detect=function(n,t,r){var e;return E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},w.filter=w.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=function(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};w.contains=w.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:E(n,function(n){return n===t})},w.invoke=function(n,t){var r=o.call(arguments,2),e=w.isFunction(t);return w.map(n,function(n){return(e?t:n[t]).apply(n,r)})},w.pluck=function(n,t){return w.map(n,function(n){return n[t]})},w.where=function(n,t,r){return w.isEmpty(t)?r?null:[]:w[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},w.findWhere=function(n,t){return w.where(n,t,!0)},w.max=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w.min=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var k=function(n){return w.isFunction(n)?n:function(t){return t[n]}};w.sortBy=function(n,t,r){var e=k(t);return w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index<t.index?-1:1}),"value")};var F=function(n,t,r,e){var u={},i=k(t||w.identity);return A(n,function(t,a){var o=i.call(r,t,a,n);e(u,o,t)}),u};w.groupBy=function(n,t,r){return F(n,t,r,function(n,t,r){(w.has(n,t)?n[t]:n[t]=[]).push(r)})},w.countBy=function(n,t,r){return F(n,t,r,function(n,t){w.has(n,t)||(n[t]=0),n[t]++})},w.sortedIndex=function(n,t,r,e){r=null==r?w.identity:k(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return i},w.toArray=function(n){return n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values(n):[]},w.size=function(n){return null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail=w.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},w.compact=function(n){return w.filter(n,w.identity)};var R=function(n,t,r){return A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flatten=function(n,t){return R(n,t,[])},w.without=function(n){return w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.isFunction(t)&&(e=r,r=t,t=!1);var u=r?w.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.push(n[e]))}),i},w.union=function(){return w.uniq(c.apply(e,arguments))},w.intersection=function(n){var t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return w.every(t,function(t){return w.indexOf(t,n)>=0})})},w.difference=function(n){var t=c.apply(e,o.call(arguments,1));return w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[e]=w.pluck(n,""+e);return r},w.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},w.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},w.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return i},w.bind=function(n,t){if(n.bind===j&&j)return j.apply(n,o.call(arguments,1));var r=o.call(arguments,2);return function(){return n.apply(t,r.concat(o.call(arguments)))}},w.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},w.bindAll=function(n){var t=o.call(arguments,1);return 0===t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var e=t.apply(this,arguments);return w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},w.defer=function(n){return w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return function(){var c=new Date,l=t-(c-a);return r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return function(){var i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return t},w.values=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return t},w.functions=w.methods=function(n){var t=[];for(var r in n)w.isFunction(n[r])&&t.push(r);return t.sort()},w.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},w.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},w.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObject(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return t(n),n};var I=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==t+"";case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=I(n[a],t[a],r,e)););}else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&I(n[s],t[s],r,e))))break;if(o){for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return r.pop(),e.pop(),o};w.isEqual=function(n,t){return I(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w.isString(n))return 0===n.length;for(var t in n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!==n.nodeType)},w.isArray=x||function(n){return"[object Array]"==l.call(n)},w.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){w["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n||!w.has(n,"callee"))}),"function"!=typeof/./&&(w.isFunction=function(n){return"function"==typeof n}),w.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},w.isNull=function(n){return null===n},w.isUndefined=function(n){return n===void 0},w.has=function(n,t){return f.call(n,t)},w.noConflict=function(){return n._=t,this},w.identity=function(n){return n},w.times=function(n,t,r){for(var e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return e},w.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var M={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};M.unescape=w.invert(M.escape);var S={escape:RegExp("["+w.keys(M.escape).join("")+"]","g"),unescape:RegExp("("+w.keys(M.unescape).join("|")+")","g")};w.each(["escape","unescape"],function(n){w[n]=function(t){return null==t?"":(""+t).replace(S[n],function(t){return M[n][t]})}}),w.result=function(n,t){if(null==n)return null;var r=n[t];return w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function(t){var r=w[t]=n[t];w.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),D.call(this,r.apply(w,n))}})};var N=0;w.uniqueId=function(n){var t=++N+"";return n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/(.)^/,q={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},B=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,r){var e;r=w.defaults({},r,w.templateSettings);var u=RegExp([(r.escape||T).source,(r.interpolate||T).source,(r.evaluate||T).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(B,function(n){return"\\"+q[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,w);var c=function(n){return e.call(this,n,w)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},w.chain=function(n){return w(n).chain()};var D=function(n){return this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];w.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],D.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];w.prototype[n]=function(){return D.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beanstalkd_view
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.2.0
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: 2013-02-26 00:00:00.000000000 Z
12
+ date: 2013-03-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
@@ -43,22 +43,6 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: 1.3.0
46
- - !ruby/object:Gem::Dependency
47
- name: sinatra-assetpack
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: 0.0.11
54
- type: :runtime
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: 0.0.11
62
46
  - !ruby/object:Gem::Dependency
63
47
  name: beaneater
64
48
  requirement: !ruby/object:Gem::Requirement
@@ -199,18 +183,13 @@ files:
199
183
  - CHANGELOG.md
200
184
  - Gemfile
201
185
  - Rakefile
186
+ - package.json
187
+ - Gruntfile.js
202
188
  - MIT-LICENSE.txt
203
189
  - lib/beanstalkd_view/beanstalkd_utils.rb
204
- - lib/beanstalkd_view/resources/css/app.css
205
- - lib/beanstalkd_view/resources/css/vendor/bootstrap.min.css
206
- - lib/beanstalkd_view/resources/js/app.js
207
- - lib/beanstalkd_view/resources/js/peek_jobs.js
208
- - lib/beanstalkd_view/resources/js/peek_range.js
209
- - lib/beanstalkd_view/resources/js/vendor/bluff-0.3.6.2/bluff-min.js
210
- - lib/beanstalkd_view/resources/js/vendor/bluff-0.3.6.2/js-class.js
211
- - lib/beanstalkd_view/resources/js/vendor/bootstrap.min.js
212
- - lib/beanstalkd_view/resources/js/vendor/jquery-1.7.1.min.js
213
- - lib/beanstalkd_view/resources/js/vendor/json2.js
190
+ - lib/beanstalkd_view/resources/css/beanstalkd_view.css
191
+ - lib/beanstalkd_view/resources/js/beanstalkd_view.js
192
+ - lib/beanstalkd_view/resources/js/beanstalkd_view.min.js
214
193
  - lib/beanstalkd_view/server.rb
215
194
  - lib/beanstalkd_view/version.rb
216
195
  - lib/beanstalkd_view/views/error.erb
@@ -220,9 +199,21 @@ files:
220
199
  - lib/beanstalkd_view/views/peek_range.erb
221
200
  - lib/beanstalkd_view/views/tube_stats.erb
222
201
  - lib/beanstalkd_view.rb
202
+ - web/css/app.css
203
+ - web/css/vendor/bootstrap.min.css
204
+ - web/js/draw_chart.js
205
+ - web/js/initialization.js
206
+ - web/js/peek_jobs.js
207
+ - web/js/peek_range.js
208
+ - web/js/vendor/bluff-0.3.6.2/bluff-min.js
209
+ - web/js/vendor/bluff-0.3.6.2/js-class.js
210
+ - web/js/vendor/bootstrap.min.js
211
+ - web/js/vendor/jquery-1.7.1.min.js
212
+ - web/js/vendor/json2.js
213
+ - web/js/vendor/underscore-min.js
223
214
  - bin/beanstalkd_view
224
- - spec/integration/rails_integration_spec.rb
225
- - spec/integration/sinatra_integration_spec.rb
215
+ - spec/features/rails_integration_spec.rb
216
+ - spec/features/sinatra_integration_spec.rb
226
217
  - spec/lib/beanstalkd_view/beanstalkd_util_spec.rb
227
218
  - spec/rails_app/config/routes.rb
228
219
  - spec/rails_app/log/test.log
@@ -244,7 +235,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
244
235
  version: '0'
245
236
  segments:
246
237
  - 0
247
- hash: -180503938276593658
238
+ hash: -3198668242665676257
248
239
  required_rubygems_version: !ruby/object:Gem::Requirement
249
240
  none: false
250
241
  requirements:
@@ -253,7 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
253
244
  version: '0'
254
245
  segments:
255
246
  - 0
256
- hash: -180503938276593658
247
+ hash: -3198668242665676257
257
248
  requirements: []
258
249
  rubyforge_project:
259
250
  rubygems_version: 1.8.25
@@ -262,8 +253,8 @@ specification_version: 3
262
253
  summary: A Sinatra app to view/manage beanstalkd queues that can be embedded in a
263
254
  Rails app similar to what's available in Resque
264
255
  test_files:
265
- - spec/integration/rails_integration_spec.rb
266
- - spec/integration/sinatra_integration_spec.rb
256
+ - spec/features/rails_integration_spec.rb
257
+ - spec/features/sinatra_integration_spec.rb
267
258
  - spec/lib/beanstalkd_view/beanstalkd_util_spec.rb
268
259
  - spec/rails_app/config/routes.rb
269
260
  - spec/rails_app/log/test.log
@@ -1,4 +0,0 @@
1
- $(document).ready(function() {
2
- //Enable Tooltips
3
- $("[rel=tooltip]").tooltip();
4
- });
@@ -1,169 +0,0 @@
1
- $(document).ready(function() {
2
- // Enable Peek Job Button Handlers
3
- if ($("#peek_ready_btn").length > 0) {
4
- $("#peek_ready_btn").click(function(event) {
5
- event.preventDefault();
6
- peek('ready');
7
- });
8
- }
9
- if ($("#peek_delayed_btn").length > 0) {
10
- $("#peek_delayed_btn").click(function(event) {
11
- event.preventDefault();
12
- peek('delayed');
13
- });
14
- }
15
- if ($("#peek_buried_btn").length > 0) {
16
- $("#peek_buried_btn").click(function(event) {
17
- event.preventDefault();
18
- peek('buried');
19
- });
20
- }
21
- if ($("#add_job_btn").length > 0) {
22
- $("#add_job_btn").click(function(event) {
23
- event.preventDefault();
24
- add_job();
25
- });
26
- }
27
-
28
- function peek(queue) {
29
- var tube = document.getElementById("form_tube_name").value;
30
- var url_base = document.getElementById("form_url_base").value;
31
- var jqxhr = $.getJSON(url_base+"peek/"+encodeURIComponent(tube)+"/"+queue, function(data) {
32
- if (data.hasOwnProperty("error")) {
33
- alert(data["error"]);
34
- } else {
35
- $("#job_info_popup_title").html(create_job_info_title(data));
36
- $("#job_info_popup_body").html(create_job_info_table(data));
37
- $("#job_info_popup_footer").html(create_job_info_buttons(tube, data, url_base));
38
- $("[rel=tooltip]").tooltip(); //refresh tooltips
39
- $("#job_info_popup").modal({});
40
- }
41
- })
42
- .error(function() { alert("An error occurred while trying to peek at the next job."); })
43
- }
44
-
45
- function add_job() {
46
- var tube = document.getElementById("form_tube_name").value;
47
- var priority = document.getElementById("form_job_priority").value;
48
- var delay = document.getElementById("form_job_delay").value;
49
- var ttr = document.getElementById("form_job_ttr").value;
50
- var body = document.getElementById("form_job_body").value;
51
- // Use defaults if empty
52
- if (tube == "") {
53
- tube = "default";
54
- document.getElementById("form_tube_name").value = tube;
55
- }
56
- if (priority == "") {
57
- priority = "65536";
58
- document.getElementById("form_job_priority").value = priority;
59
- }
60
- if (delay == "") {
61
- delay = "0"
62
- document.getElementById("form_job_delay").value = delay;
63
- }
64
- if (ttr == "") {
65
- ttr = "120"
66
- document.getElementById("form_job_ttr").value = ttr;
67
- }
68
- if (body == "") {
69
- body = "{}";
70
- document.getElementById("form_job_body").value = body;
71
- }
72
- //Ensure valid body JSON
73
- var parsed_body_json = null;
74
- var body_parse_error = null;
75
- try {
76
- parsed_body_json = JSON.parse(body);
77
- if (parsed_body_json.constructor == Array) {
78
- throw "Job Body JSON must be a Hash"
79
- }
80
- } catch(e) {
81
- body_parse_error = e;
82
- }
83
- if (body_parse_error != null) {
84
- alert("Job Body JSON parse error: "+body_parse_error);
85
- } else {
86
- // Build the confirmation popup
87
- data = {};
88
- data["tube"] = tube;
89
- data["pri"] = priority;
90
- data["delay"] = delay;
91
- data["ttr"] = ttr;
92
- data["body"] = JSON.stringify(parsed_body_json);
93
- $("#job_info_popup_title").html(create_new_job_title());
94
- $("#job_info_popup_body").html(create_job_info_table(data));
95
- $("#job_info_popup_footer").html(create_new_job_buttons());
96
- $("#confirm_add_job_btn").click(function() {
97
- $("#add_job_form").submit();
98
- });
99
- $("[rel=tooltip]").tooltip(); //refresh tooltips
100
- $("#job_info_popup").modal({});
101
- }
102
- }
103
-
104
- function create_new_job_buttons() {
105
- var job_info_buttons = "";
106
- job_info_buttons += "<a id=\"confirm_add_job_btn\" href=\"#\" class=\"btn\">Add Job</a>";
107
- return job_info_buttons;
108
- }
109
-
110
- function create_job_info_buttons(tube, data, url_base) {
111
- var job_id = data["id"];
112
- var priority = data["pri"];
113
- var job_info_buttons = "";
114
- job_info_buttons += "<a href=\""+url_base+"delete/"+encodeURIComponent(tube)+"/"+job_id+"\" class=\"btn\">Delete Job</a>";
115
- return job_info_buttons;
116
- }
117
-
118
- function create_new_job_title() {
119
- return "<h3>Add new job?</h3>";
120
- }
121
-
122
- function create_job_info_title(data) {
123
- var id = data["id"];
124
- var state = data["state"];
125
- return "<h3>Job id: "+id+" ("+state+")</h3>";
126
- }
127
-
128
- function create_job_info_table(data) {
129
- var job_info_table = "<table class=\"table\">";
130
- job_info_table += "<tbody>";
131
- job_info_table += create_job_info_row("tube", data["tube"], "The tube to which the job will be added.");
132
- job_info_table += create_job_info_row("pri", data["pri"], "The priority value set by the put, release, or bury commands.");
133
- if ("age" in data) {
134
- job_info_table += create_job_info_row("age", data["age"], "The time in seconds since the put command that created this job.");
135
- }
136
- job_info_table += create_job_info_row("delay", data["delay"], "The delay value in seconds");
137
- job_info_table += create_job_info_row("ttr", data["ttr"], "The number of seconds to allow a worker to run this job. This time is counted from the moment a worker reserves this job. If the worker does not delete, release, or bury the job within ttr seconds, the job will time out and the server will release the job.");
138
- if ("time-left" in data) {
139
- job_info_table += create_job_info_row("time-left", data["time-left"], "The number of seconds left until the server puts this job into the ready queue. This number is only meaningful if the job is reserved or delayed. If the job is reserved and this amount of time elapses before its state changes, it is considered to have timed out.");
140
- }
141
- if ("reserves" in data) {
142
- job_info_table += create_job_info_row("reserves", data["reserves"], "The number of times this job has been reserved");
143
- }
144
- if ("timeouts" in data) {
145
- job_info_table += create_job_info_row("timeouts", data["timeouts"], "The number of times this job has timed out during a reservation.");
146
- }
147
- if ("releases" in data) {
148
- job_info_table += create_job_info_row("releases", data["releases"], "The number of times a client has released this job from a reservation.");
149
- }
150
- if ("buries" in data) {
151
- job_info_table += create_job_info_row("buries", data["buries"], " The number of times this job has been buried.");
152
- }
153
- if ("kicks" in data) {
154
- job_info_table += create_job_info_row("kicks", data["kicks"], "The number of times this job has been kicked.");
155
- }
156
- job_info_table += create_job_info_row("body", data["body"], "The jobs body content.");
157
- job_info_table += "</tbody>";
158
- job_info_table += "</table>";
159
- return job_info_table;
160
- }
161
-
162
- function create_job_info_row(key, value, title) {
163
- var job_info_row = "<tr rel=\"tooltip\" title=\""+title+"\">";
164
- job_info_row += "<td>"+key+"</td>";
165
- job_info_row += "<td>"+value+"</td>";
166
- job_info_row += "</tr>";
167
- return job_info_row;
168
- }
169
- });