Merge branch 'dk_vendor_out'

This commit is contained in:
Lukas Matena 2025-02-17 15:40:32 +01:00
commit c4d5867403
10 changed files with 104 additions and 11 deletions

View File

@ -1538,6 +1538,15 @@ bool GUI_App::on_init_inner()
this->check_updates(false); this->check_updates(false);
}); });
Bind(EVT_CONFIG_UPDATER_FAILED_ARCHIVE, [this](const wxCommandEvent& evt) {
assert(!evt.GetString().empty());
// TRN Notification text, 1 is list of vendors.
std::string notification_text = format(_u8L("Update Check Failed for the Following Vendors:\n\n%1%\nThis may be due to an account logout or a lost connection. Please verify your account status and internet connection. Then select \"Check for Configuration Updates\" to repeat."), evt.GetString());
notification_manager()->push_notification(NotificationType::FailedSecretVendorUpdateSync,
NotificationManager::NotificationLevel::WarningNotificationLevel,
notification_text);
});
Bind(wxEVT_ACTIVATE_APP, [this](const wxActivateEvent &evt) { Bind(wxEVT_ACTIVATE_APP, [this](const wxActivateEvent &evt) {
if (plater_) { if (plater_) {
if (auto user_account = plater_->get_user_account()) if (auto user_account = plater_->get_user_account())

View File

@ -146,6 +146,8 @@ enum class NotificationType
SupportNozzleDiameterDiffer, SupportNozzleDiameterDiffer,
// Transient error on Prusa Account communication - user is informed and has option to cancel (logout) // Transient error on Prusa Account communication - user is informed and has option to cancel (logout)
AccountTransientRetry, AccountTransientRetry,
// Failed to download secret repo archive
FailedSecretVendorUpdateSync
}; };
class NotificationManager class NotificationManager

View File

@ -971,6 +971,7 @@ void Plater::priv::init()
std::string text = format(_u8L("Logged to Prusa Account as %1%."), username); std::string text = format(_u8L("Logged to Prusa Account as %1%."), username);
// login notification // login notification
this->notification_manager->close_notification_of_type(NotificationType::UserAccountID); this->notification_manager->close_notification_of_type(NotificationType::UserAccountID);
this->notification_manager->close_notification_of_type(NotificationType::FailedSecretVendorUpdateSync);
// show connect tab // show connect tab
this->notification_manager->push_notification(NotificationType::UserAccountID, NotificationManager::NotificationLevel::ImportantNotificationLevel, text); this->notification_manager->push_notification(NotificationType::UserAccountID, NotificationManager::NotificationLevel::ImportantNotificationLevel, text);

View File

@ -786,6 +786,7 @@ void PresetArchiveDatabase::read_server_manifest(const std::string& json_body)
) == m_archive_repositories.end()) ) == m_archive_repositories.end())
{ {
ArchiveRepository::RepositoryManifest manifest(repo_ptr->get_manifest()); ArchiveRepository::RepositoryManifest manifest(repo_ptr->get_manifest());
manifest.not_in_manifest = true;
m_archive_repositories.emplace_back(std::make_unique<OnlineArchiveRepository>(repo_ptr->get_uuid(), std::move(manifest))); m_archive_repositories.emplace_back(std::make_unique<OnlineArchiveRepository>(repo_ptr->get_uuid(), std::move(manifest)));
} }
} }
@ -809,8 +810,7 @@ SharedArchiveRepositoryVector PresetArchiveDatabase::get_selected_archive_reposi
{ {
SharedArchiveRepositoryVector result; SharedArchiveRepositoryVector result;
result.reserve(m_archive_repositories.size()); result.reserve(m_archive_repositories.size());
for (const auto &repo_ptr : m_archive_repositories) for (const auto &repo_ptr : m_archive_repositories) {
{
auto it = m_selected_repositories_uuid.find(repo_ptr->get_uuid()); auto it = m_selected_repositories_uuid.find(repo_ptr->get_uuid());
assert(it != m_selected_repositories_uuid.end()); assert(it != m_selected_repositories_uuid.end());
if (it->second) { if (it->second) {

View File

@ -37,6 +37,7 @@ public:
// not read from manifest json // not read from manifest json
boost::filesystem::path tmp_path; // Where archive is unzziped. Created each app run. 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. boost::filesystem::path source_path; // Path given by user. Stored between app runs.
bool not_in_manifest {false};
RepositoryManifest() = default; RepositoryManifest() = default;
RepositoryManifest( RepositoryManifest(
@ -47,7 +48,8 @@ public:
const std::string &description = "", const std::string &description = "",
const std::string &visibility = "", const std::string &visibility = "",
const boost::filesystem::path &tmp_path = "", const boost::filesystem::path &tmp_path = "",
const boost::filesystem::path &source_path = "" const boost::filesystem::path &source_path = "",
bool not_in_manifest = false
) )
: id(id) : id(id)
, name(name) , name(name)
@ -57,6 +59,7 @@ public:
, visibility(visibility) , visibility(visibility)
, tmp_path(tmp_path) , tmp_path(tmp_path)
, source_path(source_path) , source_path(source_path)
, not_in_manifest(not_in_manifest)
{} {}
RepositoryManifest(const RepositoryManifest &other) RepositoryManifest(const RepositoryManifest &other)
: id(other.id) : id(other.id)
@ -67,6 +70,7 @@ public:
, visibility(other.visibility) , visibility(other.visibility)
, tmp_path(other.tmp_path) , tmp_path(other.tmp_path)
, source_path(other.source_path) , source_path(other.source_path)
, not_in_manifest(other.not_in_manifest)
{} {}
}; };
// Use std::move when calling constructor. // Use std::move when calling constructor.

View File

@ -115,7 +115,7 @@ void RepositoryUpdateUIManager::fill_entries(bool init_selection/* = false*/)
if (data.source_path.empty()) { if (data.source_path.empty()) {
// online repo // online repo
m_online_entries.push_back({ is_selected, uuid, data.name, data.description, data.visibility }); m_online_entries.push_back({ is_selected, uuid, data.name, data.description, data.visibility, data.not_in_manifest });
} }
else { else {
// offline repo // offline repo
@ -161,12 +161,19 @@ void RepositoryUpdateUIManager::fill_grids()
}); });
add(chb); add(chb);
if (entry.visibility.empty()) if (entry.not_in_manifest) {
add(new wxStaticText(m_parent, wxID_ANY, "")); wxStaticBitmap* bmp = new wxStaticBitmap(m_parent, wxID_ANY, *get_bmp_bundle("notification_warning"));
else { // TRN tooltip in Configuration Wizard - Configuration Sources
bmp->SetToolTip(_L("This source has installed vendors, yet you do not have rights to receive updates of it.\n"
"This may be because you are logged out. Log in to restore access to all your subscribed sources.\n"
"If you are logged in, please concider unsubscribing this source."));
add(bmp);
} else if (!entry.visibility.empty()) {
wxStaticBitmap* bmp = new wxStaticBitmap(m_parent, wxID_ANY, *get_bmp_bundle("info")); wxStaticBitmap* bmp = new wxStaticBitmap(m_parent, wxID_ANY, *get_bmp_bundle("info"));
bmp->SetToolTip(from_u8(entry.visibility)); bmp->SetToolTip(from_u8(entry.visibility));
add(bmp); add(bmp);
} else {
add(new wxStaticText(m_parent, wxID_ANY, ""));
} }
add(new wxStaticText(m_parent, wxID_ANY, from_u8(entry.name) + " ")); add(new wxStaticText(m_parent, wxID_ANY, from_u8(entry.name) + " "));

View File

@ -21,14 +21,15 @@ namespace GUI {
class RepositoryUpdateUIManager class RepositoryUpdateUIManager
{ {
struct OnlineEntry { struct OnlineEntry {
OnlineEntry(bool use, const std::string &id, const std::string &name, const std::string &description, const std::string &visibility) : OnlineEntry(bool use, const std::string &id, const std::string &name, const std::string &description, const std::string &visibility, bool not_in_manifest) :
use(use), id(id), name(name), description(description), visibility(visibility) {} use(use), id(id), name(name), description(description), visibility(visibility) ,not_in_manifest(not_in_manifest) {}
bool use; bool use;
std::string id; std::string id;
std::string name; std::string name;
std::string description; std::string description;
std::string visibility; std::string visibility;
bool not_in_manifest;
}; };
struct OfflineEntry { struct OfflineEntry {

View File

@ -311,7 +311,8 @@ void PresetUpdater::priv::sync_config(const VendorMap& vendors, const ArchiveRep
// Download profiles archive zip // Download profiles archive zip
fs::path archive_path(cache_path / "vendor_indices.zip"); fs::path archive_path(cache_path / "vendor_indices.zip");
if (!archive_repository->get_archive(archive_path, ui_status)) { if (!archive_repository->get_archive(archive_path, ui_status)) {
BOOST_LOG_TRIVIAL(error) << "Download of vedor profiles archive zip of " << archive_repository->get_manifest().id << " repository has failed."; BOOST_LOG_TRIVIAL(error) << "Download of vendor profiles archive zip of " << archive_repository->get_manifest().id << " repository has failed.";
ui_status->add_failed_archive(archive_repository->get_manifest().id);
return; return;
} }
if (ui_status->get_canceled()) { if (ui_status->get_canceled()) {

View File

@ -1,6 +1,7 @@
#include "PresetUpdaterWrapper.hpp" #include "PresetUpdaterWrapper.hpp"
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/GUI.hpp"
#include "slic3r/GUI/I18N.hpp" #include "slic3r/GUI/I18N.hpp"
#include "slic3r/GUI/MsgDialog.hpp" #include "slic3r/GUI/MsgDialog.hpp"
#include "slic3r/GUI/format.hpp" #include "slic3r/GUI/format.hpp"
@ -15,6 +16,43 @@ namespace Slic3r {
wxDEFINE_EVENT(EVT_PRESET_UPDATER_STATUS_END, PresetUpdaterStatusSimpleEvent); wxDEFINE_EVENT(EVT_PRESET_UPDATER_STATUS_END, PresetUpdaterStatusSimpleEvent);
wxDEFINE_EVENT(EVT_PRESET_UPDATER_STATUS_PRINT, PresetUpdaterStatusMessageEvent); wxDEFINE_EVENT(EVT_PRESET_UPDATER_STATUS_PRINT, PresetUpdaterStatusMessageEvent);
wxDEFINE_EVENT(EVT_CONFIG_UPDATER_SYNC_DONE, wxCommandEvent); wxDEFINE_EVENT(EVT_CONFIG_UPDATER_SYNC_DONE, wxCommandEvent);
wxDEFINE_EVENT(EVT_CONFIG_UPDATER_FAILED_ARCHIVE, wxCommandEvent);
namespace {
// Returns string of vendors that failed archive download. divided by new line
std::string proccess_failed_archives(const std::vector<std::string>& failed_archives, const VendorMap& vendors, const SharedArchiveRepositoryVector &repos)
{
std::string failed_vendors;
for (const std::string& failed_archive : failed_archives) {
// find if failed_archive is secret
if (const auto it =
std::find_if(repos.begin(), repos.end(),
[failed_archive](const auto* rep){
return rep->get_manifest().id == failed_archive;
})
; it != repos.end())
{
// add all installed vendors of failed_archive
for (const auto& pair :vendors) {
if (pair.second.repo_id == failed_archive) {
failed_vendors += pair.second.name + "\n";
}
}
}
}
return failed_vendors;
}
void display_failed_vendors_dialog(wxWindow *parent, const std::string& failed_vendors)
{
// TRN Dialog text, 1 is list of vendors.
std::string dialog_text = format(_u8L("Update Check Failed for the Following Vendors:\n\n%1%\n"
"This may be because you are logged out. Log in to restore access to all your subscribed sources.\n"
"If you are logged in and a vendor is failing, it may no longer be available in your subscribed sources."), failed_vendors);
GUI::WarningDialog dialog(parent, dialog_text, _L("Update Check Failed"), wxOK);
dialog.ShowModal();
}
}
PresetUpdaterWrapper::PresetUpdaterWrapper() PresetUpdaterWrapper::PresetUpdaterWrapper()
: m_preset_updater(std::make_unique<PresetUpdater>()) : m_preset_updater(std::make_unique<PresetUpdater>())
@ -83,6 +121,13 @@ bool PresetUpdaterWrapper::wizard_sync(const PresetBundle* preset_bundle, const
return false; return false;
} }
// Find secret vendors that failed to download idx in archive
const SharedArchiveRepositoryVector &repos = m_preset_archive_database->get_selected_archive_repositories();
std::string failed_vendors = proccess_failed_archives(m_ui_status->get_failed_archives(), vendors_copy, repos);
if (!failed_vendors.empty()) {
display_failed_vendors_dialog(parent, failed_vendors);
}
// Offer update installation. // Offer update installation.
if (full_sync) { if (full_sync) {
const SharedArchiveRepositoryVector &repos = m_preset_archive_database->get_selected_archive_repositories(); const SharedArchiveRepositoryVector &repos = m_preset_archive_database->get_selected_archive_repositories();
@ -158,6 +203,14 @@ PresetUpdater::UpdateResult PresetUpdaterWrapper::check_updates_on_user_request(
GUI::ErrorDialog err_msg(nullptr, failed_paths, false); GUI::ErrorDialog err_msg(nullptr, failed_paths, false);
err_msg.ShowModal(); err_msg.ShowModal();
} }
// Find secret vendors that failed to download idx in archive
const SharedArchiveRepositoryVector &repos = m_preset_archive_database->get_selected_archive_repositories();
std::string failed_vendors = proccess_failed_archives(m_ui_status->get_failed_archives(), vendors_copy, repos);
if (!failed_vendors.empty()) {
display_failed_vendors_dialog(parent, failed_vendors);
}
// preset_updater::config_update does show wxDialog // preset_updater::config_update does show wxDialog
updater_result = m_preset_updater->config_update(old_slic3r_version, PresetUpdater::UpdateParams::SHOW_TEXT_BOX, m_preset_archive_database->get_selected_archive_repositories(), m_ui_status.get()); updater_result = m_preset_updater->config_update(old_slic3r_version, PresetUpdater::UpdateParams::SHOW_TEXT_BOX, m_preset_archive_database->get_selected_archive_repositories(), m_ui_status.get());
return updater_result; return updater_result;
@ -207,6 +260,14 @@ void PresetUpdaterWrapper::sync_preset_updater(wxEvtHandler* end_evt_handler, co
if (this->m_ui_status->get_canceled()) { return; } if (this->m_ui_status->get_canceled()) { return; }
wxCommandEvent* evt = new wxCommandEvent(EVT_CONFIG_UPDATER_SYNC_DONE); wxCommandEvent* evt = new wxCommandEvent(EVT_CONFIG_UPDATER_SYNC_DONE);
wxQueueEvent(end_evt_handler, evt); wxQueueEvent(end_evt_handler, evt);
// Find secret vendors that failed to download idx in archive
std::string failed_vendors = proccess_failed_archives(m_ui_status->get_failed_archives(), vendors_copy, repos);
if (!failed_vendors.empty()) {
wxCommandEvent* evt_arch = new wxCommandEvent(EVT_CONFIG_UPDATER_FAILED_ARCHIVE);
evt_arch->SetString(GUI::from_u8(failed_vendors));
wxQueueEvent(end_evt_handler, evt_arch);
}
}; };
m_worker_thread = std::thread(worker_body); m_worker_thread = std::thread(worker_body);
@ -244,6 +305,7 @@ void PresetUpdaterUIStatus::reset(PresetUpdaterUIStatus::PresetUpdaterRetryPolic
m_evt_handler = nullptr; m_evt_handler = nullptr;
m_error_msg.clear(); m_error_msg.clear();
m_target.clear(); m_target.clear();
m_failed_archives.clear();
} }
bool PresetUpdaterUIStatus::on_attempt(int attempt, unsigned delay) bool PresetUpdaterUIStatus::on_attempt(int attempt, unsigned delay)

View File

@ -25,6 +25,8 @@ using PresetUpdaterStatusMessageEvent = GUI::Event<wxString>;
wxDECLARE_EVENT(EVT_PRESET_UPDATER_STATUS_END, PresetUpdaterStatusSimpleEvent); wxDECLARE_EVENT(EVT_PRESET_UPDATER_STATUS_END, PresetUpdaterStatusSimpleEvent);
wxDECLARE_EVENT(EVT_PRESET_UPDATER_STATUS_PRINT, PresetUpdaterStatusMessageEvent); wxDECLARE_EVENT(EVT_PRESET_UPDATER_STATUS_PRINT, PresetUpdaterStatusMessageEvent);
wxDECLARE_EVENT(EVT_CONFIG_UPDATER_SYNC_DONE, wxCommandEvent); wxDECLARE_EVENT(EVT_CONFIG_UPDATER_SYNC_DONE, wxCommandEvent);
wxDECLARE_EVENT(EVT_CONFIG_UPDATER_FAILED_ARCHIVE, wxCommandEvent);
class PresetBundle; class PresetBundle;
class Semver; class Semver;
@ -55,6 +57,8 @@ public:
HttpRetryOpt get_retry_policy() const { return m_retry_policy; } HttpRetryOpt get_retry_policy() const { return m_retry_policy; }
std::string get_error() const { return m_error_msg; } std::string get_error() const { return m_error_msg; }
std::string get_target() const { return m_target; } std::string get_target() const { return m_target; }
void add_failed_archive(const std::string& id) { m_failed_archives.emplace_back(id); }
const std::vector<std::string>& get_failed_archives() { return m_failed_archives; }
// called from PresetUpdaterUIStatusCancel (ui thread) // called from PresetUpdaterUIStatusCancel (ui thread)
void set_canceled(bool val) { m_canceled.store(val); } void set_canceled(bool val) { m_canceled.store(val); }
@ -68,6 +72,8 @@ private:
HttpRetryOpt m_retry_policy; HttpRetryOpt m_retry_policy;
static const std::map<PresetUpdaterUIStatus::PresetUpdaterRetryPolicy, HttpRetryOpt> policy_map; static const std::map<PresetUpdaterUIStatus::PresetUpdaterRetryPolicy, HttpRetryOpt> policy_map;
std::vector<std::string> m_failed_archives;
}; };
// Purpose of this class: // Purpose of this class: