PrusaSlicer-NonPlainar/src/slic3r/Utils/OctoPrint.cpp

181 lines
5.1 KiB
C++
Raw Normal View History

2018-02-07 10:37:15 +00:00
#include "OctoPrint.hpp"
#include <algorithm>
2018-02-07 10:37:15 +00:00
#include <boost/format.hpp>
#include <boost/log/trivial.hpp>
2018-02-07 10:37:15 +00:00
#include "libslic3r/PrintConfig.hpp"
2018-12-11 09:33:11 +00:00
#include "slic3r/GUI/I18N.hpp"
#include "slic3r/GUI/PrintHostDialogs.hpp" // XXX
2018-02-07 10:37:15 +00:00
#include "Http.hpp"
namespace fs = boost::filesystem;
2018-02-07 10:37:15 +00:00
namespace Slic3r {
OctoPrint::OctoPrint(DynamicPrintConfig *config) :
host(config->opt_string("print_host")),
apikey(config->opt_string("printhost_apikey")),
cafile(config->opt_string("printhost_cafile"))
2018-02-07 10:37:15 +00:00
{}
2018-08-21 09:10:32 +00:00
OctoPrint::~OctoPrint() {}
bool OctoPrint::test(wxString &msg) const
2018-02-07 10:37:15 +00:00
{
2018-02-20 14:37:26 +00:00
// Since the request is performed synchronously here,
// it is ok to refer to `msg` from within the closure
2018-02-20 14:37:26 +00:00
bool res = true;
2018-06-12 10:32:03 +00:00
auto url = make_url("api/version");
BOOST_LOG_TRIVIAL(info) << boost::format("Octoprint: Get version at: %1%") % url;
auto http = Http::get(std::move(url));
2018-02-20 14:37:26 +00:00
set_auth(http);
2018-06-27 15:00:20 +00:00
http.on_error([&](std::string body, std::string error, unsigned status) {
BOOST_LOG_TRIVIAL(error) << boost::format("Octoprint: Error getting version: %1%, HTTP %2%, body: `%3%`") % error % status % body;
res = false;
2018-06-27 15:00:20 +00:00
msg = format_error(body, error, status);
2018-02-20 14:37:26 +00:00
})
.on_complete([&](std::string body, unsigned) {
BOOST_LOG_TRIVIAL(debug) << boost::format("Octoprint: Got version: %1%") % body;
})
2018-02-20 14:37:26 +00:00
.perform_sync();
return res;
2018-02-07 10:37:15 +00:00
}
wxString OctoPrint::get_test_ok_msg () const
{
return wxString::Format("%s", _(L("Connection to OctoPrint works correctly.")));
}
wxString OctoPrint::get_test_failed_msg (wxString &msg) const
{
return wxString::Format("%s: %s\n\n%s",
_(L("Could not connect to OctoPrint")), msg, _(L("Note: OctoPrint version at least 1.1.0 is required.")));
}
bool OctoPrint::send_gcode(const std::string &filename) const
2018-02-07 10:37:15 +00:00
{
enum { PROGRESS_RANGE = 1000 };
const auto errortitle = _(L("Error while uploading to the OctoPrint server"));
fs::path filepath(filename);
2018-12-11 09:33:11 +00:00
PrintHostSendDialog send_dialog(filepath.filename());
if (send_dialog.ShowModal() != wxID_OK) { return false; }
2018-12-11 09:33:11 +00:00
const bool print = send_dialog.start_print();
const auto upload_filepath = send_dialog.filename();
const auto upload_filename = upload_filepath.filename();
const auto upload_parent_path = upload_filepath.parent_path();
wxProgressDialog progress_dialog(
_(L("OctoPrint upload")),
_(L("Sending G-code file to the OctoPrint server...")),
PROGRESS_RANGE, nullptr, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
progress_dialog.Pulse();
wxString test_msg;
if (!test(test_msg)) {
auto errormsg = wxString::Format("%s: %s", errortitle, test_msg);
GUI::show_error(&progress_dialog, std::move(errormsg));
return false;
}
bool res = true;
auto url = make_url("api/files/local");
BOOST_LOG_TRIVIAL(info) << boost::format("Octoprint: Uploading file %1% at %2%, filename: %3%, path: %4%, print: %5%")
2018-06-12 10:32:03 +00:00
% filepath.string()
% url
2018-06-12 10:32:03 +00:00
% upload_filename.string()
% upload_parent_path.string()
% print;
auto http = Http::post(std::move(url));
2018-02-20 14:37:26 +00:00
set_auth(http);
http.form_add("print", print ? "true" : "false")
2018-12-11 09:33:11 +00:00
.form_add("path", upload_parent_path.string()) // XXX: slashes on windows ???
.form_add_file("file", filename, upload_filename.string())
.on_complete([&](std::string body, unsigned status) {
BOOST_LOG_TRIVIAL(debug) << boost::format("Octoprint: File uploaded: HTTP %1%: %2%") % status % body;
progress_dialog.Update(PROGRESS_RANGE);
})
.on_error([&](std::string body, std::string error, unsigned status) {
2018-06-27 15:00:20 +00:00
BOOST_LOG_TRIVIAL(error) << boost::format("Octoprint: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body;
auto errormsg = wxString::Format("%s: %s", errortitle, format_error(body, error, status));
GUI::show_error(&progress_dialog, std::move(errormsg));
res = false;
2018-02-20 14:37:26 +00:00
})
.on_progress([&](Http::Progress progress, bool &cancel) {
if (cancel) {
// Upload was canceled
res = false;
} else if (progress.ultotal > 0) {
int value = PROGRESS_RANGE * progress.ulnow / progress.ultotal;
cancel = !progress_dialog.Update(std::min(value, PROGRESS_RANGE - 1)); // Cap the value to prevent premature dialog closing
} else {
cancel = !progress_dialog.Pulse();
}
2018-02-20 14:37:26 +00:00
})
.perform_sync();
return res;
2018-02-07 10:37:15 +00:00
}
2018-12-11 09:33:11 +00:00
bool OctoPrint::upload(PrintHostUpload upload_data) const
{
throw "unimplemented";
}
2018-08-21 09:10:32 +00:00
bool OctoPrint::has_auto_discovery() const
{
return true;
}
bool OctoPrint::can_test() const
{
return true;
}
2018-02-07 10:37:15 +00:00
void OctoPrint::set_auth(Http &http) const
{
2018-02-20 14:37:26 +00:00
http.header("X-Api-Key", apikey);
2018-02-07 10:37:15 +00:00
2018-02-20 14:37:26 +00:00
if (! cafile.empty()) {
http.ca_file(cafile);
}
2018-02-07 10:37:15 +00:00
}
std::string OctoPrint::make_url(const std::string &path) const
{
2018-02-20 14:37:26 +00:00
if (host.find("http://") == 0 || host.find("https://") == 0) {
if (host.back() == '/') {
2018-06-12 10:32:03 +00:00
return (boost::format("%1%%2%") % host % path).str();
2018-02-20 14:37:26 +00:00
} else {
2018-06-12 10:32:03 +00:00
return (boost::format("%1%/%2%") % host % path).str();
2018-02-20 14:37:26 +00:00
}
} else {
2018-06-12 10:32:03 +00:00
return (boost::format("http://%1%/%2%") % host % path).str();
2018-02-20 14:37:26 +00:00
}
2018-02-07 10:37:15 +00:00
}
2018-06-27 15:00:20 +00:00
wxString OctoPrint::format_error(const std::string &body, const std::string &error, unsigned status)
2018-02-07 10:37:15 +00:00
{
if (status != 0) {
2018-06-27 15:00:20 +00:00
auto wxbody = wxString::FromUTF8(body.data());
return wxString::Format("HTTP %u: %s", status, wxbody);
2018-02-20 14:37:26 +00:00
} else {
2018-06-27 15:00:20 +00:00
return wxString::FromUTF8(error.data());
2018-02-20 14:37:26 +00:00
}
2018-02-07 10:37:15 +00:00
}
}