keepitsafe 0.1.10 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ gem 'net-scp'
6
6
  gem 'net-sftp'
7
7
  gem 'i18n'
8
8
  gem 'mail'
9
+ gem 'mailbuilder'
9
10
 
10
11
  group :development do
11
12
  gem "rspec", "~> 2.3.0"
data/Gemfile.lock CHANGED
@@ -1,6 +1,21 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ actionpack (3.1.3)
5
+ activemodel (= 3.1.3)
6
+ activesupport (= 3.1.3)
7
+ builder (~> 3.0.0)
8
+ erubis (~> 2.7.0)
9
+ i18n (~> 0.6)
10
+ rack (~> 1.3.5)
11
+ rack-cache (~> 1.1)
12
+ rack-mount (~> 0.8.2)
13
+ rack-test (~> 0.6.1)
14
+ sprockets (~> 2.0.3)
15
+ activemodel (3.1.3)
16
+ activesupport (= 3.1.3)
17
+ builder (~> 3.0.0)
18
+ i18n (~> 0.6)
4
19
  activesupport (3.1.3)
5
20
  multi_json (~> 1.0)
6
21
  builder (3.0.0)
@@ -11,19 +26,25 @@ GEM
11
26
  json (>= 1.4.6)
12
27
  term-ansicolor (>= 1.0.6)
13
28
  diff-lcs (1.1.3)
29
+ erubis (2.7.0)
14
30
  gherkin (2.7.3)
15
31
  json (>= 1.4.6)
16
32
  git (1.2.5)
33
+ hike (1.2.1)
17
34
  i18n (0.6.0)
18
35
  jeweler (1.6.4)
19
36
  bundler (~> 1.0)
20
37
  git (>= 1.2.5)
21
38
  rake
22
39
  json (1.6.5)
23
- mail (2.3.0)
40
+ mail (2.4.0)
24
41
  i18n (>= 0.4.0)
25
42
  mime-types (~> 1.16)
26
43
  treetop (~> 1.4.8)
44
+ mailbuilder (0.2.0)
45
+ actionpack (>= 3.0.0)
46
+ mail (~> 2.4.0)
47
+ nokogiri (~> 1.5.0)
27
48
  mime-types (1.17.2)
28
49
  multi_json (1.0.4)
29
50
  net-scp (1.0.4)
@@ -31,7 +52,15 @@ GEM
31
52
  net-sftp (2.0.5)
32
53
  net-ssh (>= 2.0.9)
33
54
  net-ssh (2.2.1)
55
+ nokogiri (1.5.0)
34
56
  polyglot (0.3.3)
57
+ rack (1.3.6)
58
+ rack-cache (1.2)
59
+ rack (>= 0.4)
60
+ rack-mount (0.8.3)
61
+ rack (>= 1.0.0)
62
+ rack-test (0.6.1)
63
+ rack (>= 1.0)
35
64
  rake (0.9.2.2)
36
65
  rspec (2.3.0)
37
66
  rspec-core (~> 2.3.0)
@@ -41,7 +70,12 @@ GEM
41
70
  rspec-expectations (2.3.0)
42
71
  diff-lcs (~> 1.1.2)
43
72
  rspec-mocks (2.3.0)
73
+ sprockets (2.0.3)
74
+ hike (~> 1.2)
75
+ rack (~> 1.0)
76
+ tilt (!= 1.3.0, ~> 1.1)
44
77
  term-ansicolor (1.0.7)
78
+ tilt (1.3.3)
45
79
  treetop (1.4.10)
46
80
  polyglot
47
81
  polyglot (>= 0.3.1)
@@ -56,6 +90,7 @@ DEPENDENCIES
56
90
  i18n
57
91
  jeweler (~> 1.6.4)
58
92
  mail
93
+ mailbuilder
59
94
  net-scp
60
95
  net-sftp
