From bb03a562cc7cd9def577ce11ccb53ee8a8abbd1d Mon Sep 17 00:00:00 2001 From: Dzmitry Plashchynski Date: Sat, 7 Mar 2015 23:44:37 +0200 Subject: [PATCH] Add simple web interface --- Gemfile.lock | 12 +++++++ README.md | 74 ++++++++++++++++++++++++++++------------ crono.gemspec | 2 ++ lib/crono/web.rb | 18 ++++++++++ web/views/dashboard.haml | 27 +++++++++++++++ 5 files changed, 112 insertions(+), 21 deletions(-) create mode 100644 lib/crono/web.rb create mode 100644 web/views/dashboard.haml diff --git a/Gemfile.lock b/Gemfile.lock index ccd4c19..e3e1c59 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,9 +36,14 @@ GEM diff-lcs (1.2.5) globalid (0.3.3) activesupport (>= 4.1.0) + haml (4.0.6) + tilt i18n (0.7.0) json (1.8.2) minitest (5.5.1) + rack (1.6.0) + rack-protection (1.5.3) + rack rake (10.4.2) rspec (3.2.0) rspec-core (~> 3.2.0) @@ -53,9 +58,14 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.2.0) rspec-support (3.2.2) + sinatra (1.4.5) + rack (~> 1.4) + rack-protection (~> 1.4) + tilt (~> 1.3, >= 1.3.4) slop (3.6.0) sqlite3 (1.3.10) thread_safe (0.3.4) + tilt (1.4.1) timecop (0.7.3) tzinfo (1.2.2) thread_safe (~> 0.1) @@ -67,7 +77,9 @@ DEPENDENCIES bundler (>= 1.0.0) byebug crono! + haml rake (~> 10.0) rspec (~> 3.0) + sinatra sqlite3 timecop (~> 0.7) diff --git a/README.md b/README.md index 67ebf38..7c1ed97 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,9 @@ Other versions are untested but might work fine. Add the following line to your application's Gemfile: - gem 'crono' +```ruby +gem 'crono' +``` Run the `bundle` command to install it. After you install Crono, you can run the generator: @@ -47,40 +49,48 @@ Crono can use Active Job jobs from `app/jobs/`. The only requirements is that th Here's an example of a test job: - # app/jobs/test_job.rb - class TestJob < ActiveJob::Base - def perform - # put you scheduled code here - # Comments.deleted.clean_up... - end - end +```ruby +# app/jobs/test_job.rb +class TestJob < ActiveJob::Base + def perform + # put you scheduled code here + # Comments.deleted.clean_up... + end +end +``` The ActiveJob jobs is convenient because you can use one job in both periodic and enqueued ways. But Active Job is not required. Any class can be used as a crono job if it implements a method `perform` without arguments: - class TestJob # This is not an Active Job job, but pretty legal Crono job. - def perform - # put you scheduled code here - # Comments.deleted.clean_up... - end - end - +```ruby +class TestJob # This is not an Active Job job, but pretty legal Crono job. + def perform + # put you scheduled code here + # Comments.deleted.clean_up... + end +end +``` #### Job Schedule The schedule described in the configuration file `config/cronotab.rb`, that created using `crono:install` or manually. The semantic is pretty straightforward: - # config/cronotab.rb - Crono.perform(TestJob).every 2.days, at: "15:30" +```ruby +# config/cronotab.rb +Crono.perform(TestJob).every 2.days, at: "15:30" +``` You can schedule one job a few times, if you want a job to be performed a few times a day: - Crono.perform(TestJob).every 1.day, at: "00:00" - Crono.perform(TestJob).every 1.day, at: "12:00" +```ruby +Crono.perform(TestJob).every 1.day, at: "00:00" +Crono.perform(TestJob).every 1.day, at: "12:00" +``` The `at` can be a Hash: - Crono.perform(TestJob).every 1.day, at: {hour: 12, min: 15} - +```ruby +Crono.perform(TestJob).every 1.day, at: {hour: 12, min: 15} +``` #### Run daemon @@ -98,6 +108,28 @@ Usage: crono [options] -e, --environment ENV Application environment (Default: development) ``` +## Web UI + +Crono comes with a Sinatra application that can display the current state of Crono jobs. +Add `sinatra` and `haml` to your Gemfile + +```ruby +gam 'haml' +gem 'sinatra', require: nil +``` + +Add the following to your `config/routes.rb`: + +```ruby +require 'crono/web' + +Rails.application.routes.draw do + mount Crono::Web, at: '/crono' + ... +``` + +Access management and other questions described in the [wiki](https://github.com/plashchynski/crono/wiki/Web-UI). + ## Capistrano Use the `capistrano-crono` gem ([github](https://github.com/plashchynski/capistrano-crono/)). diff --git a/crono.gemspec b/crono.gemspec index ed30f92..f1e1c78 100644 --- a/crono.gemspec +++ b/crono.gemspec @@ -22,6 +22,8 @@ Gem::Specification.new do |s| s.add_development_dependency "timecop", "~> 0.7" s.add_development_dependency "sqlite3" s.add_development_dependency "byebug" + s.add_development_dependency "sinatra" + s.add_development_dependency "haml" s.files = `git ls-files`.split("\n") s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact diff --git a/lib/crono/web.rb b/lib/crono/web.rb new file mode 100644 index 0000000..f55455f --- /dev/null +++ b/lib/crono/web.rb @@ -0,0 +1,18 @@ +require 'haml' +require 'sinatra/base' + +module Crono + class Web < Sinatra::Base + def app + Sinatra::Application + end + set :root, File.expand_path(File.dirname(__FILE__) + "/../../web") + set :public_folder, Proc.new { "#{root}/assets" } + set :views, Proc.new { "#{root}/views" } + + get '/' do + @jobs = Crono::CronoJob.all + haml :dashboard, format: :html5 + end + end +end diff --git a/web/views/dashboard.haml b/web/views/dashboard.haml new file mode 100644 index 0000000..e81971d --- /dev/null +++ b/web/views/dashboard.haml @@ -0,0 +1,27 @@ +!!! 5 +%html{lang: "en"} + %head + %meta{charset: "utf-8"} + %meta{"http-equiv" => "X-UA-Compatible", content: "IE=edge"} + %meta{name: "viewport", content: "width=device-width, initial-scale=1"} + + %title Crono Dashboard + + %link{href: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css", rel: "stylesheet"}/ + %link{href: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css", rel: "stylesheet"}/ + + %body + .container + %h2 Crono Jobs + %table.table + %tr + %th Job + %th Last performed at + %th + - for job in @jobs + %tr + %td= job.job_id + %td= job.last_performed_at + + %script{src: "https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"} + %script{src: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"}