support makerworld.com

This commit is contained in:
SoftFever 2024-05-28 00:06:50 +08:00
parent 9f73c01821
commit 6519e850ef
6 changed files with 53 additions and 85 deletions

View file

@ -12,6 +12,7 @@
#include <functional> #include <functional>
#include <type_traits> #include <type_traits>
#include <system_error> #include <system_error>
#include <regex>
#include <boost/system/error_code.hpp> #include <boost/system/error_code.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
@ -220,6 +221,24 @@ extern bool is_shapes_dir(const std::string& dir);
//BBS: add json support //BBS: add json support
extern bool is_json_file(const std::string& path); extern bool is_json_file(const std::string& path);
// Orca: custom protocal support utils
inline bool is_orca_open(const std::string& url) { return boost::starts_with(url, "orcaslicer://open"); }
inline bool is_prusaslicer_open(const std::string& url) { return boost::starts_with(url, "prusaslicer://open"); }
inline bool is_bambustudio_open(const std::string& url) { return boost::starts_with(url, "bambustudio://open"); }
inline bool is_cura_open(const std::string& url) { return boost::starts_with(url, "cura://open"); }
inline bool is_supported_open_protocol(const std::string& url) { return is_orca_open(url) || is_prusaslicer_open(url) || is_bambustudio_open(url) || is_cura_open(url); }
inline bool is_printables_link(const std::string& url) {
const std::regex url_regex("(http|https)://printables.com", std::regex_constants::icase);
return std::regex_match(url, url_regex);
}
inline bool is_makerworld_link(const std::string& url) {
const std::regex url_regex("(http|https)://makerworld.com", std::regex_constants::icase);
return std::regex_match(url, url_regex);
}
inline bool is_thingiverse_link(const std::string& url) {
const std::regex url_regex("(http|https)://www.thingiverse.com", std::regex_constants::icase);
return std::regex_match(url, url_regex);
}
// File path / name / extension splitting utilities, working with UTF-8, // File path / name / extension splitting utilities, working with UTF-8,
// to be published to Perl. // to be published to Perl.
namespace PerlUtils { namespace PerlUtils {

View file

@ -148,7 +148,7 @@ void Downloader::start_download(const std::string& full_url)
// Orca: Replace PS workaround for "mysterious slash" with a more dynamic approach // Orca: Replace PS workaround for "mysterious slash" with a more dynamic approach
// Windows seems to have fixed the issue and this provides backwards compatability for those it still affects // Windows seems to have fixed the issue and this provides backwards compatability for those it still affects
boost::regex re(R"(^(orcaslicer|prusaslicer):\/\/open[\/]?\?file=)", boost::regbase::icase); boost::regex re(R"(^(orcaslicer|prusaslicer|bambustudio|cura):\/\/open[\/]?\?file=)", boost::regbase::icase);
boost::smatch results; boost::smatch results;
if (!boost::regex_search(full_url, results, re)) { if (!boost::regex_search(full_url, results, re)) {
@ -161,23 +161,18 @@ void Downloader::start_download(const std::string& full_url)
} }
size_t id = get_next_id(); size_t id = get_next_id();
std::string escaped_url = FileGet::escape_url(full_url.substr(results.length())); std::string escaped_url = FileGet::escape_url(full_url.substr(results.length()));
// Orca:: any website that supports orcaslicer://open/?file= can be downloaded if (is_bambustudio_open(full_url) || (is_orca_open(full_url) && is_makerworld_link(full_url)))
plater->request_model_download(escaped_url);
// if (!boost::starts_with(escaped_url, "https://") || !FileGet::is_subdomain(escaped_url, "printables.com")) { else {
// std::string msg = format(_L("Download won't start. Download URL doesn't point to https://printables.com : %1%"), escaped_url); std::string text(escaped_url);
// BOOST_LOG_TRIVIAL(error) << msg; m_downloads.emplace_back(std::make_unique<Download>(id, std::move(escaped_url), this, m_dest_folder));
// NotificationManager* ntf_mngr = wxGetApp().notification_manager(); NotificationManager* ntf_mngr = wxGetApp().notification_manager();
// ntf_mngr->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::ErrorNotificationLevel, ntf_mngr->push_download_URL_progress_notification(id, m_downloads.back()->get_filename(),
// "Download failed. Download URL doesn't point to https://printables.com."); std::bind(&Downloader::user_action_callback, this, std::placeholders::_1,
// return; std::placeholders::_2));
// } m_downloads.back()->start();
}
std::string text(escaped_url); BOOST_LOG_TRIVIAL(debug) << "started download";
m_downloads.emplace_back(std::make_unique<Download>(id, std::move(escaped_url), this, m_dest_folder));
NotificationManager* ntf_mngr = wxGetApp().notification_manager();
ntf_mngr->push_download_URL_progress_notification(id, m_downloads.back()->get_filename(), std::bind(&Downloader::user_action_callback, this, std::placeholders::_1, std::placeholders::_2));
m_downloads.back()->start();
BOOST_LOG_TRIVIAL(debug) << "started download";
} }
void Downloader::on_progress(wxCommandEvent& event) void Downloader::on_progress(wxCommandEvent& event)

View file

@ -804,63 +804,39 @@ void GUI_App::post_init()
m_open_method = "double_click"; m_open_method = "double_click";
bool switch_to_3d = false; bool switch_to_3d = false;
if (!this->init_params->input_files.empty()) {
if (!this->init_params->input_files.empty()) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", init with input files, size %1%, input_gcode %2%") BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", init with input files, size %1%, input_gcode %2%")
%this->init_params->input_files.size() %this->init_params->input_gcode; %this->init_params->input_files.size() %this->init_params->input_gcode;
const auto first_url = this->init_params->input_files.front();
if (this->init_params->input_files.size() == 1 && is_supported_open_protocol(first_url)) {
switch_to_3d = true;
if (this->init_params->input_files.size() == 1 && start_download(first_url);
(boost::starts_with(this->init_params->input_files.front(), "orcaslicer://open") || m_open_method = "url";
boost::starts_with(this->init_params->input_files.front(), "prusaslicer://open"))) { } else {
if (boost::starts_with(this->init_params->input_files.front(), "orcaslicer://open")||
boost::starts_with(this->init_params->input_files.front(), "prusaslicer://open")) {
switch_to_3d = true;
start_download(this->init_params->input_files.front());
} else if (vector<string> input_str_arr = split_str(this->init_params->input_files.front(), "orcaslicer://open/?file="); input_str_arr.size() > 1) {
std::string download_origin_url;
for (auto input_str : input_str_arr) {
if (!input_str.empty())
download_origin_url = input_str;
}
std::string download_file_url = url_decode(download_origin_url);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << download_file_url;
if (!download_file_url.empty() &&
(boost::starts_with(download_file_url, "http://") || boost::starts_with(download_file_url, "https://"))) {
request_model_download(download_file_url);
}
}
m_open_method = "makerworld";
}
else {
switch_to_3d = true; switch_to_3d = true;
if (this->init_params->input_gcode) { if (this->init_params->input_gcode) {
mainframe->select_tab(size_t(MainFrame::tp3DEditor)); mainframe->select_tab(size_t(MainFrame::tp3DEditor));
plater_->select_view_3D("3D"); plater_->select_view_3D("3D");
this->plater()->load_gcode(from_u8(this->init_params->input_files.front())); this->plater()->load_gcode(from_u8(this->init_params->input_files.front()));
m_open_method = "gcode"; m_open_method = "gcode";
} } else {
else {
mainframe->select_tab(size_t(MainFrame::tp3DEditor)); mainframe->select_tab(size_t(MainFrame::tp3DEditor));
plater_->select_view_3D("3D"); plater_->select_view_3D("3D");
wxArrayString input_files; wxArrayString input_files;
for (auto & file : this->init_params->input_files) { for (auto& file : this->init_params->input_files) {
input_files.push_back(wxString::FromUTF8(file)); input_files.push_back(wxString::FromUTF8(file));
} }
this->plater()->set_project_filename(_L("Untitled")); this->plater()->set_project_filename(_L("Untitled"));
this->plater()->load_files(input_files); this->plater()->load_files(input_files);
try { try {
if (!input_files.empty()) { if (!input_files.empty()) {
std::string file_path = input_files.front().ToStdString(); std::string file_path = input_files.front().ToStdString();
std::filesystem::path path(file_path); std::filesystem::path path(file_path);
m_open_method = "file_" + path.extension().string(); m_open_method = "file_" + path.extension().string();
} }
} } catch (...) {
catch (...) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ", file path exception!"; BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ", file path exception!";
m_open_method = "file"; m_open_method = "file";
} }
@ -2630,10 +2606,6 @@ bool GUI_App::on_init_inner()
#endif #endif
this->post_init(); this->post_init();
if (!m_download_file_url.empty()) {
request_model_download(m_download_file_url);
m_download_file_url = "";
}
update_publish_status(); update_publish_status();
} }
@ -5861,32 +5833,9 @@ void GUI_App::OSXStoreOpenFiles(const wxArrayString &fileNames)
void GUI_App::MacOpenURL(const wxString& url) void GUI_App::MacOpenURL(const wxString& url)
{ {
BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << "get mac url " << url;
if (url.empty()) if (url.empty())
return; return;
start_download(boost::nowide::narrow(url));
if (boost::starts_with(url, "orcasliceropen://")) {
auto input_str_arr = split_str(url.ToStdString(), "orcasliceropen://");
std::string download_origin_url;
for (auto input_str : input_str_arr) {
if (!input_str.empty()) download_origin_url = input_str;
}
std::string download_file_url = url_decode(download_origin_url);
BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << download_file_url;
if (!download_file_url.empty() && (boost::starts_with(download_file_url, "http://") || boost::starts_with(download_file_url, "https://"))) {
if (m_post_initialized) {
request_model_download(download_file_url);
}
else {
m_download_file_url = download_file_url;
}
}
} else if (boost::starts_with(url, "orcaslicer://"))
start_download(boost::nowide::narrow(url));
} }
// wxWidgets override to get an event on open files. // wxWidgets override to get an event on open files.
@ -6685,6 +6634,7 @@ void GUI_App::start_download(std::string url)
} }
m_downloader->init(dest_folder); m_downloader->init(dest_folder);
m_downloader->start_download(url); m_downloader->start_download(url);
} }
bool is_support_filament(int extruder_id) bool is_support_filament(int extruder_id)

View file

@ -236,8 +236,6 @@ private:
bool m_opengl_initialized{ false }; bool m_opengl_initialized{ false };
#endif #endif
//import model from mall
wxString m_download_file_url;
//#ifdef _WIN32 //#ifdef _WIN32
wxColour m_color_label_modified; wxColour m_color_label_modified;

View file

@ -501,7 +501,7 @@ void OtherInstanceMessageHandler::handle_message(const std::string& message)
std::vector<boost::filesystem::path> paths; std::vector<boost::filesystem::path> paths;
std::vector<std::string> downloads; std::vector<std::string> downloads;
boost::regex re(R"(^(orcaslicer|prusaslicer):\/\/open[\/]?\?file=)", boost::regbase::icase); boost::regex re(R"(^(orcaslicer|prusaslicer|cura|bambustudio):\/\/open[\/]?\?file=)", boost::regbase::icase);
boost::smatch results; boost::smatch results;
// Skip the first argument, it is the path to the slicer executable. // Skip the first argument, it is the path to the slicer executable.

View file

@ -1075,8 +1075,13 @@ wxWindow* PreferencesDialog::create_general_page()
wxGetApp().check_url_association(L"prusaslicer", reg_bin); wxGetApp().check_url_association(L"prusaslicer", reg_bin);
auto associate_url_prusaslicer = create_item_button(_L("Current association: ") + reg_bin, _L("Associate prusaslicer://"), page, auto associate_url_prusaslicer = create_item_button(_L("Current association: ") + reg_bin, _L("Associate prusaslicer://"), page,
reg_bin.empty() ? _L("Not associated to any application") : reg_bin, reg_bin.empty() ? _L("Not associated to any application") : reg_bin,
_L("Associate OrcaSlicer with prusaslicer:// links so that Orca can open PrusaSlicer links from Printable.com"), _L("Associate OrcaSlicer with prusaslicer:// links so that Orca can open models from Printable.com"),
[]() { wxGetApp().associate_url(L"prusaslicer"); }); []() { wxGetApp().associate_url(L"prusaslicer"); });
wxGetApp().check_url_association(L"bambustudio", reg_bin);
auto associate_url_bambustudio = create_item_button(_L("Current association: ") + reg_bin, _L("Associate bambustudio://"), page,
reg_bin.empty() ? _L("Not associated to any application") : reg_bin,
_L("Associate OrcaSlicer with bambustudio:// links so that Orca can open models from makerworld.com"),
[]() { wxGetApp().associate_url(L"bambustudio"); });
#endif #endif
// auto title_modelmall = create_item_title(_L("Online Models"), page, _L("Online Models")); // auto title_modelmall = create_item_title(_L("Online Models"), page, _L("Online Models"));
@ -1143,6 +1148,7 @@ wxWindow* PreferencesDialog::create_general_page()
#endif // _WIN32 #endif // _WIN32
#if !defined(__APPLE__) #if !defined(__APPLE__)
sizer_page->Add(associate_url_prusaslicer, 0, wxTOP | wxEXPAND, FromDIP(20)); sizer_page->Add(associate_url_prusaslicer, 0, wxTOP | wxEXPAND, FromDIP(20));
sizer_page->Add(associate_url_bambustudio, 0, wxTOP | wxEXPAND, FromDIP(20));
#endif #endif
// auto item_title_modelmall = sizer_page->Add(title_modelmall, 0, wxTOP | wxEXPAND, FromDIP(20)); // auto item_title_modelmall = sizer_page->Add(title_modelmall, 0, wxTOP | wxEXPAND, FromDIP(20));
// auto item_item_modelmall = sizer_page->Add(item_modelmall, 0, wxTOP, FromDIP(3)); // auto item_item_modelmall = sizer_page->Add(item_modelmall, 0, wxTOP, FromDIP(3));