Merge branch 'dk_updater'

This commit is contained in:
David Kocik 2021-11-10 15:28:03 +01:00
commit cbc0c6ccd0
9 changed files with 117 additions and 58 deletions

View File

@ -71,8 +71,6 @@ void AppConfig::set_defaults()
if (get("drop_project_action").empty())
set("drop_project_action", "1");
if (get("version_check").empty())
set("version_check", "1");
if (get("preset_update").empty())
set("preset_update", "1");

View File

@ -1206,7 +1206,7 @@ PageUpdate::PageUpdate(ConfigWizard *parent)
boldfont.SetWeight(wxFONTWEIGHT_BOLD);
auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _L("Check for application updates"));
box_slic3r->SetValue(app_config->get("version_check") == "1");
box_slic3r->SetValue(app_config->get("notify_release") != "none");
append(box_slic3r);
append_text(wxString::Format(_L(
"If enabled, %s checks for new application versions online. When a new version becomes available, "
@ -2697,7 +2697,7 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
app_config->set_vendors(appconfig_new);
app_config->set("version_check", page_update->version_check ? "1" : "0");
app_config->set("notify_release", page_update->version_check ? "all" : "none");
app_config->set("preset_update", page_update->preset_update ? "1" : "0");
app_config->set("export_sources_full_pathnames", page_reload_from_disk->full_pathnames ? "1" : "0");

View File

@ -83,6 +83,9 @@
#include <wx/msw/dark_mode.h>
#endif // _MSW_DARK_MODE
#endif
#ifdef _WIN32
#include <boost/dll/runtime_symbol_info.hpp>
#endif
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG
#include <boost/beast/core/detail/base64.hpp>
@ -424,6 +427,56 @@ bool static check_old_linux_datadir(const wxString& app_name) {
#endif
#ifdef _WIN32
static bool run_updater_win()
{
// find updater exe
boost::filesystem::path path_to_binary = boost::dll::program_location();
for (const auto& dir_entry : boost::filesystem::directory_iterator(path_to_binary.parent_path())) {
if (dir_entry.path().filename() == "prusaslicer-updater.exe") {
// run updater. Original args: /silent -restartapp prusa-slicer.exe -startappfirst
// Using quoted string as mentioned in CreateProcessW docs.
std::wstring wcmd = L"\"" + dir_entry.path().wstring() + L"\"";
wcmd += L" /silent";
// additional information
STARTUPINFOW si;
PROCESS_INFORMATION pi;
// set the size of the structures
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// start the program up
if (CreateProcessW(NULL, // the path
wcmd.data(), // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
)) {
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
} else {
BOOST_LOG_TRIVIAL(error) << "Failed to start prusaslicer-updater.exe with command " << wcmd;
}
break;
}
}
return false;
}
#endif //_WIN32
wxString file_wildcards(FileType file_type, const std::string &custom_extension)
{
static const std::string defaults[FT_SIZE] = {
@ -678,7 +731,6 @@ void GUI_App::post_init()
this->check_updates(false);
CallAfter([this] {
bool cw_showed = this->config_wizard_startup();
this->preset_updater->slic3r_update_notify();
this->preset_updater->sync(preset_bundle);
if (! cw_showed) {
// The CallAfter is needed as well, without it, GL extensions did not show.
@ -686,6 +738,15 @@ void GUI_App::post_init()
// sees something else than "we want something" on the first start.
show_send_system_info_dialog_if_needed();
}
bool updater_running =
#ifdef _WIN32
// Run external updater on Windows.
run_updater_win();
#else
false;
#endif // _WIN32
if (!updater_running)
this->preset_updater->slic3r_update_notify();
});
}
@ -1070,26 +1131,30 @@ bool GUI_App::on_init_inner()
Bind(EVT_SLIC3R_VERSION_ONLINE, [this](const wxCommandEvent& evt) {
app_config->set("version_online", into_u8(evt.GetString()));
app_config->save();
if (this->plater_ != nullptr) {
std::string opt = app_config->get("notify_release");
if (this->plater_ != nullptr && (opt == "all" || opt == "release")) {
if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) {
this->plater_->get_notification_manager()->push_notification(NotificationType::NewAppAvailable);
this->plater_->get_notification_manager()->push_notification(NotificationType::NewAppAvailable
, NotificationManager::NotificationLevel::ImportantNotificationLevel
, Slic3r::format(_u8L("New release version %1% is available."), evt.GetString())
, _u8L("See Download page.")
, [](wxEvtHandler* evnthndlr) {wxGetApp().open_web_page_localized("https://www.prusa3d.com/slicerweb"); return true; }
);
}
}
});
Bind(EVT_SLIC3R_ALPHA_VERSION_ONLINE, [this](const wxCommandEvent& evt) {
Bind(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, [this](const wxCommandEvent& evt) {
app_config->save();
if (this->plater_ != nullptr && app_config->get("notify_testing_release") == "1") {
if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) {
this->plater_->get_notification_manager()->push_notification(NotificationType::NewAlphaAvailable);
}
}
});
Bind(EVT_SLIC3R_BETA_VERSION_ONLINE, [this](const wxCommandEvent& evt) {
app_config->save();
if (this->plater_ != nullptr && app_config->get("notify_testing_release") == "1") {
if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) {
this->plater_->get_notification_manager()->close_notification_of_type(NotificationType::NewAlphaAvailable);
this->plater_->get_notification_manager()->push_notification(NotificationType::NewBetaAvailable);
if (this->plater_ != nullptr && app_config->get("notify_release") == "all") {
std::string evt_string = into_u8(evt.GetString());
if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(evt_string)) {
auto notif_type = (evt_string.find("beta") != std::string::npos ? NotificationType::NewBetaAvailable : NotificationType::NewAlphaAvailable);
this->plater_->get_notification_manager()->push_notification( notif_type
, NotificationManager::NotificationLevel::ImportantNotificationLevel
, Slic3r::format(_u8L("New prerelease version %1% is available."), evt_string)
, _u8L("See Releases page.")
, [](wxEvtHandler* evnthndlr) {wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }
);
}
}
});

View File

@ -41,12 +41,6 @@ const NotificationManager::NotificationData NotificationManager::basic_notificat
return true;
}
},
{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New version is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
{NotificationType::NewAlphaAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New alpha release is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
{NotificationType::NewBetaAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New beta release is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
{NotificationType::EmptyColorChangeCode, NotificationLevel::PrintInfoNotificationLevel, 10,
_u8L("You have just added a G-code for color change, but its value is empty.\n"
"To export the G-code correctly, check the \"Color Change G-code\" in \"Printer Settings > Custom G-code\"") },
@ -61,6 +55,8 @@ const NotificationManager::NotificationData NotificationManager::basic_notificat
{NotificationType::UndoDesktopIntegrationFail, NotificationLevel::WarningNotificationLevel, 10,
_u8L("Undo desktop integration failed.") },
{NotificationType::ExportOngoing, NotificationLevel::RegularNotificationLevel, 0, _u8L("Exporting.") },
//{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New version is available."), _u8L("See Releases page."), [](wxEvtHandler* evnthndlr) {
// wxGetApp().open_browser_with_warning_dialog("https://github.com/prusa3d/PrusaSlicer/releases"); return true; }},
//{NotificationType::NewAppAvailable, NotificationLevel::ImportantNotificationLevel, 20, _u8L("New vesion of PrusaSlicer is available.", _u8L("Download page.") },
//{NotificationType::LoadingFailed, NotificationLevel::RegularNotificationLevel, 20, _u8L("Loading of model has Failed") },
//{NotificationType::DeviceEjected, NotificationLevel::RegularNotificationLevel, 10, _u8L("Removable device has been safely ejected")} // if we want changeble text (like here name of device), we need to do it as CustomNotification

View File

@ -150,7 +150,7 @@ public:
// Push a NotificationType::CustomNotification with NotificationLevel::RegularNotificationLevel and 10s fade out interval.
void push_notification(const std::string& text, int timestamp = 0);
// Push a NotificationType::CustomNotification with provided notification level and 10s for RegularNotificationLevel.
// ErrorNotificationLevel and ImportantNotificationLevel are never faded out.
// ErrorNotificationLevel are never faded out.
void push_notification(NotificationType type, NotificationLevel level, const std::string& text, const std::string& hypertext = "",
std::function<bool(wxEvtHandler*)> callback = std::function<bool(wxEvtHandler*)>(), int timestamp = 0);
// Pushes basic_notification with delay. See push_delayed_notification_data.
@ -720,7 +720,7 @@ private:
case NotificationLevel::ErrorNotificationLevel: return 0;
case NotificationLevel::WarningNotificationLevel: return 0;
case NotificationLevel::ImportantNotificationLevel: return 0;
case NotificationLevel::ImportantNotificationLevel: return 20;
case NotificationLevel::ProgressBarNotificationLevel: return 2;
case NotificationLevel::PrintInfoShortNotificationLevel: return 5;
case NotificationLevel::RegularNotificationLevel: return 10;

View File

@ -141,14 +141,6 @@ void PreferencesDialog::build(size_t selected_tab)
option = Option(def, "background_processing");
m_optgroup_general->append_single_option_line(option);
// Please keep in sync with ConfigWizard
def.label = L("Check for application updates");
def.type = coBool;
def.tooltip = L("If enabled, PrusaSlicer will check for the new versions of itself online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done.");
def.set_default_value(new ConfigOptionBool(app_config->get("version_check") == "1"));
option = Option(def, "version_check");
m_optgroup_general->append_single_option_line(option);
m_optgroup_general->append_separator();
// Please keep in sync with ConfigWizard

View File

@ -26,7 +26,7 @@ namespace GUI {
static const char* URL_CHANGELOG = "https://files.prusa3d.com/?latest=slicer-stable&lng=%1%";
static const char* URL_DOWNLOAD = "https://www.prusa3d.com/downloads&lng=%1%";
static const char* URL_DOWNLOAD = "https://www.prusa3d.com/slicerweb&lng=%1%";
static const char* URL_DEV = "https://github.com/prusa3d/PrusaSlicer/releases/tag/version_%1%";
static const std::string CONFIG_UPDATE_WIKI_URL("https://github.com/prusa3d/PrusaSlicer/wiki/Slic3r-PE-1.40-configuration-update");

View File

@ -137,8 +137,7 @@ struct Updates
wxDEFINE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent);
wxDEFINE_EVENT(EVT_SLIC3R_ALPHA_VERSION_ONLINE, wxCommandEvent);
wxDEFINE_EVENT(EVT_SLIC3R_BETA_VERSION_ONLINE, wxCommandEvent);
wxDEFINE_EVENT(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, wxCommandEvent);
struct PresetUpdater::priv
{
@ -189,7 +188,7 @@ PresetUpdater::priv::priv()
// Pull relevant preferences from AppConfig
void PresetUpdater::priv::set_download_prefs(AppConfig *app_config)
{
enabled_version_check = app_config->get("version_check") == "1";
enabled_version_check = app_config->get("notify_release") != "none";
version_check_url = app_config->version_check_url();
enabled_config_update = app_config->get("preset_update") == "1" && !app_config->legacy_datadir();
}
@ -276,8 +275,9 @@ void PresetUpdater::priv::parse_version_string(const std::string& body) const
version = body.substr(0, first_nl_pos);
else
version = body;
if (!Semver::parse(version)) {
BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
boost::optional<Semver> release_version = Semver::parse(version);
if (!release_version) {
BOOST_LOG_TRIVIAL(error) << format("Received invalid contents from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
return;
}
BOOST_LOG_TRIVIAL(info) << format("Got %1% online version: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
@ -286,6 +286,7 @@ void PresetUpdater::priv::parse_version_string(const std::string& body) const
GUI::wxGetApp().QueueEvent(evt);
// alpha / beta version
std::vector<std::string> prerelease_versions;
size_t nexn_nl_pos = first_nl_pos;
while (nexn_nl_pos != std::string::npos && body.size() > nexn_nl_pos + 1) {
const auto last_nl_pos = nexn_nl_pos;
@ -300,28 +301,36 @@ void PresetUpdater::priv::parse_version_string(const std::string& body) const
if (line.substr(0, 6) == "alpha=") {
version = line.substr(6);
if (!Semver::parse(version)) {
BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents for alpha release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
BOOST_LOG_TRIVIAL(error) << format("Received invalid contents for alpha release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
return;
}
BOOST_LOG_TRIVIAL(info) << format("Got %1% online version of alpha release: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_ALPHA_VERSION_ONLINE);
evt->SetString(GUI::from_u8(version));
GUI::wxGetApp().QueueEvent(evt);
prerelease_versions.emplace_back(version);
// beta
}
else if (line.substr(0, 5) == "beta=") {
version = line.substr(5);
if (!Semver::parse(version)) {
BOOST_LOG_TRIVIAL(warning) << format("Received invalid contents for beta release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
BOOST_LOG_TRIVIAL(error) << format("Received invalid contents for beta release from `%1%`: Not a correct semver: `%2%`", SLIC3R_APP_NAME, version);
return;
}
BOOST_LOG_TRIVIAL(info) << format("Got %1% online version of beta release: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_BETA_VERSION_ONLINE);
evt->SetString(GUI::from_u8(version));
GUI::wxGetApp().QueueEvent(evt);
prerelease_versions.emplace_back(version);
}
}
// find recent version that is newer than last full release.
boost::optional<Semver> recent_version;
for (const std::string& ver_string : prerelease_versions) {
boost::optional<Semver> ver = Semver::parse(ver_string);
if (ver && *release_version < *ver && ((recent_version && *recent_version < *ver) || !recent_version)) {
recent_version = ver;
version = ver_string;
}
}
if (recent_version) {
BOOST_LOG_TRIVIAL(info) << format("Got %1% online version: `%2%`. Sending to GUI thread...", SLIC3R_APP_NAME, version);
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE);
evt->SetString(GUI::from_u8(version));
GUI::wxGetApp().QueueEvent(evt);
}
}
// Download vendor indices. Also download new bundles if an index indicates there's a new one available.
@ -741,8 +750,8 @@ void PresetUpdater::sync(PresetBundle *preset_bundle)
void PresetUpdater::slic3r_update_notify()
{
if (! p->enabled_version_check) { return; }
if (! p->enabled_version_check)
return;
auto* app_config = GUI::wxGetApp().app_config;
const auto ver_online_str = app_config->get("version_online");
const auto ver_online = Semver::parse(ver_online_str);
@ -754,7 +763,7 @@ void PresetUpdater::slic3r_update_notify()
GUI::MsgUpdateSlic3r notification(Slic3r::SEMVER, *ver_online);
notification.ShowModal();
if (notification.disable_version_check()) {
app_config->set("version_check", "0");
app_config->set("notify_release", "none");
p->enabled_version_check = false;
}
}

View File

@ -63,7 +63,6 @@ private:
};
wxDECLARE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent);
wxDECLARE_EVENT(EVT_SLIC3R_ALPHA_VERSION_ONLINE, wxCommandEvent);
wxDECLARE_EVENT(EVT_SLIC3R_BETA_VERSION_ONLINE, wxCommandEvent);
wxDECLARE_EVENT(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, wxCommandEvent);
}
#endif