61
96
  net-ssh
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.10
1
+ 0.2.0
@@ -0,0 +1,107 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
5
+ <title>Email report</title>
6
+
7
+ </head>
8
+ <body style="font-family: Arial; color: #aaa; font-size: 16px;">
9
+
10
+
11
+ <center>
12
+ <table cellpadding="0" cellspacing="0" style="width: 600px; margin: 0px 0px; border: solid 1px #eee; text-align: left;" width=600>
13
+ <tr>
14
+ <td>
15
+ <div class="header" style="background: #7db725; color: white;">
16
+ <h1 style="padding: 15px; margin: 0px;">Keepitsafe backup report</h1>
17
+ </div>
18
+
19
+ <table cellpadding="0" cellspacing="0" style="width: 560px; color: black; margin: 20px;">
20
+ <tr>
21
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;">Started</td>
22
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;">Run time</td>
23
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;">Backups</td>
24
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;">Errors</td>
25
+ </tr>
26
+ <tr>
27
+ <td style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= start_time.strftime('%Y-%m-%d %H:%M') %></td>
28
+ <td style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= ((end_time - start_time) / 60).to_i %>m <%= ((end_time - start_time) % 60).to_i %>s</td>
29
+ <td style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= backups.count %></td>
30
+ <td style="background: #eee; color: red; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= backups.select {|b| !b.error.nil? }.count %></td>
31
+ </tr>
32
+ </table>
33
+
34
+ <table cellpadding="0" cellspacing="0" style="width: 560px; color: black; margin: 20px;">
35
+ <tr>
36
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;">Domain</td>
37
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;">Result</td>
38
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;" >Size</td>
39
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;"> Time</td>
40
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;" >Space left</td>
41
+ </tr>
42
+
43
+
44
+ <% backups.each do |backup| %>
45
+
46
+ <tr>
47
+ <td style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= backup.domain %></td>
48
+ <td style="background: #eee; color: <%= backup.error.nil? ? "green" : "red"%>; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= backup.error.nil? ? "Ok" : "Error"%></td>
49
+ <td style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= backup.backup_size %> mb</td>
50
+ <td style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= ((backup.end_time - backup.start_time) / 60).to_i %>m <%= ((backup.end_time - backup.start_time) % 60).to_i %>s</td>
51
+ <td style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= backup.free_after %> mb</td>
52
+ </tr>
53
+
54
+ <% end %>
55
+
56
+ </table>
57
+
58
+
59
+
60
+ <% backups.each do |backup| %>
61
+
62
+ <table cellpadding="0" cellspacing="0" style="width: 560px; color: black; margin: 20px;">
63
+ <tr>
64
+ <td colspan="4" style="background: #7db725; font-size: 20px; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;">
65
+ <%= backup.domain %>
66
+ </td>
67
+ </tr>
68
+ <tr>
69
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;">Result</td>
70
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;" >Size</td>
71
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;"> Time</td>
72
+ <td style="background: #698661; color: white; padding: 10px 0px 10px 10px; border: solid 1px white;" >Space left</td>
73
+ </tr>
74
+ <tr>
75
+ <td style="background: #eee; color: <%= backup.error.nil? ? "green" : "red"%>; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= backup.error.nil? ? "Ok" : "Error"%></td>
76
+ <td style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= backup.backup_size %> mb</td>
77
+ <td style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= ((backup.end_time - backup.start_time) / 60).to_i %>m <%= ((backup.end_time - backup.start_time) % 60).to_i %>s</td>
78
+ <td style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white;"><%= backup.free_after %> mb</td>
79
+ </tr>
80
+ <tr>
81
+ <td colspan="4" style="background: #A2AC50; color: white; padding: 10px 0px 10px 10px; border: solid 1px white; border-top: solid 4px white; border-bottom: solid 0px white;">
82
+ <h1 style="font-size: 13px; margin: 0px;">Output log</h1>
83
+ </td>
84
+ </tr>
85
+ <tr>
86
+ <td colspan="4" style="background: #eee; color: black; padding: 10px 0px 10px 10px; border: solid 1px white; border-top: 0px;">
87
+ <pre style="font-size: 10px; overflow: scroll; width: 500px; padding: 20px;"><%= backup.log_buffer.string %></pre>
88
+ </td>
89
+ </tr>
90
+ </table>
91
+
92
+ <% end %>
93
+
94
+ <div class="footer" style="background: #5b5f37; color: white; padding: 15px; padding-bottom: 50px; margin-top: 50px;">
95
+ <p style="margin: 0px; font-size: 13px;">
96
+ Backup done using <a style="color: white;" href="https://github.com/bjornblomqvist/keepitsafe">Keepitsafe</a>.
97
+ Contribute by forking and sending a pull request or opening an issue on github. A nicer email design is also welcomed!
98
+ </p>
99
+ </div>
100
+ </td>
101
+ <tr>
102
+ </table>
103
+ </center>
104
+
105
+ </body>
106
+ </html>
107
+
@@ -0,0 +1,20 @@
1
+ gem 'keepitsafe'
2
+ require 'keepitsafe'
3
+
4
+ mail_options = eval(File.read(File.expand_path("~/.config/smtp.rb"))) # Read email options, same key names as for mail gem.
5
+
6
+ ErrorMail.setup("backup_script@yourdomain.com","you@yourdomain.com",mail_options)
7
+ BackupReport.new("backup_script@yourdomain.com","you@yourdomain.com",mail_options) do
8
+
9
+ Keepitsafe.new("localhost") do |backup|
10
+
11
+ backup.all_mongo 750 # Throws an error if the db is biggar than 750 meg
12
+ backup.all_postgres 100 # Throws an error if the db is biggar than 100 meg
13
+
14
+ backup.files "/var/rails/yourapp/shared/uploads/"
15
+ backup.tar_gz # Lets save some space
16
+ backup.scp "backup.yourdomain.com" # Copy the backup of site
17
+ backup.remove_old_backups
18
+
19
+ end
20
+ end
data/keepitsafe.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "keepitsafe"
8
- s.version = "0.1.10"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Darwin"]
12
- s.date = "2012-01-20"
12
+ s.date = "2012-03-05"
13
13
  s.description = "A Gem for simple creation of backup scripts"
