Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add compatibility with Rails-based resque-web #112

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ doc
test/dump.rdb
bin/
.bundle
*.iml
110 changes: 110 additions & 0 deletions app/assets/javascripts/resque_status/application.js.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
jQuery ($) ->
$('#main').attr('id', '')
$('#resque-status').attr('id', 'main')

$('#main').on 'click', "a.status-kill", (e) ->
return false unless confirm("Are you sure you want to kill this job? There is no undo.")
$link = $(this)
$link.animate opacity: 0.5
$.post $link.attr("href"), ->
$link.remove()
return false


kill_all = $('.status-kill-all')
kill_all.on 'click', ->
$link = $(this)
return false if $link.is('.disabled')
return false unless confirm("Are you sure you want to kill this job? There is no undo.")
data = {
id: []
}
checked = $('.status-jobs-option').filter(':checked')
return false if checked.length == 0
checked.each (index, value)->
data['id'].push $(value).val()

$.post($link.attr('href'), data, ->
checked.remove()
updateKillAll()
)
return false;

updateKillAll = ->
jobs_option = $('.status-jobs-option')
if jobs_option.length == 0
kill_all.remove()
$('input.status-check-all').remove()
return
if jobs_option.is(':checked')
kill_all.removeClass('disabled')
else
kill_all.addClass('disabled')

$('#main').on 'click', 'input.status-check-all', (e) ->
$('.status-jobs-option').prop('checked', $(this).prop('checked'))
updateKillAll()

$('.status-jobs-option').on 'click', (e) ->
updateKillAll()

updateKillAll()

$('#main').on 'click', 'a.status-clear', (e) ->
return false unless confirm("Are you absolutely sure? This cannot be undone.");
$.ajax
type: "DELETE"
url: $(this).attr('href')
success: ->
window.location.reload()
return
false

status_map = {
completed: 'progress-success',
failed: 'progress-danger',
working: 'progress-info',
queued: 'progress-info',
killed: 'progress-warning'
}
# itterate over the holders
checkStatus = ($status) ->
status_path = $status.data 'url'
$.getJSON status_path, (json) ->
if json
pct = "0%"
pct = json.pct_complete + "%" if json.pct_complete

$status.find(".progress .bar").animate width: pct
$status.find(".progress .progress-pct").text pct
$status.find(".status-message").html json.message if json.message
$status.data('status', json.status)
$status.find(".progress").attr("class", "progress "+status_map[json.status]) if json.status
$status.find(".status-time").text new Date(json.time * 1000).toString() if json.time

$details = $status.find(".status-details-body")
$details.empty()
for key of json
$row = $("<tr>").appendTo($details)
$("<td>").text(key).appendTo $row
$("<td>").text(printValue(key, json[key])).appendTo $row

status = $status.data("status")
if status is "working" or status is "queued" or status is ""
setTimeout (->
checkStatus($status)
), 1500
return

return
printValue = (key, value) ->
if /(^|_)time$/.test(key) and typeof value is "number"
time = new Date()
time.setTime value * 1000
time.toUTCString()
else
JSON.stringify value

$(".status-holder").each ->
checkStatus $(this)
return
71 changes: 71 additions & 0 deletions app/assets/stylesheets/resque_status/application.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@

th.progress {
width: 100px;
}
td.status {
font-weight: bold;
}
/*td.progress .progress-bar {*/
/*position: absolute;*/
/*top: 0px;*/
/*left: 0px;*/
/*background: #999;*/
/*display:block;*/
/*height: 100%;*/
/*z-index: 0;*/
/*opacity: 0.5;*/
/*-moz-opacity: 0.5;*/
/*-webkit-opacity: 0.5;*/
/*}*/
.resque-status .progress {
margin: 0;
position: relative;
}
.resque-status .progress .progress-pct {
z-index: 10;
/*color: #333;*/
color: #ffffff;
text-shadow: 1px 1px 2px black;
text-align: center;
position: absolute;
width: 100%;
}

.status-completed {
color:#61BF55;
}
.status-failed {
color: #E47E74;
}
.status-working {
color: #528499;
}
.status-killed {
color: #B84F16;
}

.status-holder {
background: #F7F7F7;
border: 1px solid #E5E5E5;
padding: 20px;
font-size: 110%;
margin-bottom: 40px;
}
.status-message {
font-weight: bold;
}

.status-time {
font-size: 70%;
padding: 10px 0px;
color: #999;
}

#main a.status-kill:link, #main a.status-kill:visited {
color: #B84F16;
font-weight: bold;
}

.status-clear {
margin-left:5px
}
5 changes: 5 additions & 0 deletions app/controllers/resque_status/application_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module ResqueStatus
class ApplicationController < ResqueWeb::ApplicationController
helper :all
end
end
9 changes: 9 additions & 0 deletions app/controllers/resque_status/clear_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module ResqueStatus
class ClearController < ResqueStatus::ApplicationController
def destroy
params[:id] = nil if params[:id] == 'all'
Resque::Plugins::Status::Hash.clear(params[:id])
head :no_content
end
end
end
33 changes: 33 additions & 0 deletions app/controllers/resque_status/statuses_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module ResqueStatus
class StatusesController < ResqueStatus::ApplicationController
layout 'resque_web/application'
def show
@status = Resque::Plugins::Status::Hash.get(params[:id])
@polling = request.xhr?
respond_to do |format|
format.html
format.json { render :json => @status.json }
end
end

def index
@start = params[:start].to_i
@end = @start + (params[:per_page] || 20)-1
@statuses = Resque::Plugins::Status::Hash.statuses(@start, @end)
@size = Resque::Plugins::Status::Hash.count
@polling = request.xhr?
@has_killable = @statuses.select(&:killable?).size > 0
respond_to do |format|
format.html {render :layout => !request.xhr? }
end
end

