From 0ac4d13015dc93918be8ef563c435a8aaec8ca3b Mon Sep 17 00:00:00 2001
From: Vojtech Kral <vojtech@kral.hk>
Date: Wed, 19 Dec 2018 15:00:30 +0100
Subject: [PATCH] Print host: Check OctoPrint vs SLA

---
 src/slic3r/GUI/Tab.cpp         |  3 +-
 src/slic3r/Utils/Duet.hpp      | 12 ++++----
 src/slic3r/Utils/OctoPrint.cpp | 53 +++++++++++++++++++++++++++-------
 src/slic3r/Utils/OctoPrint.hpp | 25 +++++++++-------
 src/slic3r/Utils/PrintHost.cpp |  2 +-
 5 files changed, 65 insertions(+), 30 deletions(-)

diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 0b59a21ab..5a212d4ee 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -1551,7 +1551,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
 
 	auto printhost_browse = [this, optgroup] (wxWindow* parent) {
 
-		// TODO: SLA
+		// TODO: SLA Bonjour
 
 		auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
 		btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("zoom.png")), wxBITMAP_TYPE_PNG));
@@ -1562,6 +1562,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
 			BonjourDialog dialog(parent);
 			if (dialog.show_and_lookup()) {
 				optgroup->set_value("print_host", std::move(dialog.get_selected()), true);
+				// FIXME: emit killfocus on the edit widget
 			}
 		});
 
diff --git a/src/slic3r/Utils/Duet.hpp b/src/slic3r/Utils/Duet.hpp
index 0608f85a5..d0f5b3009 100644
--- a/src/slic3r/Utils/Duet.hpp
+++ b/src/slic3r/Utils/Duet.hpp
@@ -19,12 +19,12 @@ public:
 	Duet(DynamicPrintConfig *config);
 	virtual ~Duet();
 
-	bool test(wxString &curl_msg) const;
-	wxString get_test_ok_msg () const;
-	wxString get_test_failed_msg (wxString &msg) const;
-	bool upload(PrintHostUpload upload_data, Http::ProgressFn prorgess_fn, Http::ErrorFn error_fn) const;
-	bool has_auto_discovery() const;
-	bool can_test() const;
+	virtual bool test(wxString &curl_msg) const;
+	virtual wxString get_test_ok_msg () const;
+	virtual wxString get_test_failed_msg (wxString &msg) const;
+	virtual bool upload(PrintHostUpload upload_data, Http::ProgressFn prorgess_fn, Http::ErrorFn error_fn) const;
+	virtual bool has_auto_discovery() const;
+	virtual bool can_test() const;
 	virtual std::string get_host() const { return host; }
 private:
 	std::string host;
diff --git a/src/slic3r/Utils/OctoPrint.cpp b/src/slic3r/Utils/OctoPrint.cpp
index cbb81c54f..cf5fc2f54 100644
--- a/src/slic3r/Utils/OctoPrint.cpp
+++ b/src/slic3r/Utils/OctoPrint.cpp
@@ -1,8 +1,12 @@
 #include "OctoPrint.hpp"
 
 #include <algorithm>
+#include <sstream>
 #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>
 
@@ -12,6 +16,7 @@
 
 
 namespace fs = boost::filesystem;
+namespace pt = boost::property_tree;
 
 
 namespace Slic3r {
@@ -41,11 +46,29 @@ bool OctoPrint::test(wxString &msg) const
             res = false;
             msg = format_error(body, error, status);
         })
-        .on_complete([&](std::string body, unsigned) {
+        .on_complete([&, this](std::string body, unsigned) {
             BOOST_LOG_TRIVIAL(debug) << boost::format("Octoprint: Got version: %1%") % body;
 
-            // TODO: parse body, call validate_version_text
+            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 = wxString::Format("Mismatched type of print host: %s", text ? *text : "OctoPrint");
+                }
+            }
+            catch (...) {
+                res = false;
+                msg = "Could not parse server response";
+            }
         })
         .perform_sync();
 
