-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Barebone version of a Sinatra app to show cronjobs on a timeline.
- Loading branch information
Shashank Date
committed
Jan 4, 2011
1 parent
73fd59c
commit e2c4920
Showing
91 changed files
with
7,044 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
rvm use ree-1.8.7-head@timeline |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
== Description | ||
|
||
A barebone Sinatra app to show the cron jobs on a timeline. | ||
|
||
Powered by SIMILE Timeline Widget: http://www.simile-widgets.org/wiki/Timeline. | ||
|
||
Tested on Ubuntu 10.10, FireFox 3.6.13, using ree-1.8.7-head with gemset: | ||
|
||
json_pure (1.4.6) | ||
rack (1.2.1) | ||
shotgun (0.8) | ||
sinatra (1.1.2) | ||
tilt (1.2.1) | ||
|
||
== Version | ||
|
||
0.0.1 (Jan 3rd, 2011) | ||
|
||
== Installation | ||
|
||
Install the required gems and then git clone git://github.com/shanko/misc.git | ||
|
||
== Usage | ||
|
||
$ shotgun cron_timeline.rb | ||
|
||
== ToDo | ||
|
||
* Improve the rendering of the timeline | ||
* RSpec examples | ||
* Documentation | ||
|
||
== Author | ||
|
||
Shashank Date <mailto:stdate@gmail.com> | ||
|
||
== License | ||
|
||
MIT license: http://www.opensource.org/licenses/mit-license.php | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
require 'rubygems' | ||
require 'sinatra' | ||
require 'json' | ||
require 'models/parse_cron' | ||
|
||
get "/cron" do | ||
cron_jobs = ['*/15 * * 1 * whoami','*/30 * * 1 * uname' ] | ||
hr_window = 2 | ||
erb :cron, :locals => { :json => to_timeline_hash(cron_jobs,hr_window).to_json } | ||
end | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
require "pp" | ||
|
||
def parse_time_element(te,from,to) | ||
ret = [] | ||
|
||
if te =~ /^\d+$/ | ||
ret << te.to_i | ||
elsif te =~ /^[*]$/ | ||
ret = (from..to).to_a | ||
elsif te =~ /,/ | ||
te.split(',').each do |e| | ||
if e =~ /^\d+$/ | ||
ret << e.to_i | ||
elsif e =~ /-/ | ||
ret += parse_time_element(e,from,to) | ||
else | ||
raise "Cannot parse: #{te}" | ||
end | ||
end | ||
elsif te =~ /^(\d+)-(\d+)\/?(\d+)?$/ | ||
if $3.to_i < 2 | ||
ret = ($1.to_i..$2.to_i).to_a | ||
else | ||
step = $3.to_i | ||
start = $1.to_i | ||
stop = $2.to_i | ||
while start < stop do | ||
ret << start | ||
start += step | ||
end | ||
end | ||
elsif te =~ /^[*]\/(\d+)$/ | ||
freq = $1.to_i | ||
to_limit = (to - from + 1) | ||
if freq > 0 && freq < to_limit | ||
to_limit.times do |i| | ||
m = i * freq | ||
break if m >= to_limit | ||
ret << m | ||
end | ||
else | ||
raise "Cannot parse: #{te}" | ||
end | ||
else | ||
raise "Cannot parse: #{te}" | ||
end | ||
ret | ||
end | ||
|
||
def canonize(min, hr, day, month, wday, cmd) | ||
cmd_str = cmd.join(" ") | ||
minutes = parse_time_element(min, 0, 59) | ||
hours = parse_time_element(hr, 0, 23) | ||
days = parse_time_element(day, 1, 31) | ||
months = parse_time_element(month, 1, 12) | ||
week_days = parse_time_element(wday, 0, 6) | ||
return [minutes, hours, days, months, week_days, cmd_str] | ||
end | ||
|
||
def will_execute_at?(cron_entry,at_time=Time.now) | ||
val = true | ||
at = [at_time.min, at_time.hour, at_time.day, at_time.month, at_time.wday] | ||
|
||
cron_entry.each_with_index do |element,i| | ||
next if element.class == String | ||
found = false | ||
element.each{|t| found = (at[i] == t); break if found} | ||
unless found | ||
val = found | ||
break | ||
end | ||
end | ||
|
||
val | ||
end | ||
|
||
def will_execute_when?(cron_entry,from_time,to_time) | ||
times = [] | ||
return times if from_time > to_time | ||
min = 0 | ||
next_minute = from_time + min * 60 | ||
while (next_minute <= to_time) | ||
times << next_minute if will_execute_at?(cron_entry,next_minute) | ||
min += 1 | ||
next_minute = from_time + min * 60 | ||
end | ||
times | ||
end | ||
|
||
def cron_hash(cron_jobs,hour_window=1) | ||
reverse_cron_hash = {} | ||
cron_jobs.each do |line| | ||
next if (line.strip.size == 0) || (line =~ /^\s*#/) | ||
min, hr, day, month, week_day, *cmd = line.strip.split | ||
|
||
begin | ||
cron_entry = canonize(min, hr, day, month, week_day, cmd) | ||
# pp cron_entry | ||
|
||
from, to = Time.now, Time.now + (hour_window * 60 * 60) | ||
arr = will_execute_when?(cron_entry,from,to) | ||
|
||
arr.each do |time_element| | ||
if reverse_cron_hash[time_element.to_s] | ||
reverse_cron_hash[time_element.to_s] << cron_entry[-1] unless reverse_cron_hash[time_element.to_s].include?(cron_entry[-1]) | ||
else | ||
reverse_cron_hash[time_element.to_s] = [cron_entry[-1]] | ||
end | ||
end | ||
|
||
rescue | ||
puts "---------------------\n" + line + ' ' + $!.to_s | ||
end | ||
end | ||
reverse_cron_hash | ||
end | ||
|
||
def to_timeline_hash(cron_jobs,hour_window) | ||
chash = cron_hash(cron_jobs,hour_window) | ||
events_arr = [] | ||
chash.each do |key,val| | ||
val.each do |cmd| | ||
events_arr << {"start" => key, "instant" => true, "title" => cmd, "description" => ""} | ||
end | ||
end | ||
|
||
event_data = { | ||
'dateTimeFormat' => 'Gregorian', | ||
'events' => events_arr | ||
} | ||
|
||
# pp event_data | ||
|
||
event_data | ||
end | ||
|
||
if __FILE__ == $0 | ||
# min hr day month week-day command | ||
cron_jobs = ['*/15 * * 1 * whoami','*/30 * * 1 * uname' ] | ||
# cron_jobs = `crontab -l` | ||
# cron_jobs = File.readlines("cronfile.txt") | ||
|
||
puts | ||
pp to_timeline_hash(cron_jobs,2) | ||
end | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<html> | ||
<head> | ||
<title>Dummy Page for Keeping Track of History</title> | ||
</head> | ||
<body> | ||
</body> | ||
</html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/*================================================== | ||
* This file is used to detect that all outstanding | ||
* javascript files have been loaded. You can put | ||
* a function reference into SimileAjax_onLoad | ||
* to have it executed once all javascript files | ||
* have loaded. | ||
*================================================== | ||
*/ | ||
(function() { | ||
var substring = SimileAjax.urlPrefix + "scripts/signal.js"; | ||
var heads = document.documentElement.getElementsByTagName("head"); | ||
for (var h = 0; h < heads.length; h++) { | ||
var node = heads[h].firstChild; | ||
while (node != null) { | ||
if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") { | ||
var url = node.src; | ||
var i = url.indexOf(substring); | ||
if (i >= 0) { | ||
heads[h].removeChild(node); // remove it so we won't hit it again | ||
|
||
var count = parseInt(url.substr(url.indexOf(substring) + substring.length + 1)); | ||
SimileAjax.loadingScriptsCount -= count; | ||
if (SimileAjax.loadingScriptsCount == 0) { | ||
var f = null; | ||
if (typeof SimileAjax_onLoad == "string") { | ||
f = eval(SimileAjax_onLoad); | ||
SimileAjax_onLoad = null; | ||
} else if (typeof SimileAjax_onLoad == "function") { | ||
f = SimileAjax_onLoad; | ||
SimileAjax_onLoad = null; | ||
} | ||
|
||
if (f != null) { | ||
f(); | ||
} | ||
} | ||
return; | ||
} | ||
} | ||
node = node.nextSibling; | ||
} | ||
} | ||
})(); |
Oops, something went wrong.