Advertisement
M3rein

Automatic Backup System

Oct 29th, 2017
1,483
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 6.88 KB | None | 0 0
  1. #==============================================================================#
  2. #                           Automatic Backup System                            #
  3. #                                  by Marin                                    #
  4. #                                 Version 1.1                                  #
  5. #==============================================================================#
  6. # You can manually make a backup by calling this method.
  7. # In an event this would be :
  8. # Script: backup
  9. def backup(forced = true)
  10.   BackupHandler.new(forced) { |txt| Win32API.SetWindowText(_INTL(txt)) }
  11. end
  12.  
  13. class BackupHandler
  14.   # This is the folder the backup will be made in. This can be relative
  15.   # (in the folder itself), or a full path (C:\Users\....\Desktop)
  16.   # If the LAST FOLDER does not exist, it will be created. The rest has to be
  17.   # existent and valid.
  18.   # Examples:
  19.   # BACKUP_TO = "C:/Users/MyUser/Desktop/MyBackupFolder"
  20.   # BACKUP_TO = "Game Backups"
  21.   BACKUP_TO = "Backups"
  22.  
  23.   # Whatever is in this array will determine what will be backed up whenever a
  24.   # backup is being made.
  25.   # Possible values:
  26.   # :MAPS
  27.   # :SCRIPTS
  28.   # :PBS
  29.   # :GRAPHICS_PICTURES
  30.   # :GRAPHICS_AUTOTILES
  31.   # :GRAPHICS_TILESETS
  32.  
  33.   # The following can be used too, but they may cause a bit of delay.
  34.   # :AUDIO_BGM
  35.   # :AUDIO_BGS
  36.   # :AUDIO_ME
  37.  
  38.   # The following can be used too, but they will likely cause a lot of lag and
  39.   # have the potential to crash the game (this does not/should not have any
  40.   # consequences; it will just mean the backup failed (Script is hanging))
  41.   # If it does hang, it has likely still properly copied all Icon/AudioSE files.
  42.   # These two are done last, meaning that all other backups will have been
  43.   # successfully made.
  44.   # :AUDIO_SE
  45.   # :ICONS
  46.  
  47.   SHOULD_BACKUP = [
  48.     :MAPS,
  49.     :SCRIPTS,
  50.     :PBS,
  51.     :AUDIO_BGM,
  52.     :AUDIO_BGS,
  53.     :AUDIO_ME,
  54.     :AUDIO_SE,
  55.     :GRAPHICS_PICTURES,
  56.     :GRAPHICS_AUTOTILES,
  57.     :GRAPHICS_TILESETS,
  58.     :ICONS
  59.   ]
  60.  
  61.   def initialize(forced)
  62.     return if !$DEBUG
  63.     @path = BACKUP_TO
  64.     @make_backup = shouldBackup
  65.     @make_backup = true if forced
  66.     if @make_backup
  67.       yield _INTL("Clearing old backup folders...")
  68.       empty("Data")
  69.       empty("PBS")
  70.       empty("Audio")
  71.       empty("Graphics")
  72.       if SHOULD_BACKUP.include?(:SCRIPTS)
  73.         yield _INTL("Creating backups of Data/Scripts.rxdata...")
  74.         backupScripts
  75.       end
  76.       if SHOULD_BACKUP.include?(:MAPS)
  77.         yield _INTL("Creating backups of Data/MapXXX.rxdata...")
  78.         backupMaps
  79.       end
  80.       if SHOULD_BACKUP.include?(:PBS)
  81.         yield _INTL("Creating backups of PBS...")
  82.         backupPBS
  83.       end
  84.       if SHOULD_BACKUP.include?(:AUDIO_BGM)
  85.         yield _INTL("Creating backups of Audio/BGM...")
  86.         backupRec("Audio", "BGM")
  87.       end
  88.       if SHOULD_BACKUP.include?(:AUDIO_BGS)
  89.         yield _INTL("Creating backups of Audio/BGS...")
  90.         backupRec("Audio", "BGS")
  91.       end
  92.       if SHOULD_BACKUP.include?(:AUDIO_ME)
  93.         yield _INTL("Creating backups of Audio/ME...")
  94.         backupRec("Audio", "ME")
  95.       end
  96.       if SHOULD_BACKUP.include?(:AUDIO_SE)
  97.         yield _INTL("Creating backups of Audio/SE...")
  98.         backupRec("Audio", "SE")
  99.       end
  100.       if SHOULD_BACKUP.include?(:GRAPHICS_PICTURES)
  101.         yield _INTL("Creating backups of Graphics/Pictures...")
  102.         backupRec("Graphics", "Pictures")
  103.       end
  104.       if SHOULD_BACKUP.include?(:GRAPHICS_AUTOTILES)
  105.         yield _INTL("Creating backups of Graphics/Autotiles...")
  106.         backupRec("Graphics", "Autotiles")
  107.       end
  108.       if SHOULD_BACKUP.include?(:GRAPHICS_TILESETS)
  109.         yield _INTL("Creating backups of Graphics/Tilesets...")
  110.         backupRec("Graphics", "Tilesets")
  111.       end
  112.       if SHOULD_BACKUP.include?(:ICONS)
  113.         yield _INTL("Creating backups of Graphics/Icons...")
  114.         backupRec("Graphics", "Icons")
  115.       end
  116.     end
  117.   end  
  118.  
  119.   def backupScripts
  120.     copy("Data/Scripts.rxdata", @path+"/Data/Scripts.rxdata")
  121.   end
  122.  
  123.   def backupMaps
  124.     Dir.foreach("Data") do |f|
  125.       next if f == '.' || f == '..'
  126.       if f[0..2] == 'Map' # Including MapInfos.rxdata as well
  127.         copy("Data/#{f}", @path+"/Data/#{f}")
  128.       end
  129.     end
  130.   end
  131.  
  132.   def backupPBS
  133.     Dir.foreach("PBS") do |f|
  134.       next if f == '.' || f == '..'
  135.       copy("PBS/#{f}", @path+"/PBS/#{f}")
  136.     end
  137.   end
  138.  
  139.   # Recursive and dynamic
  140.   def backupRec(one, two)
  141.     return false if !File.directory?(one)
  142.     if !File.directory?(@path+"/"+one)
  143.       Dir.mkdir(@path+"/"+one)
  144.     end
  145.     empty(one+"/"+two)
  146.     Dir.glob("#{one}/#{two}/**/*") do |f|
  147.       next if !File.directory?(f)
  148.       if !File.directory?("#{@path}/#{f}")
  149.         Dir.mkdir("#{@path}/#{f}")
  150.       end
  151.     end
  152.     Dir.glob("#{one}/#{two}/**/*") do |f|
  153.       next if File.directory?(f)
  154.       copy(f, "#{@path}/#{f}")
  155.     end
  156.   end
  157.  
  158.   # Determines if it should update again
  159.   def shouldBackup
  160.     ret = false
  161.     ensureExists
  162.     if !File.file?(@path+"/last.txt")
  163.       f = File.open(@path+"/last.txt", "w")
  164.       f.write(getTime)
  165.       f.close
  166.       ret = true
  167.     else
  168.       f = File.open(@path+"/last.txt")
  169.       d = f.read
  170.       f.close
  171.       old = d.split('-').map { |e| e.to_i }
  172.       old.map
  173.       if old.size != 3
  174.         ret = false
  175.       else
  176.         new = getTime.split('-').map { |e| e.to_i }
  177.         ret = (new[2] > old[2] || new[1] > old[1] || new[0] > old[0])
  178.       end
  179.       if ret
  180.         File.truncate(@path+"/last.txt", 0)
  181.         file = File.open(@path+"/last.txt", "w")
  182.         file.write(getTime)
  183.         file.close
  184.       end
  185.     end
  186.     return ret
  187.   end
  188.  
  189.   def getTime
  190.     t = Time.now
  191.     return "#{t.day}-#{t.month}-#{t.year.to_s[2..3]}"
  192.   end
  193.  
  194.   def ensureExists
  195.     if !File.directory?(@path)
  196.       Dir.mkdir(@path)
  197.     end
  198.   end
  199.  
  200.   def copy(src, dest)
  201.     File.open(src, 'rb') do |r|
  202.       File.open(dest, 'wb') do |w|
  203.         while s = r.read(4096)
  204.           w.write(s)
  205.         end
  206.       end
  207.     end
  208.   end
  209.  
  210.   def empty(path)
  211.     return if !File.directory?(path)
  212.     ensureExists
  213.     if !File.directory?("#{@path}/#{path}")
  214.       Dir.mkdir("#{@path}/#{path}")
  215.     else
  216.       recursiveDelete(@path+"/"+path) # Clear all files first
  217.       recursiveDelete(@path+"/"+path, true) # Then all empty directories
  218.     end
  219.   end
  220.  
  221.   def recursiveDelete(file, delete_dirs = false)
  222.     Dir.glob("#{file}/**/*") do |f|
  223.       if File.directory?(f)
  224.         if delete_dirs
  225.           if Dir.entries(f).size > 2
  226.             recursiveDelete(f, true)
  227.             Dir.delete(f) rescue nil
  228.           else
  229.             Dir.delete(f)
  230.           end
  231.         else
  232.           recursiveDelete(f, delete_dirs)
  233.         end
  234.       else
  235.         File.delete(f)
  236.       end
  237.     end
  238.   end
  239. end
  240.  
  241. backup(false) # Call the method; determines if it actually SHOULD backup inside the call
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement