Skip to content

Instantly share code, notes, and snippets.

@dinhani
Last active March 21, 2024 20:01
Show Gist options
  • Save dinhani/465baab2c01246eea6a03d06bdf9f250 to your computer and use it in GitHub Desktop.
Save dinhani/465baab2c01246eea6a03d06bdf9f250 to your computer and use it in GitHub Desktop.
Watch saves folder or files and backup them on changes
# ------------------------------------------------------------------------------
# imports
# ------------------------------------------------------------------------------
from datetime import datetime
import glob
import ntpath
import os
import sys
import shutil
import time
# ------------------------------------------------------------------------------
# constants
# ------------------------------------------------------------------------------
SAVES = [
"C:/Users/Renato/AppData/Roaming/EldenRing"
]
BACKUP_FOLDER = "E:/jogos/PC/Saves/Elden Ring/Backups/"
BACKUP_MAX = 500
BACKUP_CHECK_INTERVAL_IN_SECS = 60
# ------------------------------------------------------------------------------
# functions - backup
# ------------------------------------------------------------------------------
def backup_if_necessary(filename, last_change):
current_change = last_change
try:
current_change = read_change_time(filename)
if should_backup(current_change, last_change):
execute_backup(filename)
execute_delete_old_backups()
except Exception as e:
line = sys.exc_info()[2].tb_lineno
print("Error at " + str(line) + ": " + str(e))
return current_change
def read_change_time(filename):
# if file, read the change time from the file
# if directory, iterate the entire tree and find the most recent change of all files
if os.path.isfile(filename):
return os.path.getmtime(filename)
else:
most_recent_change = 0
for root, _, files in os.walk(filename):
for file in files:
filename = os.path.join(root, file)
filename_change = read_change_time(filename)
if filename_change > most_recent_change:
most_recent_change = filename_change
return most_recent_change
def should_backup(current_change, last_change):
return current_change != last_change
# ------------------------------------------------------------------------------
# functions - backup
# ------------------------------------------------------------------------------
def execute_backup(filename):
backup_filename = generate_backup_filename(filename)
copy_file(filename, backup_filename)
def generate_backup_filename(filename):
filename = ntpath.basename(filename)
backup_filename = os.path.join(BACKUP_FOLDER, "{}--{}".format(datetime.today().strftime("%Y%m%d_%H%M%S"), filename))
return backup_filename
def copy_file(source_filename, target_filename):
print("")
print(datetime.now().strftime("%H:%M:%S"))
print("{} = {}".format("SOURCE", source_filename))
print("{} = {}".format("BACKUP", target_filename))
if os.path.isfile(source_filename):
shutil.copyfile(source_filename, target_filename)
else:
shutil.copytree(source_filename, target_filename)
# ------------------------------------------------------------------------------
# functions - delete old backups
# ------------------------------------------------------------------------------
def execute_delete_old_backups():
backups_to_delete = get_backups_to_delete()
for backup_to_delete in backups_to_delete:
delete_file(backup_to_delete)
def get_backups_to_delete():
backup_glob = BACKUP_FOLDER + "**--**"
backups = sorted(glob.glob(backup_glob), reverse=True)
if len(backups) > BACKUP_MAX:
return backups[BACKUP_MAX:len(backups)]
else:
return []
def delete_file(filename):
print("DELETE = " + filename)
if os.path.isfile(filename):
os.remove(filename)
else:
shutil.rmtree(filename)
# ==============================================================================
# main
# ==============================================================================
# init last change
saves_last_change = []
for i, save in enumerate(SAVES):
print("WATCH = " + save)
saves_last_change.append(None)
# create backup dir
if not os.path.exists(BACKUP_FOLDER):
os.makedirs(BACKUP_FOLDER)
# keep checking if save changed
while True:
for i, save in enumerate(SAVES):
save_last_change = saves_last_change[i]
saves_last_change[i] = backup_if_necessary(save, save_last_change)
# wait for next check
time.sleep(BACKUP_CHECK_INTERVAL_IN_SECS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment