resque-status-web 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +14 -0
- data/MIT-LICENSE +20 -0
- data/README.md +64 -0
- data/Rakefile +37 -0
- data/app/controllers/resque_web/plugins/resque_status/statuses_controller.rb +59 -0
- data/app/helpers/resque_web/plugins/resque_status/statuses_helper.rb +23 -0
- data/app/views/resque_web/plugins/resque_status/shared/_styles.html.erb +107 -0
- data/app/views/resque_web/plugins/resque_status/statuses/_next_more.html.erb +10 -0
- data/app/views/resque_web/plugins/resque_status/statuses/index.html.erb +79 -0
- data/app/views/resque_web/plugins/resque_status/statuses/show.html.erb +91 -0
- data/config/routes.rb +2 -0
- data/lib/resque/status/web.rb +6 -0
- data/lib/resque/status/web/version.rb +7 -0
- data/lib/resque_web/plugins/resque_status/engine.rb +31 -0
- data/lib/resque_web/plugins/status.rb +9 -0
- data/lib/tasks/resque_web/plugins/status_tasks.rake +4 -0
- data/resque-status-web.gemspec +30 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f9baa3fa062b99f757a6e293f2d8264bac680198
|
4
|
+
data.tar.gz: 6e0ffb8b8d1f7dca95b4a02de2d459b7c2503bd0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a5d3653993e635edebc104173b6005b492e05204ef0385f2026dd510999d1b16b20d47479973cd6d9f545f3a65d18f96335adb8fbdfebdf12578cbecd98b1467
|
7
|
+
data.tar.gz: 44efa9773e947885328936c7d4e4e8a6b3ff5ac1e92073e6b678fc0ceb1c19827c760a7bb0afdcc1ffebd8972509bc298724c4b4e4eefff24ac221e152798389
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.bundle/
|
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Declare your gem's dependencies in resque_web-plugins-status.gemspec.
|
4
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
5
|
+
# development dependencies will be added by default to the :development group.
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
# Declare any dependencies that are still in development here instead of in
|
9
|
+
# your gemspec. These might include edge Rails or gems from your path or
|
10
|
+
# Git. Remember to move these dependencies to your gemspec before releasing
|
11
|
+
# your gem to rubygems.org.
|
12
|
+
|
13
|
+
# To use a debugger
|
14
|
+
# gem 'byebug', group: [:development, :test]
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 Brandon Conway
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Resque::Statuse::Web
|
2
|
+
|
3
|
+
This gem provides tabs in [Resque Web](https://github.com/resque/resque-web) for managing
|
4
|
+
[Resque Status](https://github.com/quirkey/resque-status).
|
5
|
+
|
6
|
+
It works with any version of Resque and Resque Scheduler, but requires the
|
7
|
+
[Resque Web gem](https://github.com/resque/resque-web),
|
8
|
+
rather than the older [Resque Web Sinatra interface](https://github.com/resque/resque/tree/1-x-stable#the-front-end)
|
9
|
+
that comes bundled with Resque 1.x.
|
10
|
+
|
11
|
+
This gem is a port of the old Sinatra code to the new Resque Web plugin architecture.
|
12
|
+
|
13
|
+
The Sinatra interface will be deprecated when Resque 2 is released, so if you want
|
14
|
+
to get ahead of the curve, you can start using the latest Resque Web gem today.
|
15
|
+
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add this line to your application's Gemfile:
|
20
|
+
|
21
|
+
gem 'resque-scheduler-web'
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
$ bundle
|
26
|
+
|
27
|
+
Or install it yourself as:
|
28
|
+
|
29
|
+
$ gem install resque-scheduler-web
|
30
|
+
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
The gem will automatically add the correct tabs, provided you have the Resque
|
35
|
+
Web engine mounted like this in routes.rb:
|
36
|
+
|
37
|
+
mount ResqueWeb::Engine => 'admin/resque_web'
|
38
|
+
|
39
|
+
## What's Missing
|
40
|
+
|
41
|
+
Tests! This gem has no tests, mostly because it was my first engine and I was so
|
42
|
+
focused on getting it to work, I didn't write any tests during implementation.
|
43
|
+
If you would like, you are welcome to contribute tests or anything else which
|
44
|
+
you believe this gem is lacking.
|
45
|
+
|
46
|
+
|
47
|
+
## Contributing
|
48
|
+
|
49
|
+
1. Fork it ( https://github.com/brandoncc/resque-status-web/fork )
|
50
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
51
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
52
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
53
|
+
5. Create a new Pull Request
|
54
|
+
|
55
|
+
|
56
|
+
## Acknowledgements
|
57
|
+
|
58
|
+
The original code and tests for this gem were taken from the Resque Status gem's
|
59
|
+
Sinatra interface, and subsequently adapted into a Rails engine. Kudos and
|
60
|
+
thanks to the [original](https://github.com/quirkey/resque-status/commits/master/lib/resque/scheduler/server.rb)
|
61
|
+
[authors](https://github.com/quirkey/resque-status/commits/e0e91aa238c51db12794755430a7411c6ad1bfca/lib/resque_scheduler/server.rb).
|
62
|
+
|
63
|
+
Also, thanks to @mattgibson whose [resque-scheduler-web](github.com/mattgibson/resque-scheduler-web) gem was the inspiration and
|
64
|
+
blueprint I used when creating this gem. Thanks for leading the way!
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'ResqueWeb::Plugins::Status'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
require 'bundler/gem_tasks'
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'lib'
|
31
|
+
t.libs << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
task default: :test
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ResqueWeb
|
2
|
+
module Plugins
|
3
|
+
module ResqueStatus
|
4
|
+
class StatusesController < ResqueWeb::ApplicationController
|
5
|
+
include StatusesHelper
|
6
|
+
include Engine.app.url_helpers
|
7
|
+
|
8
|
+
def index
|
9
|
+
@start = params[:start].to_i
|
10
|
+
@end = @start + (params[:per_page] || per_page) - 1
|
11
|
+
@statuses = Resque::Plugins::Status::Hash.statuses(@start, @end)
|
12
|
+
@size = Resque::Plugins::Status::Hash.count
|
13
|
+
|
14
|
+
render :index
|
15
|
+
end
|
16
|
+
|
17
|
+
def show
|
18
|
+
@status = Resque::Plugins::Status::Hash.get(params[:id])
|
19
|
+
|
20
|
+
respond_to do |format|
|
21
|
+
format.html
|
22
|
+
format.js { render json: @status }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def destroy
|
27
|
+
Resque::Plugins::Status::Hash.kill(params[:id])
|
28
|
+
redirect_to statuses_path
|
29
|
+
end
|
30
|
+
|
31
|
+
def clear
|
32
|
+
Resque::Plugins::Status::Hash.clear
|
33
|
+
redirect_to statuses_path
|
34
|
+
end
|
35
|
+
|
36
|
+
def clear_completed
|
37
|
+
Resque::Plugins::Status::Hash.clear_completed
|
38
|
+
redirect_to statuses_path
|
39
|
+
end
|
40
|
+
|
41
|
+
def clear_failed
|
42
|
+
Resque::Plugins::Status::Hash.clear_failed
|
43
|
+
redirect_to statuses_path
|
44
|
+
end
|
45
|
+
|
46
|
+
def poll
|
47
|
+
@polling = true
|
48
|
+
|
49
|
+
@start = params[:start].to_i
|
50
|
+
@end = @start + (params[:per_page] || per_page) - 1
|
51
|
+
@statuses = Resque::Plugins::Status::Hash.statuses(@start, @end)
|
52
|
+
@size = Resque::Plugins::Status::Hash.count
|
53
|
+
|
54
|
+
render :index, layout: false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ResqueWeb
|
2
|
+
module Plugins
|
3
|
+
module ResqueStatus
|
4
|
+
# Helper methods for the schedule UI
|
5
|
+
module StatusesHelper
|
6
|
+
PER_PAGE = 50
|
7
|
+
|
8
|
+
def per_page
|
9
|
+
PER_PAGE
|
10
|
+
end
|
11
|
+
|
12
|
+
def status_poll(start, polling)
|
13
|
+
if polling
|
14
|
+
text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}"
|
15
|
+
else
|
16
|
+
text = link_to "Live Poll", poll_statuses_path(start: start), rel: 'poll'
|
17
|
+
end
|
18
|
+
"<p class='poll'>#{text}</p>".html_safe
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
<style type="text/css" media="screen">
|
2
|
+
th.progress {
|
3
|
+
width: 100px;
|
4
|
+
}
|
5
|
+
td.progress {
|
6
|
+
position: relative;
|
7
|
+
width: 100px;
|
8
|
+
display:block;
|
9
|
+
}
|
10
|
+
td.status {
|
11
|
+
font-weight: bold;
|
12
|
+
}
|
13
|
+
td.progress .progress-bar {
|
14
|
+
position: absolute;
|
15
|
+
top: 0px;
|
16
|
+
left: 0px;
|
17
|
+
background: #999;
|
18
|
+
display:block;
|
19
|
+
height: 100%;
|
20
|
+
z-index: 0;
|
21
|
+
opacity: 0.5;
|
22
|
+
-moz-opacity: 0.5;
|
23
|
+
-webkit-opacity: 0.5;
|
24
|
+
}
|
25
|
+
td.progress .progress-pct {
|
26
|
+
z-index: 10;
|
27
|
+
color: #333;
|
28
|
+
}
|
29
|
+
table {
|
30
|
+
min-width: 100%;
|
31
|
+
}
|
32
|
+
table.vertically-top td {
|
33
|
+
vertical-align: text-top;
|
34
|
+
}
|
35
|
+
table.vertically-top tr {
|
36
|
+
border: 1px solid #ccc;
|
37
|
+
}
|
38
|
+
|
39
|
+
.status-holder {
|
40
|
+
background: #F7F7F7;
|
41
|
+
border: 1px solid #E5E5E5;
|
42
|
+
padding: 20px;
|
43
|
+
font-size: 110%;
|
44
|
+
margin-bottom: 40px;
|
45
|
+
}
|
46
|
+
.status-progress {
|
47
|
+
width: 100%;
|
48
|
+
height: 30px;
|
49
|
+
border: 1px solid #CCC;
|
50
|
+
background: #E5E5E5;
|
51
|
+
position:relative;
|
52
|
+
margin: 5px 0px;
|
53
|
+
}
|
54
|
+
.status-progress-bar {
|
55
|
+
position:absolute;
|
56
|
+
top: 0px;
|
57
|
+
left: 0px;
|
58
|
+
height: 30px;
|
59
|
+
background: #CCC;
|
60
|
+
}
|
61
|
+
.status-progress p {
|
62
|
+
position:absolute;
|
63
|
+
top: 5px;
|
64
|
+
left: 10px;
|
65
|
+
z-index: 15;
|
66
|
+
display:block;
|
67
|
+
color: #FFF;
|
68
|
+
padding: 0px;
|
69
|
+
font-weight: bold;
|
70
|
+
}
|
71
|
+
.status-message {
|
72
|
+
font-weight: bold;
|
73
|
+
}
|
74
|
+
.status-time {
|
75
|
+
font-size: 70%;
|
76
|
+
padding: 10px 0px;
|
77
|
+
color: #999;
|
78
|
+
}
|
79
|
+
.status-progress-bar.status-completed {
|
80
|
+
background:#61BF55;
|
81
|
+
}
|
82
|
+
.status-progress-bar.status-failed {
|
83
|
+
background: #E47E74;
|
84
|
+
}
|
85
|
+
.status-progress-bar.status-working {
|
86
|
+
background: #528499;
|
87
|
+
}
|
88
|
+
.status-progress-bar.status-killed {
|
89
|
+
background: #B84F16;
|
90
|
+
}
|
91
|
+
.status-completed {
|
92
|
+
color:#61BF55;
|
93
|
+
}
|
94
|
+
.status-failed {
|
95
|
+
color: #E47E74;
|
96
|
+
}
|
97
|
+
.status-working {
|
98
|
+
color: #528499;
|
99
|
+
}
|
100
|
+
.status-killed {
|
101
|
+
color: #B84F16;
|
102
|
+
}
|
103
|
+
#main a.kill:link, #main a.kill:visited {
|
104
|
+
color: #B84F16;
|
105
|
+
font-weight: bold;
|
106
|
+
}
|
107
|
+
</style>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% if start - 20 >= 0 || start + 20 <= size %>
|
2
|
+
<p class='pagination'>
|
3
|
+
<% if start - 20 >= 0 %>
|
4
|
+
<a href="<%= request.original_url %>?start=<%= start - 20 %>" class='less'>« less</a>
|
5
|
+
<% end %>
|
6
|
+
<% if start + 20 <= size %>
|
7
|
+
<a href="<%= request.original_url %>?start=<%= start + 20 %>" class='more'>more »</a>
|
8
|
+
<% end %>
|
9
|
+
</p>
|
10
|
+
<% end %>
|
@@ -0,0 +1,79 @@
|
|
1
|
+
<%= render 'resque_web/plugins/resque_status/shared/styles' %>
|
2
|
+
|
3
|
+
<h1 class='wi'>Statuses</h1>
|
4
|
+
|
5
|
+
<%unless @statuses.empty?%>
|
6
|
+
<form method="POST" action="<%= clear_statuses_path %>" class='clear-failed'>
|
7
|
+
<input type='submit' name='' value='Clear Statuses' onclick='return confirm("Are you absolutely sure? This cannot be undone.");' />
|
8
|
+
</form>
|
9
|
+
<form method="POST" action="<%= clear_completed_statuses_path %>" class='clear-failed'>
|
10
|
+
<input type='submit' name='' value='Clear Completed Statuses' onclick='return confirm("Are you absolutely sure? This cannot be undone.");' />
|
11
|
+
</form>
|
12
|
+
<form method="POST" action="<%= clear_failed_statuses_path %>" class='clear-failed'>
|
13
|
+
<input type='submit' name='' value='Clear Failed Statuses' onclick='return confirm("Are you absolutely sure? This cannot be undone.");' />
|
14
|
+
</form>
|
15
|
+
<%end%>
|
16
|
+
|
17
|
+
<p class='intro'>These are recent jobs created with the Resque::Plugins::Status class</p>
|
18
|
+
<table class="vertically-top">
|
19
|
+
<tr>
|
20
|
+
<th>ID</th>
|
21
|
+
<th>Name</th>
|
22
|
+
<th>Status</th>
|
23
|
+
<th>Last Updated</th>
|
24
|
+
<th class="progress">% Complete</th>
|
25
|
+
<th>Message</th>
|
26
|
+
<th>Kill</th>
|
27
|
+
</tr>
|
28
|
+
<% unless @statuses.empty? %>
|
29
|
+
<% @statuses.each do |status| %>
|
30
|
+
<tr>
|
31
|
+
<td><a href="<%= status_path(status.uuid) %>"><%= status.uuid %></a></td>
|
32
|
+
<td><%= status.name %></td>
|
33
|
+
<td class="status status-<%= status.status %>"><%= status.status %></td>
|
34
|
+
<td class="time"><%= status.time.strftime("%Y/%m/%d %H:%M:%S %z") %></td>
|
35
|
+
<td class="progress">
|
36
|
+
<div class="progress-bar" style="width:<%= status.pct_complete %>%"> </div>
|
37
|
+
<div class="progress-pct"><%= status.pct_complete ? "#{status.pct_complete}%" : '' %></div>
|
38
|
+
</td>
|
39
|
+
<td><%= status.message %></td>
|
40
|
+
<td><% if status.killable? %><a href="<%= kill_status_path(id: status.uuid) %>" class="kill">Kill</a><% end %></td>
|
41
|
+
</tr>
|
42
|
+
<% end %>
|
43
|
+
<% else %>
|
44
|
+
<tr>
|
45
|
+
<td colspan="7" class='no-data'>No Statuses right now...</td>
|
46
|
+
</tr>
|
47
|
+
<% end %>
|
48
|
+
</table>
|
49
|
+
|
50
|
+
<% unless @statuses.empty? %>
|
51
|
+
<%= render 'next_more', :start => @start, :size => @size, :per_page => per_page %>
|
52
|
+
<% end %>
|
53
|
+
|
54
|
+
<%= status_poll(@start, @polling) %>
|
55
|
+
|
56
|
+
<script type="text/javascript" charset="utf-8">
|
57
|
+
jQuery(function($) {
|
58
|
+
|
59
|
+
$('a.kill').click(function(e) {
|
60
|
+
e.preventDefault();
|
61
|
+
var $link = $(this),
|
62
|
+
url = $link.attr('href'),
|
63
|
+
confirmed = confirm("Are you sure you want to kill this job? There is no undo.");
|
64
|
+
if (confirmed) {
|
65
|
+
$link.animate({opacity: 0.5});
|
66
|
+
$.ajax({
|
67
|
+
url: url,
|
68
|
+
type: 'post',
|
69
|
+
success: function() {
|
70
|
+
$link.remove();
|
71
|
+
}
|
72
|
+
});
|
73
|
+
} else {
|
74
|
+
return false
|
75
|
+
}
|
76
|
+
});
|
77
|
+
|
78
|
+
});
|
79
|
+
</script>
|
@@ -0,0 +1,91 @@
|
|
1
|
+
<%= render 'resque_web/plugins/resque_status/shared/styles' %>
|
2
|
+
|
3
|
+
<h1 class='wi'>Status <%= @status.uuid %></h1>
|
4
|
+
<p class='intro'>Viewing a specific job created with Resque::Plugins::Status. <a href="<%= statuses_path %>">Return to the list of statuses</a></p>
|
5
|
+
|
6
|
+
<div class="status-holder" rel="<%= @status.status %>" id="status_<%= @status.uuid %>">
|
7
|
+
<h2>Overview</h2>
|
8
|
+
<div class="status-progress">
|
9
|
+
<div class="status-progress-bar status-<%= @status.status %>" style="width: <%= @status.pct_complete %>%;"></div>
|
10
|
+
<p><%= @status.pct_complete %>%</p>
|
11
|
+
</div>
|
12
|
+
<div class="status-message"><%= @status.message %></div>
|
13
|
+
<div class="status-time"><%= @status.time? ? @status.time : 'Not started' %></div>
|
14
|
+
|
15
|
+
<h2>Details</h2>
|
16
|
+
<div class="status-details">
|
17
|
+
<table class="vertically-top">
|
18
|
+
<thead>
|
19
|
+
<tr>
|
20
|
+
<th>Key</th>
|
21
|
+
<th>Value</th>
|
22
|
+
</tr>
|
23
|
+
</thead>
|
24
|
+
<tbody class="status-details-body">
|
25
|
+
</tbody>
|
26
|
+
</table>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<script type="text/javascript" charset="utf-8">
|
31
|
+
jQuery(function($) {
|
32
|
+
|
33
|
+
// itterate over the holders
|
34
|
+
$('.status-holder').each(function() {
|
35
|
+
checkStatus($(this));
|
36
|
+
});
|
37
|
+
|
38
|
+
function checkStatus($status) {
|
39
|
+
var status_id = $status.attr('id').replace('status_', '');
|
40
|
+
$.getJSON('<%= status_path(id: params[:id], format: 'js') %>', function(json) {
|
41
|
+
if (json) {
|
42
|
+
var pct = "0%";
|
43
|
+
if (json.pct_complete) {
|
44
|
+
var pct = json.pct_complete + "%";
|
45
|
+
}
|
46
|
+
$status.find('.status-progress-bar').animate({width: pct});
|
47
|
+
$status.find('.status-progress p').text(pct)
|
48
|
+
if (json.message) {
|
49
|
+
$status.find('.status-message').html(json.message)
|
50
|
+
}
|
51
|
+
if (json.status) {
|
52
|
+
$status
|
53
|
+
.attr('rel', json.status)
|
54
|
+
.find('.status-progress-bar')
|
55
|
+
.attr('class', '')
|
56
|
+
.addClass('status-progress-bar status-' + json.status);
|
57
|
+
}
|
58
|
+
if (json.time) {
|
59
|
+
$status.find('.status-time').text(new Date(json.time * 1000).toString())
|
60
|
+
}
|
61
|
+
|
62
|
+
var $details = $status.find('.status-details-body');
|
63
|
+
$details.empty();
|
64
|
+
|
65
|
+
for (key in json) {
|
66
|
+
var $row = $("<tr>").appendTo($details);
|
67
|
+
$("<td>").text(key).appendTo($row);
|
68
|
+
$("<td>").text(printValue(key, json[key])).appendTo($row);
|
69
|
+
}
|
70
|
+
};
|
71
|
+
var status = $status.attr('rel');
|
72
|
+
if (status == '<%= Resque::Plugins::Status::STATUS_WORKING %>' || status == '<%= Resque::Plugins::Status::STATUS_QUEUED %>' || status == "") {
|
73
|
+
setTimeout(function() {
|
74
|
+
checkStatus($status)
|
75
|
+
}, 1500);
|
76
|
+
}
|
77
|
+
});
|
78
|
+
};
|
79
|
+
|
80
|
+
function printValue(key, value) {
|
81
|
+
if (/(^|_)time$/.test(key) && typeof value == 'number') {
|
82
|
+
var time = new Date();
|
83
|
+
time.setTime(value * 1000);
|
84
|
+
return time.toUTCString();
|
85
|
+
} else {
|
86
|
+
return JSON.stringify(value, null, " ");
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
});
|
91
|
+
</script>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module ResqueWeb
|
2
|
+
module Plugins
|
3
|
+
module ResqueStatus
|
4
|
+
class Engine < ::Rails::Engine
|
5
|
+
isolate_namespace ResqueWeb::Plugins::ResqueStatus
|
6
|
+
end
|
7
|
+
|
8
|
+
Engine.routes do
|
9
|
+
get '/statuses', to: 'statuses#index', as: 'statuses'
|
10
|
+
get '/statuses/poll', to: 'statuses#poll', as: 'poll_statuses'
|
11
|
+
get '/statuses/:id(.:format)', to: 'statuses#show', as: 'status'
|
12
|
+
post '/statuses/:id/kill', to: 'statuses#destroy', as: 'kill_status'
|
13
|
+
post '/statuses/clear', to: 'statuses#clear', as: 'clear_statuses'
|
14
|
+
post '/statuses/clear/completed', to: 'statuses#clear_completed', as: 'clear_completed_statuses'
|
15
|
+
post '/statuses/clear/failed', to: 'statuses#clear_failed', as: 'clear_failed_statuses'
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.engine_path
|
19
|
+
'/status'
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.tabs
|
23
|
+
[
|
24
|
+
{
|
25
|
+
'status' => Engine.app.url_helpers.statuses_path
|
26
|
+
}
|
27
|
+
]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
require "resque/status/web/version"
|
4
|
+
|
5
|
+
# Describe your gem and declare its dependencies:
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "resque-status-web"
|
8
|
+
s.version = Resque::Status::Web::VERSION
|
9
|
+
s.authors = ["Brandon Conway"]
|
10
|
+
s.email = ["brandoncc@gmail.com"]
|
11
|
+
s.homepage = "http://github.com/brandoncc/resque-status-web"
|
12
|
+
s.summary = "This gem provides tabs in Resque Web for managing statuses " +
|
13
|
+
"provided by resque-status."
|
14
|
+
|
15
|
+
s.description = "resque-status comes bundled with the ui for the sinatra " +
|
16
|
+
"based web interface. This gem is a direct extraction of " +
|
17
|
+
"that ui then converted to a Rails Engine as a plugin for " +
|
18
|
+
"resque-web."
|
19
|
+
s.license = "MIT"
|
20
|
+
|
21
|
+
s.files = `git ls-files -z`.split("\x0")
|
22
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
24
|
+
s.require_paths = ['lib']
|
25
|
+
|
26
|
+
s.add_runtime_dependency 'resque-web', '~> 0.0.8'
|
27
|
+
s.add_runtime_dependency 'resque-status', '~> 0.5'
|
28
|
+
|
29
|
+
s.add_development_dependency "rails", "~> 4.2"
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: resque-status-web
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brandon Conway
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-06-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: resque-web
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.8
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.8
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: resque-status
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.5'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.2'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.2'
|
55
|
+
description: resque-status comes bundled with the ui for the sinatra based web interface.
|
56
|
+
This gem is a direct extraction of that ui then converted to a Rails Engine as a
|
57
|
+
plugin for resque-web.
|
58
|
+
email:
|
59
|
+
- brandoncc@gmail.com
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- ".gitignore"
|
65
|
+
- Gemfile
|
66
|
+
- MIT-LICENSE
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- app/controllers/resque_web/plugins/resque_status/statuses_controller.rb
|
70
|
+
- app/helpers/resque_web/plugins/resque_status/statuses_helper.rb
|
71
|
+
- app/views/resque_web/plugins/resque_status/shared/_styles.html.erb
|
72
|
+
- app/views/resque_web/plugins/resque_status/statuses/_next_more.html.erb
|
73
|
+
- app/views/resque_web/plugins/resque_status/statuses/index.html.erb
|
74
|
+
- app/views/resque_web/plugins/resque_status/statuses/show.html.erb
|
75
|
+
- config/routes.rb
|
76
|
+
- lib/resque/status/web.rb
|
77
|
+
- lib/resque/status/web/version.rb
|
78
|
+
- lib/resque_web/plugins/resque_status/engine.rb
|
79
|
+
- lib/resque_web/plugins/status.rb
|
80
|
+
- lib/tasks/resque_web/plugins/status_tasks.rake
|
81
|
+
- resque-status-web.gemspec
|
82
|
+
homepage: http://github.com/brandoncc/resque-status-web
|
83
|
+
licenses:
|
84
|
+
- MIT
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 2.5.2
|
103
|
+
signing_key:
|
104
|
+
specification_version: 4
|
105
|
+
summary: This gem provides tabs in Resque Web for managing statuses provided by resque-status.
|
106
|
+
test_files: []
|