14
14
  s.email = "darwin.git@marianna.se"
15
15
  s.extra_rdoc_files = [
@@ -25,6 +25,8 @@ Gem::Specification.new do |s|
25
25
  "README.rdoc",
26
26
  "Rakefile",
27
27
  "VERSION",
28
+ "email/report/report.html.erb",
29
+ "example/localhost.rb",
28
30
  "example/server.com.rb",
29
31
  "features/keepitsafe.feature",
30
32
  "features/step_definitions/keepitsafe_steps.rb",
@@ -44,7 +46,8 @@ Gem::Specification.new do |s|
44
46
  "lib/plugins/tar.rb",
45
47
  "lib/stdcapture.rb",
46
48
  "spec/keepitsafe_spec.rb",
47
- "spec/spec_helper.rb"
49
+ "spec/spec_helper.rb",
50
+ "todo.txt"
48
51
  ]
49
52
  s.homepage = "http://github.com/bjornblomqvist/keepitsafe"
50
53
  s.licenses = ["MIT"]
@@ -62,6 +65,7 @@ Gem::Specification.new do |s|
62
65
  s.add_runtime_dependency(%q<net-sftp>, [">= 0"])
63
66
  s.add_runtime_dependency(%q<i18n>, [">= 0"])
64
67
  s.add_runtime_dependency(%q<mail>, [">= 0"])
68
+ s.add_runtime_dependency(%q<mailbuilder>, [">= 0"])
65
69
  s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
66
70
  s.add_development_dependency(%q<cucumber>, [">= 0"])
67
71
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
@@ -73,6 +77,7 @@ Gem::Specification.new do |s|
73
77
  s.add_dependency(%q<net-sftp>, [">= 0"])
74
78
  s.add_dependency(%q<i18n>, [">= 0"])
75
79
  s.add_dependency(%q<mail>, [">= 0"])
80
+ s.add_dependency(%q<mailbuilder>, [">= 0"])
76
81
  s.add_dependency(%q<rspec>, ["~> 2.3.0"])
77
82
  s.add_dependency(%q<cucumber>, [">= 0"])
78
83
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
@@ -85,6 +90,7 @@ Gem::Specification.new do |s|
85
90
  s.add_dependency(%q<net-sftp>, [">= 0"])
86
91
  s.add_dependency(%q<i18n>, [">= 0"])
87
92
  s.add_dependency(%q<mail>, [">= 0"])
93
+ s.add_dependency(%q<mailbuilder>, [">= 0"])
88
94
  s.add_dependency(%q<rspec>, ["~> 2.3.0"])
89
95
  s.add_dependency(%q<cucumber>, [">= 0"])
90
96
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
data/lib/backup_report.rb CHANGED
@@ -1,31 +1,33 @@
1
- require 'mail'
1
+
2
+ require 'mail_builder'
2
3
  require "socket"
3
4
 
4
5
  class BackupReport
5
6
 
6
7
  def initialize from = ENV['USER'],to = "root",mail_options = {}
7
8
 
9
+ backups = []
10
+
11
+ Keepitsafe.after_backup do |backup,values|
12
+ backups << backup
13
+ end
14
+
15
+ start_time = Time.now
8
16
  capture = STDCapture.capture do
9
17
  yield
10
18
  end
19
+ end_time = Time.now
11
20
 
12
21
  # Send email report
