mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 06:52:03 +08:00
repo_prefix parameter and removing prefix before send to connect.
Change printer_model in full config before applying to print printer_model prefix handling when showing online printers in sidebar Select printer from connect by nozzle diameter (instead of pritner_variant) and by additional config options. + Moved standalone functions to UserAccountUtils Set as current without repo prefix when selecting preset with prefix, mind visible presets. prefer visible printers for selecting fix of selecting SLA printer Added prusalink for prefixed printer_model
This commit is contained in:
parent
a55c85ecef
commit
756a76a773
@ -165,6 +165,13 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
|
||||
res.repo_id = "";
|
||||
}
|
||||
|
||||
const auto repo_prefix = vendor_section.find("repo_prefix");
|
||||
if (repo_prefix != vendor_section.not_found()) {
|
||||
res.repo_prefix = repo_prefix->second.data();
|
||||
} else {
|
||||
res.repo_prefix = "";
|
||||
}
|
||||
|
||||
if (! load_all) {
|
||||
return res;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
std::string config_update_url;
|
||||
std::string changelog_url;
|
||||
std::string repo_id;
|
||||
std::string repo_prefix;
|
||||
bool templates_profile { false };
|
||||
|
||||
struct PrinterVariant {
|
||||
|
@ -23,6 +23,8 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/UserAccountCommunication.hpp
|
||||
GUI/UserAccountSession.cpp
|
||||
GUI/UserAccountSession.hpp
|
||||
GUI/UserAccountUtils.cpp
|
||||
GUI/UserAccountUtils.hpp
|
||||
GUI/UserAccount.cpp
|
||||
GUI/UserAccount.hpp
|
||||
GUI/WebViewDialog.cpp
|
||||
|
@ -101,6 +101,7 @@
|
||||
#include "PhysicalPrinterDialog.hpp"
|
||||
#include "WifiConfigDialog.hpp"
|
||||
#include "UserAccount.hpp"
|
||||
#include "UserAccountUtils.hpp"
|
||||
#include "WebViewDialog.hpp"
|
||||
#include "LoginDialog.hpp" // IWYU pragma: keep
|
||||
#include "PresetArchiveDatabase.hpp"
|
||||
@ -3823,14 +3824,98 @@ bool GUI_App::select_printer_preset(const Preset* preset)
|
||||
return is_installed;
|
||||
}
|
||||
|
||||
namespace {
|
||||
const Preset* find_preset_by_nozzle_and_options(
|
||||
const PrinterPresetCollection& collection
|
||||
, const std::string& model_id
|
||||
, const std::string& nozzle
|
||||
, const std::map<std::string
|
||||
, std::string>& options)
|
||||
{
|
||||
// find all matching presets when repo prefix is ommited
|
||||
std::vector<const Preset*> results;
|
||||
for (const Preset &preset : collection) {
|
||||
// trim repo prefix
|
||||
std::string printer_model = preset.config.opt_string("printer_model");
|
||||
std::string vendor_repo_prefix;
|
||||
if (preset.vendor) {
|
||||
vendor_repo_prefix = preset.vendor->repo_prefix;
|
||||
} else if (std::string inherits = preset.inherits(); !inherits.empty()) {
|
||||
const Preset *parent = wxGetApp().preset_bundle->printers.find_preset(inherits);
|
||||
if (parent && parent->vendor) {
|
||||
vendor_repo_prefix = parent->vendor->repo_prefix;
|
||||
}
|
||||
}
|
||||
if (printer_model.find(vendor_repo_prefix) == 0) {
|
||||
printer_model = printer_model.substr(vendor_repo_prefix.size()
|
||||
);
|
||||
boost::trim_left(printer_model);
|
||||
}
|
||||
|
||||
if (!preset.is_system || printer_model != model_id)
|
||||
continue;
|
||||
// nozzle diameter
|
||||
if (!nozzle.empty() && preset.config.has("nozzle_diameter")) {
|
||||
double nozzle_diameter = static_cast<const ConfigOptionFloats*>(preset.config.option("nozzle_diameter"))->values[0];
|
||||
std::string nozzle_diameter_serialized = into_u8(double_to_string(nozzle_diameter));
|
||||
if (size_t pos = nozzle_diameter_serialized.find(",") != std::string::npos) {
|
||||
nozzle_diameter_serialized.replace(pos, 1, 1, '.');
|
||||
}
|
||||
if (nozzle != nozzle_diameter_serialized) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// other options
|
||||
bool failed = false;
|
||||
for (const auto& opt : options) {
|
||||
if (!preset.config.has(opt.first)) {
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
if (preset.config.option(opt.first)->serialize() != opt.second) {
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (failed) {
|
||||
continue;
|
||||
}
|
||||
results.push_back(&preset);
|
||||
}
|
||||
// find visible without prefix
|
||||
for (const Preset *preset : results) {
|
||||
if (preset->is_visible && preset->config.opt_string("printer_model") == model_id) {
|
||||
return preset;
|
||||
}
|
||||
}
|
||||
// find one visible
|
||||
for (const Preset *preset : results) {
|
||||
if (preset->is_visible) {
|
||||
return preset;
|
||||
}
|
||||
}
|
||||
// find one without prefix
|
||||
for (const Preset* preset : results) {
|
||||
if (preset->config.opt_string("printer_model") == model_id) {
|
||||
return preset;
|
||||
}
|
||||
}
|
||||
if (results.size() != 0) {
|
||||
return results.front();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool GUI_App::select_printer_from_connect(const std::string& msg)
|
||||
{
|
||||
// parse message
|
||||
std::string model_name = plater()->get_user_account()->get_keyword_from_json(msg, "printer_model");
|
||||
std::string uuid = plater()->get_user_account()->get_keyword_from_json(msg, "uuid");
|
||||
// parse message "binary_gcode"
|
||||
boost::property_tree::ptree ptree;
|
||||
std::string model_name = UserAccountUtils::get_keyword_from_json(ptree, msg, "printer_model");
|
||||
std::string uuid = UserAccountUtils::get_keyword_from_json(ptree, msg, "uuid");
|
||||
if (model_name.empty()) {
|
||||
std::vector<std::string> compatible_printers;
|
||||
plater()->get_user_account()->fill_supported_printer_models_from_json(msg, compatible_printers);
|
||||
UserAccountUtils::fill_supported_printer_models_from_json(ptree, compatible_printers);
|
||||
if (!compatible_printers.empty()) {
|
||||
model_name = compatible_printers.front();
|
||||
}
|
||||
@ -3839,10 +3924,12 @@ bool GUI_App::select_printer_from_connect(const std::string& msg)
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to select printer from Connect. Printer_model is empty.";
|
||||
return false;
|
||||
}
|
||||
std::string nozzle = plater()->get_user_account()->get_nozzle_from_json(msg);
|
||||
std::string nozzle = UserAccountUtils::get_nozzle_from_json(ptree);
|
||||
std::map<std::string, std::string> config_options_to_match;
|
||||
//UserAccountUtils::fill_config_options_from_json(ptree, config_options_to_match);
|
||||
BOOST_LOG_TRIVIAL(info) << "Select printer from Connect. Model: " << model_name << "nozzle: " << nozzle;
|
||||
// select printer
|
||||
const Preset* printer_preset = preset_bundle->printers.find_system_preset_by_model_and_variant(model_name, nozzle);
|
||||
const Preset* printer_preset = find_preset_by_nozzle_and_options(preset_bundle->printers, model_name, nozzle, config_options_to_match);
|
||||
bool is_installed = printer_preset && select_printer_preset(printer_preset);
|
||||
// notification
|
||||
std::string out = printer_preset ?
|
||||
@ -3935,7 +4022,7 @@ void GUI_App::select_filament_from_connect(const std::string& msg)
|
||||
{
|
||||
// parse message
|
||||
std::vector<std::string> materials;
|
||||
plater()->get_user_account()->fill_material_from_json(msg, materials);
|
||||
UserAccountUtils::fill_material_from_json(msg, materials);
|
||||
if (materials.empty()) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to select filament from Connect. No material data.";
|
||||
return;
|
||||
@ -3969,7 +4056,8 @@ void GUI_App::handle_connect_request_printer_select(const std::string& msg)
|
||||
// Here comes code from ConnectWebViewPanel
|
||||
// It only contains uuid of a printer to be selected
|
||||
// Lets queue it and wait on result. The result is send via event to plater, where it is send to handle_connect_request_printer_select_inner
|
||||
std::string uuid = plater()->get_user_account()->get_keyword_from_json(msg, "uuid");
|
||||
boost::property_tree::ptree ptree;
|
||||
std::string uuid = UserAccountUtils::get_keyword_from_json(ptree, msg, "uuid");
|
||||
plater()->get_user_account()->enqueue_printer_data_action(uuid);
|
||||
}
|
||||
void GUI_App::handle_connect_request_printer_select_inner(const std::string & msg)
|
||||
|
@ -728,9 +728,10 @@ void PhysicalPrinterDialog::update_host_type(bool printer_change)
|
||||
for (PresetForPrinter* prstft : m_presets) {
|
||||
std::string preset_name = prstft->get_preset_name();
|
||||
if (Preset* preset = wxGetApp().preset_bundle->printers.find_preset(preset_name)) {
|
||||
std::string model_id = preset->config.opt_string("printer_model");
|
||||
std::string model_id = preset->config.opt_string("printer_model");
|
||||
if (preset->vendor) {
|
||||
if (preset->vendor->name == "Prusa Research") {
|
||||
// No need to remove prefix from printer_model, family is not prefixed
|
||||
if (preset->vendor->name.find("Prusa Research") != std::string::npos) {
|
||||
const std::vector<VendorProfile::PrinterModel>& models = preset->vendor->models;
|
||||
auto it = std::find_if(models.begin(), models.end(),
|
||||
[model_id](const VendorProfile::PrinterModel& model) { return model.id == model_id; });
|
||||
@ -754,11 +755,16 @@ void PhysicalPrinterDialog::update_host_type(bool printer_change)
|
||||
break;
|
||||
}
|
||||
std::string model_id = preset->config.opt_string("printer_model");
|
||||
if (preset->vendor && preset->vendor->name != "Prusa Research") {
|
||||
connect.supported = false;
|
||||
break;
|
||||
// remove prefix from printer_model
|
||||
if (preset->vendor) {
|
||||
std::string vendor_repo_prefix;
|
||||
vendor_repo_prefix = preset->vendor->repo_prefix;
|
||||
if (model_id.find(vendor_repo_prefix) == 0) {
|
||||
model_id = model_id.substr(vendor_repo_prefix.size());
|
||||
boost::trim_left(model_id);
|
||||
}
|
||||
}
|
||||
if (preset->vendor && preset->vendor->name != "Prusa Research") {
|
||||
if (preset->vendor && preset->vendor->name.find("Prusa Research") == std::string::npos) {
|
||||
connect.supported = false;
|
||||
break;
|
||||
}
|
||||
|
@ -123,6 +123,7 @@
|
||||
#include "Gizmos/GLGizmoCut.hpp"
|
||||
#include "FileArchiveDialog.hpp"
|
||||
#include "UserAccount.hpp"
|
||||
#include "UserAccountUtils.hpp"
|
||||
#include "DesktopIntegrationDialog.hpp"
|
||||
#include "WebViewDialog.hpp"
|
||||
#include "PresetArchiveDatabase.hpp"
|
||||
@ -2059,6 +2060,22 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
|
||||
if (full_config.has("binary_gcode")) // needed for SLA
|
||||
full_config.set("binary_gcode", bool(full_config.opt_bool("binary_gcode") & wxGetApp().app_config->get_bool("use_binary_gcode_when_supported")));
|
||||
|
||||
const Preset &selected_printer = wxGetApp().preset_bundle->printers.get_selected_preset();
|
||||
std::string printer_model_serialized = full_config.option("printer_model")->serialize();
|
||||
std::string vendor_repo_prefix;
|
||||
if (selected_printer.vendor) {
|
||||
vendor_repo_prefix = selected_printer.vendor->repo_prefix;
|
||||
} else if (std::string inherits = selected_printer.inherits(); !inherits.empty()) {
|
||||
const Preset *parent = wxGetApp().preset_bundle->printers.find_preset(inherits);
|
||||
if (parent && parent->vendor) {
|
||||
vendor_repo_prefix = parent->vendor->repo_prefix;
|
||||
}
|
||||
}
|
||||
if (printer_model_serialized.find(vendor_repo_prefix) == 0) {
|
||||
printer_model_serialized = printer_model_serialized.substr(vendor_repo_prefix.size());
|
||||
boost::trim_left(printer_model_serialized);
|
||||
full_config.set("printer_model", printer_model_serialized);
|
||||
}
|
||||
// If the update_background_process() was not called by the timer, kill the timer,
|
||||
// so the update_restart_background_process() will not be called again in vain.
|
||||
background_process_timer.Stop();
|
||||
@ -3648,7 +3665,9 @@ bool Plater::priv::can_show_upload_to_connect() const
|
||||
vendor_id = parent->vendor->id;
|
||||
}
|
||||
}
|
||||
return vendor_id.compare(0, 5, "Prusa") == 0;
|
||||
// Upload to Connect should show only for prusa printers
|
||||
// Some vendors might have prefixed name due to repository id.
|
||||
return vendor_id.find("Prusa") != std::string::npos;
|
||||
}
|
||||
|
||||
void Plater::priv::show_action_buttons(const bool ready_to_slice_) const
|
||||
@ -6022,10 +6041,11 @@ void Plater::connect_gcode()
|
||||
*/
|
||||
const Preset* selected_printer_preset = &wxGetApp().preset_bundle->printers.get_selected_preset();
|
||||
|
||||
const std::string filename = p->user_account->get_keyword_from_json(dialog_msg, "filename");
|
||||
const std::string team_id = p->user_account->get_keyword_from_json(dialog_msg, "team_id");
|
||||
boost::property_tree::ptree ptree;
|
||||
const std::string filename = UserAccountUtils::get_keyword_from_json(ptree, dialog_msg, "filename");
|
||||
const std::string team_id = UserAccountUtils::get_keyword_from_json(ptree, dialog_msg, "team_id");
|
||||
|
||||
std::string data_subtree = p->user_account->get_print_data_from_json(dialog_msg, "data");
|
||||
std::string data_subtree = UserAccountUtils::get_print_data_from_json(dialog_msg, "data");
|
||||
if (filename.empty() || team_id.empty() || data_subtree.empty()) {
|
||||
std::string msg = _u8L("Failed to read response from Prusa Connect server. Upload is cancelled.");
|
||||
BOOST_LOG_TRIVIAL(error) << msg;
|
||||
|
@ -970,7 +970,22 @@ static std::string get_connect_state_suffix_for_printer(const Preset& printer_pr
|
||||
!printer_state_map.empty()) {
|
||||
|
||||
for (const auto& [printer_model_nozzle_pair, states] : printer_state_map) {
|
||||
if (printer_model_nozzle_pair.first == printer_preset.config.opt_string("printer_model")
|
||||
std::string printer_model = printer_preset.config.opt_string("printer_model");
|
||||
std::string vendor_repo_prefix;
|
||||
if (printer_preset.vendor) {
|
||||
vendor_repo_prefix = printer_preset.vendor->repo_prefix;
|
||||
} else if (std::string inherits = printer_preset.inherits(); !inherits.empty()) {
|
||||
const Preset *parent = wxGetApp().preset_bundle->printers.find_preset(inherits);
|
||||
if (parent && parent->vendor) {
|
||||
vendor_repo_prefix = parent->vendor->repo_prefix;
|
||||
}
|
||||
}
|
||||
if (printer_model.find(vendor_repo_prefix) == 0) {
|
||||
printer_model = printer_model.substr(vendor_repo_prefix.size());
|
||||
boost::trim_left(printer_model);
|
||||
}
|
||||
|
||||
if (printer_model_nozzle_pair.first == printer_model
|
||||
&& printer_model_nozzle_pair.second == printer_preset.config.opt_string("printer_variant"))
|
||||
{
|
||||
PrinterStatesCount states_cnt = get_printe_states_count(states);
|
||||
@ -1002,7 +1017,23 @@ static bool fill_data_to_connect_info_line( const Preset& printer_preset,
|
||||
!printer_state_map.empty()) {
|
||||
|
||||
for (const auto& [printer_model_nozzle_pair, states] : printer_state_map) {
|
||||
if (printer_model_nozzle_pair.first == printer_preset.config.opt_string("printer_model")
|
||||
// get printer_model without repo prefix
|
||||
std::string printer_model = printer_preset.config.opt_string("printer_model");
|
||||
std::string vendor_repo_prefix;
|
||||
if (printer_preset.vendor) {
|
||||
vendor_repo_prefix = printer_preset.vendor->repo_prefix;
|
||||
} else if (std::string inherits = printer_preset.inherits(); !inherits.empty()) {
|
||||
const Preset *parent = wxGetApp().preset_bundle->printers.find_preset(inherits);
|
||||
if (parent && parent->vendor) {
|
||||
vendor_repo_prefix = parent->vendor->repo_prefix;
|
||||
}
|
||||
}
|
||||
if (printer_model.find(vendor_repo_prefix) == 0) {
|
||||
printer_model = printer_model.substr(vendor_repo_prefix.size());
|
||||
boost::trim_left(printer_model);
|
||||
}
|
||||
|
||||
if (printer_model_nozzle_pair.first == printer_model
|
||||
&& printer_model_nozzle_pair.second == printer_preset.config.opt_string("printer_variant"))
|
||||
{
|
||||
PrinterStatesCount states_cnt = get_printe_states_count(states);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "UserAccount.hpp"
|
||||
|
||||
#include "UserAccountUtils.hpp"
|
||||
#include "format.hpp"
|
||||
#include "GUI.hpp"
|
||||
|
||||
@ -160,64 +161,7 @@ void UserAccount::on_communication_fail()
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::string parse_tree_for_param(const pt::ptree& tree, const std::string& param)
|
||||
{
|
||||
for (const auto& section : tree) {
|
||||
if (section.first == param) {
|
||||
return section.second.data();
|
||||
}
|
||||
if (std::string res = parse_tree_for_param(section.second, param); !res.empty()) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void parse_tree_for_param_vector(const pt::ptree& tree, const std::string& param, std::vector<std::string>& results)
|
||||
{
|
||||
for (const auto& section : tree) {
|
||||
if (section.first == param) {
|
||||
results.emplace_back(section.second.data());
|
||||
} else {
|
||||
parse_tree_for_param_vector(section.second, param, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pt::ptree parse_tree_for_subtree(const pt::ptree& tree, const std::string& param)
|
||||
{
|
||||
for (const auto& section : tree) {
|
||||
if (section.first == param) {
|
||||
return section.second;
|
||||
}
|
||||
else {
|
||||
if (pt::ptree res = parse_tree_for_subtree(section.second, param); !res.empty())
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
return pt::ptree();
|
||||
}
|
||||
|
||||
void fill_supported_printer_models_from_json_inner(const pt::ptree& ptree, std::vector<std::string>& result) {
|
||||
std::string printer_model = parse_tree_for_param(ptree, "printer_model");
|
||||
if (!printer_model.empty()) {
|
||||
result.emplace_back(printer_model);
|
||||
}
|
||||
pt::ptree out = parse_tree_for_subtree(ptree, "supported_printer_models");
|
||||
if (out.empty()) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to find supported_printer_models in printer detail.";
|
||||
return;
|
||||
}
|
||||
for (const auto& sub : out) {
|
||||
if (printer_model != sub.second.data()) {
|
||||
result.emplace_back(sub.second.data());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool UserAccount::on_connect_printers_success(const std::string& data, AppConfig* app_config, bool& out_printers_changed)
|
||||
{
|
||||
@ -327,8 +271,8 @@ bool UserAccount::on_connect_uiid_map_success(const std::string& data, AppConfig
|
||||
return on_connect_printers_success(data, app_config, out_printers_changed);
|
||||
}
|
||||
|
||||
std::string UserAccount::get_current_printer_uuid_from_connect(const std::string& selected_printer_id) const
|
||||
{
|
||||
std::string UserAccount::get_current_printer_uuid_from_connect(const std::string &selected_printer_id
|
||||
) const {
|
||||
if (m_current_printer_data_json_from_connect.empty() || m_current_printer_uuid_from_connect.empty()) {
|
||||
return {};
|
||||
}
|
||||
@ -343,12 +287,12 @@ std::string UserAccount::get_current_printer_uuid_from_connect(const std::string
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string data_uuid = parse_tree_for_param(ptree, "uuid");
|
||||
std::string data_uuid = UserAccountUtils::get_keyword_from_json(ptree, "", "uuid");
|
||||
assert(data_uuid == m_current_printer_uuid_from_connect);
|
||||
|
||||
//std::string model_name = parse_tree_for_param(ptree, "printer_model");
|
||||
std::vector<std::string> compatible_printers;
|
||||
fill_supported_printer_models_from_json_inner(ptree, compatible_printers);
|
||||
UserAccountUtils::fill_supported_printer_models_from_json(ptree, compatible_printers);
|
||||
if (compatible_printers.empty()) {
|
||||
return {};
|
||||
}
|
||||
@ -356,173 +300,4 @@ std::string UserAccount::get_current_printer_uuid_from_connect(const std::string
|
||||
return std::find(compatible_printers.begin(), compatible_printers.end(), selected_printer_id) == compatible_printers.end() ? "" : m_current_printer_uuid_from_connect;
|
||||
}
|
||||
|
||||
|
||||
std::string UserAccount::get_nozzle_from_json(const std::string& message) const
|
||||
{
|
||||
std::string out;
|
||||
try {
|
||||
std::stringstream ss(message);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
|
||||
out = parse_tree_for_param(ptree, "nozzle_diameter");
|
||||
//assert(!out.empty());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Could not parse prusaconnect message. " << e.what();
|
||||
}
|
||||
|
||||
// Get rid of trailing zeros.
|
||||
// This is because somtimes we get "nozzle_diameter":0.40000000000000002
|
||||
// This will return wrong result for f.e. 0.05. But we dont have such profiles right now.
|
||||
if (size_t fist_dot = out.find('.'); fist_dot != std::string::npos) {
|
||||
if (size_t first_zero = out.find('0', fist_dot); first_zero != std::string::npos) {
|
||||
return out.substr(0, first_zero);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string UserAccount::get_keyword_from_json(const std::string& json, const std::string& keyword) const
|
||||
{
|
||||
std::string out;
|
||||
try {
|
||||
std::stringstream ss(json);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
|
||||
out = parse_tree_for_param(ptree, keyword);
|
||||
//assert(!out.empty());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Could not parse prusaconnect message. " << e.what();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string UserAccount::get_print_data_from_json(const std::string &json, const std::string &keyword) const
|
||||
{
|
||||
// copy subtree string f.e.
|
||||
// { "<keyword>": {"param1": "something", "filename":"abcd.gcode", "param3":true}, "something_else" : 0 }
|
||||
// into: {"param1": "something", "filename":"%1%", "param3":true, "size":%2%}
|
||||
// yes there will be 2 placeholders for later format
|
||||
|
||||
// this will fail if not flat subtree
|
||||
size_t start_of_keyword = json.find("\""+keyword+"\"");
|
||||
if (start_of_keyword == std::string::npos)
|
||||
return {};
|
||||
size_t start_of_sub = json.find('{', start_of_keyword);
|
||||
if (start_of_sub == std::string::npos)
|
||||
return {};
|
||||
size_t end_of_sub = json.find('}', start_of_sub);
|
||||
if (end_of_sub == std::string::npos)
|
||||
return {};
|
||||
size_t start_of_filename = json.find("\"filename\"", start_of_sub);
|
||||
if (start_of_filename == std::string::npos)
|
||||
return {};
|
||||
size_t filename_doubledot = json.find(':', start_of_filename);
|
||||
if (filename_doubledot == std::string::npos)
|
||||
return {};
|
||||
size_t start_of_filename_data = json.find('\"', filename_doubledot);
|
||||
if (start_of_filename_data == std::string::npos)
|
||||
return {};
|
||||
size_t end_of_filename_data = json.find('\"', start_of_filename_data + 1);
|
||||
if (end_of_filename_data == std::string::npos)
|
||||
return {};
|
||||
size_t size = json.size();
|
||||
std::string result = json.substr(start_of_sub, start_of_filename_data - start_of_sub + 1);
|
||||
result += "%1%";
|
||||
result += json.substr(end_of_filename_data, end_of_sub - end_of_filename_data);
|
||||
result += ",\"size\":%2%}";
|
||||
return result;
|
||||
}
|
||||
|
||||
void UserAccount::fill_supported_printer_models_from_json(const std::string& json, std::vector<std::string>& result) const
|
||||
{
|
||||
try {
|
||||
std::stringstream ss(json);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
|
||||
fill_supported_printer_models_from_json_inner(ptree, result);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Could not parse prusaconnect message. " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void UserAccount::fill_material_from_json(const std::string& json, std::vector<std::string>& result) const
|
||||
{
|
||||
|
||||
/* option 1:
|
||||
"slot": {
|
||||
"active": 2,
|
||||
"slots": {
|
||||
"1": {
|
||||
"material": "PLA",
|
||||
"temp": 170,
|
||||
"fan_hotend": 7689,
|
||||
"fan_print": 0
|
||||
},
|
||||
"2": {
|
||||
"material": "PLA",
|
||||
"temp": 225,
|
||||
"fan_hotend": 7798,
|
||||
"fan_print": 6503
|
||||
},
|
||||
"3": {
|
||||
"material": "PLA",
|
||||
"temp": 36,
|
||||
"fan_hotend": 6636,
|
||||
"fan_print": 0
|
||||
},
|
||||
"4": {
|
||||
"material": "PLA",
|
||||
"temp": 35,
|
||||
"fan_hotend": 0,
|
||||
"fan_print": 0
|
||||
},
|
||||
"5": {
|
||||
"material": "PETG",
|
||||
"temp": 136,
|
||||
"fan_hotend": 8132,
|
||||
"fan_print": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
/* option 2
|
||||
"filament": {
|
||||
"material": "PLA",
|
||||
"bed_temperature": 60,
|
||||
"nozzle_temperature": 210
|
||||
}
|
||||
*/
|
||||
// try finding "slot" subtree a use it to
|
||||
// if not found, find "filament" subtree
|
||||
try {
|
||||
std::stringstream ss(json);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
// find "slot" subtree
|
||||
pt::ptree slot_subtree = parse_tree_for_subtree(ptree, "slot");
|
||||
if (slot_subtree.empty()) {
|
||||
// if not found, find "filament" subtree
|
||||
pt::ptree filament_subtree = parse_tree_for_subtree(ptree, "filament");
|
||||
if (!filament_subtree.empty()) {
|
||||
std::string material = parse_tree_for_param(filament_subtree, "material");
|
||||
if (!material.empty()) {
|
||||
result.emplace_back(std::move(material));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// search "slot" subtree for all "material"s
|
||||
parse_tree_for_param_vector(slot_subtree, "material", result);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Could not parse prusaconnect message. " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace slic3r::GUI
|
@ -67,13 +67,6 @@ public:
|
||||
const ConnectPrinterStateMap& get_printer_state_map() const { return m_printer_map; }
|
||||
boost::filesystem::path get_avatar_path(bool logged) const;
|
||||
|
||||
// standalone utility methods
|
||||
std::string get_nozzle_from_json(const std::string& message) const;
|
||||
std::string get_keyword_from_json(const std::string& json, const std::string& keyword) const;
|
||||
std::string get_print_data_from_json(const std::string &json, const std::string &keyword) const;
|
||||
void fill_supported_printer_models_from_json(const std::string& json, std::vector<std::string>& result) const;
|
||||
void fill_material_from_json(const std::string& json, std::vector<std::string>& result) const;
|
||||
|
||||
const std::map<std::string, ConnectPrinterState>& get_printer_state_table() const { return printer_state_table; }
|
||||
|
||||
void set_current_printer_uuid_from_connect(const std::string& uuid) { m_current_printer_uuid_from_connect = uuid; }
|
||||
|
222
src/slic3r/GUI/UserAccountUtils.cpp
Normal file
222
src/slic3r/GUI/UserAccountUtils.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
#include "UserAccountUtils.hpp"
|
||||
|
||||
#include "format.hpp"
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
namespace Slic3r { namespace GUI { namespace UserAccountUtils {
|
||||
|
||||
namespace {
|
||||
std::string parse_tree_for_param(const pt::ptree &tree, const std::string ¶m) {
|
||||
for (const auto §ion : tree) {
|
||||
if (section.first == param) {
|
||||
return section.second.data();
|
||||
}
|
||||
if (std::string res = parse_tree_for_param(section.second, param); !res.empty()) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void parse_tree_for_param_vector(
|
||||
const pt::ptree &tree, const std::string ¶m, std::vector<std::string> &results
|
||||
) {
|
||||
for (const auto §ion : tree) {
|
||||
if (section.first == param) {
|
||||
results.emplace_back(section.second.data());
|
||||
} else {
|
||||
parse_tree_for_param_vector(section.second, param, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pt::ptree parse_tree_for_subtree(const pt::ptree &tree, const std::string ¶m) {
|
||||
for (const auto §ion : tree) {
|
||||
if (section.first == param) {
|
||||
return section.second;
|
||||
} else {
|
||||
if (pt::ptree res = parse_tree_for_subtree(section.second, param); !res.empty())
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return pt::ptree();
|
||||
}
|
||||
|
||||
void json_to_ptree(boost::property_tree::ptree &ptree, const std::string &json) {
|
||||
try {
|
||||
std::stringstream ss(json);
|
||||
pt::read_json(ss, ptree);
|
||||
} catch (const std::exception &e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to parse json to ptree. " << e.what();
|
||||
BOOST_LOG_TRIVIAL(error) << "json: " << json;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string get_nozzle_from_json(boost::property_tree::ptree &ptree) {
|
||||
assert(!ptree.empty());
|
||||
|
||||
std::string out = parse_tree_for_param(ptree, "nozzle_diameter");
|
||||
// Get rid of trailing zeros.
|
||||
// This is because somtimes we get "nozzle_diameter":0.40000000000000002
|
||||
// This will return wrong result for f.e. 0.05. But we dont have such profiles right now.
|
||||
if (size_t fist_dot = out.find('.'); fist_dot != std::string::npos) {
|
||||
if (size_t first_zero = out.find('0', fist_dot); first_zero != std::string::npos) {
|
||||
return out.substr(0, first_zero);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string get_keyword_from_json(boost::property_tree::ptree &ptree, const std::string &json, const std::string &keyword )
|
||||
{
|
||||
if (ptree.empty()) {
|
||||
json_to_ptree(ptree, json);
|
||||
}
|
||||
assert(!ptree.empty());
|
||||
return parse_tree_for_param(ptree, keyword);
|
||||
}
|
||||
|
||||
void fill_supported_printer_models_from_json(boost::property_tree::ptree &ptree, std::vector<std::string> &result)
|
||||
{
|
||||
assert(!ptree.empty());
|
||||
std::string printer_model = parse_tree_for_param(ptree, "printer_model");
|
||||
if (!printer_model.empty()) {
|
||||
result.emplace_back(printer_model);
|
||||
}
|
||||
pt::ptree out = parse_tree_for_subtree(ptree, "supported_printer_models");
|
||||
if (out.empty()) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to find supported_printer_models in printer detail.";
|
||||
return;
|
||||
}
|
||||
for (const auto &sub : out) {
|
||||
if (printer_model != sub.second.data()) {
|
||||
result.emplace_back(sub.second.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fill_config_options_from_json(boost::property_tree::ptree& ptree, std::map<std::string, std::string>& result)
|
||||
{
|
||||
assert(!ptree.empty());
|
||||
pt::ptree subtree = parse_tree_for_subtree(ptree, "config_options");
|
||||
for (const auto &item : subtree) {
|
||||
result[item.first] = item.second.data();
|
||||
}
|
||||
}
|
||||
|
||||
void fill_material_from_json(const std::string &json, std::vector<std::string> &result)
|
||||
{
|
||||
pt::ptree ptree;
|
||||
json_to_ptree(ptree, json);
|
||||
assert(!ptree.empty());
|
||||
|
||||
/* option 1:
|
||||
"slot": {
|
||||
"active": 2,
|
||||
"slots": {
|
||||
"1": {
|
||||
"material": "PLA",
|
||||
"temp": 170,
|
||||
"fan_hotend": 7689,
|
||||
"fan_print": 0
|
||||
},
|
||||
"2": {
|
||||
"material": "PLA",
|
||||
"temp": 225,
|
||||
"fan_hotend": 7798,
|
||||
"fan_print": 6503
|
||||
},
|
||||
"3": {
|
||||
"material": "PLA",
|
||||
"temp": 36,
|
||||
"fan_hotend": 6636,
|
||||
"fan_print": 0
|
||||
},
|
||||
"4": {
|
||||
"material": "PLA",
|
||||
"temp": 35,
|
||||
"fan_hotend": 0,
|
||||
"fan_print": 0
|
||||
},
|
||||
"5": {
|
||||
"material": "PETG",
|
||||
"temp": 136,
|
||||
"fan_hotend": 8132,
|
||||
"fan_print": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
/* option 2
|
||||
"filament": {
|
||||
"material": "PLA",
|
||||
"bed_temperature": 60,
|
||||
"nozzle_temperature": 210
|
||||
}
|
||||
*/
|
||||
// try finding "slot" subtree a use it to
|
||||
// if not found, find "filament" subtree
|
||||
|
||||
// find "slot" subtree
|
||||
pt::ptree slot_subtree = parse_tree_for_subtree(ptree, "slot");
|
||||
if (slot_subtree.empty()) {
|
||||
// if not found, find "filament" subtree
|
||||
pt::ptree filament_subtree = parse_tree_for_subtree(ptree, "filament");
|
||||
if (!filament_subtree.empty()) {
|
||||
std::string material = parse_tree_for_param(filament_subtree, "material");
|
||||
if (!material.empty()) {
|
||||
result.emplace_back(std::move(material));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// search "slot" subtree for all "material"s
|
||||
parse_tree_for_param_vector(slot_subtree, "material", result);
|
||||
}
|
||||
|
||||
std::string get_print_data_from_json(const std::string &json, const std::string &keyword) {
|
||||
// copy subtree string f.e.
|
||||
// { "<keyword>": {"param1": "something", "filename":"abcd.gcode", "param3":true},
|
||||
// "something_else" : 0 } into: {"param1": "something", "filename":"%1%", "param3":true,
|
||||
// "size":%2%} yes there will be 2 placeholders for later format
|
||||
|
||||
// this will fail if not flat subtree
|
||||
size_t start_of_keyword = json.find("\"" + keyword + "\"");
|
||||
if (start_of_keyword == std::string::npos)
|
||||
return {};
|
||||
size_t start_of_sub = json.find('{', start_of_keyword);
|
||||
if (start_of_sub == std::string::npos)
|
||||
return {};
|
||||
size_t end_of_sub = json.find('}', start_of_sub);
|
||||
if (end_of_sub == std::string::npos)
|
||||
return {};
|
||||
size_t start_of_filename = json.find("\"filename\"", start_of_sub);
|
||||
if (start_of_filename == std::string::npos)
|
||||
return {};
|
||||
size_t filename_doubledot = json.find(':', start_of_filename);
|
||||
if (filename_doubledot == std::string::npos)
|
||||
return {};
|
||||
size_t start_of_filename_data = json.find('\"', filename_doubledot);
|
||||
if (start_of_filename_data == std::string::npos)
|
||||
return {};
|
||||
size_t end_of_filename_data = json.find('\"', start_of_filename_data + 1);
|
||||
if (end_of_filename_data == std::string::npos)
|
||||
return {};
|
||||
size_t size = json.size();
|
||||
std::string result = json.substr(start_of_sub, start_of_filename_data - start_of_sub + 1);
|
||||
result += "%1%";
|
||||
result += json.substr(end_of_filename_data, end_of_sub - end_of_filename_data);
|
||||
result += ",\"size\":%2%}";
|
||||
return result;
|
||||
}
|
||||
|
||||
}}} // Slic3r::GUI::UserAccountUtils
|
||||
|
||||
|
27
src/slic3r/GUI/UserAccountUtils.hpp
Normal file
27
src/slic3r/GUI/UserAccountUtils.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef slic3r_UserAccountUtils_hpp_
|
||||
#define slic3r_UserAccountUtils_hpp_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
namespace UserAccountUtils {
|
||||
|
||||
// If ptree parameter is empty, json parameter needs to contain data and ptree is filled.
|
||||
// If ptree is non-epty, json parameter is not used.
|
||||
std::string get_keyword_from_json(boost::property_tree::ptree& ptree, const std::string& json, const std::string& keyword);
|
||||
// Only ptree is passed since these functions are called on places that already has the ptree from get_keyword_from_json call
|
||||
std::string get_nozzle_from_json(boost::property_tree::ptree &ptree);
|
||||
void fill_supported_printer_models_from_json(boost::property_tree::ptree& ptree, std::vector<std::string>& result);
|
||||
void fill_config_options_from_json(boost::property_tree::ptree& ptree, std::map<std::string, std::string>& result);
|
||||
|
||||
// Since fill_material_from_json is called only from one place where ptree doesnt need to be shared, it is not always read from json.
|
||||
void fill_material_from_json(const std::string& json, std::vector<std::string>& result);
|
||||
|
||||
std::string get_print_data_from_json(const std::string &json, const std::string &keyword);
|
||||
|
||||
}}} // Slic3r::GUI::UserAccountUtils
|
||||
|
||||
#endif // slic3r_UserAccountUtils_hpp_
|
@ -1274,22 +1274,41 @@ void PrinterPickWebViewDialog::on_connect_action_webapp_ready(const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
void PrinterPickWebViewDialog::request_compatible_printers_FFF()
|
||||
{
|
||||
//PrinterParams: {
|
||||
//material: Material;
|
||||
//nozzleDiameter: number;
|
||||
//printerType: string;
|
||||
//filename: string;
|
||||
//}
|
||||
const Preset& selected_printer = wxGetApp().preset_bundle->printers.get_selected_preset();
|
||||
const Preset& selected_filament = wxGetApp().preset_bundle->filaments.get_selected_preset();
|
||||
double nozzle_diameter = static_cast<const ConfigOptionFloats*>(selected_printer.config.option("nozzle_diameter"))->values[0];
|
||||
void PrinterPickWebViewDialog::request_compatible_printers_FFF() {
|
||||
// PrinterParams: {
|
||||
// material: Material;
|
||||
// nozzleDiameter: number;
|
||||
// printerType: string;
|
||||
// filename: string;
|
||||
// }
|
||||
const Preset &selected_printer = wxGetApp().preset_bundle->printers.get_selected_preset();
|
||||
const Preset &selected_filament = wxGetApp().preset_bundle->filaments.get_selected_preset();
|
||||
double nozzle_diameter = static_cast<const ConfigOptionFloats *>(
|
||||
selected_printer.config.option("nozzle_diameter")
|
||||
)
|
||||
->values[0];
|
||||
wxString nozzle_diameter_serialized = double_to_string(nozzle_diameter);
|
||||
nozzle_diameter_serialized.Replace(L",", L".");
|
||||
// Sending only first filament type for now. This should change to array of values
|
||||
const std::string filament_type_serialized = selected_filament.config.option("filament_type")->serialize();
|
||||
const std::string printer_model_serialized = selected_printer.config.option("printer_model")->serialize();
|
||||
const std::string filament_type_serialized = selected_filament.config.option("filament_type")
|
||||
->serialize();
|
||||
std::string printer_model_serialized = selected_printer.config.option("printer_model")
|
||||
->serialize();
|
||||
|
||||
std::string vendor_repo_prefix;
|
||||
if (selected_printer.vendor) {
|
||||
vendor_repo_prefix = selected_printer.vendor->repo_prefix;
|
||||
} else if (std::string inherits = selected_printer.inherits(); !inherits.empty()) {
|
||||
const Preset *parent = wxGetApp().preset_bundle->printers.find_preset(inherits);
|
||||
if (parent && parent->vendor) {
|
||||
vendor_repo_prefix = parent->vendor->repo_prefix;
|
||||
}
|
||||
}
|
||||
if (printer_model_serialized.find(vendor_repo_prefix) == 0) {
|
||||
printer_model_serialized = printer_model_serialized.substr(vendor_repo_prefix.size());
|
||||
boost::trim_left(printer_model_serialized);
|
||||
}
|
||||
|
||||
const std::string uuid = wxGetApp().plater()->get_user_account()->get_current_printer_uuid_from_connect(printer_model_serialized);
|
||||
const std::string filename = wxGetApp().plater()->get_upload_filename();
|
||||
const std::string request = GUI::format(
|
||||
@ -1307,7 +1326,21 @@ void PrinterPickWebViewDialog::request_compatible_printers_FFF()
|
||||
void PrinterPickWebViewDialog::request_compatible_printers_SLA()
|
||||
{
|
||||
const Preset& selected_printer = wxGetApp().preset_bundle->printers.get_selected_preset();
|
||||
const std::string printer_model_serialized = selected_printer.config.option("printer_model")->serialize();
|
||||
std::string printer_model_serialized = selected_printer.config.option("printer_model")->serialize();
|
||||
|
||||
std::string vendor_repo_prefix;
|
||||
if (selected_printer.vendor) {
|
||||
vendor_repo_prefix = selected_printer.vendor->repo_prefix;
|
||||
} else if (std::string inherits = selected_printer.inherits(); !inherits.empty()) {
|
||||
const Preset *parent = wxGetApp().preset_bundle->printers.find_preset(inherits);
|
||||
if (parent && parent->vendor) {
|
||||
vendor_repo_prefix = parent->vendor->repo_prefix;
|
||||
}
|
||||
}
|
||||
if (printer_model_serialized.find(vendor_repo_prefix) == 0) {
|
||||
printer_model_serialized = printer_model_serialized.substr(vendor_repo_prefix.size());
|
||||
boost::trim_left(printer_model_serialized);
|
||||
}
|
||||
const Preset& selected_material = wxGetApp().preset_bundle->sla_materials.get_selected_preset();
|
||||
const std::string material_type_serialized = selected_material.config.option("material_type")->serialize();
|
||||
const std::string uuid = wxGetApp().plater()->get_user_account()->get_current_printer_uuid_from_connect(printer_model_serialized);
|
||||
|
Loading…
x
Reference in New Issue
Block a user