diff options
author | Alexander Bachler Jansson <drbachler@users.noreply.github.com> | 2021-11-11 15:57:55 +0300 |
---|---|---|
committer | supermerill <merill@free.fr> | 2021-12-13 01:50:59 +0300 |
commit | 7a524609e9a4b568b84c3f8c6d99d78030f708b4 (patch) | |
tree | eb4622a125588a600187918c051f6d0be899871a /src | |
parent | b1e044855e1f38a5b177ce9b58d3d09cef89c3f1 (diff) |
Adding MPMDv2 Print host upload support (#1807)
* Adding MPMDv2 Print host upload support
Diffstat (limited to 'src')
-rw-r--r-- | src/libslic3r/PrintConfig.cpp | 2 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.hpp | 2 | ||||
-rw-r--r-- | src/slic3r/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/slic3r/GUI/PhysicalPrinterDialog.cpp | 6 | ||||
-rw-r--r-- | src/slic3r/Utils/MPMDv2.cpp | 155 | ||||
-rw-r--r-- | src/slic3r/Utils/MPMDv2.hpp | 45 | ||||
-rw-r--r-- | src/slic3r/Utils/PrintHost.cpp | 2 |
7 files changed, 214 insertions, 0 deletions
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 7d7974457..1ef590af2 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2994,6 +2994,7 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("astrobox"); def->enum_values.push_back("repetier"); def->enum_values.push_back("klipper"); + def->enum_values.push_back("mpmdv2"); def->enum_labels.push_back("PrusaLink"); def->enum_labels.push_back("OctoPrint"); def->enum_labels.push_back("Duet"); @@ -3001,6 +3002,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back("AstroBox"); def->enum_labels.push_back("Repetier"); def->enum_labels.push_back("Klipper"); + def->enum_labels.push_back("MPMDv2"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionEnum<PrintHostType>(htOctoPrint)); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 8e64e70ea..7d3bedb11 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -79,6 +79,7 @@ enum PrintHostType { htAstroBox, htRepetier, htKlipper, + htMPMDv2, }; enum AuthorizationType { @@ -242,6 +243,7 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<PrintHostType>::g {"astrobox", htAstroBox}, {"repetier", htRepetier}, {"klipper", htKlipper}, + {"mpmdv2", htMPMDv2}, }; return keys_map; } diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 3beacae68..820171ae1 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -238,6 +238,8 @@ set(SLIC3R_GUI_SOURCES Utils/UndoRedo.hpp Utils/HexFile.cpp Utils/HexFile.hpp + Utils/MPMDv2.cpp + Utils/MPMDv2.hpp ) if (APPLE) diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index 54701eedd..6d54b2d71 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -528,6 +528,12 @@ void PhysicalPrinterDialog::update(bool printer_change) if (opt && opt->value == htKlipper) { m_optgroup->hide_field("printhost_apikey"); } + + // hide api key and ca file for MPMDv2 + if (opt && opt->value == htMPMDv2) { + m_optgroup->hide_field("printhost_apikey"); + m_optgroup->hide_field("printhost_cafile"); + } } else { m_optgroup->set_value("host_type", int(PrintHostType::htOctoPrint), false); diff --git a/src/slic3r/Utils/MPMDv2.cpp b/src/slic3r/Utils/MPMDv2.cpp new file mode 100644 index 000000000..e6b3c3da3 --- /dev/null +++ b/src/slic3r/Utils/MPMDv2.cpp @@ -0,0 +1,155 @@ +#include "MPMDv2.hpp" + +#include <algorithm> +#include <sstream> +#include <exception> +#include <boost/format.hpp> +#include <boost/log/trivial.hpp> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/json_parser.hpp> +#include <boost/algorithm/string/predicate.hpp> + +#include <wx/progdlg.h> + +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/GUI.hpp" +#include "Http.hpp" + + +namespace fs = boost::filesystem; +namespace pt = boost::property_tree; + + +namespace Slic3r { + +MPMDv2::MPMDv2(DynamicPrintConfig *config) : + host(config->opt_string("print_host")) +{} + +const char* MPMDv2::get_name() const { return "MPMDv2"; } + +bool MPMDv2::test(wxString &msg) const +{ + // Since the request is performed synchronously here, + // it is ok to refer to `msg` from within the closure + + const char *name = get_name(); + + bool res = true; + auto url = make_url("api/version"); + + BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get version at: %2%") % name % url; + + auto http = Http::get(std::move(url)); + http.on_error([&](std::string body, std::string error, unsigned status) { + BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status % body; + res = false; + msg = format_error(body, error, status); + }) + .on_complete([&, this](std::string body, unsigned) { + BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got version: %2%") % name % body; + + try { + std::stringstream ss(body); + pt::ptree ptree; + pt::read_json(ss, ptree); + + if (! ptree.get_optional<std::string>("api")) { + res = false; + return; + } + + const auto text = ptree.get_optional<std::string>("text"); + res = validate_version_text(text); + if (! res) { + msg = GUI::from_u8((boost::format(_utf8(L("Mismatched type of print host: %s"))) % (text ? *text : "MiniDeltaLCD")).str()); + } + } + catch (const std::exception &) { + res = false; + msg = "Could not parse server response"; + } + }) + .perform_sync(); + + return res; +} + +bool MPMDv2::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const +{ + const char *name = get_name(); + + const auto upload_filename = upload_data.upload_path.filename(); + const auto upload_parent_path = upload_data.upload_path.parent_path(); + + wxString test_msg; + if (! test(test_msg)) { + error_fn(std::move(test_msg)); + return false; + } + + bool res = true; + + auto url = make_url("api/files/local"); + + BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3%, filename: %4%, path: %5%, print: %6%") + % name + % upload_data.source_path + % url + % upload_filename.string() + % upload_parent_path.string() + % upload_data.start_print; + + auto http = Http::post(std::move(url)); + http.form_add("path", upload_parent_path.string()) // XXX: slashes on windows ??? + .form_add_file("file", upload_data.source_path.string(), upload_filename.string()) + .form_add("print", upload_data.start_print ? "true" : "false") + .on_complete([&](std::string body, unsigned status) { + BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: File uploaded: HTTP %2%: %3%") % name % status % body; + }) + .on_error([&](std::string body, std::string error, unsigned status) { + BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error uploading file: %2%, HTTP %3%, body: `%4%`") % name % error % status % body; + error_fn(format_error(body, error, status)); + res = false; + }) + .on_progress([&](Http::Progress progress, bool &cancel) { + prorgess_fn(std::move(progress), cancel); + if (cancel) { + // Upload was canceled + BOOST_LOG_TRIVIAL(info) << get_name() << ": Upload canceled"; + res = false; + } + }) + .perform_sync(); + + return res; +} + +bool MPMDv2::validate_version_text(const boost::optional<std::string> &version_text) const +{ + return version_text ? boost::starts_with(*version_text, "MiniDeltaLCD") : true; +} + +wxString MPMDv2::get_test_failed_msg (wxString &msg) const +{ + return GUI::from_u8((boost::format("%s: %s\n\n%s") + % (boost::format(_u8L("Could not connect to %s")) % get_name()) + % std::string(msg.ToUTF8()) + % _u8L("Note: MiniDeltaLCD version at least 1.0 is required.") + ).str()); +} + +std::string MPMDv2::make_url(const std::string &path) const +{ + if (host.find("http://") == 0 || host.find("https://") == 0) { + if (host.back() == '/') { + return (boost::format("%1%%2%") % host % path).str(); + } else { + return (boost::format("%1%/%2%") % host % path).str(); + } + } else { + return (boost::format("http://%1%/%2%") % host % path).str(); + } +} + +} diff --git a/src/slic3r/Utils/MPMDv2.hpp b/src/slic3r/Utils/MPMDv2.hpp new file mode 100644 index 000000000..d103b0ef8 --- /dev/null +++ b/src/slic3r/Utils/MPMDv2.hpp @@ -0,0 +1,45 @@ +#ifndef slic3r_MPMDv2_hpp_ +#define slic3r_MPMDv2_hpp_ + +#include <string> +#include <wx/string.h> +#include <wx/arrstr.h> +#include <boost/optional.hpp> + +#include "PrintHost.hpp" +#include "libslic3r/PrintConfig.hpp" + + +namespace Slic3r { + +class DynamicPrintConfig; +class Http; + +class MPMDv2 : public PrintHost +{ +public: + MPMDv2(DynamicPrintConfig *config); + ~MPMDv2() override = default; + + const char* get_name() const; + + bool test(wxString &curl_msg) const override; + wxString get_test_failed_msg (wxString &msg) const override; + bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override; + bool has_auto_discovery() const override { return false; } + bool can_test() const override { return true; } + bool can_start_print() const override { return true; } + std::string get_host() const override { return host; } + +protected: + virtual bool validate_version_text(const boost::optional<std::string> &version_text) const; + +private: + std::string host; + + std::string make_url(const std::string &path) const; +}; + +} + +#endif diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp index 52ec8bbfe..4eb6a9a29 100644 --- a/src/slic3r/Utils/PrintHost.cpp +++ b/src/slic3r/Utils/PrintHost.cpp @@ -19,6 +19,7 @@ #include "AstroBox.hpp" #include "Repetier.hpp" #include "Klipper.hpp" +#include "MPMDv2.hpp" #include "../GUI/PrintHostDialogs.hpp" #include "slic3r/GUI/I18N.hpp" @@ -67,6 +68,7 @@ PrintHost* PrintHost::get_print_host(DynamicPrintConfig *config) case htAstroBox: return new AstroBox(config); case htRepetier: return new Repetier(config); case htKlipper: return new Klipper(config); + case htMPMDv2: return new MPMDv2(config); default: return nullptr; } } else { |