13
- mail = Mail.new
22
+ mail = MailBuilder.new("#{File.dirname(__FILE__)}/../email/report").build({:backups => backups, :start_time => start_time, :end_time => end_time})
14
23
  mail.to to
15
24
  mail.from from
16
25
  mail.subject "Backup report"
17
- mail.body %@
18
-
19
- We are runnig on: #{Socket.gethostname}
20
- Below is the output log.
21
-
22
- ----
23
- #{capture}
24
- ----@
25
-
26
26
  mail.delivery_method.settings = mail.delivery_method.settings.merge(mail_options)
27
27
  mail.deliver!
28
28
 
29
+ puts "Sent backup report to: #{to}"
30
+
29
31
  end
30
32
 
31
33
  end
data/lib/keepitsafe.rb CHANGED
@@ -156,45 +156,84 @@ class Keepitsafe
156
156
  end
157
157
 
158
158
  def check_disk_left limit = 1000
159
- disk_free_on_root = run_cmd('df -ha').match(/^(.*)\/$/)[0].scan(/([0-9MG\.%]{2,10})/)[2].join("")
160
- if disk_free_on_root.match(/g$/i)
161
- disk_free_on_root = disk_free_on_root.match(/(\d*)/)[1].to_i * 1000
162
- elsif disk_free_on_root.match(/t$/i)
163
- disk_free_on_root = disk_free_on_root.match(/(\d*)/)[1].to_i * 1000 * 1000
164
- end
165
159
 
166
- raise "root disk limit reached limit:#{limit} disk_free_on_root:#{disk_free_on_root}" if disk_free_on_root < limit
160
+ free = free_disk_space
167
161
 
162
+ raise "root disk limit reached limit:#{limit} disk_free_on_root:#{free}" if free < limit
168
163
  end
169
164
 
165
+
166
+
170
167
  def on_localhost?
171
168
  @server_domain == "localhost"
172
169
  end
173
170
 
171
+ attr_accessor :start_time, :end_time, :log_buffer, :error, :free_before, :free_after, :backup_size
172
+
173
+ def set_backup_size remote_path
174
+
175
+ raw = run_cmd("du -hc #{remote_path}").gsub("\n",' ').gsub("\t",' ').strip.match(/([0-9kmgt.]{2,10})\s*total/i)[1]
176
+ @backup_size = raw_to_meg(raw)
177
+ end
178
+
174
179
  private
175
180
 
181
+ def create_backups_dir
182
+ puts run_cmd "mkdir -p ~/backups/"
183
+ end
184
+
185
+ def free_disk_space
186
+ disk_free_on_root = run_cmd('df -ha ~/backups/').scan(/([0-9MGT\.%]{2,10})/)[2].join("")
187
+
188
+ disk_free_on_root = raw_to_meg(disk_free_on_root)
189
+
190
+ disk_free_on_root.to_i
191
+ end
192
+
193
+ def raw_to_meg raw
194
+ if raw.match(/t$/i)
195
+ raw = raw.match(/(\d*)/)[1].to_f * 1000 * 1000
196
+ elsif raw.match(/g$/i)
197
+ raw = raw.match(/(\d*)/)[1].to_f * 1000
198
+ elsif raw.match(/k$/i)
199
+ raw = raw.match(/(\d*)/)[1].to_f / 1000
200
+ else
201
+ raw = raw.match(/(\d*)/)[1].to_i
202
+ end
203
+ end
204
+
176
205
  def do_the_stuff
177
206
  @log_buffer = StringIO.new
178
207
 
179
- STDCapture.capture(@log_buffer) do
180
- begin
181
-
182
- check_disk_left
183
- create_backup_target_dir
184
- create_pending_file
208
+ @start_time = Time.now
209
+ create_backups_dir
210
+ @free_before = free_disk_space
211
+ trigger('before_backup')
212
+
213
+ begin
214
+ STDCapture.capture(@log_buffer) do
215
+ check_disk_left
216
+ create_backup_target_dir
217
+ create_pending_file
185
218
 
186
- yield self
187
-
188
- remove_pending_file
189
- rescue StandardError => e
190
- puts e.inspect
191
- puts e.backtrace
219
+ yield self
192
220
 
193
- trigger('on_error',{:error => e})
221
+ remove_pending_file
194
222
  end
223
+ rescue StandardError => e
224
+ @error = e
225
+ puts e.inspect
226
+ puts e.backtrace
227
+
228
+ trigger('on_error',{:error => e})
195
229
  end
