rubycron 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -3
- data/README.md +9 -2
- data/lib/rubycron.rb +2 -169
- data/lib/rubycron/main.rb +168 -0
- data/lib/{report.erb → rubycron/report.erb} +0 -0
- data/lib/rubycron/version.rb +3 -0
- data/sample/test.rcj +8 -5
- metadata +9 -7
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -17,6 +17,13 @@ This gem depends on [Mikel's wonderful mail gem](https://github.com/mikel/mail).
|
|
17
17
|
|
18
18
|
By default, RubyCron assumes you have a local smtp server running on port 25 in order to send mail.
|
19
19
|
|
20
|
+
### Tested on
|
21
|
+
|
22
|
+
* ruby-1.8.7-p371 [ i686 ]
|
23
|
+
* ruby-1.9.2-p320 [ x86_64 ]
|
24
|
+
* ruby-1.9.3-p327 [ x86_64 ]
|
25
|
+
* jruby-1.7.3 [ x86_64 ]
|
26
|
+
|
20
27
|
## Usage
|
21
28
|
|
22
29
|
### Configure the basics
|
@@ -157,7 +164,7 @@ Note that in the latter case the values of the directives specified within the R
|
|
157
164
|
|
158
165
|
## License
|
159
166
|
|
160
|
-
Copyright (c) 2011 -
|
167
|
+
Copyright (c) 2011 - 2013, Bart Kamphorst
|
161
168
|
|
162
169
|
(Modified BSD License)
|
163
170
|
|
@@ -184,4 +191,4 @@ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
184
191
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
185
192
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
186
193
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
187
|
-
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
194
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/lib/rubycron.rb
CHANGED
@@ -1,169 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
module RubyCron
|
5
|
-
|
6
|
-
class RubyCronJob
|
7
|
-
|
8
|
-
require 'net/smtp'
|
9
|
-
require 'yaml'
|
10
|
-
require 'open-uri'
|
11
|
-
require 'rubygems'
|
12
|
-
require 'mail'
|
13
|
-
require 'erb'
|
14
|
-
|
15
|
-
attr_accessor :name, :author, :mailto, :mailfrom, :mailsubject, :mailon, :exiton, :template, :smtpsettings, :logfile, :verbose
|
16
|
-
attr_reader :warnings, :errors, :report
|
17
|
-
|
18
|
-
def initialize(args = nil)
|
19
|
-
@warnings, @errors = [], []
|
20
|
-
|
21
|
-
case args
|
22
|
-
when NilClass then yield self if block_given?
|
23
|
-
when Proc then instance_eval(&args)
|
24
|
-
when Hash then
|
25
|
-
|
26
|
-
args = load_config(:file, args[:configfile]).merge(args) if args[:configfile]
|
27
|
-
args = load_config(:url, args[:configurl]).merge(args) if args[:configurl]
|
28
|
-
|
29
|
-
args.each do |key, value|
|
30
|
-
instance_variable_set("@#{key}", value) if value
|
31
|
-
end
|
32
|
-
else terminate "Expected a hash or a block to initialize, but instead received a #{args.class} object."
|
33
|
-
end
|
34
|
-
|
35
|
-
check_sanity
|
36
|
-
|
37
|
-
rescue => e
|
38
|
-
terminate(e.message)
|
39
|
-
end
|
40
|
-
|
41
|
-
def load_config(source_type, source)
|
42
|
-
if source_type == :file
|
43
|
-
io = File.open(source) if File.file?(source)
|
44
|
-
elsif source_type == :url
|
45
|
-
io = open(source)
|
46
|
-
end
|
47
|
-
yml = YAML::load(io)
|
48
|
-
if yml.is_a?(Hash)
|
49
|
-
return yml
|
50
|
-
else
|
51
|
-
terminate "Could not load the YAML configuration."
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def check_sanity
|
56
|
-
raise "This job has no name." unless @name
|
57
|
-
raise "This job has no author." unless @author
|
58
|
-
raise "No To: header was set. " unless @mailto
|
59
|
-
|
60
|
-
check_smtp_settings
|
61
|
-
set_defaults
|
62
|
-
enable_file_logging if @logfile
|
63
|
-
end
|
64
|
-
|
65
|
-
def check_smtp_settings
|
66
|
-
if @smtpsettings
|
67
|
-
raise "SMTP settings have to be passed in as a hash." unless @smtpsettings.instance_of?(Hash)
|
68
|
-
raise "SMTP settings should include at least an address (:address)." unless @smtpsettings.keys.include?(:address)
|
69
|
-
raise "SMTP settings should include at least a port number (:port)." unless @smtpsettings.keys.include?(:port)
|
70
|
-
elsif @smtpsettings.nil?
|
71
|
-
raise "Cannot connect to local smtp server." unless smtp_connection?
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def set_defaults
|
76
|
-
@mailfrom ||= 'root@localhost'
|
77
|
-
@verbose ||= false
|
78
|
-
@template ||= File.join(File.dirname(__FILE__), '/report.erb')
|
79
|
-
@mailon = :all unless self.mailon && [:none, :warning, :error, :all].include?(self.mailon)
|
80
|
-
@exiton = :all unless self.exiton && [:none, :warning, :error, :all].include?(self.exiton)
|
81
|
-
end
|
82
|
-
|
83
|
-
def enable_file_logging
|
84
|
-
$stdout.reopen(@logfile, "a")
|
85
|
-
$stdout.sync = true
|
86
|
-
$stderr.reopen($stdout)
|
87
|
-
rescue => e
|
88
|
-
$stdout, $stderr = STDOUT, STDERR
|
89
|
-
raise e
|
90
|
-
end
|
91
|
-
|
92
|
-
def terminate(message)
|
93
|
-
$stderr.puts "## Cannot complete job. Reason: #{message}" unless ENV['RSPEC']
|
94
|
-
exit 1
|
95
|
-
end
|
96
|
-
|
97
|
-
# Execute a given block of code (the cronjob), rescue encountered errors,
|
98
|
-
# and send a report about it if necessary.
|
99
|
-
def execute(&block)
|
100
|
-
@starttime = Time.now
|
101
|
-
puts "\nStarting run of #{self.name} at #{@starttime}.\n----" if self.verbose || self.logfile
|
102
|
-
instance_eval(&block)
|
103
|
-
rescue Exception => e
|
104
|
-
@errors << e.message
|
105
|
-
terminate(e.message) if exiton == (:error || :all)
|
106
|
-
ensure
|
107
|
-
@endtime = Time.now
|
108
|
-
if self.verbose || self.logfile
|
109
|
-
puts "Run ended at #{@endtime}.\n----"
|
110
|
-
puts "Number of warnings: #{@warnings.size}"
|
111
|
-
puts "Number of errors : #{@errors.size}"
|
112
|
-
end
|
113
|
-
unless self.mailon == :none || (@warnings.empty? && @errors.empty? && self.mailon != :all)
|
114
|
-
send_report
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def warning(message)
|
119
|
-
$stderr.puts message if self.verbose || self.logfile
|
120
|
-
raise "Configured to exit on warning." if exiton == (:warning || :all)
|
121
|
-
@warnings << message
|
122
|
-
end
|
123
|
-
|
124
|
-
def error(message)
|
125
|
-
$stderr.puts message if self.verbose || self.logfile
|
126
|
-
raise "Configured to exit on error." if exiton == (:error || :all)
|
127
|
-
@errors << message
|
128
|
-
end
|
129
|
-
|
130
|
-
private
|
131
|
-
def smtp_connection?
|
132
|
-
#return true if ENV['RSPEC']
|
133
|
-
return true if Net::SMTP.start('localhost', 25)
|
134
|
-
rescue
|
135
|
-
return false
|
136
|
-
end
|
137
|
-
|
138
|
-
# Report on the status of the cronjob through the use of
|
139
|
-
# an erb template file, and mikel's excellent mail gem.
|
140
|
-
private
|
141
|
-
def send_report
|
142
|
-
@report = ERB.new(File.read(@template)).result(binding)
|
143
|
-
@mailsubject = "Cron report for #{name}: #{@warnings.size} warnings & #{@errors.size} errors" unless @mailsubject
|
144
|
-
|
145
|
-
mailfrom = @mailfrom
|
146
|
-
mailto = @mailto
|
147
|
-
mailsubject = @mailsubject
|
148
|
-
mailbody = @report
|
149
|
-
|
150
|
-
if @smtpsettings
|
151
|
-
smtpsettings = @smtpsettings
|
152
|
-
Mail.defaults do
|
153
|
-
delivery_method :smtp, smtpsettings
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
mail = Mail.new do
|
158
|
-
from mailfrom
|
159
|
-
to mailto
|
160
|
-
subject mailsubject
|
161
|
-
body mailbody
|
162
|
-
end
|
163
|
-
|
164
|
-
mail.deliver!
|
165
|
-
rescue => e
|
166
|
-
terminate(e.message)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
1
|
+
require 'rubycron/main'
|
2
|
+
require 'rubycron/version'
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# Copyright (c) Bart Kamphorst <rubycron@kamphorst.com>, 2011 - 2013.
|
2
|
+
# Licensed under the modified BSD License. All rights reserved.
|
3
|
+
|
4
|
+
module RubyCron
|
5
|
+
|
6
|
+
class RubyCronJob
|
7
|
+
|
8
|
+
require 'net/smtp'
|
9
|
+
require 'yaml'
|
10
|
+
require 'open-uri'
|
11
|
+
require 'rubygems'
|
12
|
+
require 'mail'
|
13
|
+
require 'erb'
|
14
|
+
|
15
|
+
attr_accessor :name, :author, :mailto, :mailfrom, :mailsubject, :mailon, :exiton, :template, :smtpsettings, :logfile, :verbose
|
16
|
+
attr_reader :warnings, :errors, :report
|
17
|
+
|
18
|
+
def initialize(args = nil)
|
19
|
+
@warnings, @errors = [], []
|
20
|
+
|
21
|
+
case args
|
22
|
+
when NilClass then yield self if block_given?
|
23
|
+
when Proc then instance_eval(&args)
|
24
|
+
when Hash then
|
25
|
+
|
26
|
+
args = load_config(:file, args[:configfile]).merge(args) if args[:configfile]
|
27
|
+
args = load_config(:url, args[:configurl]).merge(args) if args[:configurl]
|
28
|
+
|
29
|
+
args.each do |key, value|
|
30
|
+
instance_variable_set("@#{key}", value) if value
|
31
|
+
end
|
32
|
+
else terminate "Expected a hash or a block to initialize, but instead received a #{args.class} object."
|
33
|
+
end
|
34
|
+
|
35
|
+
check_sanity
|
36
|
+
|
37
|
+
rescue => e
|
38
|
+
terminate(e.message)
|
39
|
+
end
|
40
|
+
|
41
|
+
def load_config(source_type, source)
|
42
|
+
if source_type == :file
|
43
|
+
io = File.open(source) if File.file?(source)
|
44
|
+
elsif source_type == :url
|
45
|
+
io = open(source)
|
46
|
+
end
|
47
|
+
yml = YAML::load(io)
|
48
|
+
if yml.is_a?(Hash)
|
49
|
+
return yml
|
50
|
+
else
|
51
|
+
terminate "Could not load the YAML configuration."
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def check_sanity
|
56
|
+
raise "This job has no name." unless @name
|
57
|
+
raise "This job has no author." unless @author
|
58
|
+
raise "No To: header was set. " unless @mailto
|
59
|
+
|
60
|
+
check_smtp_settings
|
61
|
+
set_defaults
|
62
|
+
enable_file_logging if @logfile
|
63
|
+
end
|
64
|
+
|
65
|
+
def check_smtp_settings
|
66
|
+
if @smtpsettings
|
67
|
+
raise "SMTP settings have to be passed in as a hash." unless @smtpsettings.instance_of?(Hash)
|
68
|
+
raise "SMTP settings should include at least an address (:address)." unless @smtpsettings.keys.include?(:address)
|
69
|
+
raise "SMTP settings should include at least a port number (:port)." unless @smtpsettings.keys.include?(:port)
|
70
|
+
elsif @smtpsettings.nil?
|
71
|
+
raise "Cannot connect to local smtp server." unless smtp_connection?
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def set_defaults
|
76
|
+
@mailfrom ||= 'root@localhost'
|
77
|
+
@verbose ||= false
|
78
|
+
@template ||= File.join(File.dirname(__FILE__), '/report.erb')
|
79
|
+
@mailon = :all unless self.mailon && [:none, :warning, :error, :all].include?(self.mailon)
|
80
|
+
@exiton = :all unless self.exiton && [:none, :warning, :error, :all].include?(self.exiton)
|
81
|
+
end
|
82
|
+
|
83
|
+
def enable_file_logging
|
84
|
+
$stdout.reopen(@logfile, "a")
|
85
|
+
$stdout.sync = true
|
86
|
+
$stderr.reopen($stdout)
|
87
|
+
rescue => e
|
88
|
+
$stdout, $stderr = STDOUT, STDERR
|
89
|
+
raise e
|
90
|
+
end
|
91
|
+
|
92
|
+
def terminate(message)
|
93
|
+
$stderr.puts "## Cannot complete job. Reason: #{message}" unless ENV['RSPEC']
|
94
|
+
exit 1
|
95
|
+
end
|
96
|
+
|
97
|
+
# Execute a given block of code (the cronjob), rescue encountered errors,
|
98
|
+
# and send a report about it if necessary.
|
99
|
+
def execute(&block)
|
100
|
+
@starttime = Time.now
|
101
|
+
puts "\nStarting run of #{self.name} at #{@starttime}.\n----" if self.verbose || self.logfile
|
102
|
+
instance_eval(&block)
|
103
|
+
rescue Exception => e
|
104
|
+
@errors << e.message
|
105
|
+
terminate(e.message) if exiton == (:error || :all)
|
106
|
+
ensure
|
107
|
+
@endtime = Time.now
|
108
|
+
if self.verbose || self.logfile
|
109
|
+
puts "Run ended at #{@endtime}.\n----"
|
110
|
+
puts "Number of warnings: #{@warnings.size}"
|
111
|
+
puts "Number of errors : #{@errors.size}"
|
112
|
+
end
|
113
|
+
unless self.mailon == :none || (@warnings.empty? && @errors.empty? && self.mailon != :all)
|
114
|
+
send_report
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def warning(message)
|
119
|
+
$stderr.puts message if self.verbose || self.logfile
|
120
|
+
raise "Configured to exit on warning." if exiton == (:warning || :all)
|
121
|
+
@warnings << message
|
122
|
+
end
|
123
|
+
|
124
|
+
def error(message)
|
125
|
+
$stderr.puts message if self.verbose || self.logfile
|
126
|
+
raise "Configured to exit on error." if exiton == (:error || :all)
|
127
|
+
@errors << message
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
def smtp_connection?
|
132
|
+
return true if Net::SMTP.start('localhost', 25)
|
133
|
+
rescue
|
134
|
+
return false
|
135
|
+
end
|
136
|
+
|
137
|
+
# Report on the status of the cronjob through the use of
|
138
|
+
# an erb template file, and mikel's excellent mail gem.
|
139
|
+
private
|
140
|
+
def send_report
|
141
|
+
@report = ERB.new(File.read(@template)).result(binding)
|
142
|
+
@mailsubject = "Cron report for #{name}: #{@warnings.size} warnings & #{@errors.size} errors" unless @mailsubject
|
143
|
+
|
144
|
+
mailfrom = @mailfrom
|
145
|
+
mailto = @mailto
|
146
|
+
mailsubject = @mailsubject
|
147
|
+
mailbody = @report
|
148
|
+
|
149
|
+
if @smtpsettings
|
150
|
+
smtpsettings = @smtpsettings
|
151
|
+
Mail.defaults do
|
152
|
+
delivery_method :smtp, smtpsettings
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
mail = Mail.new do
|
157
|
+
from mailfrom
|
158
|
+
to mailto
|
159
|
+
subject mailsubject
|
160
|
+
body mailbody
|
161
|
+
end
|
162
|
+
|
163
|
+
mail.deliver!
|
164
|
+
rescue => e
|
165
|
+
terminate(e.message)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
File without changes
|
data/sample/test.rcj
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
4
|
+
require 'RubyCron'
|
5
5
|
include RubyCron
|
6
|
+
require 'tmpdir'
|
6
7
|
|
7
8
|
rcj = RubyCronJob.new(
|
8
9
|
:author => 'John Doe',
|
@@ -14,12 +15,14 @@ rcj = RubyCronJob.new(
|
|
14
15
|
:verbose => false )
|
15
16
|
|
16
17
|
rcj.execute do
|
17
|
-
unless File.directory?(
|
18
|
-
warning "Something awry is going on with
|
18
|
+
unless File.directory?(Dir.tmpdir)
|
19
|
+
warning "Something awry is going on with the tmp directory."
|
19
20
|
end
|
20
21
|
begin
|
21
|
-
|
22
|
-
|
22
|
+
Dir.mktmpdir do |dir|
|
23
|
+
File.open(File.join(dir, 'rubycrontest'), 'w') do |f|
|
24
|
+
f.write("Test completed successfully.")
|
25
|
+
end
|
23
26
|
end
|
24
27
|
rescue => e
|
25
28
|
error "Something went wrong trying to write to file: #{e.message}"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubycron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-04-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mail
|
@@ -32,17 +32,17 @@ dependencies:
|
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: 0.7.1
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 0.7.1
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: rspec
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,7 +70,9 @@ files:
|
|
70
70
|
- README.md
|
71
71
|
- Gemfile
|
72
72
|
- lib/rubycron.rb
|
73
|
-
- lib/
|
73
|
+
- lib/rubycron/main.rb
|
74
|
+
- lib/rubycron/report.erb
|
75
|
+
- lib/rubycron/version.rb
|
74
76
|
- sample/test.rcj
|
75
77
|
- bin/rcjrunner.rb
|
76
78
|
homepage: https://github.com/bartkamphorst/rubycron
|