From c3eb6b4fe686a83ce90ad42dbd605537a34cd136 Mon Sep 17 00:00:00 2001 From: derrod Date: Sun, 6 Nov 2022 17:14:02 +0100 Subject: [PATCH] [core/utils] Respect include/exclude filter when deleting save data Not doing this would result in some titles that save their save data in the install directory having their game data deleted... Fixes #497 --- legendary/core.py | 17 +++++++++++++++-- legendary/utils/savegame_helper.py | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/legendary/core.py b/legendary/core.py index 3914b5a..4b40cbf 100644 --- a/legendary/core.py +++ b/legendary/core.py @@ -999,9 +999,22 @@ class LegendaryCore: if not os.path.exists(_save_dir): os.makedirs(_save_dir) - if clean_dir: + if app_name and clean_dir: + game = self.lgd.get_game_meta(app_name) + custom_attr = game.metadata['customAttributes'] + include_f = exclude_f = None + + # Make sure to only delete files that match the include/exclude filters. + # This is particularly import for games that store save games in their install dir... + if (_include := custom_attr.get('CloudIncludeList', {}).get('value', None)) is not None: + include_f = _include.split(',') + if (_exclude := custom_attr.get('CloudExcludeList', {}).get('value', None)) is not None: + exclude_f = _exclude.split(',') + + sgh = SaveGameHelper() + save_files = sgh.get_deletion_list(_save_dir, include_f, exclude_f) self.log.info('Deleting old save files...') - delete_folder(_save_dir) + delete_filelist(_save_dir, save_files, silent=True) self.log.info(f'Downloading "{fname.split("/", 2)[2]}"...') # download manifest diff --git a/legendary/utils/savegame_helper.py b/legendary/utils/savegame_helper.py index 132b289..aadba25 100644 --- a/legendary/utils/savegame_helper.py +++ b/legendary/utils/savegame_helper.py @@ -167,3 +167,21 @@ class SaveGameHelper: # return dict with created files for uploading/whatever return self.files + + def get_deletion_list(self, save_folder, include_filter=None, exclude_filter=None): + files = [] + for _dir, _, _files in os.walk(save_folder): + for _file in _files: + _file_path = os.path.join(_dir, _file) + _file_path_rel = os.path.relpath(_file_path, save_folder).replace('\\', '/') + + if include_filter and not _filename_matches(_file_path_rel, include_filter): + self.log.debug(f'Excluding "{_file_path_rel}" (does not match include filter)') + continue + elif exclude_filter and _filename_matches(_file_path_rel, exclude_filter): + self.log.debug(f'Excluding "{_file_path_rel}" (does match exclude filter)') + continue + + files.append(_file_path_rel) + + return files