@@ -71,7 +94,7 @@ bool OctoPrint::upload(PrintHostUpload upload_data, Http::ProgressFn prorgess_fn
     wxString test_msg;
     if (! test(test_msg)) {
 
-        // TODO:
+        // FIXME:
 
         // auto errormsg = wxString::Format("%s: %s", errortitle, test_msg);
         // GUI::show_error(&progress_dialog, std::move(errormsg));
@@ -125,10 +148,9 @@ bool OctoPrint::can_test() const
     return true;
 }
 
-bool OctoPrint::validate_version_text(const std::string &version_text)
+bool OctoPrint::validate_version_text(const boost::optional<std::string> &version_text) const
 {
-    // FIXME
-    return true;
+    return version_text ? boost::starts_with(*version_text, "OctoPrint") : true;
 }
 
 void OctoPrint::set_auth(Http &http) const
@@ -164,14 +186,23 @@ wxString OctoPrint::format_error(const std::string &body, const std::string &err
 }
 
 
-// SL1
+// SLAHost
 
-SL1Host::~SL1Host() {}
+SLAHost::~SLAHost() {}
 
-bool SL1Host::validate_version_text(const std::string &version_text)
+wxString SLAHost::get_test_ok_msg () const
 {
-    // FIXME
-    return true;
+    return wxString::Format("%s", _(L("Connection to Prusa SLA works correctly.")));
+}
+
+wxString SLAHost::get_test_failed_msg (wxString &msg) const
+{
+    return wxString::Format("%s: %s", _(L("Could not connect to Prusa SLA")), msg);
+}
+
+bool SLAHost::validate_version_text(const boost::optional<std::string> &version_text) const
+{
+    return version_text ? boost::starts_with(*version_text, "Prusa SLA") : false;
 }
 
 
diff --git a/src/slic3r/Utils/OctoPrint.hpp b/src/slic3r/Utils/OctoPrint.hpp
index 4d6555e13..57aae672a 100644
--- a/src/slic3r/Utils/OctoPrint.hpp
+++ b/src/slic3r/Utils/OctoPrint.hpp
@@ -3,6 +3,7 @@
 
 #include <string>
 #include <wx/string.h>
+#include <boost/optional.hpp>
 
 #include "PrintHost.hpp"
 
@@ -19,16 +20,16 @@ public:
     OctoPrint(DynamicPrintConfig *config);
     virtual ~OctoPrint();
 
-    bool test(wxString &curl_msg) const;
-    wxString get_test_ok_msg () const;
-    wxString get_test_failed_msg (wxString &msg) const;
-    bool upload(PrintHostUpload upload_data, Http::ProgressFn prorgess_fn, Http::ErrorFn error_fn) const;
-    bool has_auto_discovery() const;
-    bool can_test() const;
+    virtual bool test(wxString &curl_msg) const;
+    virtual wxString get_test_ok_msg () const;
+    virtual wxString get_test_failed_msg (wxString &msg) const;
+    virtual bool upload(PrintHostUpload upload_data, Http::ProgressFn prorgess_fn, Http::ErrorFn error_fn) const;
+    virtual bool has_auto_discovery() const;
+    virtual bool can_test() const;
     virtual std::string get_host() const { return host; }
 
 protected:
-    virtual bool validate_version_text(const std::string &version_text);
+    virtual bool validate_version_text(const boost::optional<std::string> &version_text) const;
 
 private:
     std::string host;
@@ -41,14 +42,16 @@ private:
 };
 
 
-class SL1Host: public OctoPrint
+class SLAHost: public OctoPrint
 {
 public:
-    SL1Host(DynamicPrintConfig *config) : OctoPrint(config) {}
-    virtual ~SL1Host();
+    SLAHost(DynamicPrintConfig *config) : OctoPrint(config) {}
+    virtual ~SLAHost();
 
+    virtual wxString get_test_ok_msg () const;
+    virtual wxString get_test_failed_msg (wxString &msg) const;
 protected:
-    virtual bool validate_version_text(const std::string &version_text);
+    virtual bool validate_version_text(const boost::optional<std::string> &version_text) const;
 };
 
 
diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp
index cdd0c107e..5c4507816 100644
--- a/src/slic3r/Utils/PrintHost.cpp
+++ b/src/slic3r/Utils/PrintHost.cpp
@@ -30,8 +30,8 @@ PrintHost* PrintHost::get_print_host(DynamicPrintConfig *config)
 
     switch (opt->value) {
         case htOctoPrint: return new OctoPrint(config);
-        case htSL1:       return new SL1Host(config);
         case htDuet:      return new Duet(config);
+        case htSL1:       return new SLAHost(config);
         default: return nullptr;
     }
 }