From 7c1122d06f9f1af97e419c9e60db23a94f1c603c Mon Sep 17 00:00:00 2001 From: SoftFever Date: Tue, 18 Mar 2025 00:37:47 +0800 Subject: [PATCH] backup user folder for each version (#8939) * backup user folder for each version --- src/libslic3r/PresetBundle.cpp | 88 +++++++++++++++++++++++++++++++++- src/libslic3r/PresetBundle.hpp | 2 + src/slic3r/GUI/GUI_App.cpp | 2 + 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index f3a3adba44..0370788446 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -367,6 +367,92 @@ bool PresetBundle::use_bbl_device_tab() { return cfg.opt_string("print_host_webui").empty(); } +bool PresetBundle::backup_user_folder() const +{ + const std::string backup_filename = (boost::format("Orca_user_folder_backup_%1%.zip") % SoftFever_VERSION).str(); + const std::string backup_filepath = data_dir() + "/" + backup_filename; + + // Check if backup file already exists + if (boost::filesystem::exists(boost::filesystem::path(backup_filepath))) { + BOOST_LOG_TRIVIAL(info) << "User folder backup already exists at: " << backup_filepath; + return false; + } + + BOOST_LOG_TRIVIAL(info) << "Backing up user folder to: " << backup_filepath; + + try { + // Create a temporary zip archive + mz_zip_archive zip_archive; + mz_zip_zero_struct(&zip_archive); + + if (!mz_zip_writer_init_file(&zip_archive, backup_filepath.c_str(), 0)) { + BOOST_LOG_TRIVIAL(error) << "Failed to initialize zip writer for backup"; + return false; + } + + // Recursively add all files from the user directory to the zip + boost::filesystem::path user_folder(data_dir() + "/" + PRESET_USER_DIR); + + // Helper lambda to recursively add files to zip + std::function add_dir_to_zip; + add_dir_to_zip = [&zip_archive, &add_dir_to_zip, &user_folder](const boost::filesystem::path& dir_path, + const std::string& zip_path) -> bool { + if (!boost::filesystem::exists(dir_path) || !boost::filesystem::is_directory(dir_path)) + return false; + + for (auto& entry : boost::filesystem::directory_iterator(dir_path)) { + boost::filesystem::path entry_path = entry.path(); + // get relative path of entry_path compare to backup_dir + std::string rel_path = boost::filesystem::relative(entry_path, user_folder).string(); + if (boost::filesystem::is_directory(entry_path)) { + // Recursively add contents + if (!add_dir_to_zip(entry_path, rel_path)) + return false; + } else { + // Skip adding the backup file itself + if (entry_path.filename().extension() == ".zip") + continue; + + // Add file to zip + if (!mz_zip_writer_add_file(&zip_archive, rel_path.c_str(), encode_path(entry_path.string().c_str()).c_str(), nullptr, + 0, MZ_DEFAULT_COMPRESSION)) { + BOOST_LOG_TRIVIAL(error) << "Failed to add file to zip: " << entry_path.string(); + return false; + } + } + } + return true; + }; + + // Start the recursive addition from the user folder, with the base path being empty + if (!add_dir_to_zip(user_folder, "")) { + mz_zip_writer_end(&zip_archive); + boost::filesystem::remove(boost::filesystem::path(backup_filepath)); + return false; + } + + // Finalize the zip file + if (!mz_zip_writer_finalize_archive(&zip_archive)) { + BOOST_LOG_TRIVIAL(error) << "Failed to finalize zip archive for backup"; + mz_zip_writer_end(&zip_archive); + boost::filesystem::remove(boost::filesystem::path(backup_filepath)); + return false; + } + + // Close the zip writer + mz_zip_writer_end(&zip_archive); + + BOOST_LOG_TRIVIAL(info) << "User folder backup completed successfully"; + return true; + } catch (const std::exception& ex) { + BOOST_LOG_TRIVIAL(error) << "Exception during user folder backup: " << ex.what(); + // Try to clean up partially created zip file + if (boost::filesystem::exists(boost::filesystem::path(backup_filepath))) + boost::filesystem::remove(boost::filesystem::path(backup_filepath)); + return false; + } +} + //BBS: load project embedded presets PresetsConfigSubstitutions PresetBundle::load_project_embedded_presets(std::vector project_presets, ForwardCompatibilitySubstitutionRule substitution_rule) { @@ -2504,7 +2590,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool old_filament_profile_names->values.resize(num_filaments, std::string()); if (num_filaments <= 1) { - // Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets. + // Split the "compatible_printers_condition" and "inherits" values from the cummulative vectors to separate filament presets. inherits = inherits_values[1]; compatible_printers_condition = compatible_printers_condition_values[1]; compatible_prints_condition = compatible_prints_condition_values.front(); diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 58b5941168..91555ee379 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -97,6 +97,8 @@ public: // Whether using bbl's device tab bool use_bbl_device_tab(); + bool backup_user_folder() const; + //BBS: project embedded preset logic PresetsConfigSubstitutions load_project_embedded_presets(std::vector project_presets, ForwardCompatibilitySubstitutionRule substitution_rule); std::vector get_current_project_embedded_presets(); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 099aa97403..b04739f860 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2501,6 +2501,8 @@ bool GUI_App::on_init_inner() // Suppress the '- default -' presets. preset_bundle->set_default_suppressed(true); + preset_bundle->backup_user_folder(); + Bind(EVT_SET_SELECTED_MACHINE, &GUI_App::on_set_selected_machine, this); Bind(EVT_UPDATE_MACHINE_LIST, &GUI_App::on_update_machine_list, this); Bind(EVT_USER_LOGIN, &GUI_App::on_user_login, this);