mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 17:27:52 -06:00
support makerworld.com
This commit is contained in:
parent
9f73c01821
commit
6519e850ef
6 changed files with 53 additions and 85 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue