paparazzi 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -39,14 +39,14 @@ Create a ruby script that you'll run hourly from a cron.
39
39
  Available Settings
40
40
  ------------------
41
41
 
42
- * `:source` : **required** The source folder to be backed up. Trailing '/' recommended. See rsync manpage
42
+ * `:source` **required** The source folder to be backed up. Trailing '/' recommended. See rsync manpage
43
43
  for explanation of trailing '/'
44
- * `:destination` : **required** The destination folder for backups to be written to, preferably on a different
44
+ * `:destination` **required** The destination folder for backups to be written to, preferably on a different
45
45
  physical drive.
46
- * `:reserves` : A hash of snapshot intervals and number of snapshots of each to keep before purging.
47
- default: {:hourly => 24, :daily => 7, :weekly => 5, :monthly => 12, :yearly => 9999}
48
- * `:rsync_flags` : additional flags to pass to rsync. Paparazzi uses -aq, --delete, & --link_dest, plus
49
- whatever you add. The author suggests considering -L and --exclude.
46
+ * `:intervals` A hash of snapshot intervals and number of snapshots of each to keep before purging.
47
+ default: `{:hourly => 24, :daily => 7, :weekly => 5, :monthly => 12, :yearly => 9999}`
48
+ * `:rsync_flags` Additional flags to pass to rsync. Paparazzi uses `-aq`, `--delete`, & `--link_dest`, plus
49
+ whatever you add. The author suggests considering `-L` and `--exclude`.
50
50
 
51
51
 
52
52
  Supported Operating Systems
@@ -8,7 +8,7 @@ module Paparazzi
8
8
  REQUIRED_SETTINGS = [:source,:destination]
9
9
 
10
10
  class << self
11
- attr_accessor :source, :destination, :rsync_flags, :reserves
11
+ attr_accessor :source, :destination, :rsync_flags, :intervals
12
12
 
13
13
  def trigger(settings = {})
14
14
  validate_and_cache_settings(settings)
@@ -25,7 +25,7 @@ module Paparazzi
25
25
  #######
26
26
 
27
27
  def validate_and_cache_settings(settings)
28
- [:source,:destination,:rsync_flags,:reserves].each do |setting_name|
28
+ [:source,:destination,:rsync_flags,:intervals,:reserves].each do |setting_name|
29
29
  if REQUIRED_SETTINGS.include?(setting_name) and settings[setting_name].nil?
30
30
  raise MissingSettingError, "#{setting_name} is required"
31
31
  else
@@ -42,21 +42,21 @@ module Paparazzi
42
42
 
43
43
  def setup
44
44
  @previous_snapshot_name = {}
45
- frequencies.each do |frequency|
46
- Dir.mkdir(destination(frequency)) unless File.exists?(destination(frequency)) && File.directory?(destination(frequency))
45
+ interval_names.each do |interval_name|
46
+ Dir.mkdir(destination(interval_name)) unless File.exists?(destination(interval_name)) && File.directory?(destination(interval_name))
47
47
 
48
- full_path = Dir[destination(frequency)+'/*'].sort{|a,b| File.ctime(b) <=> File.ctime(a) }.first
49
- @previous_snapshot_name[frequency] = full_path ? File.basename(full_path) : ''
48
+ full_path = Dir[destination(interval_name)+'/*'].sort{|a,b| File.ctime(b) <=> File.ctime(a) }.first
49
+ @previous_snapshot_name[interval_name] = full_path ? File.basename(full_path) : ''
50
50
  end
51
51
 
52
- if @previous_snapshot_name[frequencies.first] != last_successful_snapshot and !last_successful_snapshot.nil? and File.exists?(destination(frequencies.first) + '/' + last_successful_snapshot)
53
- File.rename(previous_snapshot(frequencies.first), current_snapshot(frequencies.first))
54
- @previous_snapshot_name[frequencies.first] = last_successful_snapshot
52
+ if @previous_snapshot_name[interval_names.first] != last_successful_snapshot and !last_successful_snapshot.nil? and File.exists?(destination(interval_names.first) + '/' + last_successful_snapshot)
53
+ File.rename(previous_snapshot(interval_names.first), current_snapshot(interval_names.first))
54
+ @previous_snapshot_name[interval_names.first] = last_successful_snapshot
55
55
  end