def kill
ids = params[:ids] || Array(params[:id])
ids.each do |id|
Resque::Plugins::Status::Hash.kill(params[:id])
end
head :no_content
end
end
end
12 changes: 12 additions & 0 deletions app/helpers/resque_status/status_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module ResqueStatus
module StatusHelper
def status_poll(start)
if @polling
text = "<a href='#{statuses_path}?start=#{start}'>Last Updated: #{Time.now.strftime("%H:%M:%S")}</a>"
else
text = "<a href='#{statuses_path}?start=#{start}' rel='poll'>Live Poll</a>"
end
"<p class='poll'>#{text}</p>"
end
end
end
88 changes: 88 additions & 0 deletions app/views/resque_status/statuses/index.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<% unless @polling %>
<div id="resque-status">
<% end %>
<div class="resque-status">
<h1 class='wi'>Statuses</h1>
<p class='intro'>These are recent jobs created with the Resque::Plugins::Status class</p>

<% unless @statuses.empty? %>

<div class="btn-group pull-right">

<a href="<%= clear_path(:completed) %>" class='btn-small btn status-clear'>Clear Completed
Statuses</a>
<a href="<%= clear_path(:killed) %>" class='btn-small btn status-clear'>Clear Killed Statuses</a>

<a href="<%= clear_path(:failed) %>" class='btn-small btn status-clear'>Clear Failed Statuses</a>
<a href="<%= clear_path(:all) %>" class='btn-small btn btn-danger status-clear'>Clear All
Statuses</a>
</div>
<% if @has_killable && !@polling %>
<a href="<%= kill_status_path(:all) %>" class='btn-small btn btn-danger status-kill-all disabled'>Kill sellected</a>
<% end %>
<div class="clearfix"></div>
<p></p>
<% end %>


<table class="table table-bordered">
<tr>
<th class="status-check-all">
<% if @has_killable && !@polling%>
<input type="checkbox" value="1" class="status-check-all" name="check_all">
<% end %>
</th>
<th>ID</th>
<th>Name</th>
<th>Status</th>
<th>Last Updated</th>
<th class="status-progress" style="width:130px">% Complete</th>
<th>Message</th>
<th>Kill</th>
</tr>
<% unless @statuses.empty? %>
<% @statuses.each do |status| %>
<tr>
<td>
<% if status.killable? && !@polling %>
<input type="checkbox" value="<%= status.uuid %>" class="status-jobs-option" name="jobs[]">
<%end%>
</td>
<td><a href="<%= status_path(status.uuid) %>"><%= status.uuid %></a></td>
<td><%= status.name %></td>
<td class="status status-<%= status.status %>"><%= status.status %></td>
<td class="time"><%= status.time.strftime("%Y/%m/%d %H:%M:%S %z") %></td>
<td>
<div class="progress">
<div class="progress-pct"><%= status.pct_complete ? "#{status.pct_complete}%" : '' %></div>
<div class="bar" style="width:<%= status.pct_complete %>%">

</div>
</div>
</td>
<td><%= status.message %></td>
<td>
<% if status.killable? %><a href="<%= kill_status_path(status.uuid) %>" class="status-kill">Kill</a>
<% end %></td>
</tr>
<% end %>
<% else %>
<tr>
<td colspan="8" class='no-data'>No Statuses right now...</td>
</tr>
<% end %>
</table>

<% unless @statuses.empty? %>
<%= pagination :start => @start, :total => @size, :per_page => 20 %>
<% end %>

<%= status_poll(@start).html_safe%>
</div>

<% unless @polling %>
</div>
<!-- Kill Host -->
<%= javascript_include_tag "resque_status/application" %>
<%= stylesheet_link_tag "resque_status/application", :media => "all" %>
<% end %>
31 changes: 31 additions & 0 deletions app/views/resque_status/statuses/show.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div class="resque-status">
<h1 class='wi'>Statuses: <%= @status.uuid %>/<%= @status.name %></h1>

<p class='intro'>Viewing a specific job created with Resque::Plugins::Status.
<a href="<%= statuses_path %>">Return to the list of statuses</a></p>

<div class="status-holder" data-url="<%= status_path(@status.uuid, :json) %>" data-status="<%= @status.status %>" id="status_<%= @status.uuid %>">
<div class="progress">
<div class="bar" style="width: <%= @status.pct_complete %>%;"></div>
<div class="progress-pct"><%= @status.pct_complete %>%</div>
</div>
<div class="status-message"><%= @status.message %></div>
<div class="status-time"><%= @status.time? ? @status.time : 'Not started' %></div>
<h2>Details</h2>

<div class="status-details">
<table class="table table-bordered">
<thead>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
</thead>
<tbody class="status-details-body">
</tbody>
</table>
</div>
</div>
</div>
<%= javascript_include_tag "resque_status/application" %>
<%= stylesheet_link_tag "resque_status/application", :media => "all" %>
2 changes: 2 additions & 0 deletions config/initializers/resque_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
config = ENV.fetch("RAILS_RESQUE_REDIS", "127.0.0.1:6379")
Resque.redis = config
15 changes: 15 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Match IDs with dots in them
id_pattern = /[^\/]+/
ResqueWeb::Plugins::ResqueStatus::Engine.routes.draw do
resources :statuses, :only => [:show,:index] do
member do
post :kill
end
collection do
resources :clear, :only => [:destroy]
end
end
root 'statuses#index'


end
3 changes: 3 additions & 0 deletions lib/resque-status.rb
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
require "#{File.dirname(__FILE__)}/resque/status"
require 'resque_status'
require 'resque_web/plugins/resque_status/engine' if defined?(Rails)

Loading