From 3e0483b405a8ffbbec761044afb171d166c74da9 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Thu, 6 Jun 2024 16:15:50 +0200 Subject: [PATCH] Changes in PresetArchiveDatabase and PresetUpdater PresetArchiveDatabase stores if repo is has installed printers and offers secret repo even if user is unloged or unworthy if repo has installed printers. PresetArchiveDatabase shares its pointers to archives by doing copy of pointer. So only selected repos are shared to PresetUpdater. PresetUpdater does copy both index and ini file to vendor folder durring installation of profile, so index is available f.e. for secret repo when not logged in. --- src/slic3r/GUI/ConfigWizard.cpp | 27 +++- src/slic3r/GUI/GUI_App.cpp | 6 +- src/slic3r/GUI/Plater.cpp | 2 +- src/slic3r/GUI/PresetArchiveDatabase.cpp | 187 ++++++++++++++++++++--- src/slic3r/GUI/PresetArchiveDatabase.hpp | 53 ++++++- src/slic3r/GUI/UpdatesUIManager.cpp | 4 +- src/slic3r/Utils/PresetUpdater.cpp | 68 ++++----- src/slic3r/Utils/PresetUpdater.hpp | 12 +- 8 files changed, 277 insertions(+), 82 deletions(-) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index e8b0bc9647..39cebc885f 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -3276,6 +3276,17 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese const auto enabled_vendors = appconfig_new.vendors(); const auto enabled_vendors_old = app_config->vendors(); + std::vector used_repo_ids; + for (const auto& vendor : enabled_vendors) { + const auto& it = bundles.find(vendor.first); + assert(it != bundles.end()); + const std::string repo_id = it->second.vendor_profile->repo_id; + if (std::find(used_repo_ids.begin(), used_repo_ids.end(), repo_id) == used_repo_ids.end()) { + used_repo_ids.emplace_back(repo_id); + } + } + wxGetApp().plater()->get_preset_archive_database()->set_installed_printer_repositories(std::move(used_repo_ids)); + bool suppress_sla_printer = model_has_multi_part_objects(wxGetApp().model()); PrinterTechnology preferred_pt = ptAny; auto get_preferred_printer_technology = [enabled_vendors, enabled_vendors_old, suppress_sla_printer](const std::string& bundle_name, const Bundle& bundle) { @@ -3406,7 +3417,7 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese // Don't create snapshot - we've already done that above if applicable. GUI_App& app = wxGetApp(); const auto* archive_db = app.plater()->get_preset_archive_database(); - bool install_result = updater->install_bundles_rsrc_or_cache_vendor(std::move(install_bundles), archive_db->get_archive_repositories(), false); + bool install_result = updater->install_bundles_rsrc_or_cache_vendor(std::move(install_bundles), archive_db->get_selected_archive_repositories(), false); if (!install_result) return false; } else { @@ -3625,8 +3636,8 @@ void ConfigWizard::priv::set_config_updated_from_archive(bool is_updated) // This set with preset_updater used to be done in GUI_App::run_wizard before ConfigWizard::run() GUI_App& app = wxGetApp(); // Do blocking sync on every change of archive repos, so user is always offered recent profiles. - const ArchiveRepositoryVector &repos = app.plater()->get_preset_archive_database()->get_archive_repositories(); - app.preset_updater->sync_blocking(app.preset_bundle, &app, repos, app.plater()->get_preset_archive_database()->get_selected_repositories_uuid()); + const SharedArchiveRepositoryVector &repos = app.plater()->get_preset_archive_database()->get_selected_archive_repositories(); + app.preset_updater->sync_blocking(app.preset_bundle, &app, repos); // Offer update installation. It used to be offered only when wizard run reason was RR_USER. app.preset_updater->update_index_db(); app.preset_updater->config_update(app.app_config->orig_version(), PresetUpdater::UpdateParams::SHOW_TEXT_BOX, repos); @@ -3681,12 +3692,12 @@ static bool to_delete(PagePrinters* page, const std::set& selected_ static void unselect(PagePrinters* page) { - const PresetArchiveDatabase* pad = wxGetApp().plater()->get_preset_archive_database(); - const ArchiveRepositoryVector& archs = pad->get_archive_repositories(); + const PresetArchiveDatabase* pad = wxGetApp().plater()->get_preset_archive_database(); + const SharedArchiveRepositoryVector& archs = pad->get_all_archive_repositories(); bool unselect_all = true; - for (const auto& archive : archs) { + for (const auto* archive : archs) { if (page->get_vendor_repo_id() == archive->get_manifest().id) { if (pad->is_selected_repository_by_uuid(archive->get_uuid())) unselect_all = false; @@ -3780,12 +3791,12 @@ void ConfigWizard::priv::load_pages_from_archive() auto pad = wxGetApp().plater()->get_preset_archive_database(); - const ArchiveRepositoryVector& archs = pad->get_archive_repositories(); + const SharedArchiveRepositoryVector& archs = pad->get_all_archive_repositories(); only_sla_mode = true; bool is_primary_printer_page_set = false; - for (const auto& archive : archs) { + for (const auto* archive : archs) { const auto& data = archive->get_manifest(); const bool is_selected_arch = pad->is_selected_repository_by_uuid(archive->get_uuid()); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 86018a4157..803a342a69 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -836,7 +836,7 @@ void GUI_App::post_init() CallAfter([this] { // preset_updater->sync downloads profile updates and than via event checks updates and incompatible presets. We need to run it on startup. // start before cw so it is canceled by cw if needed? - this->preset_updater->sync(preset_bundle, this, plater()->get_preset_archive_database()->get_archive_repositories(), plater()->get_preset_archive_database()->get_selected_repositories_uuid()); + this->preset_updater->sync(preset_bundle, this, std::move(plater()->get_preset_archive_database()->get_selected_archive_repositories())); bool cw_showed = this->config_wizard_startup(); if (! cw_showed) { // The CallAfter is needed as well, without it, GL extensions did not show. @@ -3463,14 +3463,14 @@ bool GUI_App::check_updates(const bool invoked_automatically) if (dlg.ShowModal() != wxID_OK) return true; // then its time for preset_updater sync - preset_updater->sync_blocking(preset_bundle, this, plater()->get_preset_archive_database()->get_archive_repositories(), plater()->get_preset_archive_database()->get_selected_repositories_uuid()); + preset_updater->sync_blocking(preset_bundle, this, plater()->get_preset_archive_database()->get_selected_archive_repositories()); // and then we check updates } PresetUpdater::UpdateResult updater_result; try { preset_updater->update_index_db(); - updater_result = preset_updater->config_update(app_config->orig_version(), invoked_automatically ? PresetUpdater::UpdateParams::SHOW_TEXT_BOX : PresetUpdater::UpdateParams::SHOW_NOTIFICATION, plater()->get_preset_archive_database()->get_archive_repositories()); + updater_result = preset_updater->config_update(app_config->orig_version(), invoked_automatically ? PresetUpdater::UpdateParams::SHOW_TEXT_BOX : PresetUpdater::UpdateParams::SHOW_NOTIFICATION, plater()->get_preset_archive_database()->get_selected_archive_repositories()); if (updater_result == PresetUpdater::R_INCOMPAT_EXIT) { mainframe->Close(); // Applicaiton is closing. diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7293602b2a..90decf492e 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -783,7 +783,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) this->q->Bind(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, [this](ExportGcodeNotificationClickedEvent&) { this->q->export_gcode(true); }); this->q->Bind(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, [](PresetUpdateAvailableClickedEvent&) { GUI_App &app = wxGetApp(); - app.get_preset_updater()->on_update_notification_confirm(app.plater()->get_preset_archive_database()->get_archive_repositories()); + app.get_preset_updater()->on_update_notification_confirm(app.plater()->get_preset_archive_database()->get_selected_archive_repositories()); }); this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this, q](RemovableDriveEjectEvent &evt) { if (evt.data.second) { diff --git a/src/slic3r/GUI/PresetArchiveDatabase.cpp b/src/slic3r/GUI/PresetArchiveDatabase.cpp index ffaf64f05c..893e0b6368 100644 --- a/src/slic3r/GUI/PresetArchiveDatabase.cpp +++ b/src/slic3r/GUI/PresetArchiveDatabase.cpp @@ -358,6 +358,34 @@ bool PresetArchiveDatabase::set_selected_repositories(const std::vector &used_ids) +{ + // set all uuids as not having installed printer + m_has_installed_printer_repositories_uuid.clear(); + for (const auto &archive : m_archive_repositories) { + m_has_installed_printer_repositories_uuid.emplace(archive->get_uuid(), false); + } + // set correct repos as having installed printer + for (const std::string &used_id : used_ids) { + // find archive with id and is used + for (const auto &archive : m_archive_repositories) { + if (archive->get_manifest().id != used_id) { + continue; + } + const std::string uuid = archive->get_uuid(); + + const auto& it = m_selected_repositories_uuid.find(uuid); + assert(it != m_selected_repositories_uuid.end()); + if (it->second == false) { + continue; + } + + // set archive as has installed printer + m_has_installed_printer_repositories_uuid[uuid] = true; + } + } + save_app_manifest_json(); +} std::string PresetArchiveDatabase::add_local_archive(const boost::filesystem::path path, std::string& msg) { @@ -425,6 +453,8 @@ void PresetArchiveDatabase::load_app_manifest_json() } m_archive_repositories.clear(); + m_selected_repositories_uuid.clear(); + m_has_installed_printer_repositories_uuid.clear(); try { std::stringstream ss(data); @@ -439,11 +469,20 @@ void PresetArchiveDatabase::load_app_manifest_json() BOOST_LOG_TRIVIAL(error) << "Local archive repository not extracted: " << *source_path; continue; } + // "selected" flag if(const auto used = subtree.second.get_optional("selected"); used) { m_selected_repositories_uuid[uuid] = *used; } else { assert(true); + m_selected_repositories_uuid[uuid] = true; } + // "has_installed_printers" flag + if (const auto used = subtree.second.get_optional("has_installed_printers"); used) { + m_has_installed_printer_repositories_uuid[uuid] = *used; + } else { + assert(true); + m_has_installed_printer_repositories_uuid[uuid] = true; + } m_archive_repositories.emplace_back(std::make_unique(std::move(uuid), std::move(manifest))); continue; @@ -456,13 +495,20 @@ void PresetArchiveDatabase::load_app_manifest_json() BOOST_LOG_TRIVIAL(error) << "Failed to read one of repository headers."; continue; } - auto search = m_selected_repositories_uuid.find(uuid); - assert(search == m_selected_repositories_uuid.end()); + // "selected" flag if (const auto used = subtree.second.get_optional("selected"); used) { m_selected_repositories_uuid[uuid] = *used; } else { assert(true); + m_selected_repositories_uuid[uuid] = true; } + // "has_installed_printers" flag + if (const auto used = subtree.second.get_optional("has_installed_printers"); used) { + m_has_installed_printer_repositories_uuid[uuid] = *used; + } else { + assert(true); + m_has_installed_printer_repositories_uuid[uuid] = true; + } m_archive_repositories.emplace_back(std::make_unique(std::move(uuid), std::move(manifest))); } } @@ -498,13 +544,17 @@ void PresetArchiveDatabase::save_app_manifest_json() const "id": "prod", "url": "http://10.24.3.3:8001/v1/repos/prod", "index_url": "http://10.24.3.3:8001/v1/repos/prod/vendor_indices.zip" + "selected": 1 + "has_installed_printers": 1 }, { "name": "Development", "description": "Production repository", - "visibility": null, + "visibility": "developers only", "id": "dev", "url": "http://10.24.3.3:8001/v1/repos/dev", "index_url": "http://10.24.3.3:8001/v1/repos/dev/vendor_indices.zip" + "selected": 0 + "has_installed_printers": 0 }] */ std::string data = "["; @@ -515,9 +565,15 @@ void PresetArchiveDatabase::save_app_manifest_json() const const ArchiveRepository::RepositoryManifest& man = archive->get_manifest(); std::string line = archive == m_archive_repositories.front() ? std::string() : ","; line += GUI::format( - "{\"source_path\": \"%1%\"," - "\"selected\": %2%}" - , man.source_path.generic_string(), is_selected(archive->get_uuid()) ? "1" : "0"); + "{" + "\"source_path\": \"%1%\"," + "\"selected\": %2%," + "\"has_installed_printers\": %3%" + "}", + man.source_path.generic_string() + , is_selected(archive->get_uuid()) ? "1" : "0" + , has_installed_printers(archive->get_uuid()) ? "1" : "0" + ); data += line; continue; } @@ -531,8 +587,17 @@ void PresetArchiveDatabase::save_app_manifest_json() const "\"id\": \"%4%\"," "\"url\": \"%5%\"," "\"index_url\": \"%6%\"," - "\"selected\": %7%}" - , man.name, man.description, man. visibility, man.id, man.url, man.index_url, is_selected(archive->get_uuid()) ? "1" : "0"); + "\"selected\": %7%," + "\"has_installed_printers\": %8%" + "}" + , man.name, man.description + , man. visibility + , man.id + , man.url + , man.index_url + , is_selected(archive->get_uuid()) ? "1" : "0" + , has_installed_printers(archive->get_uuid()) ? "1" : "0" + ); data += line; } data += "]"; @@ -559,12 +624,18 @@ bool PresetArchiveDatabase::is_selected(const std::string& uuid) const assert(search != m_selected_repositories_uuid.end()); return search->second; } - +bool PresetArchiveDatabase::has_installed_printers(const std::string &uuid) const +{ + auto search = m_has_installed_printer_repositories_uuid.find(uuid); + assert(search != m_has_installed_printer_repositories_uuid.end()); + return search->second; +} void PresetArchiveDatabase::clear_online_repos() { auto it = m_archive_repositories.begin(); while (it != m_archive_repositories.end()) { - if ((*it)->get_manifest().tmp_path.empty()) { + // Do not clean repos with local path (local repo) and with visibility filled (secret repo) + if ((*it)->get_manifest().tmp_path.empty()) { it = m_archive_repositories.erase(it); } else { ++it; @@ -585,7 +656,7 @@ void PresetArchiveDatabase::read_server_manifest(const std::string& json_body) BOOST_LOG_TRIVIAL(error) << "Failed to read archives JSON. " << e.what(); } - // Online repo manifests are in json_body. We already read local manifest and online manifest from last run. + // Online repo manifests are in json_body. We already have read local manifest and online manifest from last run. // Keep the local ones and replace the online ones but keep uuid for same id so the selected map is correct. // Solution: Create id - uuid translate table for online repos. std::map id_to_uuid; @@ -594,7 +665,23 @@ void PresetArchiveDatabase::read_server_manifest(const std::string& json_body) id_to_uuid[repo_ptr->get_manifest().id] = repo_ptr->get_uuid(); } } - clear_online_repos(); + + // Make a stash of secret repos that are online and has installed printers. + // If some of these will be missing afer reading the json tree, it needs to be added back to main population. + PrivateArchiveRepositoryVector secret_online_used_repos_cache; + for (const auto &repo_ptr : m_archive_repositories) { + if (repo_ptr->get_manifest().visibility.empty() || !repo_ptr->get_manifest().tmp_path.empty()) { + continue; + } + const auto &it = m_has_installed_printer_repositories_uuid.find(repo_ptr->get_uuid()); + assert(it != m_has_installed_printer_repositories_uuid.end()); + if (it->second) { + ArchiveRepository::RepositoryManifest manifest(repo_ptr->get_manifest()); + secret_online_used_repos_cache.emplace_back(std::make_unique(repo_ptr->get_uuid(), std::move(manifest))); + } + } + + clear_online_repos(); for (const auto& subtree : ptree) { ArchiveRepository::RepositoryManifest manifest; @@ -605,17 +692,61 @@ void PresetArchiveDatabase::read_server_manifest(const std::string& json_body) } auto id_it = id_to_uuid.find(manifest.id); std::string uuid = (id_it == id_to_uuid.end() ? get_next_uuid() : id_it->second); - // Set default used value to true - its a never before seen repository + // Set default selected value to true - its a never before seen repository if (auto search = m_selected_repositories_uuid.find(uuid); search == m_selected_repositories_uuid.end()) { m_selected_repositories_uuid[uuid] = true; } + // Set default "has installed printers" value to false - its a never before seen repository + if (auto search = m_has_installed_printer_repositories_uuid.find(uuid); + search == m_has_installed_printer_repositories_uuid.end()) { + m_has_installed_printer_repositories_uuid[uuid] = false; + } m_archive_repositories.emplace_back(std::make_unique(uuid, std::move(manifest))); } - consolidate_selected_uuids_map(); + // return missing secret online repos with installed printers to the vector + for (const auto &repo_ptr : secret_online_used_repos_cache) { + std::string uuid = repo_ptr->get_uuid(); + if (std::find_if( + m_archive_repositories.begin(), m_archive_repositories.end(), + [uuid](const std::unique_ptr &ptr) { + return ptr->get_uuid() == uuid; + } + ) == m_archive_repositories.end()) + { + ArchiveRepository::RepositoryManifest manifest(repo_ptr->get_manifest()); + m_archive_repositories.emplace_back(std::make_unique(repo_ptr->get_uuid(), std::move(manifest))); + } + } + + consolidate_uuid_maps(); save_app_manifest_json(); } +SharedArchiveRepositoryVector PresetArchiveDatabase::get_all_archive_repositories() const +{ + SharedArchiveRepositoryVector result; + for (const auto &repo_ptr : m_archive_repositories) + { + result.emplace_back(repo_ptr.get()); + } + return result; +} + +SharedArchiveRepositoryVector PresetArchiveDatabase::get_selected_archive_repositories() const +{ + SharedArchiveRepositoryVector result; + for (const auto &repo_ptr : m_archive_repositories) + { + auto it = m_selected_repositories_uuid.find(repo_ptr->get_uuid()); + assert(it != m_selected_repositories_uuid.end()); + if (it->second) { + result.emplace_back(repo_ptr.get()); + } + } + return result; +} + bool PresetArchiveDatabase::is_selected_repository_by_uuid(const std::string& uuid) const { auto selected_it = m_selected_repositories_uuid.find(uuid); @@ -632,25 +763,41 @@ bool PresetArchiveDatabase::is_selected_repository_by_id(const std::string& repo } return false; } -void PresetArchiveDatabase::consolidate_selected_uuids_map() +void PresetArchiveDatabase::consolidate_uuid_maps() { //std::vector> m_archive_repositories; //std::map m_selected_repositories_uuid; - auto it = m_selected_repositories_uuid.begin(); - while (it != m_selected_repositories_uuid.end()) { + auto selected_it = m_selected_repositories_uuid.begin(); + while (selected_it != m_selected_repositories_uuid.end()) { bool found = false; for (const auto& repo_ptr : m_archive_repositories) { - if (repo_ptr->get_uuid() == it->first) { + if (repo_ptr->get_uuid() == selected_it->first) { found = true; break; } } if (!found) { - it = m_selected_repositories_uuid.erase(it); + selected_it = m_selected_repositories_uuid.erase(selected_it); } else { - ++it; + ++selected_it; } } + // Do the same for m_has_installed_printer_repositories_uuid + auto installed_it = m_has_installed_printer_repositories_uuid.begin(); + while (installed_it != m_has_installed_printer_repositories_uuid.end()) { + bool found = false; + for (const auto &repo_ptr : m_archive_repositories) { + if (repo_ptr->get_uuid() == installed_it->first) { + found = true; + break; + } + } + if (!found) { + installed_it = m_has_installed_printer_repositories_uuid.erase(installed_it); + } else { + ++installed_it; + } + } } std::string PresetArchiveDatabase::get_next_uuid() diff --git a/src/slic3r/GUI/PresetArchiveDatabase.hpp b/src/slic3r/GUI/PresetArchiveDatabase.hpp index 4e729e0180..6a0de68e42 100644 --- a/src/slic3r/GUI/PresetArchiveDatabase.hpp +++ b/src/slic3r/GUI/PresetArchiveDatabase.hpp @@ -38,9 +38,43 @@ public: // not read from manifest json boost::filesystem::path tmp_path; // Where archive is unzziped. Created each app run. boost::filesystem::path source_path; // Path given by user. Stored between app runs. + + RepositoryManifest() = default; + RepositoryManifest( + const std::string &id, + const std::string &name, + const std::string &url, + const std::string &index_url = "", + const std::string &description = "", + const std::string &visibility = "", + const boost::filesystem::path &tmp_path = "", + const boost::filesystem::path &source_path = "" + ) + : id(id) + , name(name) + , url(url) + , index_url(index_url) + , description(description) + , visibility(visibility) + , tmp_path(tmp_path) + , source_path(source_path) + {} + RepositoryManifest(const RepositoryManifest &other) + : id(other.id) + , name(other.name) + , url(other.url) + , index_url(other.index_url) + , description(other.description) + , visibility(other.visibility) + , tmp_path(other.tmp_path) + , source_path(other.source_path) + {} }; // Use std::move when calling constructor. - ArchiveRepository(const std::string& uuid, RepositoryManifest&& data) : m_data(std::move(data)), m_uuid(uuid) {} + ArchiveRepository(const std::string& uuid, RepositoryManifest&& data) + : m_data(std::move(data)) + , m_uuid(uuid) + {} virtual ~ArchiveRepository() {} // Gets vendor_indices.zip to target_path virtual bool get_archive(const boost::filesystem::path& target_path) const = 0; @@ -93,7 +127,8 @@ private: bool get_file_inner(const boost::filesystem::path& source_path, const boost::filesystem::path& target_path) const; }; -typedef std::vector> ArchiveRepositoryVector; +typedef std::vector> PrivateArchiveRepositoryVector; +typedef std::vector SharedArchiveRepositoryVector; class PresetArchiveDatabase { @@ -103,11 +138,15 @@ public: void sync_blocking(); - const ArchiveRepositoryVector& get_archive_repositories() const { return m_archive_repositories; } + // Do not use get_all_archive_repositories to perform any GET calls. Use get_selected_archive_repositories instead. + SharedArchiveRepositoryVector get_all_archive_repositories() const; + // Creates copy of m_archive_repositories of shared pointers that are selected in m_selected_repositories_uuid. + SharedArchiveRepositoryVector get_selected_archive_repositories() const; bool is_selected_repository_by_uuid(const std::string& uuid) const; bool is_selected_repository_by_id(const std::string& repo_id) const; const std::map& get_selected_repositories_uuid() const { assert(m_selected_repositories_uuid.size() == m_archive_repositories.size()); return m_selected_repositories_uuid; } bool set_selected_repositories(const std::vector& used_uuids, std::string& msg); + void set_installed_printer_repositories(const std::vector &used_ids); std::string add_local_archive(const boost::filesystem::path path, std::string& msg); void remove_local_archive(const std::string& uuid); private: @@ -116,14 +155,16 @@ private: void read_server_manifest(const std::string& json_body); void save_app_manifest_json() const; void clear_online_repos(); - bool is_selected(const std::string& id) const; + bool is_selected(const std::string& uuid) const; + bool has_installed_printers(const std::string &uuid) const; boost::filesystem::path get_stored_manifest_path() const; - void consolidate_selected_uuids_map(); + void consolidate_uuid_maps(); std::string get_next_uuid(); wxEvtHandler* p_evt_handler; boost::filesystem::path m_unq_tmp_path; - ArchiveRepositoryVector m_archive_repositories; + PrivateArchiveRepositoryVector m_archive_repositories; std::map m_selected_repositories_uuid; + std::map m_has_installed_printer_repositories_uuid; boost::uuids::random_generator m_uuid_generator; }; diff --git a/src/slic3r/GUI/UpdatesUIManager.cpp b/src/slic3r/GUI/UpdatesUIManager.cpp index bd25307788..884f1903ae 100644 --- a/src/slic3r/GUI/UpdatesUIManager.cpp +++ b/src/slic3r/GUI/UpdatesUIManager.cpp @@ -61,8 +61,8 @@ void RepositoryUpdateUIManager::fill_entries(bool init_selection/* = false*/) m_online_entries.clear(); m_offline_entries.clear(); - const ArchiveRepositoryVector& archs = m_pad->get_archive_repositories(); - for (const auto& archive : archs) { + const SharedArchiveRepositoryVector& archs = m_pad->get_all_archive_repositories(); + for (const auto* archive : archs) { const std::string& uuid = archive->get_uuid(); if (init_selection && m_pad->is_selected_repository_by_uuid(uuid)) m_selected_uuids.emplace(uuid); diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 567385f6e4..3843f3c884 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -118,6 +118,10 @@ struct Update void install() const { copy_file_fix(source, target); + // Since 2.8.0 and introduction of Preset Repositories also install index to vendor folder. + // Thanks to that, the index will always be found f.e. by BundleMap::load(), + // which makes the ini file accessible even if recent version was not downloaded (due to repo shenanigans) + copy_file_fix(fs::path(source).replace_extension(".idx"), fs::path(target).replace_extension(".idx")); } friend std::ostream& operator<<(std::ostream& os, const Update &self) @@ -186,16 +190,16 @@ struct PresetUpdater::priv void set_download_prefs(const AppConfig *app_config); void prune_tmps() const; void clear_cache_vendor() const; - void sync_config(const VendorMap& vendors, const GUI::ArchiveRepository& archive); + void sync_config(const VendorMap& vendors, const GUI::ArchiveRepository* archive); void check_install_indices() const; Updates get_config_updates(const Semver& old_slic3r_version) const; - bool perform_updates(Updates &&updates, const ArchiveRepositoryVector& repositories, bool snapshot = true) const; + bool perform_updates(Updates &&updates, const SharedArchiveRepositoryVector& repositories, bool snapshot = true) const; void set_waiting_updates(Updates u); // checks existence and downloads resource to cache - void get_missing_resource(const GUI::ArchiveRepository& archive, const std::string& vendor, const std::string& filename, const std::string& repository_id_from_ini) const; + void get_missing_resource(const GUI::ArchiveRepository* archive, const std::string& vendor, const std::string& filename, const std::string& repository_id_from_ini) const; // checks existence and downloads resource to vendor or copy from cache to vendor - void get_or_copy_missing_resource(const GUI::ArchiveRepository& archive, const std::string& vendor, const std::string& filename, const std::string& repository_id_from_ini) const; + void get_or_copy_missing_resource(const GUI::ArchiveRepository* archive, const std::string& vendor, const std::string& filename, const std::string& repository_id_from_ini) const; void update_index_db(); }; @@ -249,7 +253,7 @@ void PresetUpdater::priv::clear_cache_vendor() const } // gets resource to cache// -void PresetUpdater::priv::get_missing_resource(const GUI::ArchiveRepository& archive, const std::string& vendor, const std::string& filename, const std::string& repository_id_from_ini) const +void PresetUpdater::priv::get_missing_resource(const GUI::ArchiveRepository* archive, const std::string& vendor, const std::string& filename, const std::string& repository_id_from_ini) const { assert(!filename.empty() && !vendor.empty()); //if (filename.empty() || vendor.empty()) { @@ -280,11 +284,11 @@ void PresetUpdater::priv::get_missing_resource(const GUI::ArchiveRepository& arc //std::string escaped_filename = escape_string_url(filename); const std::string resource_subpath = GUI::format("%1%/%2%",vendor, filename); - archive.get_file(resource_subpath, file_in_cache, repository_id_from_ini); + archive->get_file(resource_subpath, file_in_cache, repository_id_from_ini); return; } // gets resource to vendor// -void PresetUpdater::priv::get_or_copy_missing_resource(const GUI::ArchiveRepository& archive, const std::string& vendor, const std::string& filename, const std::string& repository_id_from_ini) const +void PresetUpdater::priv::get_or_copy_missing_resource(const GUI::ArchiveRepository* archive, const std::string& vendor, const std::string& filename, const std::string& repository_id_from_ini) const { assert(!filename.empty() && !vendor.empty()); @@ -311,7 +315,7 @@ void PresetUpdater::priv::get_or_copy_missing_resource(const GUI::ArchiveReposit //std::string escaped_filename = escape_string_url(filename); const std::string resource_subpath = GUI::format("%1%/%2%", vendor, filename); - archive.get_file(resource_subpath, file_in_vendor, repository_id_from_ini); + archive->get_file(resource_subpath, file_in_vendor, repository_id_from_ini); return; } BOOST_LOG_TRIVIAL(debug) << "Copiing: " << file_in_cache << " to " << file_in_vendor; @@ -320,7 +324,7 @@ void PresetUpdater::priv::get_or_copy_missing_resource(const GUI::ArchiveReposit // Download vendor indices. Also download new bundles if an index indicates there's a new one available. // Both are saved in cache. -void PresetUpdater::priv::sync_config(const VendorMap& vendors, const GUI::ArchiveRepository& archive_repository) +void PresetUpdater::priv::sync_config(const VendorMap& vendors, const GUI::ArchiveRepository* archive_repository) { BOOST_LOG_TRIVIAL(info) << "Syncing configuration cache"; @@ -328,7 +332,7 @@ void PresetUpdater::priv::sync_config(const VendorMap& vendors, const GUI::Archi // Download profiles archive zip fs::path archive_path(cache_path / "vendor_indices.zip"); - if (!archive_repository.get_archive(archive_path)) { + if (!archive_repository->get_archive(archive_path)) { BOOST_LOG_TRIVIAL(error) << "Download of vedor profiles archive zip failed."; return; } @@ -476,7 +480,7 @@ void PresetUpdater::priv::sync_config(const VendorMap& vendors, const GUI::Archi BOOST_LOG_TRIVIAL(info) << "Downloading new bundle for vendor: " << vendor.name; const std::string source_subpath = GUI::format("%1%/%2%.ini", vendor.id, recommended.to_string()); const fs::path bundle_path = cache_path / (vendor.id + ".ini"); - if (!archive_repository.get_file(source_subpath, bundle_path, vendor.repo_id)) + if (!archive_repository->get_file(source_subpath, bundle_path, vendor.repo_id)) continue; if (cancel) return; @@ -535,7 +539,7 @@ void PresetUpdater::priv::sync_config(const VendorMap& vendors, const GUI::Archi if (!fs::exists(ini_path_in_archive)){ // Download recommneded to vendor - we do not have any existing ini file so we have to use archive url. const std::string source_subpath = GUI::format("%1%/%2%.ini", vendor.first, recommended.to_string()); - if (!archive_repository.get_ini_no_id(source_subpath, ini_path_in_archive)) + if (!archive_repository->get_ini_no_id(source_subpath, ini_path_in_archive)) continue; } else { // check existing ini version @@ -556,7 +560,7 @@ void PresetUpdater::priv::sync_config(const VendorMap& vendors, const GUI::Archi if (vp.config_version != recommended) { // Take url from existing ini. This way we prevent downloading files from multiple sources. const std::string source_subpath = GUI::format("%1%/%2%.ini", vp.id, recommended.to_string()); - if (!archive_repository.get_file(source_subpath, ini_path_in_archive, vp.repo_id)) + if (!archive_repository->get_file(source_subpath, ini_path_in_archive, vp.repo_id)) continue; } } @@ -649,7 +653,7 @@ void PresetUpdater::priv::sync_config(const VendorMap& vendors, const GUI::Archi continue; } const std::string source_subpath = GUI::format("%1%/%2%.ini", vp.id, recommended_archive.to_string()); - if (!archive_repository.get_file(source_subpath, ini_path_in_archive, vp.repo_id)) { + if (!archive_repository->get_file(source_subpath, ini_path_in_archive, vp.repo_id)) { BOOST_LOG_TRIVIAL(error) << format("Failed to get new vendor .ini file when checking missing resources: %1%", ini_path_in_archive.string()); continue; } @@ -666,7 +670,7 @@ void PresetUpdater::priv::sync_config(const VendorMap& vendors, const GUI::Archi } if (vp.config_version != recommended_archive) { const std::string source_subpath = GUI::format("%1%/%2%.ini", vp.id, recommended_archive.to_string()); - if (!archive_repository.get_file(source_subpath, ini_path_in_archive, vp.repo_id)) { + if (!archive_repository->get_file(source_subpath, ini_path_in_archive, vp.repo_id)) { BOOST_LOG_TRIVIAL(error) << format("Failed to open vendor .ini file when checking missing resources: %1%", ini_path_in_archive); continue; } @@ -958,7 +962,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version return updates; } -bool PresetUpdater::priv::perform_updates(Updates &&updates, const ArchiveRepositoryVector& repositories, bool snapshot) const +bool PresetUpdater::priv::perform_updates(Updates &&updates, const SharedArchiveRepositoryVector& repositories, bool snapshot) const { if (updates.incompats.size() > 0) { if (snapshot) { @@ -1045,9 +1049,9 @@ bool PresetUpdater::priv::perform_updates(Updates &&updates, const ArchiveReposi continue; try { - auto it = std::find_if(repositories.begin(), repositories.end(), [&vp](const auto& i){ return vp.repo_id == i->get_manifest().id; }); + auto it = std::find_if(repositories.begin(), repositories.end(), [&vp](const auto* i){ return vp.repo_id == i->get_manifest().id; }); if (it != repositories.end()) - get_or_copy_missing_resource(*(*it), vp.id, resource, vp.repo_id); + get_or_copy_missing_resource((*it), vp.id, resource, vp.repo_id); else { BOOST_LOG_TRIVIAL(error) << "Failed to prepare " << resource << " for " << vp.id << " " << model.id << ": Missing record for repository with repo_id " << vp.repo_id; } @@ -1089,20 +1093,16 @@ PresetUpdater::~PresetUpdater() } } -void PresetUpdater::sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map& selected_repo_uuids) +void PresetUpdater::sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler,SharedArchiveRepositoryVector&& repositories) { p->set_download_prefs(GUI::wxGetApp().app_config); if (!p->enabled_config_update) { return; } - p->thread = std::thread([this, &vendors = preset_bundle->vendors, &repositories, &selected_repo_uuids, evt_handler]() { + p->thread = std::thread([this, &vendors = preset_bundle->vendors, repositories = std::move(repositories), evt_handler]() { this->p->clear_cache_vendor(); this->p->prune_tmps(); - for(const auto& archive : repositories) { - auto it = selected_repo_uuids.find(archive->get_uuid()); - assert(it != selected_repo_uuids.end()); - if (it->second) { - this->p->sync_config(vendors, *archive); - } + for (const GUI::ArchiveRepository* archive : repositories) { + this->p->sync_config(vendors, archive); } wxCommandEvent* evt = new wxCommandEvent(EVT_CONFIG_UPDATER_SYNC_DONE); evt_handler->QueueEvent(evt); @@ -1120,19 +1120,15 @@ void PresetUpdater::cancel_sync() p->cancel = false; } -void PresetUpdater::sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map& selected_repo_uuids) +void PresetUpdater::sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const SharedArchiveRepositoryVector& repositories) { p->set_download_prefs(GUI::wxGetApp().app_config); if (!p->enabled_config_update) { return; } this->p->clear_cache_vendor(); this->p->prune_tmps(); - for (const auto& archive : repositories) { - auto it = selected_repo_uuids.find(archive->get_uuid()); - assert(it != selected_repo_uuids.end()); - if (it->second) { - this->p->sync_config(preset_bundle->vendors, *archive); - } + for (const GUI::ArchiveRepository* archive : repositories) { + this->p->sync_config(preset_bundle->vendors, archive); } } @@ -1179,7 +1175,7 @@ static bool reload_configs_update_gui() return true; } -PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3r_version, UpdateParams params, const ArchiveRepositoryVector& repositories) const +PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3r_version, UpdateParams params, const SharedArchiveRepositoryVector& repositories) const { if (! p->enabled_config_update) { return R_NOOP; } @@ -1319,7 +1315,7 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3 return R_NOOP; } -bool PresetUpdater::install_bundles_rsrc_or_cache_vendor(std::vector bundles, const ArchiveRepositoryVector& repositories, bool snapshot) const +bool PresetUpdater::install_bundles_rsrc_or_cache_vendor(std::vector bundles, const SharedArchiveRepositoryVector& repositories, bool snapshot) const { Updates updates; @@ -1425,7 +1421,7 @@ bool PresetUpdater::install_bundles_rsrc_or_cache_vendor(std::vectorperform_updates(std::move(updates), repositories, snapshot); } -void PresetUpdater::on_update_notification_confirm(const ArchiveRepositoryVector& repositories) +void PresetUpdater::on_update_notification_confirm(const SharedArchiveRepositoryVector& repositories) { if (!p->has_waiting_updates) return; diff --git a/src/slic3r/Utils/PresetUpdater.hpp b/src/slic3r/Utils/PresetUpdater.hpp index c1d8c43f48..25e8494253 100644 --- a/src/slic3r/Utils/PresetUpdater.hpp +++ b/src/slic3r/Utils/PresetUpdater.hpp @@ -19,7 +19,7 @@ class AppConfig; class PresetBundle; class Semver; -typedef std::vector> ArchiveRepositoryVector; +typedef std::vector SharedArchiveRepositoryVector; static constexpr const int SLIC3R_VERSION_BODY_MAX = 256; @@ -34,10 +34,10 @@ public: ~PresetUpdater(); // If either version check or config updating is enabled, get the appropriate data in the background and cache it. - void sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map& selected_repo_uuids); + void sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, SharedArchiveRepositoryVector&& repositories); void cancel_sync(); - void sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map& selected_repo_uuids); + void sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const SharedArchiveRepositoryVector& repositories); // If version check is enabled, check if chaced online slic3r version is newer, notify if so. void slic3r_update_notify(); @@ -62,14 +62,14 @@ public: // A false return value implies Slic3r should exit due to incompatibility of configuration. // Providing old slic3r version upgrade profiles on upgrade of an application even in case // that the config index installed from the Internet is equal to the index contained in the installation package. - UpdateResult config_update(const Semver &old_slic3r_version, UpdateParams params, const ArchiveRepositoryVector& repositories) const; + UpdateResult config_update(const Semver &old_slic3r_version, UpdateParams params, const SharedArchiveRepositoryVector& repositories) const; void update_index_db(); // "Update" a list of bundles from resources or cache/vendor (behaves like an online update). - bool install_bundles_rsrc_or_cache_vendor(std::vector bundles, const ArchiveRepositoryVector& repositories, bool snapshot = true) const; + bool install_bundles_rsrc_or_cache_vendor(std::vector bundles, const SharedArchiveRepositoryVector& repositories, bool snapshot = true) const; - void on_update_notification_confirm(const ArchiveRepositoryVector& repositories); + void on_update_notification_confirm(const SharedArchiveRepositoryVector& repositories); bool version_check_enabled() const;