Fix of backward compability issue

Added recommended version checks to ConfigWizard and PresetUpdater
This commit is contained in:
David Kocik 2023-04-20 17:27:09 +02:00
parent 3848a8eda2
commit 2e3b5c2bbc
2 changed files with 95 additions and 25 deletions

View File

@ -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<const fs::path&, BundleLocation> DirData;
std::vector<DirData> 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));

View File

@ -1320,7 +1320,35 @@ bool PresetUpdater::install_bundles_rsrc_or_cache_vendor(std::vector<std::string
bool is_in_rsrc = fs::exists(path_in_rsrc);
bool is_in_cache_vendor = fs::exists(path_in_cache_vendor) && !fs::is_empty(path_in_cache_vendor);
// find if in cache vendor is newer version than in resources
// Find if in cache vendor is newer version than in resources.
// But we also need to mind too new versions - have to read index.
// Fresh index should be in archive_dir, otherwise look for it in cache
fs::path idx_path (path_in_cache_vendor);
idx_path.replace_extension(".idx");
if (!boost::filesystem::exists(idx_path)) {
BOOST_LOG_TRIVIAL(error) << GUI::format("Couldn't locate idx file %1% when performing updates.", idx_path.string());
idx_path = fs::path(p->cache_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<std::string
}
catch (const std::exception& e) {
BOOST_LOG_TRIVIAL(error) << format("Corrupted profile file for vendor %1%, message: %2%", path_in_cache_vendor, e.what());
// lets use file in resources
if (is_in_rsrc) {
updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), "", "");
}
continue;
version_cache = Semver::zero();
}
if (version_cache > 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<std::string
}
catch (const std::exception& e) {
BOOST_LOG_TRIVIAL(error) << format("Corrupted profile file for vendor %1%, message: %2%", path_in_rsrc, e.what());
continue;
//continue;
version_rsrc = Semver::zero();
}
// Should not happen!
if (version_rsrc > 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) {