rake_ui 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.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +43 -0
- data/Rakefile +55 -0
- data/app/assets/images/rake_ui/ajax-loader.gif +0 -0
- data/app/assets/javascripts/jquery.js +6883 -0
- data/app/assets/javascripts/jquery_ujs.js +160 -0
- data/app/assets/javascripts/rake_ui/application.js +9 -0
- data/app/assets/javascripts/rake_ui/rake_tasks.js +2 -0
- data/app/assets/stylesheets/rake_ui/application.css +13 -0
- data/app/assets/stylesheets/rake_ui/rake_tasks.css +4 -0
- data/app/assets/stylesheets/scaffold.css +56 -0
- data/app/controllers/rake_ui/application_controller.rb +4 -0
- data/app/controllers/rake_ui/rake_tasks_controller.rb +28 -0
- data/app/helpers/rake_ui/application_helper.rb +7 -0
- data/app/helpers/rake_ui/rake_tasks_helper.rb +4 -0
- data/app/models/rake_ui/rake_task.rb +14 -0
- data/app/views/layouts/rake_ui/application.html.erb +14 -0
- data/app/views/rake_ui/rake_tasks/create.js +2 -0
- data/app/views/rake_ui/rake_tasks/index.html +16 -0
- data/app/views/rake_ui/rake_tasks/index.html.erb +48 -0
- data/app/views/rake_ui/rake_tasks/new.html.erb +0 -0
- data/app/views/rake_ui/rake_tasks/server.js +64 -0
- data/app/views/rake_ui/rake_tasks/server2.js +12 -0
- data/config/initializers/rake_tasks.rb +27 -0
- data/config/initializers/rake_ui.rb +1 -0
- data/config/routes.rb +4 -0
- data/lib/rake_ui.rb +5 -0
- data/lib/rake_ui/engine.rb +5 -0
- data/lib/rake_ui/version.rb +3 -0
- data/lib/tasks/rake_ui_tasks.rake +8 -0
- metadata +81 -0
@@ -0,0 +1,160 @@
|
|
1
|
+
/*
|
2
|
+
* jquery-ujs
|
3
|
+
*
|
4
|
+
* http://github.com/rails/jquery-ujs/blob/master/src/rails.js
|
5
|
+
*
|
6
|
+
* This rails.js file supports jQuery 1.4.3 and 1.4.4 .
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
|
10
|
+
jQuery(function ($) {
|
11
|
+
var csrf_token = $('meta[name=csrf-token]').attr('content'),
|
12
|
+
csrf_param = $('meta[name=csrf-param]').attr('content');
|
13
|
+
|
14
|
+
$.fn.extend({
|
15
|
+
/**
|
16
|
+
* Triggers a custom event on an element and returns the event result
|
17
|
+
* this is used to get around not being able to ensure callbacks are placed
|
18
|
+
* at the end of the chain.
|
19
|
+
*
|
20
|
+
* TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our
|
21
|
+
* own events and placing ourselves at the end of the chain.
|
22
|
+
*/
|
23
|
+
triggerAndReturn: function (name, data) {
|
24
|
+
var event = new $.Event(name);
|
25
|
+
this.trigger(event, data);
|
26
|
+
|
27
|
+
return event.result !== false;
|
28
|
+
},
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Handles execution of remote calls. Provides following callbacks:
|
32
|
+
*
|
33
|
+
* - ajax:beforeSend - is executed before firing ajax call
|
34
|
+
* - ajax:success - is executed when status is success
|
35
|
+
* - ajax:complete - is executed when the request finishes, whether in failure or success.
|
36
|
+
* - ajax:error - is execute in case of error
|
37
|
+
*/
|
38
|
+
callRemote: function () {
|
39
|
+
var el = this,
|
40
|
+
method = el.attr('method') || el.attr('data-method') || 'GET',
|
41
|
+
url = el.attr('action') || el.attr('href'),
|
42
|
+
dataType = el.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);
|
43
|
+
|
44
|
+
if (url === undefined) {
|
45
|
+
throw "No URL specified for remote call (action or href must be present).";
|
46
|
+
} else {
|
47
|
+
var $this = $(this), data = el.is('form') ? el.serializeArray() : [];
|
48
|
+
|
49
|
+
$.ajax({
|
50
|
+
url: url,
|
51
|
+
data: data,
|
52
|
+
dataType: dataType,
|
53
|
+
type: method.toUpperCase(),
|
54
|
+
beforeSend: function (xhr) {
|
55
|
+
xhr.setRequestHeader("Accept", "text/javascript");
|
56
|
+
if ($this.triggerHandler('ajax:beforeSend') === false) {
|
57
|
+
return false;
|
58
|
+
}
|
59
|
+
},
|
60
|
+
success: function (data, status, xhr) {
|
61
|
+
el.trigger('ajax:success', [data, status, xhr]);
|
62
|
+
},
|
63
|
+
complete: function (xhr) {
|
64
|
+
el.trigger('ajax:complete', xhr);
|
65
|
+
},
|
66
|
+
error: function (xhr, status, error) {
|
67
|
+
el.trigger('ajax:error', [xhr, status, error]);
|
68
|
+
}
|
69
|
+
});
|
70
|
+
}
|
71
|
+
}
|
72
|
+
});
|
73
|
+
|
74
|
+
/**
|
75
|
+
* confirmation handler
|
76
|
+
*/
|
77
|
+
|
78
|
+
$('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () {
|
79
|
+
var el = $(this);
|
80
|
+
if (el.triggerAndReturn('confirm')) {
|
81
|
+
if (!confirm(el.attr('data-confirm'))) {
|
82
|
+
return false;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
});
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
/**
|
90
|
+
* remote handlers
|
91
|
+
*/
|
92
|
+
$('form[data-remote]').live('submit.rails', function (e) {
|
93
|
+
$(this).callRemote();
|
94
|
+
e.preventDefault();
|
95
|
+
});
|
96
|
+
|
97
|
+
$('a[data-remote],input[data-remote]').live('click.rails', function (e) {
|
98
|
+
$(this).callRemote();
|
99
|
+
e.preventDefault();
|
100
|
+
});
|
101
|
+
|
102
|
+
/**
|
103
|
+
* <%= link_to "Delete", user_path(@user), :method => :delete, :confirm => "Are you sure?" %>
|
104
|
+
*
|
105
|
+
* <a href="/users/5" data-confirm="Are you sure?" data-method="delete" rel="nofollow">Delete</a>
|
106
|
+
*/
|
107
|
+
$('a[data-method]:not([data-remote])').live('click.rails', function (e){
|
108
|
+
var link = $(this),
|
109
|
+
href = link.attr('href'),
|
110
|
+
method = link.attr('data-method'),
|
111
|
+
form = $('<form method="post" action="'+href+'"></form>'),
|
112
|
+
metadata_input = '<input name="_method" value="'+method+'" type="hidden" />';
|
113
|
+
|
114
|
+
if (csrf_param !== undefined && csrf_token !== undefined) {
|
115
|
+
metadata_input += '<input name="'+csrf_param+'" value="'+csrf_token+'" type="hidden" />';
|
116
|
+
}
|
117
|
+
|
118
|
+
form.hide()
|
119
|
+
.append(metadata_input)
|
120
|
+
.appendTo('body');
|
121
|
+
|
122
|
+
e.preventDefault();
|
123
|
+
form.submit();
|
124
|
+
});
|
125
|
+
|
126
|
+
/**
|
127
|
+
* disable-with handlers
|
128
|
+
*/
|
129
|
+
var disable_with_input_selector = 'input[data-disable-with]',
|
130
|
+
disable_with_form_remote_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')',
|
131
|
+
disable_with_form_not_remote_selector = 'form:not([data-remote]):has(' + disable_with_input_selector + ')';
|
132
|
+
|
133
|
+
var disable_with_input_function = function () {
|
134
|
+
$(this).find(disable_with_input_selector).each(function () {
|
135
|
+
var input = $(this);
|
136
|
+
input.data('enable-with', input.val())
|
137
|
+
.attr('value', input.attr('data-disable-with'))
|
138
|
+
.attr('disabled', 'disabled');
|
139
|
+
});
|
140
|
+
};
|
141
|
+
|
142
|
+
$(disable_with_form_remote_selector).live('ajax:before.rails', disable_with_input_function);
|
143
|
+
$(disable_with_form_not_remote_selector).live('submit.rails', disable_with_input_function);
|
144
|
+
|
145
|
+
$(disable_with_form_remote_selector).live('ajax:complete.rails', function () {
|
146
|
+
$(this).find(disable_with_input_selector).each(function () {
|
147
|
+
var input = $(this);
|
148
|
+
input.removeAttr('disabled')
|
149
|
+
.val(input.data('enable-with'));
|
150
|
+
});
|
151
|
+
});
|
152
|
+
|
153
|
+
var jqueryVersion = $().jquery;
|
154
|
+
|
155
|
+
if (!( (jqueryVersion === '1.4.3') || (jqueryVersion === '1.4.4'))){
|
156
|
+
alert('This rails.js does not support the jQuery version you are using. Please read documentation.');
|
157
|
+
}
|
158
|
+
|
159
|
+
|
160
|
+
});
|
@@ -0,0 +1,9 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into including all the files listed below.
|
2
|
+
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
3
|
+
// be included in the compiled file accessible from http://example.com/assets/application.js
|
4
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
5
|
+
// the compiled file.
|
6
|
+
//
|
7
|
+
//= require jquery
|
8
|
+
//= require jquery_ujs
|
9
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll automatically include all the stylesheets available in this directory
|
3
|
+
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
4
|
+
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
5
|
+
*= require_self
|
6
|
+
*= require_tree .
|
7
|
+
*/
|
8
|
+
|
9
|
+
body {font-family: arial, sans-serif;font-size:.8em;}
|
10
|
+
form label {float:left; width:150px;}
|
11
|
+
.actions{margin-left:150px;}
|
12
|
+
label{font-weight:bold;}
|
13
|
+
#task_description{margin-left:150px;margin-top:10px;}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
body { background-color: #fff; color: #333; }
|
2
|
+
|
3
|
+
body, p, ol, ul, td {
|
4
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
5
|
+
font-size: 13px;
|
6
|
+
line-height: 18px;
|
7
|
+
}
|
8
|
+
|
9
|
+
pre {
|
10
|
+
background-color: #eee;
|
11
|
+
padding: 10px;
|
12
|
+
font-size: 11px;
|
13
|
+
}
|
14
|
+
|
15
|
+
a { color: #000; }
|
16
|
+
a:visited { color: #666; }
|
17
|
+
a:hover { color: #fff; background-color:#000; }
|
18
|
+
|
19
|
+
div.field, div.actions {
|
20
|
+
margin-bottom: 10px;
|
21
|
+
}
|
22
|
+
|
23
|
+
#notice {
|
24
|
+
color: green;
|
25
|
+
}
|
26
|
+
|
27
|
+
.field_with_errors {
|
28
|
+
padding: 2px;
|
29
|
+
background-color: red;
|
30
|
+
display: table;
|
31
|
+
}
|
32
|
+
|
33
|
+
#error_explanation {
|
34
|
+
width: 450px;
|
35
|
+
border: 2px solid red;
|
36
|
+
padding: 7px;
|
37
|
+
padding-bottom: 0;
|
38
|
+
margin-bottom: 20px;
|
39
|
+
background-color: #f0f0f0;
|
40
|
+
}
|
41
|
+
|
42
|
+
#error_explanation h2 {
|
43
|
+
text-align: left;
|
44
|
+
font-weight: bold;
|
45
|
+
padding: 5px 5px 5px 15px;
|
46
|
+
font-size: 12px;
|
47
|
+
margin: -7px;
|
48
|
+
margin-bottom: 0px;
|
49
|
+
background-color: #c00;
|
50
|
+
color: #fff;
|
51
|
+
}
|
52
|
+
|
53
|
+
#error_explanation ul li {
|
54
|
+
font-size: 12px;
|
55
|
+
list-style: square;
|
56
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RakeUi
|
2
|
+
class RakeTasksController < ApplicationController
|
3
|
+
respond_to :js
|
4
|
+
before_filter :load_tasks
|
5
|
+
|
6
|
+
def index
|
7
|
+
@rake_task = RakeUi::RakeTask.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
@rake_task = RakeUi::RakeTask.new(params[:rake_task])
|
12
|
+
@rake_task.command = @tasks.select {|task| task['id'] == @rake_task.id }.pop['cmd']
|
13
|
+
Kernel.system("RAILS_ENV=#{Rails.env} #{@rake_task.command} #{@rake_task.arguments} >> #{Rails.root}/log/rake.log")
|
14
|
+
respond_to do |format|
|
15
|
+
format.js {}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def load_tasks
|
22
|
+
@tasks = JSON.parse(RAKE_TASKS)
|
23
|
+
arr = ['rake deploy:local_test','rake db:migrate:all','rake about','rake routes']
|
24
|
+
@tasks = @tasks.select { |task| arr.index(task['cmd']) }
|
25
|
+
@host = RakeUiCfg['host']
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module RakeUi
|
2
|
+
class RakeTask
|
3
|
+
include ActiveModel::Validations
|
4
|
+
|
5
|
+
attr_accessor :command
|
6
|
+
attr_accessor :arguments
|
7
|
+
attr_accessor :id
|
8
|
+
|
9
|
+
def initialize(opts={})
|
10
|
+
@id, @command, @arguments = opts[:id], opts[:command], opts[:arguments]
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
|
2
|
+
<script src="http://localhost:1337/socket.io/socket.io.js"></script>
|
3
|
+
<style type="text/css" media="screen">
|
4
|
+
body {background:#000; color:#fff;}
|
5
|
+
</style>
|
6
|
+
|
7
|
+
<div style='width:100%'>
|
8
|
+
<pre id="tail"></pre>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<script type="text/javascript">
|
12
|
+
var socket = io.connect('http://localhost:1337');
|
13
|
+
socket.on('tail', function (data) {
|
14
|
+
$('#tail').append(data.tail);
|
15
|
+
});
|
16
|
+
</script>
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<h1>Rake Tasks</h1>
|
2
|
+
|
3
|
+
<div style='width:100%'>
|
4
|
+
<div style='float:left;width:35%'>
|
5
|
+
<%= form_for @rake_task, :as => :rake_task, :url => rake_tasks_path, :remote => true do |f| %>
|
6
|
+
<div>
|
7
|
+
<label>Select a Rake Task</label>
|
8
|
+
<%= f.select :id, @tasks.map{|t| [t['cmd'], t['id']]}.unshift(['-- select a task --','']) %>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div>
|
12
|
+
<label>Optional Arguments</label>
|
13
|
+
<%= f.text_area :arguments, :size => '30x4' %>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div class='actions'>
|
17
|
+
<%= f.submit 'run', :id => 'submit' %>
|
18
|
+
<span id='loading' style='display:none;'><%= image_tag 'rake_ui/ajax-loader.gif', :valign => 'middle' %>Your task is running...</span>
|
19
|
+
</div>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<div id='task_description'>
|
23
|
+
<% @tasks.each do |task| %>
|
24
|
+
<div id='<%= task['id'] %>' class='task_description' style='display:none;'><%= task['desc'] %></div>
|
25
|
+
<% end %>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<div style='float:left;width:55%'>
|
30
|
+
<div><strong>Terminal Output</strong></div>
|
31
|
+
<iframe src="http://<%= @host %>:1337" width="100%" height="600" frameborder='0'></iframe>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<script type="text/javascript" charset="utf-8">
|
36
|
+
$('#rake_task_id').change(function(){
|
37
|
+
$('.task_description').hide();
|
38
|
+
$( '#' + $(this).val() ).show();
|
39
|
+
});
|
40
|
+
|
41
|
+
$('#submit').click(function(){
|
42
|
+
if($('#rake_task_id').val() == ''){
|
43
|
+
alert('Select a Rake Task');
|
44
|
+
return false;
|
45
|
+
}
|
46
|
+
$('#loading').show();
|
47
|
+
});
|
48
|
+
</script>
|
File without changes
|
@@ -0,0 +1,64 @@
|
|
1
|
+
// node /data/projects/rake_ui/app/views/rake_ui/rake_tasks/server.js -host=192.168.10.107 -log=/data/projects/entos/log/rake.log
|
2
|
+
|
3
|
+
var app = require('http').createServer(handler)
|
4
|
+
, io = require('socket.io').listen(app)
|
5
|
+
, fs = require('fs')
|
6
|
+
|
7
|
+
var args = process.argv.slice(2);
|
8
|
+
var host = args[0].substr(6);
|
9
|
+
var log = args[1].substr(5)
|
10
|
+
|
11
|
+
// console.log(host);
|
12
|
+
console.log("listeing log:" + log);
|
13
|
+
|
14
|
+
|
15
|
+
app.listen(1337);
|
16
|
+
|
17
|
+
// function handler (req, res) {
|
18
|
+
// fs.readFile(__dirname + '/index.html',
|
19
|
+
// function (err, data) {
|
20
|
+
// if (err) {
|
21
|
+
// res.writeHead(500);
|
22
|
+
// return res.end('Error loading index.html');
|
23
|
+
// }
|
24
|
+
// res.writeHead(200);
|
25
|
+
// res.end(data);
|
26
|
+
// });
|
27
|
+
// }
|
28
|
+
|
29
|
+
// console.log('<script src="http://'+ host +':1337/socket.io/socket.io.js"></script>');
|
30
|
+
|
31
|
+
function handler (req, res) {
|
32
|
+
|
33
|
+
var data = '<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>' +
|
34
|
+
'<script src="http://'+ host +':1337/socket.io/socket.io.js"></script>' +
|
35
|
+
'<style type="text/css" media="screen">' +
|
36
|
+
'body {background:#000; color:#fff;}' +
|
37
|
+
'</style>' +
|
38
|
+
|
39
|
+
'<div style="width:100%">' +
|
40
|
+
'<pre id="tail"></pre>' +
|
41
|
+
'</div>' +
|
42
|
+
|
43
|
+
'<script type="text/javascript">' +
|
44
|
+
'var socket = io.connect("http://'+ host +':1337");' +
|
45
|
+
'socket.on("tail", function (data) {' +
|
46
|
+
'$("#tail").append(data.tail);' +
|
47
|
+
'}); ' +
|
48
|
+
'</script>';
|
49
|
+
|
50
|
+
res.writeHead(200);
|
51
|
+
res.end(data);
|
52
|
+
|
53
|
+
}
|
54
|
+
|
55
|
+
io.sockets.on('connection', function (socket) {
|
56
|
+
var spawn = require('child_process').spawn;
|
57
|
+
var tail = spawn("tail", ["-f", log]);
|
58
|
+
|
59
|
+
tail.stdout.on("data", function (data) {
|
60
|
+
socket.emit('tail', { tail : data.toString('utf-8') } )
|
61
|
+
});
|
62
|
+
});
|
63
|
+
|
64
|
+
console.log('Log Server running now at http://'+ host +':1337/ in your browser');
|