Welcome to mirror list, hosted at ThFree Co, Russian Federation.

OctoPrint.cpp « Utils « slic3r « src « xs - github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e63a16c386ee8fe19b8ec2b4ef0a8a6eb7d93cc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "OctoPrint.hpp"

#include <algorithm>
#include <boost/format.hpp>

#include <wx/frame.h>
#include <wx/event.h>
#include <wx/progdlg.h>

#include "libslic3r/PrintConfig.hpp"
#include "slic3r/GUI/GUI.hpp"
#include "Http.hpp"


namespace Slic3r {


OctoPrint::OctoPrint(DynamicPrintConfig *config) :
	host(config->opt_string("octoprint_host")),
	apikey(config->opt_string("octoprint_apikey")),
	cafile(config->opt_string("octoprint_cafile"))
{}

bool OctoPrint::test(wxString &msg) const
{
	// Since the request is performed synchronously here,
	// it is ok to refer to `msg` from within the closure

	bool res = true;

	auto url = std::move(make_url("api/version"));
	auto http = Http::get(std::move(url));
	set_auth(http);
	http.on_error([&](std::string, std::string error, unsigned status) {
			res = false;
			msg = format_error(error, status);
		})
		.perform_sync();

	return res;
}

bool OctoPrint::send_gcode(const std::string &filename, bool print) const
{
	enum { PROGRESS_RANGE = 1000 };

	const auto errortitle = _(L("Error while uploading to the OctoPrint server"));

	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 http = Http::post(std::move(make_url("api/files/local")));
	set_auth(http);
	http.form_add("print", print ? "true" : "false")
		.form_add_file("file", filename)
		.on_complete([&](std::string body, unsigned status) {
			progress_dialog.Update(PROGRESS_RANGE);
		})
		.on_error([&](std::string body, std::string error, unsigned status) {
			auto errormsg = wxString::Format("%s: %s", errortitle, format_error(error, status));
			GUI::show_error(&progress_dialog, std::move(errormsg));
			res = false;
		})
		.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();
			}
		})
		.perform_sync();

	return res;
}

void OctoPrint::set_auth(Http &http) const
{
	http.header("X-Api-Key", apikey);

	if (! cafile.empty()) {
		http.ca_file(cafile);
	}
}

std::string OctoPrint::make_url(const std::string &path) const
{
	if (host.find("http://") == 0 || host.find("https://") == 0) {
		if (host.back() == '/') {
			return std::move((boost::format("%1%%2%") % host % path).str());
		} else {
			return std::move((boost::format("%1%/%2%") % host % path).str());
		}
	} else {
		return std::move((boost::format("http://%1%/%2%") % host % path).str());
	}
}

wxString OctoPrint::format_error(std::string error, unsigned status)
{
	const wxString wxerror = error;

	if (status != 0) {
		return wxString::Format("HTTP %u: %s", status,
			(status == 401 ? _(L("Invalid API key")) : wxerror));
	} else {
		return std::move(wxerror);
	}
}


}