From 2e3b5c2bbc0e31c1737a7824051002afa92c92d7 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 20 Apr 2023 17:27:09 +0200 Subject: [PATCH 1/2] Fix of backward compability issue Added recommended version checks to ConfigWizard and PresetUpdater --- src/slic3r/GUI/ConfigWizard.cpp | 41 +++++++++++++++- src/slic3r/Utils/PresetUpdater.cpp | 79 +++++++++++++++++++++--------- 2 files changed, 95 insertions(+), 25 deletions(-) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 11b116a05..866d5a817 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -57,6 +57,7 @@ #include "UnsavedChangesDialog.hpp" #include "slic3r/Utils/AppUpdater.hpp" #include "slic3r/GUI/I18N.hpp" +#include "slic3r/Config/Version.hpp" #if defined(__linux__) && defined(__WXGTK3__) #define wxLinux_gtk3 true @@ -118,7 +119,7 @@ BundleMap BundleMap::load() const auto vendor_dir = (boost::filesystem::path(Slic3r::data_dir()) / "vendor").make_preferred(); const auto archive_dir = (boost::filesystem::path(Slic3r::data_dir()) / "cache" / "vendor").make_preferred(); const auto rsrc_vendor_dir = (boost::filesystem::path(resources_dir()) / "profiles").make_preferred(); - + const auto cache_dir = boost::filesystem::path(Slic3r::data_dir()) / "cache"; // for Index // Load Prusa bundle from the datadir/vendor directory or from datadir/cache/vendor (archive) or from resources/profiles. auto prusa_bundle_path = (vendor_dir / PresetBundle::PRUSA_BUNDLE).replace_extension(".ini"); BundleLocation prusa_bundle_loc = BundleLocation::IN_VENDOR; @@ -138,7 +139,7 @@ BundleMap BundleMap::load() // Load the other bundles in the datadir/vendor directory // and then additionally from datadir/cache/vendor (archive) and resources/profiles. - // Should we concider case where archive has older profiles than resources (shouldnt happen)? + // Should we concider case where archive has older profiles than resources (shouldnt happen)? -> YES, it happens during re-configuration when running older PS after newer version typedef std::pair DirData; std::vector dir_list { {vendor_dir, BundleLocation::IN_VENDOR}, {archive_dir, BundleLocation::IN_ARCHIVE}, {rsrc_vendor_dir, BundleLocation::IN_RESOURCES} }; for ( auto dir : dir_list) { @@ -151,6 +152,42 @@ BundleMap BundleMap::load() // Don't load this bundle if we've already loaded it. if (res.find(id) != res.end()) { continue; } + // Fresh index should be in archive_dir, otherwise look for it in cache + fs::path idx_path (archive_dir / (id + ".idx")); + if (!boost::filesystem::exists(idx_path)) { + BOOST_LOG_TRIVIAL(warning) << format("Missing index %1% when loading bundle %2%.", idx_path.string(), id); + idx_path = fs::path(cache_dir / (id + ".idx")); + } + if (!boost::filesystem::exists(idx_path)) { + BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to missing index %1%.", id, idx_path.string()); + continue; + } + Slic3r::GUI::Config::Index index; + try { + index.load(idx_path); + } + catch (const std::exception& /* err */) { + BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to invalid index %1%.", id, idx_path.string()); + continue; + } + const auto recommended_it = index.recommended(); + if (recommended_it == index.end()) { + BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to no recommended version in index %2%.", id, idx_path.string()); + continue; + } + const auto recommended = recommended_it->config_version; + VendorProfile vp; + try { + vp = VendorProfile::from_ini(dir_entry, true); + } + catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to corrupted profile file %2%. Message: %3%", id, dir_entry.path().string(), e.what()); + continue; + } + // Don't load + if (vp.config_version > recommended) + continue; + Bundle bundle; if (bundle.load(dir_entry.path(), dir.second)) res.emplace(std::move(id), std::move(bundle)); diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 028c7ce0a..e75b5420a 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -1320,7 +1320,35 @@ bool PresetUpdater::install_bundles_rsrc_or_cache_vendor(std::vectorcache_path / idx_path.filename()); + } + if (!boost::filesystem::exists(idx_path)) { + std::string msg = GUI::format(_L("Couldn't locate index file for vendor %1% when performing updates. The profile will not be installed."), bundle); + BOOST_LOG_TRIVIAL(error) << msg; + GUI::show_error(nullptr, msg); + continue; + } + Slic3r::GUI::Config::Index index; + try { + index.load(idx_path); + } + catch (const std::exception& /* err */) { + std::string msg = GUI::format(_L("Couldn't load index file for vendor %1% when performing updates. The profile will not be installed. Reason: Corrupted index file %2%."), bundle, idx_path.string()); + BOOST_LOG_TRIVIAL(error) << msg; + GUI::show_error(nullptr, msg); + continue; + } + const auto recommended_it = index.recommended(); + const auto recommended = recommended_it->config_version; + if (is_in_cache_vendor) { Semver version_cache = Semver::zero(); try { @@ -1329,13 +1357,11 @@ bool PresetUpdater::install_bundles_rsrc_or_cache_vendor(std::vector recommended) + version_cache = Semver::zero(); + Semver version_rsrc = Semver::zero(); try { if (is_in_rsrc) { @@ -1345,26 +1371,33 @@ bool PresetUpdater::install_bundles_rsrc_or_cache_vendor(std::vector recommended) + version_rsrc = Semver::zero(); - if (!is_in_rsrc || version_cache > version_rsrc) { - // in case we are installing from cache / vendor. we should also copy index to cache - // This needs to be done now bcs the current one would be missing this version on next start - // dk: Should we copy it to vendor dir too? - auto path_idx_cache_vendor(path_in_cache_vendor); - path_idx_cache_vendor.replace_extension(".idx"); - auto path_idx_cache = (p->cache_path / bundle).replace_extension(".idx"); - // DK: do this during perform_updates() too? - if (fs::exists(path_idx_cache_vendor)) - copy_file_fix(path_idx_cache_vendor, path_idx_cache); - else // Should we dialog this? - BOOST_LOG_TRIVIAL(error) << GUI::format(_L("Couldn't locate idx file %1% when performing updates."), path_idx_cache_vendor.string()); + if (version_cache == Semver::zero() && version_rsrc == Semver::zero()) { + std::string msg = GUI::format(_L("Couldn't open profile file for vendor %1% when performing updates. The profile will not be installed. This installation might be corrupted."), bundle); + BOOST_LOG_TRIVIAL(error) << msg; + GUI::show_error(nullptr, msg); + continue; + } else if (version_cache == Semver::zero()) { + // cache vendor cannot be used, use resources + updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), "", ""); + } else if (version_rsrc == Semver::zero()) { + // resources cannto be used, use cache vendor + updates.updates.emplace_back(std::move(path_in_cache_vendor), std::move(path_in_vendors), Version(), "", ""); + } else if (version_cache > version_rsrc) { + // in case we are installing from cache / vendor. we should also copy index to cache + // This needs to be done now bcs the current one would be missing this version on the next start + auto path_idx_cache = (p->cache_path / bundle).replace_extension(".idx"); + if (idx_path != path_idx_cache) + copy_file_fix(idx_path, path_idx_cache); updates.updates.emplace_back(std::move(path_in_cache_vendor), std::move(path_in_vendors), Version(), "", ""); - } else { - if (is_in_rsrc) - updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), "", ""); + updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), "", ""); } } else { if (! is_in_rsrc) { From f346b42886d394c8a7b1388acf957ba31397e4ed Mon Sep 17 00:00:00 2001 From: David Kocik Date: Wed, 10 May 2023 11:17:10 +0200 Subject: [PATCH 2/2] Commented Part of config update algorythm that searches in snapshots. --- src/slic3r/Utils/PresetUpdater.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index e75b5420a..995891db9 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -961,7 +961,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version BOOST_LOG_TRIVIAL(error) << format("Cannot load the installed index at `%1%`: %2%", bundle_path_idx, err.what()); } } - +#if 0 // Check if the update is already present in a snapshot if(!current_not_supported) { @@ -974,7 +974,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version continue; } } - +#endif // 0 updates.updates.emplace_back(std::move(new_update)); // 'Install' the index in the vendor directory. This is used to memoize // offered updates and to not offer the same update again if it was cancelled by the user.