SHARE
TWEET

Untitled

a guest Oct 20th, 2019 75 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env ruby
  2.  
  3. # Cleans up backup files transferred to a remote directory.
  4. # Place this file in the root of your backup account and it will clean up all
  5. # subdirectories. You may prevent or customize action by a config file.
  6.  
  7. class Directory
  8.  
  9.   # The script will keep 24 hourly backups by default. So up to 24 files will
  10.   # be kept that get stored on the server within one day.
  11.   # After that, the latest of the hourly backups will be kept as daily backup.
  12.   # 7 daily backups will be kept and on the 8th day, the backup of the 7th day
  13.   # will be kept as backup for the week.
  14.   # Same logic applies to weekly and monthly backups.
  15.  
  16.   CONFIG = {
  17.     'hourly'  => 24, # Number of hourly backups to keep
  18.     'daily'   =>  7, # Number of daily backups to keep
  19.     'weekly'  =>  4, # Number of weekly backups to keep
  20.     'monthly' =>  6, # Number of monthly backups to keep
  21.     'forever' =>  5, # Number of backups to keep forever
  22.     'pattern' => '*.tar.gz', # Pattern to find files
  23.     'cleanup' => 'yes' # To prevent action, set 'no' (will affect all subdirs)
  24.   }
  25.  
  26.   # Each default can be overwritten in a file .bakrm like this:
  27.   # hourly: 4
  28.   # daily: 2
  29.   # weekly: 0
  30.   # monthly: 0
  31.   # forever: 4
  32.  
  33.   CONFIG_FILE = '.bakrm'
  34.  
  35.   def initialize(path)
  36.     @path = path
  37.   end
  38.  
  39.   # Returns folders
  40.   def folders
  41.     @folders ||= Dir.chdir(@path) do
  42.       Dir.glob('*').
  43.         select { |f| File.directory?(f) }.
  44.         map { |f| File.join(@path, f) }
  45.     end
  46.   end
  47.  
  48.   # Returns files, sorted by date
  49.   def files
  50.     @files ||= Dir.chdir(@path) do
  51.       Dir[pattern].
  52.         reject { |f| %[bakrm.rb #{CONFIG_FILE}].include?(f) }.
  53.         select { |f| File.file?(f) }.
  54.         sort_by { |f| File.mtime(f) }.
  55.         map { |f| File.join(@path, f) }.
  56.         reverse
  57.     end
  58.   end
  59.  
  60.   def reload_files
  61.     @files = nil
  62.     files
  63.   end
  64.  
  65.   # Returns config
  66.   def config
  67.     @config ||= begin
  68.       path = File.join(@path, CONFIG_FILE)
  69.       if File.exists?(path)
  70.         text = File.read(path)
  71.         values = text.scan(/(.+):\s*(.+)/)
  72.         Hash[values]
  73.       end
  74.     end
  75.   end
  76.  
  77.   def cleanup
  78.     if cleanup?
  79.       cleanup_files
  80.       cleanup_folders
  81.     end
  82.   end
  83.  
  84.   private
  85.  
  86.   def cleanup_files
  87.     reject_empty_files
  88.     keep = keep_files
  89.     delete = reload_files - keep
  90.     # puts "keep: #{keep.count}; delete: #{delete.count}"
  91.     delete.each { |f| File.delete(f) }
  92.   end
  93.  
  94.   def cleanup_folders
  95.     folders.each do |dir|
  96.       Directory.new(dir).cleanup
  97.     end
  98.   end
  99.  
  100.   def config_value(key)
  101.     value = config && config[key]
  102.     value || CONFIG[key]
  103.   end
  104.  
  105.   def cleanup?
  106.     config_value('cleanup') == 'yes'
  107.   end
  108.  
  109.   def pattern
  110.     config_value('pattern')
  111.   end
  112.  
  113.   def hourly
  114.     config_value('hourly').to_i
  115.   end
  116.  
  117.   def daily
  118.     config_value('daily').to_i
  119.   end
  120.  
  121.   def weekly
  122.     config_value('weekly').to_i
  123.   end
  124.  
  125.   def monthly
  126.     config_value('monthly').to_i
  127.   end
  128.  
  129.   def forever
  130.     config_value('forever')
  131.   end
  132.  
  133.   def keep_files
  134.     keep = []
  135.     keep += hourly_files if hourly > 0
  136.     keep += daily_files if daily > 0
  137.     keep += weekly_files if weekly > 0
  138.     keep += monthly_files if monthly > 0
  139.     keep.uniq!
  140.     if keep.length < forever
  141.       if files.length < forever
  142.         keep = files
  143.       else
  144.         keep = files[0, forever]
  145.       end
  146.     end
  147.     keep
  148.   end
  149.  
  150.   def hourly_files
  151.     pick_files(hourly, 3600)
  152.   end
  153.  
  154.   def daily_files
  155.     pick_files(daily, 3600*24)
  156.   end
  157.  
  158.   def weekly_files
  159.     pick_files(weekly, 3600*24*7)
  160.   end
  161.  
  162.   def monthly_files
  163.     pick_files(monthly, 3600*24*30)
  164.   end
  165.  
  166.   # Remove empty files from list
  167.   def reject_empty_files
  168.     files.reject! { |f| File.size(f) == 0 }
  169.   end
  170.  
  171.   # Pick files matching given time interval.
  172.   def pick_files(counter, increment)
  173.     picked = []
  174.     range_start = now
  175.     counter.times do
  176.       range_end = range_start - increment
  177.       files.each do |f|
  178.         mtime = File.mtime(f)
  179.         if mtime < range_start && mtime >= range_end
  180.           picked << f
  181.           break
  182.         end
  183.       end
  184.       range_start = range_end
  185.     end
  186.     picked
  187.   end
  188.  
  189.   def now
  190.     @now ||= Time.now
  191.   end
  192. end
  193.  
  194. def run
  195.   Directory.new(Dir.pwd).cleanup
  196. end
  197.  
  198. run
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top