diff --git a/.gitignore b/.gitignore index 8e4de46..4966f5c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ local_files/ +.ropeproject/ +__pycache__/ diff --git a/ftl-backup_script.py b/ftl-backup_script.py deleted file mode 100644 index 39d1f80..0000000 --- a/ftl-backup_script.py +++ /dev/null @@ -1,167 +0,0 @@ -import os -import time -from datetime import datetime - -version = 0.01 -settings_path = "local_files/settings.txt" # containes two lines, first path of game, second path of savelocation -backup_files = {"1": "initiating"} # initiating global variable to be used in functions. - -def menu(options, names): - """"Use dict to select an option (function).""" - print_menu(options, names) - while True: - choice = input("Selection Option: ") - if choice in options: - options[choice]() - print_menu(options, names) - else: - print("Try again") - continue - -def print_menu(options, names): - #print("\033[H\033[J", end="") - print("Menu options") - for key in options: - print(f"{key}: {names[key]}") - -def copy_file(src, dst): - """"Simply copies a file from a to b.""" - if not os.path.isfile(src): - print(f"File to copy {src} does not exist.") - return False - os.system(f"cp {src} {dst}") - print(f"Wrote: {dst}") - -def list_backup(): - """"List all files inside the backup folder.""" - files = os.listdir(backup_path) - files.reverse() # this way the newest file is the top one. - backup_files.clear() - i = 1 - for file in files: - new_item = {f"{i}": file} - print(f"[{i}] {file}") - backup_files.update(new_item) - i += 1 - -def backup(): - """Copies the game file to the backup folder and adds date-time stamp.""" - now = datetime.now() - formatted_now = now.strftime("%Y-%m-%d_%H-%M") - copy_file(f"{game_path}/continue.sav", f"{backup_path}/{formatted_now}.bkup") - time.sleep(1) - -def restore(): - """Copies a selected backup file to the game folder.""" - print("Select a file to restore (back [b]):") - list_backup() - while True: - choice = input("Enter number (b = back): ") - if choice in backup_files: - copy_file(f"{backup_path}/{backup_files[choice]}", f"{game_path}/continue.sav") - print(f"{backup_files[choice]} restored.") - time.sleep(1) - break - elif choice == "b": - break - else: - print("not a valid option") - continue - -def delete_backup_file(): - # Making a yes/no function would be cleaner - if yes_no("Backup"): - for file in os.listdir(backup_path): - if file[-5:] == ".bkup": - try: - print(f"Deleting {file}.") - os.remove(f"{backup_path}/{file}") - time.sleep(1) - except Exception as e: - print(f"Failed to delete {file}. Reason: {e}.") - time.sleep(3) - -def yes_no(str): - while True: - choice = input(f"Are you sure you want to delete all {str} files? (y/n)") - if choice == "y": - return 1 - elif choice == "n": - print(f"Deleting {str} files aborted") - time.sleep(1) - return 0 - else: - print("Not a valid option, try again") - -def read_settings(): - if os.path.exists(settings_path): - with open(settings_path, "r") as f: - data = f.readlines() - for i in range(len(data)): - data[i] = data[i].strip() #stripping white space - return(data) - else: - print("settings file does not exit.") - return 0 - -def ask_for_path(): - paths = ["game_path", "backup_path"] - - paths[0] = get_path("Absolut save path") - paths[1] = get_path("Backup path") - return(paths) - -def get_path(str): - while True: - path = input(f"please enter {str}: ") - if os.path.exists(path): - break - else: - print("Path not valid, try again.") - continue - return path - -def write_settings(list): - with open(settings_path, "w") as f: - for item in list: - f.write(item + "\n") - - print("write settings.") - -settings = read_settings() -if settings != False: - game_path = settings[0] - backup_path = settings[1] - if not os.path.exists(f"{game_path}/ae_prof.sav") and not os.path.exists(backup_path): - print("Path in settings file are incorrect.") - paths = ask_for_path() - game_path = paths[0] - backup_path = paths[1] - write_settings((game_path, backup_path)) -else: - paths = ask_for_path() - game_path = paths[0] - backup_path = paths[1] - write_settings((game_path, backup_path)) - -print(f"Game location: {game_path}.\nSave loction: {backup_path}\n") -time.sleep(1) - -menu_options = { - "b": backup, - "r": restore, - "d": delete_backup_file, - "q": exit -} -menu_names = { - "b": "Backup now", - "r": "Restore backup", - "d": "Delete backup files", - "q": "Exit" -} -menu(menu_options, menu_names) - - -# TODO -# Backup profile -# updater diff --git a/ftl-savemanager.py b/ftl-savemanager.py new file mode 100644 index 0000000..7aa2217 --- /dev/null +++ b/ftl-savemanager.py @@ -0,0 +1,178 @@ +import os +import time +from datetime import datetime + +class BackupApp: + """"Backup class, copy FTL continue file to backup location and restores it.""" + def __init__(self, settings_file_path): + self.version = 0.1 + self.backup_files = {"1": "initiating"} # initiating variable + self.settings_path = settings_file_path + self.settings = self.read_settings() + + if self.settings: + self.game_path = self.settings[0] + self.backup_path = self.settings[1] + else: + self.game_path, self.backup_path = self.ask_for_path() + self.write_settings([self.game_path, self.backup_path]) + + print(f"Game location: {self.game_path}.\nSave location: {self.backup_path}\n") + + def read_settings(self): + """Reading the settings file.""" + if os.path.exists(self.settings_path): + with open(self.settings_path, "r") as f: + data = f.readlines() + for i in range(len(data)): + data[i] = data[i].strip() #stripping white space + return(data) + else: + print("settings file does not exit.") + return 0 + + def ask_for_path(self): + """Uses get_path to request path from the user.""" + game_path = self.get_path("Game save path", 1) + backup_path = self.get_path("Backup path") + return(game_path, backup_path) + + def get_path(self, str, ftl = 0): + """Get path from user and check if exists.""" + while True: + path = input(f"please enter {str}: ") + if ftl: + profile_file = path + "/ae_prof.sav" + if os.path.isfile(profile_file): + return path + else: + print("Path is not valid, try again.") + continue + if os.path.exists(path): + return path + break + else: + print("Path not valid, try again.") + continue + return path + + def write_settings(self, list): + """Write the settings (path)""" + with open(self.settings_path, "w") as f: + for item in list: + f.write(item + "\n") + print("write settings.") + + def copy_file(self, src, dst): + """"Simply copies a file from a to b.""" + if not os.path.isfile(src): + print(f"File to copy {src} does not exist.") + return False + os.system(f"cp {src} {dst}") + print(f"Wrote: {dst}") + + def list_backup(self): + """"List all files inside the backup folder.""" + files = os.listdir(self.backup_path) + files.reverse() # this way the newest file is the top one. + self.backup_files.clear() + i = 1 + for file in files: + new_item = {f"{i}": file} + print(f"[{i}] {file}") + self.backup_files.update(new_item) + i += 1 + + def backup(self): + """Copies the game file to the backup folder and adds date-time stamp.""" + now = datetime.now() + formatted_now = now.strftime("%Y-%m-%d_%H-%M") + self.copy_file(f"{self.game_path}/continue.sav", f"{self.backup_path}/{formatted_now}.bkup") + time.sleep(1) + + def restore(self): + """Copies a selected backup file to the game folder and renames it.""" + print("Select a file to restore (back [b]):") + self.list_backup() + while True: + choice = input("Enter number (b = back): ") + if choice in self.backup_files: + self.copy_file(f"{self.backup_path}/{self.backup_files[choice]}", f"{self.game_path}/continue.sav") + print(f"{self.backup_files[choice]} restored.") + time.sleep(1) + break + elif choice == "b": + break + else: + print("not a valid option") + continue + + def delete_backup_file(self): + """Deltes all .bkup files in the backup folder.""" + # Making a yes/no function would be cleaner + if self.yes_no("Backup"): + for file in os.listdir(self.backup_path): + if file[-5:] == ".bkup": + try: + print(f"Deleting {file}.") + os.remove(f"{self.backup_path}/{file}") + time.sleep(0.1) + except Exception as e: + print(f"Failed to delete {file}. Reason: {e}.") + time.sleep(2) + + def yes_no(self, str): + """Ask user y/n question regaring deletion of a string.""" + while True: + choice = input(f"Are you sure you want to delete all {str} files? (y/n)") + if choice == "y": + return 1 + elif choice == "n": + print(f"Deleting {str} files aborted") + time.sleep(1) + return 0 + else: + print("Not a valid option, try again") + +class SimpleUI: + """'UI for the backup class, simply displayes a menu and accepts letter to choice option.""" + def __init__(self, options, names): + self.options = options + self.names = names + + def menu(self): + """"Use dict to select an option (function).""" + self.print_menu() + while True: + choice = input("Selection Option: ") + if choice in self.options: + self.options[choice]() + self.print_menu() + else: + print("Try again") + continue + + def print_menu(self): + print("\033[H\033[J", end="") + print("Menu options") + for key in self.options: + print(f"{key}: {self.names[key]}") + +app = BackupApp("local_files/settings.txt") + +menu_options = { + "b": app.backup, + "r": app.restore, + "d": app.delete_backup_file, + "q": exit +} +menu_names = { + "b": "Backup now", + "r": "Restore backup", + "d": "Delete backup files", + "q": "Exit" +} + +sui = SimpleUI(menu_options, menu_names) + +sui.menu()