-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into Orangestorm-giga
- Loading branch information
Showing
7 changed files
with
292 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
#include "CrealityPrint.hpp" | ||
|
||
#include <algorithm> | ||
#include <sstream> | ||
#include <exception> | ||
#include <boost/format.hpp> | ||
#include <boost/foreach.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 <boost/asio.hpp> | ||
#include <boost/algorithm/string/split.hpp> | ||
#include <boost/nowide/convert.hpp> | ||
|
||
#include <curl/curl.h> | ||
#include <wx/progdlg.h> | ||
|
||
#include "slic3r/GUI/GUI.hpp" | ||
#include "slic3r/GUI/I18N.hpp" | ||
#include "slic3r/GUI/GUI_App.hpp" | ||
#include "slic3r/GUI/format.hpp" | ||
#include "Http.hpp" | ||
#include "libslic3r/AppConfig.hpp" | ||
#include "Bonjour.hpp" | ||
#include "slic3r/GUI/BonjourDialog.hpp" | ||
|
||
#include <boost/beast/core.hpp> | ||
#include <boost/beast/websocket.hpp> | ||
#include <boost/asio/connect.hpp> | ||
#include <boost/asio/ip/tcp.hpp> | ||
#include <cstdlib> | ||
#include <iostream> | ||
#include <string> | ||
|
||
#include <fstream> | ||
#include <nlohmann/json.hpp> | ||
using json = nlohmann::json; | ||
using std::to_string; | ||
|
||
namespace beast = boost::beast; | ||
namespace http = beast::http; | ||
namespace websocket = beast::websocket; | ||
namespace net = boost::asio; | ||
using tcp = boost::asio::ip::tcp; | ||
|
||
namespace fs = boost::filesystem; | ||
namespace pt = boost::property_tree; | ||
|
||
namespace Slic3r { | ||
|
||
CrealityPrint::CrealityPrint(DynamicPrintConfig* config) : | ||
m_host(config->opt_string("print_host")), | ||
m_web_ui(config->opt_string("print_host_webui")), | ||
m_cafile(config->opt_string("printhost_cafile")), | ||
m_port(config->opt_string("printhost_port")), | ||
m_apikey(config->opt_string("printhost_apikey")), | ||
m_ssl_revoke_best_effort(config->opt_bool("printhost_ssl_ignore_revoke")) | ||
{} | ||
|
||
const char* CrealityPrint::get_name() const { return "Creality Print"; } | ||
|
||
std::string CrealityPrint::get_host() const { | ||
return m_host; | ||
} | ||
void CrealityPrint::set_auth(Http& http) const | ||
{ | ||
http.header("Authorization", "Bearer " + m_apikey); | ||
if (!m_cafile.empty()) { | ||
http.ca_file(m_cafile); | ||
} | ||
} | ||
|
||
wxString CrealityPrint::get_test_ok_msg() const { return _(L("Connected to CrealityPrint successfully!")); } | ||
|
||
wxString CrealityPrint::get_test_failed_msg(wxString& msg) const | ||
{ | ||
return GUI::format_wxstr("%s: %s", _L("Could not connect to CrealityPrint"), msg.Truncate(256)); | ||
} | ||
|
||
bool CrealityPrint::test(wxString& msg) const | ||
{ | ||
bool res = true; | ||
const char* name = get_name(); | ||
auto url = make_url("info"); | ||
|
||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get version at: %2%") % name % url; | ||
// Here we do not have to add custom "Host" header - the url contains host filled by user and libCurl will set the header by itself. | ||
auto http = Http::get(std::move(url)); | ||
set_auth(http); | ||
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; | ||
}) | ||
#ifdef WIN32 | ||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort) | ||
.on_ip_resolve([&](std::string address) { | ||
// Workaround for Windows 10/11 mDNS resolve issue, where two mDNS resolves in succession fail. | ||
// Remember resolved address to be reused at successive REST API call. | ||
msg = GUI::from_u8(address); | ||
}) | ||
#endif // WIN32 | ||
.perform_sync(); | ||
|
||
return res; | ||
} | ||
|
||
PrintHostPostUploadActions CrealityPrint::get_post_upload_actions() const { | ||
return PrintHostPostUploadAction::StartPrint; | ||
} | ||
|
||
bool CrealityPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_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("upload/" + safe_filename(upload_filename.string())); | ||
|
||
auto http = Http::post(url); // std::move(url)); | ||
set_auth(http); | ||
http.form_add("path", upload_parent_path.string()) | ||
.form_add_file("file", upload_data.source_path.string(), upload_filename.string()) | ||
|
||
.on_complete([&](std::string body, unsigned status) { | ||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: File uploaded: HTTP %2%: %3%") % name % status % body; | ||
|
||
if (upload_data.post_action == PrintHostPostUploadAction::StartPrint) { | ||
start_print(safe_filename(upload_filename.string())); | ||
} | ||
}) | ||
.on_error([&](std::string body, std::string error, unsigned status) { | ||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error uploading file to %2%: %3%, HTTP %4%, body: `%5%`") % name % url % 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) << name << ": Upload canceled"; | ||
res = false; | ||
} | ||
}) | ||
#ifdef WIN32 | ||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort) | ||
#endif | ||
.perform_sync(); | ||
return res; | ||
} | ||
|
||
std::string CrealityPrint::make_url(const std::string &path) const | ||
{ | ||
if (m_host.find("http://") == 0 || m_host.find("https://") == 0) { | ||
if (m_host.back() == '/') { | ||
return (boost::format("%1%%2%") % m_host % path).str(); | ||
} else { | ||
return (boost::format("%1%/%2%") % m_host % path).str(); | ||
} | ||
} else { | ||
return (boost::format("http://%1%/%2%") % m_host % path).str(); | ||
} | ||
} | ||
|
||
std::string CrealityPrint::safe_filename(const std::string &filename) const | ||
{ | ||
std::string safe_filename = filename; | ||
std::replace(safe_filename.begin(), safe_filename.end(), ' ', '_'); | ||
|
||
return safe_filename; | ||
} | ||
|
||
void CrealityPrint::start_print(const std::string &filename) const | ||
{ | ||
try { | ||
std::string host = m_host; | ||
auto const port = "9999"; | ||
|
||
json j2 = { | ||
{ "method", "set" }, | ||
{ | ||
"params", { | ||
{ "opGcodeFile", "printprt:/usr/data/printer_data/gcodes/" + filename } | ||
} | ||
} | ||
}; | ||
|
||
net::io_context ioc; | ||
|
||
tcp::resolver resolver{ioc}; | ||
websocket::stream<tcp::socket> ws{ioc}; | ||
|
||
auto const results = resolver.resolve(host, port); | ||
|
||
auto ep = net::connect(ws.next_layer(), results); | ||
|
||
host += ':' + std::to_string(ep.port()); | ||
|
||
ws.set_option(websocket::stream_base::decorator( | ||
[](websocket::request_type& req) | ||
{ | ||
req.set(http::field::user_agent, | ||
std::string(BOOST_BEAST_VERSION_STRING) + | ||
" websocket-client-coro"); | ||
})); | ||
|
||
ws.handshake(host, "/"); | ||
|
||
ws.write(net::buffer(to_string(j2))); | ||
|
||
beast::flat_buffer buffer; | ||
|
||
ws.read(buffer); | ||
|
||
ws.close(websocket::close_code::normal); | ||
} catch(std::exception const& e) { | ||
std::cerr << "Error: " << e.what() << std::endl; | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#ifndef slic3r_CrealityPrint_hpp_ | ||
#define slic3r_CrealityPrint_hpp_ | ||
|
||
#include <string> | ||
#include <wx/string.h> | ||
#include <boost/optional.hpp> | ||
#include <boost/asio/ip/address.hpp> | ||
|
||
#include "PrintHost.hpp" | ||
#include "libslic3r/PrintConfig.hpp" | ||
|
||
namespace Slic3r { | ||
|
||
class DynamicPrintConfig; | ||
class Http; | ||
class CrealityPrint : public PrintHost | ||
{ | ||
public: | ||
CrealityPrint(DynamicPrintConfig* config); | ||
~CrealityPrint() override = default; | ||
|
||
const char* get_name() const override; | ||
virtual bool can_test() const { return true; }; | ||
std::string get_host() const override; | ||
bool has_auto_discovery() const override { return true; } | ||
|
||
wxString get_test_ok_msg() const override; | ||
wxString get_test_failed_msg(wxString& msg) const override; | ||
virtual bool test(wxString& curl_msg) const override; | ||
PrintHostPostUploadActions get_post_upload_actions() const; | ||
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const override; | ||
|
||
protected: | ||
virtual void set_auth(Http& http) const; | ||
private: | ||
std::string m_host; | ||
std::string m_port; | ||
std::string m_apikey; | ||
std::string m_cafile; | ||
std::string m_web_ui; | ||
bool m_ssl_revoke_best_effort; | ||
|
||
std::string make_url(const std::string& path) const; | ||
void start_print(const std::string& path) const; | ||
std::string safe_filename(const std::string& filename) const; | ||
}; | ||
} // namespace Slic3r | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters