mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-30 00:22:01 +08:00
PrusaConnectNew class - new way to upload to Connect
Several bugs in UI fixed Added Connect user data action, we might need it in future Missing file in cmake and smaller fixes new Connect frontend
This commit is contained in:
parent
b232894451
commit
0c7e6cb063
@ -102,7 +102,9 @@ static const t_config_enum_values s_keys_map_PrintHostType {
|
||||
{ "flashair", htFlashAir },
|
||||
{ "astrobox", htAstroBox },
|
||||
{ "repetier", htRepetier },
|
||||
{ "mks", htMKS }
|
||||
{ "mks", htMKS },
|
||||
{ "prusaconnectnew", htPrusaConnectNew },
|
||||
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrintHostType)
|
||||
|
||||
|
@ -65,7 +65,7 @@ enum class MachineLimitsUsage {
|
||||
};
|
||||
|
||||
enum PrintHostType {
|
||||
htPrusaLink, htPrusaConnect, htOctoPrint, htMoonraker, htDuet, htFlashAir, htAstroBox, htRepetier, htMKS
|
||||
htPrusaLink, htPrusaConnect, htOctoPrint, htMoonraker, htDuet, htFlashAir, htAstroBox, htRepetier, htMKS, htPrusaConnectNew
|
||||
};
|
||||
|
||||
enum AuthorizationType {
|
||||
|
@ -351,6 +351,8 @@ set(SLIC3R_GUI_SOURCES
|
||||
Utils/WifiScanner.cpp
|
||||
Utils/Secrets.hpp
|
||||
Utils/Secrets.cpp
|
||||
Utils/PrusaConnect.hpp
|
||||
Utils/PrusaConnect.cpp
|
||||
)
|
||||
|
||||
find_package(NanoSVG REQUIRED)
|
||||
|
@ -852,8 +852,9 @@ void MainFrame::create_preset_tabs()
|
||||
|
||||
void MainFrame::add_connect_webview_tab()
|
||||
{
|
||||
assert(!m_connect_webview_added);
|
||||
// parameters of InsertPage (to prevent ambigous overloaded function)
|
||||
if (m_connect_webview_added) {
|
||||
return;
|
||||
} // parameters of InsertPage (to prevent ambigous overloaded function)
|
||||
// insert to positon 4, if physical printer is already added, it moves to 5
|
||||
// order of tabs: Plater - Print Settings - Filaments - Printers - Prusa Connect - Prusa Link
|
||||
size_t n = 4;
|
||||
@ -867,7 +868,9 @@ void MainFrame::add_connect_webview_tab()
|
||||
}
|
||||
void MainFrame::remove_connect_webview_tab()
|
||||
{
|
||||
assert(m_connect_webview_added);
|
||||
if (!m_connect_webview_added) {
|
||||
return;
|
||||
}
|
||||
// connect tab should always be at position 4
|
||||
if (m_tabpanel->GetSelection() == 4)
|
||||
m_tabpanel->SetSelection(0);
|
||||
@ -877,7 +880,10 @@ void MainFrame::remove_connect_webview_tab()
|
||||
|
||||
void MainFrame::add_printer_webview_tab(const wxString& url)
|
||||
{
|
||||
assert(!m_printer_webview_added);
|
||||
if (m_printer_webview_added) {
|
||||
set_printer_webview_tab_url(url);
|
||||
return;
|
||||
}
|
||||
m_printer_webview_added = true;
|
||||
// add as the last (rightmost) panel
|
||||
dynamic_cast<TopBar*>(m_tabpanel)->AddPage(m_printer_webview, L"Physical Printer", "", false);
|
||||
@ -886,7 +892,9 @@ void MainFrame::add_printer_webview_tab(const wxString& url)
|
||||
}
|
||||
void MainFrame::remove_printer_webview_tab()
|
||||
{
|
||||
assert(m_printer_webview_added);
|
||||
if (!m_printer_webview_added) {
|
||||
return;
|
||||
}
|
||||
m_printer_webview_added = false;
|
||||
m_printer_webview->Hide();
|
||||
// always remove the last tab
|
||||
@ -894,7 +902,10 @@ void MainFrame::remove_printer_webview_tab()
|
||||
}
|
||||
void MainFrame::set_printer_webview_tab_url(const wxString& url)
|
||||
{
|
||||
assert(m_printer_webview_added);
|
||||
if (!m_printer_webview_added) {
|
||||
add_printer_webview_tab(url);
|
||||
return;
|
||||
}
|
||||
m_printer_webview->clear();
|
||||
m_printer_webview->set_default_url(url);
|
||||
if (m_tabpanel->GetSelection() == m_tabpanel->GetPageCount() - 1) {
|
||||
|
@ -892,8 +892,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
this->main_frame->refresh_account_menu(true);
|
||||
// Update sidebar printer status
|
||||
sidebar->update_printer_presets_combobox();
|
||||
this->main_frame->refresh_account_menu();
|
||||
wxGetApp().update_login_dialog();
|
||||
this->show_action_buttons(this->ready_to_slice);
|
||||
});
|
||||
|
||||
this->q->Bind(EVT_UA_ID_USER_SUCCESS, [this](UserAccountSuccessEvent& evt) {
|
||||
@ -908,6 +908,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
// Update User name in TopBar
|
||||
this->main_frame->refresh_account_menu();
|
||||
wxGetApp().update_login_dialog();
|
||||
this->show_action_buttons(this->ready_to_slice);
|
||||
} else {
|
||||
// data were corrupt and username was not retrieved
|
||||
// procced as if EVT_UA_RESET was recieved
|
||||
@ -917,7 +918,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
this->notification_manager->push_notification(NotificationType::UserAccountID, NotificationManager::NotificationLevel::WarningNotificationLevel, _u8L("Failed to connect to Prusa Account."));
|
||||
this->main_frame->remove_connect_webview_tab();
|
||||
// Update User name in TopBar
|
||||
this->main_frame->refresh_account_menu();
|
||||
this->main_frame->refresh_account_menu(true);
|
||||
// Update sidebar printer status
|
||||
sidebar->update_printer_presets_combobox();
|
||||
}
|
||||
@ -930,7 +931,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
this->notification_manager->push_notification(NotificationType::UserAccountID, NotificationManager::NotificationLevel::WarningNotificationLevel, _u8L("Failed to connect to Prusa Account."));
|
||||
this->main_frame->remove_connect_webview_tab();
|
||||
// Update User name in TopBar
|
||||
this->main_frame->refresh_account_menu();
|
||||
this->main_frame->refresh_account_menu(true);
|
||||
// Update sidebar printer status
|
||||
sidebar->update_printer_presets_combobox();
|
||||
});
|
||||
@ -944,6 +945,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
this->notification_manager->close_notification_of_type(NotificationType::UserAccountID);
|
||||
this->notification_manager->push_notification(NotificationType::UserAccountID, NotificationManager::NotificationLevel::ImportantNotificationLevel, evt.data);
|
||||
});
|
||||
this->q->Bind(EVT_UA_CONNECT_USER_DATA_SUCCESS, [this](UserAccountSuccessEvent& evt) {
|
||||
BOOST_LOG_TRIVIAL(error) << evt.data;
|
||||
user_account->on_connect_user_data_success(evt.data);
|
||||
});
|
||||
#endif // 0
|
||||
this->q->Bind(EVT_UA_PRUSACONNECT_PRINTERS_SUCCESS, [this](UserAccountSuccessEvent& evt) {
|
||||
std::string text;
|
||||
@ -965,7 +970,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
fclose(file);
|
||||
this->main_frame->refresh_account_menu(true);
|
||||
wxGetApp().update_login_dialog();
|
||||
});
|
||||
});
|
||||
|
||||
wxGetApp().other_instance_message_handler()->init(this->q);
|
||||
|
||||
@ -5852,15 +5857,17 @@ void Plater::connect_gcode()
|
||||
return;
|
||||
}
|
||||
if (dialog_msg.empty()) {
|
||||
show_error(this, _L("Failed to select a printer. PrusaConnect did not return a value."));
|
||||
return;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(error) << dialog_msg;
|
||||
BOOST_LOG_TRIVIAL(debug) << "Message from Printer pick webview: " << dialog_msg;
|
||||
|
||||
std::string model_name = p->user_account->get_model_from_json(dialog_msg);
|
||||
std::string nozzle = p->user_account->get_nozzle_from_json(dialog_msg);
|
||||
assert(!model_name.empty());
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
const Preset* preset = preset_bundle->printers.find_system_preset_by_model_and_variant(model_name, nozzle);
|
||||
// TODO: preset check
|
||||
|
||||
// if selected (in connect) preset is not visible, make it visible and selected
|
||||
if (!preset->is_visible) {
|
||||
@ -5875,8 +5882,7 @@ void Plater::connect_gcode()
|
||||
}
|
||||
|
||||
// if selected (in connect) preset is not selected in slicer, select it
|
||||
if (preset_bundle->printers.get_selected_preset_name() != preset->name)
|
||||
{
|
||||
if (preset_bundle->printers.get_selected_preset_name() != preset->name) {
|
||||
size_t preset_id = preset_bundle->printers.get_preset_idx_by_name(preset->name);
|
||||
assert(preset_id != size_t(-1));
|
||||
preset_bundle->printers.select_preset(preset_id);
|
||||
@ -5887,21 +5893,45 @@ void Plater::connect_gcode()
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: break if printer not ready
|
||||
|
||||
// get api key from dialog_msg and upload the file
|
||||
std::string api_key = p->user_account->get_apikey_from_json(dialog_msg);
|
||||
if (api_key.empty())
|
||||
{
|
||||
const std::string connect_state = p->user_account->get_keyword_from_json(dialog_msg, "connect_state");
|
||||
const std::string printer_state = p->user_account->get_keyword_from_json(dialog_msg, "printer_state");
|
||||
const std::map<std::string, ConnectPrinterState>& printer_state_table = p->user_account->get_printer_state_table();
|
||||
const auto state = printer_state_table.find(connect_state);
|
||||
assert(state != printer_state_table.end());
|
||||
// TODO: all states that does not allow to upload
|
||||
if (state->second == ConnectPrinterState::CONNECT_PRINTER_OFFLINE) {
|
||||
show_error(this, _L("Failed to select a printer. Chosen printer is in offline state."));
|
||||
return;
|
||||
}
|
||||
std::string connect_address = p->user_account->get_connect_address();
|
||||
|
||||
|
||||
const std::string uuid = p->user_account->get_keyword_from_json(dialog_msg, "uuid");
|
||||
const std::string team_id = p->user_account->get_keyword_from_json(dialog_msg, "team_id");
|
||||
if (uuid.empty() || team_id.empty()) {
|
||||
show_error(this, _L("Failed to select a printer. Missing data (uuid and team id) for chosen printer."));
|
||||
return;
|
||||
}
|
||||
PhysicalPrinter ph_printer("connect_temp_printer", wxGetApp().preset_bundle->physical_printers.default_config(), *preset);
|
||||
ph_printer.config.opt_string("printhost_apikey") = api_key;
|
||||
ph_printer.config.opt_string("print_host") = connect_address;
|
||||
ph_printer.config.set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaConnect));
|
||||
ph_printer.config.set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaConnectNew));
|
||||
// use existing structures to pass data
|
||||
ph_printer.config.opt_string("printhost_apikey") = team_id;
|
||||
ph_printer.config.opt_string("print_host") = uuid;
|
||||
DynamicPrintConfig* physical_printer_config = &ph_printer.config;
|
||||
|
||||
|
||||
// Old PrusaConnect - requires prusaconnect_api_key in
|
||||
//std::string api_key = p->user_account->get_keyword_from_json(dialog_msg, "prusaconnect_api_key");
|
||||
//if (api_key.empty()) {
|
||||
// // TODO error dialog
|
||||
// return;
|
||||
//}
|
||||
//const std::string connect_address = "https://dev.connect.prusa3d.com";
|
||||
|
||||
//PhysicalPrinter ph_printer("connect_temp_printer", wxGetApp().preset_bundle->physical_printers.default_config(), *preset);
|
||||
//ph_printer.config.opt_string("printhost_apikey") = api_key;
|
||||
//ph_printer.config.opt_string("print_host") = connect_address;
|
||||
//ph_printer.config.set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaConnect));
|
||||
//DynamicPrintConfig* physical_printer_config = &ph_printer.config;
|
||||
|
||||
send_gcode_inner(physical_printer_config);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ void UserAccount::set_username(const std::string& username)
|
||||
void UserAccount::clear()
|
||||
{
|
||||
m_username = {};
|
||||
m_user_data.clear();
|
||||
m_account_user_data.clear();
|
||||
m_printer_map.clear();
|
||||
m_communication->do_clear();
|
||||
}
|
||||
@ -86,6 +86,10 @@ void UserAccount::enqueue_connect_dummy_action()
|
||||
{
|
||||
m_communication->enqueue_connect_dummy_action();
|
||||
}
|
||||
void UserAccount::enqueue_connect_user_data_action()
|
||||
{
|
||||
m_communication->enqueue_connect_user_data_action();
|
||||
}
|
||||
#endif
|
||||
|
||||
void UserAccount::enqueue_connect_printers_action()
|
||||
@ -94,7 +98,7 @@ void UserAccount::enqueue_connect_printers_action()
|
||||
}
|
||||
void UserAccount::enqueue_avatar_action()
|
||||
{
|
||||
m_communication->enqueue_avatar_action(m_user_data["avatar"]);
|
||||
m_communication->enqueue_avatar_action(m_account_user_data["avatar"]);
|
||||
}
|
||||
|
||||
bool UserAccount::on_login_code_recieved(const std::string& url_message)
|
||||
@ -114,24 +118,24 @@ bool UserAccount::on_user_id_success(const std::string data, std::string& out_us
|
||||
BOOST_LOG_TRIVIAL(error) << "UserIDUserAction Could not parse server response.";
|
||||
return false;
|
||||
}
|
||||
m_user_data.clear();
|
||||
m_account_user_data.clear();
|
||||
for (const auto& section : ptree) {
|
||||
const auto opt = ptree.get_optional<std::string>(section.first);
|
||||
if (opt) {
|
||||
BOOST_LOG_TRIVIAL(debug) << static_cast<std::string>(section.first) << " " << *opt;
|
||||
m_user_data[section.first] = *opt;
|
||||
m_account_user_data[section.first] = *opt;
|
||||
}
|
||||
|
||||
}
|
||||
if (m_user_data.find("public_username") == m_user_data.end()) {
|
||||
if (m_account_user_data.find("public_username") == m_account_user_data.end()) {
|
||||
BOOST_LOG_TRIVIAL(error) << "User ID message from PrusaAuth did not contain public_username. Login failed. Message data: " << data;
|
||||
return false;
|
||||
}
|
||||
std::string public_username = m_user_data["public_username"];
|
||||
std::string public_username = m_account_user_data["public_username"];
|
||||
set_username(public_username);
|
||||
out_username = public_username;
|
||||
// equeue GET with avatar url
|
||||
if (m_user_data.find("avatar") != m_user_data.end()) {
|
||||
if (m_account_user_data.find("avatar") != m_account_user_data.end()) {
|
||||
enqueue_avatar_action();
|
||||
}
|
||||
else {
|
||||
@ -168,7 +172,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
bool UserAccount::on_connect_printers_success(const std::string data, AppConfig* app_config, bool& out_printers_changed)
|
||||
bool UserAccount::on_connect_printers_success(const std::string& data, AppConfig* app_config, bool& out_printers_changed)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << "PrusaConnect printers message: " << data;
|
||||
pt::ptree ptree;
|
||||
@ -280,15 +284,15 @@ std::string UserAccount::get_nozzle_from_json(const std::string& message) const
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string UserAccount::get_apikey_from_json(const std::string& message) const
|
||||
std::string UserAccount::get_keyword_from_json(const std::string& json, const std::string& keyword) const
|
||||
{
|
||||
std::string out;
|
||||
try {
|
||||
std::stringstream ss(message);
|
||||
std::stringstream ss(json);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
|
||||
out = parse_tree_for_param(ptree, "prusaconnect_api_key");
|
||||
out = parse_tree_for_param(ptree, keyword);
|
||||
//assert(!out.empty());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
|
@ -18,6 +18,7 @@ enum class ConnectPrinterState {
|
||||
CONNECT_PRINTER_IDLE,
|
||||
CONNECT_PRINTER_FINISHED,
|
||||
CONNECT_PRINTER_READY, //?
|
||||
CONNECT_PRINTER_ATTENTION,
|
||||
CONNECT_PRINTER_STATE_COUNT
|
||||
};
|
||||
|
||||
@ -40,31 +41,34 @@ public:
|
||||
#if 0
|
||||
void enqueue_user_id_action();
|
||||
void enqueue_connect_dummy_action();
|
||||
void enqueue_connect_user_data_action();
|
||||
#endif
|
||||
void enqueue_connect_printers_action();
|
||||
void enqueue_avatar_action();
|
||||
|
||||
// Clears all data and connections, called on logout or EVT_UA_RESET
|
||||
void clear();
|
||||
|
||||
// Functions called from UI where events emmited from UserAccountSession are binded
|
||||
// Returns bool if data were correctly proccessed
|
||||
bool on_login_code_recieved(const std::string& url_message);
|
||||
bool on_user_id_success(const std::string data, std::string& out_username);
|
||||
// Called on EVT_UA_FAIL, triggers test after several calls
|
||||
void on_communication_fail();
|
||||
// Clears all data and connections, called on logout or EVT_UA_RESET
|
||||
void clear();
|
||||
bool on_connect_printers_success(const std::string data, AppConfig* app_config, bool& out_printers_changed);
|
||||
bool on_connect_printers_success(const std::string& data, AppConfig* app_config, bool& out_printers_changed);
|
||||
|
||||
std::string get_username() const { return m_username; }
|
||||
std::string get_access_token();
|
||||
const ConnectPrinterStateMap& get_printer_state_map() const { return m_printer_map; }
|
||||
const std::map<std::string, std::string> get_user_data() const { return m_user_data; }
|
||||
std::string get_connect_address() const { return "https://dev.connect.prusa3d.com"; }
|
||||
boost::filesystem::path get_avatar_path(bool logged) const;
|
||||
|
||||
// standalone utility methods
|
||||
std::string get_model_from_json(const std::string& message) const;
|
||||
std::string get_nozzle_from_json(const std::string& message) const;
|
||||
std::string get_apikey_from_json(const std::string& message) const;
|
||||
//std::string get_apikey_from_json(const std::string& message) const;
|
||||
std::string get_keyword_from_json(const std::string& json, const std::string& keyword) const;
|
||||
|
||||
const std::map<std::string, ConnectPrinterState>& get_printer_state_table() const { return printer_state_table; }
|
||||
private:
|
||||
void set_username(const std::string& username);
|
||||
|
||||
@ -73,7 +77,7 @@ private:
|
||||
std::unique_ptr<Slic3r::GUI::UserAccountCommunication> m_communication;
|
||||
|
||||
ConnectPrinterStateMap m_printer_map;
|
||||
std::map<std::string, std::string> m_user_data;
|
||||
std::map<std::string, std::string> m_account_user_data;
|
||||
std::string m_username;
|
||||
size_t m_fail_counter { 0 };
|
||||
|
||||
@ -116,6 +120,7 @@ private:
|
||||
{"IDLE" , ConnectPrinterState::CONNECT_PRINTER_IDLE},
|
||||
{"FINISHED" , ConnectPrinterState::CONNECT_PRINTER_FINISHED},
|
||||
{"READY" , ConnectPrinterState::CONNECT_PRINTER_READY},
|
||||
{"ATTENTION", ConnectPrinterState::CONNECT_PRINTER_ATTENTION},
|
||||
};
|
||||
};
|
||||
}} // namespace slic3r::GUI
|
||||
|
@ -276,7 +276,6 @@ void UserAccountCommunication::enqueue_user_id_action()
|
||||
}
|
||||
wakeup_session_thread();
|
||||
}
|
||||
|
||||
void UserAccountCommunication::enqueue_connect_dummy_action()
|
||||
{
|
||||
{
|
||||
@ -289,6 +288,18 @@ void UserAccountCommunication::enqueue_connect_dummy_action()
|
||||
}
|
||||
wakeup_session_thread();
|
||||
}
|
||||
void UserAccountCommunication::enqueue_connect_user_data_action()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_session_mutex);
|
||||
if (!m_session->is_initialized()) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Connect Printers endpoint connection failed - Not Logged in.";
|
||||
return;
|
||||
}
|
||||
m_session->enqueue_action(UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_USER_DATA, nullptr, nullptr, {});
|
||||
}
|
||||
wakeup_session_thread();
|
||||
}
|
||||
#endif 0
|
||||
|
||||
void UserAccountCommunication::enqueue_connect_printers_action()
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
#if 0
|
||||
void enqueue_user_id_action();
|
||||
void enqueue_connect_dummy_action();
|
||||
void enqueue_connect_user_data_action();
|
||||
#endif
|
||||
void enqueue_connect_printers_action();
|
||||
void enqueue_avatar_action(const std::string url);
|
||||
|
@ -23,9 +23,12 @@ wxDEFINE_EVENT(EVT_UA_LOGGEDOUT, UserAccountSuccessEvent);
|
||||
wxDEFINE_EVENT(EVT_UA_ID_USER_SUCCESS, UserAccountSuccessEvent);
|
||||
wxDEFINE_EVENT(EVT_UA_SUCCESS, UserAccountSuccessEvent);
|
||||
wxDEFINE_EVENT(EVT_UA_PRUSACONNECT_PRINTERS_SUCCESS, UserAccountSuccessEvent);
|
||||
wxDEFINE_EVENT(EVT_UA_AVATAR_SUCCESS, UserAccountSuccessEvent);
|
||||
wxDEFINE_EVENT(EVT_UA_AVATAR_SUCCESS, UserAccountSuccessEvent);
|
||||
wxDEFINE_EVENT(EVT_UA_FAIL, UserAccountFailEvent);
|
||||
wxDEFINE_EVENT(EVT_UA_RESET, UserAccountFailEvent);
|
||||
#if 0
|
||||
wxDEFINE_EVENT(EVT_UA_FAIL, UserAccountFailEvent);
|
||||
#endif // 0
|
||||
|
||||
|
||||
void UserActionPost::perform(/*UNUSED*/ wxEvtHandler* evt_handler, /*UNUSED*/ const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input)
|
||||
|
@ -24,6 +24,10 @@ wxDECLARE_EVENT(EVT_UA_PRUSACONNECT_PRINTERS_SUCCESS, UserAccountSuccessEvent);
|
||||
wxDECLARE_EVENT(EVT_UA_AVATAR_SUCCESS, UserAccountSuccessEvent);
|
||||
wxDECLARE_EVENT(EVT_UA_FAIL, UserAccountFailEvent); // Soft fail - clears only after some number of fails
|
||||
wxDECLARE_EVENT(EVT_UA_RESET, UserAccountFailEvent); // Hard fail - clears all
|
||||
#if 0
|
||||
wxDECLARE_EVENT(EVT_UA_CONNECT_USER_DATA_SUCCESS, UserAccountSuccessEvent);
|
||||
#endif // 0
|
||||
|
||||
|
||||
typedef std::function<void(const std::string& body)> UserActionSuccessFn;
|
||||
typedef std::function<void(const std::string& body)> UserActionFailFn;
|
||||
@ -39,6 +43,7 @@ enum class UserAccountActionID {
|
||||
USER_ACCOUNT_ACTION_CONNECT_PRINTERS,
|
||||
USER_ACCOUNT_ACTION_AVATAR,
|
||||
#if 0
|
||||
USER_ACCOUNT_ACTION_CONNECT_USER_DATA,
|
||||
USER_ACCOUNT_ACTION_CONNECT_DUMMY,
|
||||
#endif // 0
|
||||
|
||||
@ -115,6 +120,7 @@ public:
|
||||
m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_PRINTERS] = std::make_unique<UserActionGetWithEvent>("CONNECT_PRINTERS", "https://dev.connect.prusa3d.com/slicer/printers", EVT_UA_PRUSACONNECT_PRINTERS_SUCCESS, EVT_UA_FAIL);
|
||||
m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_AVATAR] = std::make_unique<UserActionGetWithEvent>("AVATAR", "https://test-media.printables.com/media/", EVT_UA_AVATAR_SUCCESS, EVT_UA_FAIL);
|
||||
#if 0
|
||||
m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_USER_DATA] = std::make_unique<UserActionGetWithEvent>("CONNECT_USER_DATA", "https://dev.connect.prusa3d.com/app/login", EVT_UA_CONNECT_USER_DATA_SUCCESS, EVT_UA_FAIL);
|
||||
m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_DUMMY] = std::make_unique<UserActionGetWithEvent>("CONNECT_DUMMY", "https://dev.connect.prusa3d.com/slicer/dummy", EVT_UA_SUCCESS, EVT_UA_FAIL);
|
||||
#endif // 0
|
||||
|
||||
@ -130,6 +136,7 @@ public:
|
||||
m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_PRINTERS].reset(nullptr);
|
||||
m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_AVATAR].reset(nullptr);
|
||||
#if 0
|
||||
m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_USER_DATA].reset(nullptr);
|
||||
m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_DUMMY].reset(nullptr);
|
||||
#endif // 0
|
||||
|
||||
|
@ -442,9 +442,11 @@ SourceViewDialog::SourceViewDialog(wxWindow* parent, wxString source) :
|
||||
ConnectRequestHandler::ConnectRequestHandler()
|
||||
{
|
||||
m_actions["REQUEST_ACCESS_TOKEN"] = std::bind(&ConnectRequestHandler::on_request_access_token, this);
|
||||
m_actions["REQUEST_CONFIG"] = std::bind(&ConnectRequestHandler::on_request_config, this);
|
||||
m_actions["REQUEST_LANGUAGE"] = std::bind(&ConnectRequestHandler::on_request_language_action, this);
|
||||
m_actions["REQUEST_SESSION_ID"] = std::bind(&ConnectRequestHandler::on_request_session_id_action, this);
|
||||
m_actions["UPDATE_SELECTED_PRINTER"] = std::bind(&ConnectRequestHandler::on_request_update_selected_printer_action, this);
|
||||
|
||||
}
|
||||
ConnectRequestHandler::~ConnectRequestHandler()
|
||||
{
|
||||
@ -489,8 +491,23 @@ void ConnectRequestHandler::on_request_access_token()
|
||||
wxString script = GUI::format_wxstr("window._prusaConnect_v1.setAccessToken(\'%1%\')", token);
|
||||
run_script_bridge(script);
|
||||
}
|
||||
|
||||
void ConnectRequestHandler::on_request_config()
|
||||
{
|
||||
/*
|
||||
accessToken?: string;
|
||||
clientVersion?: string;
|
||||
language?: ConnectLanguage;
|
||||
sessionId?: string;
|
||||
*/
|
||||
const std::string token = wxGetApp().plater()->get_user_account()->get_access_token();
|
||||
const std::string init_options = GUI::format("{\"accessToken\": \"%1%\" }", token);
|
||||
wxString script = GUI::format_wxstr("window._prusaConnect_v1.init(%1%)", init_options);
|
||||
run_script_bridge(script);
|
||||
}
|
||||
void ConnectRequestHandler::on_request_language_action()
|
||||
{
|
||||
assert(true);
|
||||
// TODO:
|
||||
//std::string lang = "en";
|
||||
//wxString script = GUI::format_wxstr("window._prusaConnect_v1.setAccessToken(\'en\')", lang);
|
||||
@ -498,6 +515,7 @@ void ConnectRequestHandler::on_request_language_action()
|
||||
}
|
||||
void ConnectRequestHandler::on_request_session_id_action()
|
||||
{
|
||||
assert(true);
|
||||
/*
|
||||
std::string token = wxGetApp().plater()->get_user_account()->get_access_token();
|
||||
wxString script = GUI::format_wxstr("window._prusaConnect_v1.setAccessToken(\'%1%\')", token);
|
||||
@ -506,7 +524,7 @@ void ConnectRequestHandler::on_request_session_id_action()
|
||||
}
|
||||
|
||||
ConnectWebViewPanel::ConnectWebViewPanel(wxWindow* parent)
|
||||
: WebViewPanel(parent, L"https://dev.connect.prusa3d.com/connect-slicer-app/printer-list")
|
||||
: WebViewPanel(parent, L"https://dev.connect.prusa3d.com/connect-slicer-app/")
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,7 @@ public:
|
||||
protected:
|
||||
// action callbacs stored in m_actions
|
||||
virtual void on_request_access_token();
|
||||
virtual void on_request_config();
|
||||
virtual void on_request_language_action();
|
||||
virtual void on_request_session_id_action();
|
||||
virtual void on_request_update_selected_printer_action() = 0;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "Repetier.hpp"
|
||||
#include "MKS.hpp"
|
||||
#include "Moonraker.hpp"
|
||||
#include "PrusaConnect.hpp"
|
||||
#include "../GUI/PrintHostDialogs.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
@ -63,6 +64,7 @@ PrintHost* PrintHost::get_print_host(DynamicPrintConfig *config)
|
||||
case htRepetier: return new Repetier(config);
|
||||
case htPrusaLink: return new PrusaLink(config);
|
||||
case htPrusaConnect: return new PrusaConnect(config);
|
||||
case htPrusaConnectNew: return new PrusaConnectNew(config);
|
||||
case htMKS: return new MKS(config);
|
||||
case htMoonraker: return new Moonraker(config);
|
||||
default: return nullptr;
|
||||
|
328
src/slic3r/Utils/PrusaConnect.cpp
Normal file
328
src/slic3r/Utils/PrusaConnect.cpp
Normal file
@ -0,0 +1,328 @@
|
||||
#include "PrusaConnect.hpp"
|
||||
|
||||
#include "Http.hpp"
|
||||
#include "slic3r/GUI/format.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/UserAccount.hpp"
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <curl/curl.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
namespace
|
||||
{
|
||||
std::string escape_string(const std::string& unescaped)
|
||||
{
|
||||
std::string ret_val;
|
||||
CURL* curl = curl_easy_init();
|
||||
if (curl) {
|
||||
char* decoded = curl_easy_escape(curl, unescaped.c_str(), unescaped.size());
|
||||
if (decoded) {
|
||||
ret_val = std::string(decoded);
|
||||
curl_free(decoded);
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
std::string escape_path_by_element(const boost::filesystem::path& path)
|
||||
{
|
||||
std::string ret_val = escape_string(path.filename().string());
|
||||
boost::filesystem::path parent(path.parent_path());
|
||||
while (!parent.empty() && parent.string() != "/") // "/" check is for case "/file.gcode" was inserted. Then boost takes "/" as parent_path.
|
||||
{
|
||||
ret_val = escape_string(parent.filename().string()) + "/" + ret_val;
|
||||
parent = parent.parent_path();
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
PrusaConnectNew::PrusaConnectNew(DynamicPrintConfig *config)
|
||||
: m_uuid(config->opt_string("print_host"))
|
||||
, m_team_id(config->opt_string("printhost_apikey"))
|
||||
{}
|
||||
|
||||
const char* PrusaConnectNew::get_name() const { return "PrusaConnectNew"; }
|
||||
|
||||
|
||||
bool PrusaConnectNew::test(wxString& curl_msg) const
|
||||
{
|
||||
// Test is not used by upload and gets list of files on a device.
|
||||
const std::string name = get_name();
|
||||
std::string url = GUI::format("https://dev.connect.prusa3d.com/app/teams/%1%/files?printer_uuid=%2%", m_team_id, m_uuid);
|
||||
const std::string access_token = GUI::wxGetApp().plater()->get_user_account()->get_access_token();
|
||||
BOOST_LOG_TRIVIAL(info) << GUI::format("%1%: Get files/raw at: %2%", name, url);
|
||||
bool res = true;
|
||||
|
||||
auto http = Http::get(std::move(url));
|
||||
http.header("Authorization", "Bearer " + access_token);
|
||||
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;
|
||||
curl_msg = format_error(body, error, status);
|
||||
})
|
||||
.on_complete([&, this](std::string body, unsigned) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Got files/raw: %2%") % name % body;
|
||||
})
|
||||
.perform_sync();
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
bool PrusaConnectNew::init_upload(PrintHostUpload upload_data, std::string& out) const
|
||||
{
|
||||
// Register upload. Then upload must be performed immediately with returned "id"
|
||||
bool res = true;
|
||||
boost::system::error_code ec;
|
||||
boost::uintmax_t size = boost::filesystem::file_size(upload_data.source_path, ec);
|
||||
const std::string name = get_name();
|
||||
const std::string file_size = std::to_string(size);
|
||||
const std::string access_token = GUI::wxGetApp().plater()->get_user_account()->get_access_token();
|
||||
const std::string escaped_upload_path = escape_path_by_element(upload_data.upload_path);
|
||||
const std::string escaped_upload_filename = escape_path_by_element(upload_data.upload_path.filename());
|
||||
std::string url = GUI::format("%1%/app/users/teams/%2%/uploads", get_host(), m_team_id);
|
||||
const std::string request_body_json = GUI::format(
|
||||
"{"
|
||||
"\"filename\": \"%1%\", "
|
||||
"\"size\": %2%, "
|
||||
"\"path\": \"%3%\", "
|
||||
"\"force\": true, "
|
||||
"\"printer_uuid\": \"%4%\""
|
||||
"}"
|
||||
, escaped_upload_filename
|
||||
, file_size
|
||||
, upload_data.storage + "/" + escaped_upload_path
|
||||
, m_uuid
|
||||
);
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Register upload to "<< name<<". Url: " << url << "\nBody: " << request_body_json;
|
||||
Http http = Http::post(std::move(url));
|
||||
http.header("Authorization", "Bearer " + access_token)
|
||||
.header("Content-Type", "application/json")
|
||||
.set_post_body(request_body_json)
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: File upload registered: HTTP %2%: %3%") % name % status % body;
|
||||
out = body;
|
||||
})
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(error) << body;
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error registering file: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
|
||||
res = false;
|
||||
out = GUI::into_u8(format_error(body, error, status));
|
||||
})
|
||||
.perform_sync();
|
||||
return res;
|
||||
}
|
||||
|
||||
bool PrusaConnectNew::upload(PrintHostUpload upload_data, ProgressFn progress_fn, ErrorFn error_fn, InfoFn info_fn) const
|
||||
{
|
||||
std::string init_out;
|
||||
if (!init_upload(upload_data, init_out))
|
||||
{
|
||||
error_fn(std::move(GUI::from_u8(init_out)));
|
||||
return false;
|
||||
}
|
||||
|
||||
// init reply format: {"id": 1234, "team_id": 12345, "name": "filename.gcode", "size": 123, "hash": "QhE0LD76vihC-F11Jfx9rEqGsk4.", "state": "INITIATED", "source": "CONNECT_USER", "path": "/usb/filename.bgcode"}
|
||||
std::string upload_id;
|
||||
try
|
||||
{
|
||||
std::stringstream ss(init_out);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
const auto id_opt = ptree.get_optional<std::string>("id");
|
||||
if (!id_opt) {
|
||||
error_fn(std::move(_L("Failed to extract upload id from server reply.")));
|
||||
return false;
|
||||
}
|
||||
upload_id = *id_opt;
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
error_fn(std::move(_L("Failed to extract upload id from server reply.")));
|
||||
return false;
|
||||
}
|
||||
const std::string name = get_name();
|
||||
const std::string access_token = GUI::wxGetApp().plater()->get_user_account()->get_access_token();
|
||||
const std::string escaped_upload_path = escape_string(upload_data.storage + "/" + upload_data.upload_path.string());
|
||||
const std::string to_print = upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false";
|
||||
const std::string to_queue = upload_data.post_action == PrintHostPostUploadAction::QueuePrint ? "true" : "false";
|
||||
std::string url = GUI::format("%1%/app/teams/%2%/files/raw?upload_id=%3%&force=true&printer_uuid=%4%&path=%5%&to_print=%6%&to_queue=%7%", get_host(), m_team_id, upload_id, m_uuid, escaped_upload_path, to_print, to_queue);
|
||||
bool res = true;
|
||||
|
||||
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_data.upload_path.filename().string()
|
||||
% upload_data.upload_path.parent_path().string()
|
||||
% (upload_data.post_action == PrintHostPostUploadAction::StartPrint ? "true" : "false");
|
||||
|
||||
Http http = Http::put(std::move(url));
|
||||
http.set_put_body(upload_data.source_path)
|
||||
.header("Content-Type", "text/x.gcode")
|
||||
.header("Authorization", "Bearer " + access_token)
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(info) << 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) {
|
||||
progress_fn(std::move(progress), cancel);
|
||||
if (cancel) {
|
||||
// Upload was canceled
|
||||
BOOST_LOG_TRIVIAL(info) << name << ": Upload canceled";
|
||||
res = false;
|
||||
}
|
||||
})
|
||||
.perform_sync();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool PrusaConnectNew::get_storage(wxArrayString& storage_path, wxArrayString& storage_name) const
|
||||
{
|
||||
const char* name = get_name();
|
||||
bool res = true;
|
||||
std::string url = GUI::format("%1%/app/printers/%2%/storages", get_host(), m_uuid);
|
||||
const std::string access_token = GUI::wxGetApp().plater()->get_user_account()->get_access_token();
|
||||
wxString error_msg;
|
||||
|
||||
struct StorageInfo {
|
||||
wxString path;
|
||||
wxString name;
|
||||
bool read_only = false;
|
||||
long long free_space = -1;
|
||||
};
|
||||
std::vector<StorageInfo> storage;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get storage at: %2%") % name % url;
|
||||
|
||||
wxString wlang = GUI::wxGetApp().current_language_code();
|
||||
std::string lang = GUI::format(wlang.SubString(0, 1));
|
||||
|
||||
auto http = Http::get(std::move(url));
|
||||
http.header("Authorization", "Bearer " + access_token)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting storage: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
|
||||
error_msg = L"\n\n" + boost::nowide::widen(error);
|
||||
res = false;
|
||||
// If status is 0, the communication with the printer has failed completely (most likely a timeout), if the status is <= 400, it is an error returned by the pritner.
|
||||
// If 0, we can show error to the user now, as we know the communication has failed. (res = true will do the trick.)
|
||||
// if not 0, we must not show error, as not all printers support api/v1/storage endpoint.
|
||||
// So we must be extra careful here, or we might be showing errors on perfectly fine communication.
|
||||
if (status == 0)
|
||||
res = true;
|
||||
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got storage: %2%") % name % body;
|
||||
// {"storages": [{"mountpoint": "/usb", "name": "usb", "free_space": 16340844544, "type": "USB", "is_sfn": true, "read_only": false, "file_count": 1}]}
|
||||
try
|
||||
{
|
||||
std::stringstream ss(body);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
|
||||
// what if there is more structure added in the future? Enumerate all elements?
|
||||
if (ptree.front().first != "storages") {
|
||||
res = false;
|
||||
return;
|
||||
}
|
||||
// each storage has own subtree of storage_list
|
||||
for (const auto& section : ptree.front().second) {
|
||||
const auto name = section.second.get_optional<std::string>("name");
|
||||
const auto path = section.second.get_optional<std::string>("mountpoint");
|
||||
const auto space = section.second.get_optional<std::string>("free_space");
|
||||
const auto read_only = section.second.get_optional<bool>("read_only");
|
||||
const auto ro = section.second.get_optional<bool>("ro"); // In PrusaLink 0.7.0RC2 "read_only" value is stored under "ro".
|
||||
const auto available = section.second.get_optional<bool>("available");
|
||||
if (path && (!available || *available)) {
|
||||
StorageInfo si;
|
||||
si.path = boost::nowide::widen(*path);
|
||||
si.name = name ? boost::nowide::widen(*name) : wxString();
|
||||
// If read_only is missing, assume it is NOT read only.
|
||||
// si.read_only = read_only ? *read_only : false; // version without "ro"
|
||||
si.read_only = (read_only ? *read_only : (ro ? *ro : false));
|
||||
si.free_space = space ? std::stoll(*space) : 1; // If free_space is missing, assume there is free space.
|
||||
storage.emplace_back(std::move(si));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
res = false;
|
||||
}
|
||||
})
|
||||
.perform_sync();
|
||||
|
||||
for (const auto& si : storage) {
|
||||
if (!si.read_only && si.free_space > 0) {
|
||||
storage_path.push_back(si.path);
|
||||
storage_name.push_back(si.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (res && storage_path.empty()) {
|
||||
if (!storage.empty()) { // otherwise error_msg is already filled
|
||||
error_msg = L"\n\n" + _L("Storages found") + L": \n";
|
||||
for (const auto& si : storage) {
|
||||
error_msg += GUI::format_wxstr(si.read_only ?
|
||||
// TRN %1% = storage path
|
||||
_L("%1% : read only") :
|
||||
// TRN %1% = storage path
|
||||
_L("%1% : no free space"), si.path) + L"\n";
|
||||
}
|
||||
}
|
||||
// TRN %1% = host
|
||||
std::string message = GUI::format(_L("Upload has failed. There is no suitable storage found at %1%. "), get_host()) + GUI::into_u8(error_msg);
|
||||
BOOST_LOG_TRIVIAL(error) << message;
|
||||
throw Slic3r::IOError(message);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
wxString PrusaConnectNew::get_test_ok_msg() const
|
||||
{
|
||||
return _L("Test OK.");
|
||||
}
|
||||
wxString PrusaConnectNew::get_test_failed_msg(wxString& msg) const
|
||||
{
|
||||
return _L("Test NOK.");
|
||||
}
|
||||
|
||||
std::string PrusaConnectNew::get_team_id(const std::string& data) const
|
||||
{
|
||||
boost::property_tree::ptree ptree;
|
||||
try {
|
||||
std::stringstream ss(data);
|
||||
boost::property_tree::read_json(ss, ptree);
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto team_id = ptree.get_optional<std::string>("team_id");
|
||||
if (team_id)
|
||||
{
|
||||
return *team_id;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
49
src/slic3r/Utils/PrusaConnect.hpp
Normal file
49
src/slic3r/Utils/PrusaConnect.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef slic3r_PrusaConnect_hpp_
|
||||
#define slic3r_PrusaConnect_hpp_
|
||||
|
||||
#include "PrintHost.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
/*
|
||||
#include <string>
|
||||
#include <wx/string.h>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
|
||||
|
||||
*/
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class DynamicPrintConfig;
|
||||
class Http;
|
||||
|
||||
class PrusaConnectNew : public PrintHost
|
||||
{
|
||||
public:
|
||||
PrusaConnectNew(DynamicPrintConfig *config);
|
||||
~PrusaConnectNew() override = default;
|
||||
|
||||
const char* get_name() const override;
|
||||
|
||||
virtual bool test(wxString &curl_msg) const override;
|
||||
wxString get_test_ok_msg () const override;
|
||||
wxString get_test_failed_msg (wxString &msg) const override;
|
||||
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn, InfoFn info_fn) const override;
|
||||
bool has_auto_discovery() const override { return true; }
|
||||
bool can_test() const override { return true; }
|
||||
PrintHostPostUploadActions get_post_upload_actions() const override { return PrintHostPostUploadAction::StartPrint | PrintHostPostUploadAction::QueuePrint; }
|
||||
std::string get_host() const override { return "https://dev.connect.prusa3d.com"; }
|
||||
bool get_storage(wxArrayString& storage_path, wxArrayString& storage_name) const override;
|
||||
//const std::string& get_apikey() const { return m_apikey; }
|
||||
//const std::string& get_cafile() const { return m_cafile; }
|
||||
|
||||
private:
|
||||
std::string m_uuid;
|
||||
std::string m_team_id;
|
||||
|
||||
bool init_upload(PrintHostUpload upload_data, std::string& out) const;
|
||||
std::string get_team_id(const std::string& data) const;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user