ENH: [STUDIO-4029] sync printer config with cloud

Change-Id: Icffee9d5987131e1d78d51ccfcafeefff18f26cb
Jira: STUDIO-4029
(cherry picked from commit 5b58e5f2658753efbf11037f0b6cbb023070c0ea)
This commit is contained in:
chunmao.guo 2023-08-16 15:38:16 +08:00 committed by Lane.Wei
parent 11f0fb6016
commit 042e6bf991
8 changed files with 186 additions and 15 deletions

View File

@ -470,6 +470,12 @@ PrinterArch MachineObject::get_printer_arch() const
return DeviceManager::get_printer_arch(printer_type);
}
void MachineObject::reload_printer_settings()
{
print_json.load_compatible_settings("", "");
parse_json("{}");
}
MachineObject::MachineObject(NetworkAgent* agent, std::string name, std::string id, std::string ip)
:dev_name(name),
dev_id(id),
@ -2592,9 +2598,7 @@ int MachineObject::parse_json(std::string payload)
if (j_pre["print"]["msg"].get<int>() == 0) { //all message
BOOST_LOG_TRIVIAL(trace) << "static: get push_all msg, dev_id=" << dev_id;
m_push_count++;
if (j_pre["print"].contains("printer_type")) {
printer_type = parse_printer_type(j_pre["print"]["printer_type"].get<std::string>());
}
if (!printer_type.empty())
print_json.load_compatible_settings(printer_type, "");
print_json.diff2all_base_reset(j_pre);
} else if (j_pre["print"]["msg"].get<int>() == 1) { //diff message
@ -4764,6 +4768,12 @@ MachineObject* DeviceManager::get_local_selected_machine()
return get_local_machine(local_selected_machine);
}
void DeviceManager::reload_printer_settings()
{
for (auto obj : this->userMachineList)
obj.second->reload_printer_settings();
}
MachineObject* DeviceManager::get_default_machine() {
std::string dev_id;

View File

@ -413,6 +413,7 @@ public:
std::string printer_type; /* model_id */
PrinterSeries get_printer_series() const;
PrinterArch get_printer_arch() const;
void reload_printer_settings();
std::string printer_thumbnail_img;
std::string monitor_upgrade_printer_img;
@ -911,6 +912,7 @@ public:
MachineObject* get_my_machine(std::string dev_id);
void erase_user_machine(std::string dev_id);
void clean_user_info();
void reload_printer_settings();
bool set_selected_machine(std::string dev_id, bool need_disconnect = false);
MachineObject* get_selected_machine();

View File

@ -39,6 +39,7 @@ namespace GUI {
wxDEFINE_EVENT(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, EjectDriveNotificationClickedEvent);
wxDEFINE_EVENT(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, ExportGcodeNotificationClickedEvent);
wxDEFINE_EVENT(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, PresetUpdateAvailableClickedEvent);
wxDEFINE_EVENT(EVT_PRINTER_CONFIG_UPDATE_AVAILABLE_CLICKED, PrinterConfigUpdateAvailableClickedEvent);
namespace {
/* // not used?

View File

@ -27,6 +27,8 @@ using ExportGcodeNotificationClickedEvent = SimpleEvent;
wxDECLARE_EVENT(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, ExportGcodeNotificationClickedEvent);
using PresetUpdateAvailableClickedEvent = SimpleEvent;
wxDECLARE_EVENT(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, PresetUpdateAvailableClickedEvent);
using PrinterConfigUpdateAvailableClickedEvent = SimpleEvent;
wxDECLARE_EVENT(EVT_PRINTER_CONFIG_UPDATE_AVAILABLE_CLICKED, PrinterConfigUpdateAvailableClickedEvent);
using CancelFn = std::function<void()>;
@ -141,6 +143,7 @@ enum class NotificationType
BBLPluginInstallHint,
BBLPluginUpdateAvailable,
BBLPreviewOnlyMode,
BBLPrinterConfigUpdateAvailable,
};
class NotificationManager
@ -914,6 +917,15 @@ private:
return true;
}},
NotificationData{NotificationType::BBLPrinterConfigUpdateAvailable, NotificationLevel::ImportantNotificationLevel, BBL_NOTICE_MAX_INTERVAL,
_u8L("New printer config available."),
_u8L("Details"),
[](wxEvtHandler* evnthndlr) {
if (evnthndlr != nullptr)
wxPostEvent(evnthndlr, PrinterConfigUpdateAvailableClickedEvent(EVT_PRINTER_CONFIG_UPDATE_AVAILABLE_CLICKED));
return true;
}},
NotificationData{NotificationType::UndoDesktopIntegrationFail, NotificationLevel::WarningNotificationLevel, 10,
_u8L("Undo integration failed.") },
NotificationData{NotificationType::ExportOngoing, NotificationLevel::RegularNotificationLevel, 0, _u8L("Exporting.")},

View File

@ -2693,6 +2693,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
this->q->Bind(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, [this](EjectDriveNotificationClickedEvent&) { this->q->eject_drive(); });
this->q->Bind(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, [this](ExportGcodeNotificationClickedEvent&) { this->q->export_gcode(true); });
this->q->Bind(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, [](PresetUpdateAvailableClickedEvent&) { wxGetApp().get_preset_updater()->on_update_notification_confirm(); });
this->q->Bind(EVT_PRINTER_CONFIG_UPDATE_AVAILABLE_CLICKED, [](PrinterConfigUpdateAvailableClickedEvent&) {
wxGetApp().get_preset_updater()->do_printer_config_update();
wxGetApp().getDeviceManager()->reload_printer_settings(); });
/* BBS do not handle removeable driver event */
this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this](RemovableDriveEjectEvent &evt) {

View File

@ -212,6 +212,8 @@ struct PresetUpdater::priv
bool has_waiting_updates { false };
Updates waiting_updates;
bool has_waiting_printer_updates { false };
Updates waiting_printer_updates;
struct Resource
{
@ -235,11 +237,13 @@ struct PresetUpdater::priv
void sync_config(std::string http_url, const VendorMap vendors);
void sync_tooltip(std::string http_url, std::string language);
void sync_plugins(std::string http_url, std::string plugin_version);
bool get_cached_plugins_version(std::string& cached_version);
void sync_printer_config(std::string http_url);
bool get_cached_plugins_version(std::string &cached_version);
//BBS: refine preset update logic
bool install_bundles_rsrc(std::vector<std::string> bundles, bool snapshot) const;
void check_installed_vendor_profiles() const;
Updates get_printer_config_updates(bool update = false) const;
Updates get_config_updates(const Semver& old_slic3r_version) const;
bool perform_updates(Updates &&updates, bool snapshot = true) const;
void set_waiting_updates(Updates u);
@ -257,6 +261,7 @@ PresetUpdater::priv::priv()
set_download_prefs(GUI::wxGetApp().app_config);
// Install indicies from resources. Only installs those that are either missing or older than in resources.
check_installed_vendor_profiles();
perform_updates(get_printer_config_updates(), false);
// Load indices from the cache directory.
//index_db = Index::load_db();
}
@ -869,7 +874,7 @@ void PresetUpdater::priv::sync_tooltip(std::string http_url, std::string languag
}
}
//return true means there are plugins files
// return true means there are plugins files
bool PresetUpdater::priv::get_cached_plugins_version(std::string& cached_version)
{
std::string data_dir_str = data_dir();
@ -1013,6 +1018,68 @@ void PresetUpdater::priv::sync_plugins(std::string http_url, std::string plugin_
}
}
void PresetUpdater::priv::sync_printer_config(std::string http_url)
{
std::string curr_version = SLIC3R_VERSION;
std::string using_version = curr_version.substr(0, 6) + "00.00";
std::string cached_version;
std::string data_dir_str = data_dir();
boost::filesystem::path data_dir_path(data_dir_str);
auto config_folder = data_dir_path / "printers";
auto cache_folder = data_dir_path / "ota" / "printers";
try {
boost::filesystem::load_string_file(config_folder / "version.txt", curr_version);
boost::algorithm::trim(curr_version);
} catch (...) {}
try {
boost::filesystem::load_string_file(cache_folder / "version.txt", cached_version);
boost::algorithm::trim(cached_version);
} catch (...) {}
if (!cached_version.empty()) {
bool need_delete_cache = false;
Semver current_semver = curr_version;
Semver cached_semver = cached_version;
if ((cached_semver.maj() != current_semver.maj()) || (cached_semver.min() != current_semver.min())) {
need_delete_cache = true;
BOOST_LOG_TRIVIAL(info) << boost::format("cached printer config version %1% not match with current %2%") % cached_version % curr_version;
} else if (cached_semver.patch() <= current_semver.patch()) {
need_delete_cache = true;
BOOST_LOG_TRIVIAL(info) << boost::format("cached printer config version %1% not newer than current %2%") % cached_version % curr_version;
} else {
using_version = cached_version;
}
if (need_delete_cache) {
std::string data_dir_str = data_dir();
cached_version = curr_version;
}
}
try {
std::map<std::string, Resource> resources{{"slicer/printer/bbl", {using_version, "", "", cache_folder.string()}}};
sync_resources(http_url, resources, false, cached_version, "printer.json");
} catch (std::exception &e) {
BOOST_LOG_TRIVIAL(warning) << format("[BBL Updater] sync_printer_config: %1%", e.what());
}
bool result = false;
try {
boost::filesystem::load_string_file(cache_folder / "version.txt", cached_version);
boost::algorithm::trim(cached_version);
result = true;
} catch (...) {}
if (result) {
BOOST_LOG_TRIVIAL(info) << format("[BBL Updater] found new printer config: %1%, prompt to update", cached_version);
waiting_printer_updates = get_printer_config_updates(true);
if (waiting_printer_updates.updates.size() > 0) {
has_waiting_printer_updates = true;
GUI::wxGetApp().plater()->get_notification_manager()->push_notification(GUI::NotificationType::BBLPrinterConfigUpdateAvailable);
}
}
}
bool PresetUpdater::priv::install_bundles_rsrc(std::vector<std::string> bundles, bool snapshot) const
{
@ -1109,6 +1176,53 @@ void PresetUpdater::priv::check_installed_vendor_profiles() const
install_bundles_rsrc(bundles, false);
}
Updates PresetUpdater::priv::get_printer_config_updates(bool update) const
{
std::string data_dir_str = data_dir();
boost::filesystem::path data_dir_path(data_dir_str);
boost::filesystem::path resc_dir_path(resources_dir());
auto config_folder = data_dir_path / "printers";
auto resc_folder = (update ? cache_path : resc_dir_path) / "printers";
std::string curr_version;
std::string resc_version;
try {
boost::filesystem::load_string_file(resc_folder / "version.txt", resc_version);
boost::algorithm::trim(resc_version);
} catch (...) {}
try {
boost::filesystem::load_string_file(config_folder / "version.txt", curr_version);
boost::algorithm::trim(curr_version);
} catch (...) {}
if (!curr_version.empty()) {
Semver curr_ver = curr_version;
Semver resc_ver = resc_version;
bool version_match = ((resc_ver.maj() == curr_ver.maj()) && (resc_ver.min() == curr_ver.min()));
if (!version_match || (curr_ver < resc_ver)) {
BOOST_LOG_TRIVIAL(info) << "[BBL Updater]:found newer version " << resc_version << " from resource, old version " << curr_version;
} else {
return {};
}
}
Updates updates;
Version version;
version.config_version = resc_version;
std::string change_log;
if (update) {
std::string changelog_file = (resc_folder / "printer.json").string();
try {
boost::nowide::ifstream ifs(changelog_file);
json j;
ifs >> j;
version.comment = j["description"];
} catch (...) {}
}
updates.updates.emplace_back(std::move(resc_folder), std::move(config_folder), version, "bbl", change_log, version.comment, false, true);
return updates;
}
// Generates a list of bundle updates that are to be performed.
// Version of slic3r that was running the last time and which was read out from PrusaSlicer.ini is provided
// as a parameter.
@ -1304,6 +1418,7 @@ void PresetUpdater::sync(std::string http_url, std::string language, std::string
if (p->cancel)
return;
this->p->sync_plugins(http_url, plugin_version);
this->p->sync_printer_config(http_url);
//if (p->cancel)
// return;
//remove the tooltip currently
@ -1492,6 +1607,30 @@ void PresetUpdater::on_update_notification_confirm()
}
}
void PresetUpdater::do_printer_config_update()
{
if (!p->has_waiting_printer_updates)
return;
BOOST_LOG_TRIVIAL(info) << "Update of printer configs available. Asking for confirmation ...";
std::vector<GUI::MsgUpdateConfig::Update> updates_msg;
for (const auto &update : p->waiting_printer_updates.updates) {
std::string changelog = update.change_log;
updates_msg.emplace_back(update.vendor, update.version.config_version, update.descriptions, std::move(changelog));
}
GUI::MsgUpdateConfig dlg(updates_msg);
const auto res = dlg.ShowModal();
if (res == wxID_OK) {
BOOST_LOG_TRIVIAL(debug) << "User agreed to perform the update";
if (p->perform_updates(std::move(p->waiting_printer_updates)))
p->has_waiting_printer_updates = false;
} else {
BOOST_LOG_TRIVIAL(info) << "User refused the update";
}
}
bool PresetUpdater::version_check_enabled() const
{
return p->enabled_version_check;

View File

@ -57,6 +57,7 @@ public:
bool install_bundles_rsrc(std::vector<std::string> bundles, bool snapshot = true) const;
void on_update_notification_confirm();
void do_printer_config_update();
bool version_check_enabled() const;

View File

@ -75,21 +75,24 @@ int json_diff::all2diff_base_reset(json const &base)
bool json_diff::load_compatible_settings(std::string const &type, std::string const &version)
{
// Reload on empty type and version
if (!type.empty() || !version.empty()) {
std::string type2 = type.empty() ? printer_type : type;
std::string version2 = version.empty() ? printer_version : version;
if (type2 == printer_type && version2 == printer_version)
return false;
printer_type = type2;
printer_version = version2;
}
settings_base.clear();
std::string config_file = Slic3r::resources_dir() + "/printers/" + type2 + ".json";
std::string config_file = Slic3r::data_dir() + "/printers/" + printer_type + ".json";
boost::nowide::ifstream json_file(config_file.c_str());
try {
json versions;
if (json_file.is_open()) {
json_file >> versions;
for (auto iter = versions.begin(); iter != versions.end(); ++iter) {
if (iter.key() > version2)
if (iter.key() > printer_version)
break;
merge_objects(*iter, settings_base);
}