56
56
  end
57
57
 
58
- def destination(frequency = nil)
59
- frequency.nil? ? @destination : "#{@destination}/#{frequency}"
58
+ def destination(interval_name = nil)
59
+ interval_name.nil? ? @destination : "#{@destination}/#{interval_name}"
60
60
  end
61
61
 
62
62
  def last_successful_snapshot
@@ -70,35 +70,34 @@ module Paparazzi
70
70
  end
71
71
 
72
72
  def purge_old_snapshots
73
- frequencies.each do |frequency|
74
- #raise RuntimeError, frequency if reserves[frequency].nil?
75
- while Dir[destination(frequency)+'/*'].size > (reserves[frequency]-1)
76
- full_path = Dir[destination(frequency)+'/*'].sort{|a,b| File.ctime(a) <=> File.ctime(b) }.first
73
+ interval_names.each do |interval_name|
74
+ while Dir[destination(interval_name)+'/*'].size > (intervals[interval_name]-1)
75
+ full_path = Dir[destination(interval_name)+'/*'].sort{|a,b| File.ctime(a) <=> File.ctime(b) }.first
77
76
  FileUtils.rm_rf(full_path)
78
77
  end
79
78
  end
80
79
  end
81
80
 
82
81
  def make_snapshots
83
- frequencies.each do |frequency|
84
- Dir.mkdir(current_snapshot(frequency)) unless File.exists?(current_snapshot(frequency))
85
- if frequency == frequencies.first and previous_snapshot_name(frequency) == ''
86
- system 'rsync', *(['-aq', '--delete'] + rsync_flags + [source, current_snapshot(frequency)])
87
- self.last_successful_snapshot = current_snapshot_name(frequency)
88
- elsif previous_snapshot_name(frequency) != current_snapshot_name(frequency)
89
- system 'rsync', *(['-aq', '--delete', "--link-dest=#{link_destination(frequency)}"] + rsync_flags + [source, current_snapshot(frequency)])
90
- self.last_successful_snapshot = current_snapshot_name(frequencies.first)
82
+ interval_names.each do |interval_name|
83
+ Dir.mkdir(current_snapshot(interval_name)) unless File.exists?(current_snapshot(interval_name))
84
+ if interval_name == interval_names.first and previous_snapshot_name(interval_name) == ''
85
+ system 'rsync', *(['-aq', '--delete'] + rsync_flags + [source, current_snapshot(interval_name)])
86
+ self.last_successful_snapshot = current_snapshot_name(interval_name)
87
+ elsif previous_snapshot_name(interval_name) != current_snapshot_name(interval_name)
88
+ system 'rsync', *(['-aq', '--delete', "--link-dest=#{link_destination(interval_name)}"] + rsync_flags + [source, current_snapshot(interval_name)])
89
+ self.last_successful_snapshot = current_snapshot_name(interval_names.first)
91
90
  end
92
91
  end
93
92
  end
94
93
 
95
- def current_snapshot(frequency)
96
- destination(frequency) + '/' + current_snapshot_name(frequency)
94
+ def current_snapshot(interval_name)
95
+ destination(interval_name) + '/' + current_snapshot_name(interval_name)
97
96
  end
98
97
 
99
- def current_snapshot_name(frequency)
98
+ def current_snapshot_name(interval_name)
100
99
  @start_time ||= Time.now #lock in time so that all results stay consistent over long runs
101
- case frequency
100
+ case interval_name
102
101
  when :hourly then @start_time.strftime('%Y-%m-%d.%H')
103
102
  when :daily then @start_time.strftime('%Y-%m-%d')
104
103
  when :weekly then sprintf("%04d-%02d-week-%02d", @start_time.year, @start_time.month, (@start_time.day/7))
@@ -107,28 +106,35 @@ module Paparazzi
107
106
  end
108
107
  end
109
108
 
110
- def previous_snapshot(frequency)
111
- destination(frequency) + '/' + previous_snapshot_name(frequency)
109
+ def previous_snapshot(interval_name)
110
+ destination(interval_name) + '/' + previous_snapshot_name(interval_name)
112
111
  end