196
230
 
197
231
  upload_log
232
+
233
+ @end_time = Time.now
234
+ @free_after = free_disk_space
235
+ set_backup_size(backup_target_dir) unless @backup_size
236
+ trigger('after_backup')
198
237
  end
199
238
 
200
239
  end
data/lib/plugins/tar.rb CHANGED
@@ -26,6 +26,8 @@ module BackupPlugins
26
26
  puts "\n\tRemoving backup dir"
27
27
  puts run_cmd "rm -rf #{backup_target_dir}"
28
28
  end
29
+
30
+ set_backup_size(tar_gz_path)
29
31
  end
30
32
 
31
33
  private
data/todo.txt ADDED
@@ -0,0 +1,4 @@
1
+
2
+ - Add a stdout/stderr log to a file on the server to be able to debug problems
3
+ - Add localhost detection, that means detect if a domain is actually localhost so that things like downloading
4
+ doesn't have the strange effect of over writing the file its downloading.
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: keepitsafe
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.10
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Darwin
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-01-20 00:00:00 Z
13
+ date: 2012-03-05 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -79,8 +79,19 @@ dependencies:
79
79
  prerelease: false
80
80
  version_requirements: *id006
81
81
  - !ruby/object:Gem::Dependency
82
- name: rspec
82
+ name: mailbuilder
83
83
  requirement: &id007 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: *id007
92
+ - !ruby/object:Gem::Dependency
93
+ name: rspec
94
+ requirement: &id008 !ruby/object:Gem::Requirement
84
95
  none: false
85
96
  requirements:
86
97
  - - ~>
@@ -88,10 +99,10 @@ dependencies:
88
99
  version: 2.3.0
89
100
  type: :development
90
101
  prerelease: false
91
- version_requirements: *id007
102
+ version_requirements: *id008
92
103
  - !ruby/object:Gem::Dependency
93
104
  name: cucumber
94
- requirement: &id008 !ruby/object:Gem::Requirement
105
+ requirement: &id009 !ruby/object:Gem::Requirement
95
106
  none: false
96
107
  requirements:
97
108
  - - ">="
@@ -99,10 +110,10 @@ dependencies:
99
110
  version: "0"
100
111
  type: :development
101
112
  prerelease: false
102
- version_requirements: *id008
113
+ version_requirements: *id009
103
114
  - !ruby/object:Gem::Dependency
104
115
  name: bundler
105
- requirement: &id009 !ruby/object:Gem::Requirement
116
+ requirement: &id010 !ruby/object:Gem::Requirement
106
117
  none: false
107
118
  requirements:
108
119
  - - ~>
@@ -110,10 +121,10 @@ dependencies:
110
121
  version: 1.0.0
111
122
  type: :development
112
123
  prerelease: false
113
- version_requirements: *id009
124
+ version_requirements: *id010
114
125
  - !ruby/object:Gem::Dependency
115
126
  name: jeweler
116
- requirement: &id010 !ruby/object:Gem::Requirement
127
+ requirement: &id011 !ruby/object:Gem::Requirement
117
128
  none: false
118
129
  requirements:
119
130
  - - ~>
@@ -121,7 +132,7 @@ dependencies:
121
132
  version: 1.6.4
122
133
  type: :development
123
134
  prerelease: false
124
- version_requirements: *id010
135
+ version_requirements: *id011
125
136
  description: A Gem for simple creation of backup scripts
126
137
  email: darwin.git@marianna.se
127
138
  executables: []
@@ -140,6 +151,8 @@ files:
140
151
  - README.rdoc
141
152
  - Rakefile
142
153
  - VERSION
154
+ - email/report/report.html.erb
155
+ - example/localhost.rb
143
156
  - example/server.com.rb
144
157
  - features/keepitsafe.feature
145
158
  - features/step_definitions/keepitsafe_steps.rb
@@ -160,6 +173,7 @@ files:
160
173
  - lib/stdcapture.rb
161
174
  - spec/keepitsafe_spec.rb
162
175
  - spec/spec_helper.rb
176
+ - todo.txt
163
177
  homepage: http://github.com/bjornblomqvist/keepitsafe
164
178
  licenses:
165
179
  - MIT
@@ -173,7 +187,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
187
  requirements:
174
188
  - - ">="
175
189
  - !ruby/object:Gem::Version
176
- hash: -880363802644508244
190
+ hash: -719854199361266435
177
191
  segments:
178
192
  - 0
179
193
  version: "0"