113
112
 
114
- def previous_snapshot_name(frequency)
115
- @previous_snapshot_name[frequency]
113
+ def previous_snapshot_name(interval_name)
114
+ @previous_snapshot_name[interval_name]
116
115
  end
117
116
 
118
- def link_destination(frequency)
119
- frequency == frequencies.first ? "../#{previous_snapshot_name(frequencies.first)}" : "../../#{frequencies.first}/#{current_snapshot_name(frequencies.first)}"
117
+ def link_destination(interval_name)
118
+ interval_name == interval_names.first ? "../#{previous_snapshot_name(interval_names.first)}" : "../../#{interval_names.first}/#{current_snapshot_name(interval_names.first)}"
120
119
  end
121
120
 
122
- def reserves
123
- @reserves ||= {:hourly => 24, :daily => 7, :weekly => 5, :monthly => 12, :yearly => 9999}
121
+ def intervals
122
+ @intervals ||= {:hourly => 24, :daily => 7, :weekly => 5, :monthly => 12, :yearly => 9999}
124
123
  end
125
124
 
126
- def frequencies
127
- reserves.keys.select{ |key| reserves[key] > 0 }.sort{ |a,b|
125
+ def interval_names
126
+ intervals.keys.select{ |key| intervals[key] > 0 }.sort{ |a,b|
128
127
  [:hourly,:daily,:weekly,:monthly,:yearly].find_index(a) <=> [:hourly,:daily,:weekly,:monthly,:yearly].find_index(b)
129
128
  }
130
129
  end
131
130
 
131
+ # provide backwards compatability with silly setting name
132
+ def reserves=(x)
133
+ if x.is_a?(Hash)
134
+ $stderr.puts ':reserves is deprecated. Please use :intervals instead.'
135
+ self.intervals=x
136
+ end
137
+ end
132
138
  end
133
139
  end
134
140
 
@@ -1,3 +1,3 @@
1
1
  module Paparazzi
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
@@ -107,11 +107,24 @@ class CameraTest < Test::Unit::TestCase
107
107
 
108
108
  def test_should_not_make_un_requested_frequency_snapshots
109
109
  my_settings = default_test_settings
110
- my_settings[:reserves][:hourly] = 0
110
+ my_settings[:intervals][:hourly] = 0
111
111
  Paparazzi::Camera.trigger(my_settings)
112
112
  assert(!File.exists?("#{destination}/hourly"))
113
113
  end
114
114
 
115
+ def test_should_be_backwards_compatible_with_deprecated_config_option
116
+ original_stderr, $stderr = $stderr, StringIO.new
117
+ my_settings = default_test_settings
118
+ my_settings[:reserves] = my_settings[:intervals]
119
+ my_settings[:reserves][:hourly] = 1
120
+ my_settings.delete(:intervals)
121
+ Paparazzi::Camera.trigger(my_settings)
122
+ assert_equal(my_settings[:reserves],Paparazzi::Camera.instance_variable_get('@intervals'))
123
+ assert_equal(':reserves is deprecated. Please use :intervals instead.',$stderr.string.chomp)
124
+ ensure
125
+ $stderr = original_stderr
126
+ end
127
+
115
128
  #######
116
129
  private
117
130
  #######
@@ -124,7 +137,7 @@ class CameraTest < Test::Unit::TestCase
124
137
  {
125
138
  :source => "#{File.expand_path('../../source', __FILE__)}/",
126
139
  :destination => destination,
127
- :reserves => {:hourly => 24, :daily => 7, :weekly => 5, :monthly => 12, :yearly => 9999},
140
+ :intervals => {:hourly => 24, :daily => 7, :weekly => 5, :monthly => 12, :yearly => 9999},
128
141
  :rsync_flags => '-L --exclude test.exclude'
129
142
 
130
143
  }
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 0
9
- version: 0.2.0
8
+ - 1
9
+ version: 0.2.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jonathan S. Garvin
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-05-23 00:00:00 -06:00
17
+ date: 2011-05-28 00:00:00 -06:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency