Multiple downloads witch mid download saving to file

This commit is contained in:
David Kocik 2022-05-30 17:25:29 +02:00
parent 816dd9490d
commit 648e56d8bf
10 changed files with 374 additions and 83 deletions

View File

@ -24,9 +24,12 @@ Download::Download(int ID, std::string url, wxEvtHandler* evt_handler, const boo
void Download::start()
{
m_state = DownloadState::DownloadOngoing;
m_file_get->get();
}
void Download::stop()
void Download::cancel()
{
m_state = DownloadState::DownloadStopped;
m_file_get->cancel();
}
}

View File

@ -7,21 +7,34 @@
namespace Downloader {
enum DownloadState
{
DownloadPending,
DownloadOngoing,
DownloadStopped,
DownloadDone,
DownloadError,
};
class Download {
public:
Download(int ID, std::string url, wxEvtHandler* evt_handler,const boost::filesystem::path& dest_folder);
void start();
void stop();
void cancel();
// void pause();
int get_id() const { return m_id; }
boost::filesystem::path get_final_path() const { return m_final_path; }
std::string get_filename() const { return m_filename; }
DownloadState get_state() const { return m_state; }
void set_state(DownloadState state) { m_state = state; }
private:
const int m_id;
std::string m_filename;
boost::filesystem::path m_final_path;
std::shared_ptr<FileGet> m_file_get;
DownloadState m_state { DownloadState::DownloadPending };
};
}

View File

@ -9,6 +9,61 @@
namespace Downloader {
namespace{
void open_folder(const wxString& widepath)
{
// Code taken from desktop_open_datadir_folder()
// Execute command to open a file explorer, platform dependent.
// FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
#ifdef _WIN32
//const wxString widepath = wxString::FromUTF8(path.c_str());
const wchar_t* argv[] = { L"explorer", widepath.GetData(), nullptr };
::wxExecute(const_cast<wchar_t**>(argv), wxEXEC_ASYNC, nullptr);
#elif __APPLE__
std::string path = boost::nowide::narrow(widepath);
const char* argv[] = { "open", path.data(), nullptr };
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr);
#else
std::string path = boost::nowide::narrow(widepath);
const char* argv[] = { "xdg-open", path.data(), nullptr };
// Check if we're running in an AppImage container, if so, we need to remove AppImage's env vars,
// because they may mess up the environment expected by the file manager.
// Mostly this is about LD_LIBRARY_PATH, but we remove a few more too for good measure.
if (wxGetEnv("APPIMAGE", nullptr)) {
// We're running from AppImage
wxEnvVariableHashMap env_vars;
wxGetEnvMap(&env_vars);
env_vars.erase("APPIMAGE");
env_vars.erase("APPDIR");
env_vars.erase("LD_LIBRARY_PATH");
env_vars.erase("LD_PRELOAD");
env_vars.erase("UNION_PRELOAD");
wxExecuteEnv exec_env;
exec_env.env = std::move(env_vars);
wxString owd;
if (wxGetEnv("OWD", &owd)) {
// This is the original work directory from which the AppImage image was run,
// set it as CWD for the child process:
exec_env.cwd = std::move(owd);
}
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr, &exec_env);
}
else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr, nullptr);
}
#endif
}
} // namespace
bool DownloadApp::OnInit()
{
m_dwnldr_send = std::make_unique<DownloaderSend>();
@ -16,10 +71,10 @@ bool DownloadApp::OnInit()
if (m_dwnldr_send->get_instance_exists()) {
m_other_exists = true;
m_frame = new DownloadFrame("PrusaSlicer-Downloader", wxPoint(50, 50), wxSize(0,0));
m_frame = new DownloadFrame("Downloader", wxPoint(50, 50), wxSize(0,0));
return wxApp::OnInit();
}
m_frame = new DownloadFrame("PrusaSlicer-Downloader", wxPoint(50, 50), wxSize(450, 340));
m_frame = new DownloadFrame("Downloader", wxPoint(50, 50), wxSize(450, 340));
m_frame->Show(true);
wxWindow::MSWRegisterMessageHandler(WM_COPYDATA, [](wxWindow* win, WXUINT /* nMsg */, WXWPARAM wParam, WXLPARAM lParam) {
@ -70,6 +125,8 @@ bool DownloadApp::OnCmdLineParsed(wxCmdLineParser& parser)
if (!url.empty() && m_frame != nullptr)
m_frame->start_download(std::move(url));
m_frame->start_download("open?file=https%3A%2F%2Fmedia.printables.com%2Fmedia%2Fprints%2F152208%2Fstls%2F1431590_8b8287b3-03b1-4cbe-82d0-268a0affa171%2Ff1_logo.stl");
return wxApp::OnCmdLineParsed(parser);
}
}
@ -78,35 +135,62 @@ bool DownloadApp::OnCmdLineParsed(wxCmdLineParser& parser)
DownloadFrame::DownloadFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame(NULL, wxID_ANY, title, pos, size)
, m_instance_send(std::make_unique<SlicerSend>())
, m_slicer_send(std::make_unique<SlicerSend>())
{
dataview = new wxDataViewListCtrl(this, wxID_ANY);
auto * data_sizer = new wxBoxSizer(wxVERTICAL);
/* dataview->AppendColumn(new wxDataViewColumn("ID", new TextRenderer(), 0, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE));
dataview->AppendColumn(new wxDataViewColumn("Filename", new TextRenderer(), 1, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE));
dataview->AppendProgressColumn("Progress", wxDATAVIEW_CELL_INERT, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
dataview->AppendColumn(new wxDataViewColumn("status", new TextRenderer(), 2, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE));*/
m_dataview = new wxDataViewListCtrl(this, wxID_ANY);
/* m_dataview->AppendColumn(new wxDataViewColumn("ID", new TextRenderer(), 0, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE));
m_dataview->AppendColumn(new wxDataViewColumn("Filename", new TextRenderer(), 1, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE));
m_dataview->AppendProgressColumn("Progress", wxDATAVIEW_CELL_INERT, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
m_dataview->AppendColumn(new wxDataViewColumn("status", new TextRenderer(), 2, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE));*/
dataview->AppendTextColumn("ID", wxDATAVIEW_CELL_INERT, 30, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
dataview->AppendTextColumn("Filename", wxDATAVIEW_CELL_INERT, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
dataview->AppendProgressColumn("Progress", wxDATAVIEW_CELL_INERT, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
dataview->AppendTextColumn("status", wxDATAVIEW_CELL_INERT, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
m_dataview->AppendTextColumn("ID", wxDATAVIEW_CELL_INERT, 30, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
m_dataview->AppendTextColumn("Filename", wxDATAVIEW_CELL_INERT, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
m_dataview->AppendProgressColumn("Progress", wxDATAVIEW_CELL_INERT, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
m_dataview->AppendTextColumn("status", wxDATAVIEW_CELL_INERT, 100, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
data_sizer->Add(m_dataview, 1, wxEXPAND | wxBOTTOM);
m_dest_folder = boost::filesystem::path("C:\\Users\\User\\Downloads");
m_log_label = new wxStaticText(this, wxID_ANY, "Log:");
auto* sizer = new wxBoxSizer(wxVERTICAL);
//sizer->Add(m_log_label, wxEXPAND);
sizer->Add(dataview, 1, wxEXPAND | wxBOTTOM);
SetSizer(sizer);
//m_log_label = new wxStaticText(this, wxID_ANY, "Log:");
////sizer->Add(m_log_label, wxEXPAND);
//
wxBoxSizer* btn_sizer = new wxBoxSizer(wxHORIZONTAL);
wxButton* btn_run = new wxButton(this, wxID_OK, "Run");
btn_run->Bind(wxEVT_BUTTON, [this](wxCommandEvent& evt) { on_open_in_slicer(evt); });
btn_sizer->Add(btn_run, 0, wxLEFT | wxALIGN_CENTER_VERTICAL);
wxButton* btn_run_new = new wxButton(this, wxID_EDIT, "Run new");
btn_run_new->Bind(wxEVT_BUTTON, [this](wxCommandEvent& evt) { on_open_in_new_slicer(evt); });
btn_sizer->Add(btn_run_new, 0, wxLEFT | wxALIGN_CENTER_VERTICAL);
wxButton* btn_folder = new wxButton(this, wxID_EDIT, "Open");
btn_folder->Bind(wxEVT_BUTTON, [this](wxCommandEvent& evt) { on_open_in_explorer(evt); });
btn_sizer->Add(btn_folder, 0, wxLEFT | wxALIGN_CENTER_VERTICAL);
wxButton* btn_cancel = new wxButton(this, wxID_EDIT, "Cancel");
btn_cancel->Bind(wxEVT_BUTTON, [this](wxCommandEvent& evt) { on_cancel_button(evt); });
btn_sizer->Add(btn_cancel, 0, wxLEFT | wxALIGN_CENTER_VERTICAL);
//main_sizer->Add(data_sizer);
//main_sizer->Add(btn_sizer);
data_sizer->Add(btn_sizer, 0, wxEXPAND);
SetSizer(data_sizer);
Bind(EVT_FILE_COMPLETE, &DownloadFrame::on_complete, this);
Bind(EVT_FILE_PROGRESS, &DownloadFrame::on_progress, this);
Bind(EVT_FILE_ERROR, &DownloadFrame::on_error, this);
Bind(EVT_FILE_NAME_CHANGE, &DownloadFrame::on_name_change, this);
}
void DownloadFrame::start_download(wxString url)
@ -115,62 +199,177 @@ void DownloadFrame::start_download(wxString url)
if (url.starts_with("open?file=")) {
int id = get_next_id();
std::string escaped_url = FileGet::escape_url(boost::nowide::narrow(url.substr(10)));
log(std::to_string(id) + ": start " + escaped_url);
//log(std::to_string(id) + ": start " + escaped_url);
escaped_url = "https://media.printables.com/media/prints/216267/gcodes/1974221_32d21613-b567-4328-8261-49b46d9dd249/01_big_trex_skull_with_threads_015mm_pla_mk3_2d.gcode";
m_downloads.emplace_back(std::make_unique<Download>(id, std::move(escaped_url), this, m_dest_folder));
m_downloads.back()->start();
//
wxVector<wxVariant> fields;
fields.push_back(wxVariant(std::to_wstring(id)));
fields.push_back(wxVariant(m_downloads.back()->get_filename()));
fields.push_back(wxVariant(0));
fields.push_back(wxVariant("Pending"));
dataview->AppendItem(fields);
m_dataview->AppendItem(fields);
bool can_start = true;
for (size_t i = 0; i < m_downloads.size(); i++) {
if (m_downloads[i]->get_state() == DownloadState::DownloadOngoing) {
//can_start = false;
break;
}
}
if (can_start)
m_downloads.back()->start();
} else {
log("wrong url: " + url);
//log("wrong url: " + url);
}
}
void DownloadFrame::log(const wxString& msg)
{
m_log_lines++;
wxString old_log = m_log_label->GetLabel();
if (m_log_lines > 10) {
size_t endline = old_log.Find('\n');
endline = old_log.find('\n', endline + 1);
if (endline != wxString::npos) {
old_log = "Log:\n" + old_log.substr(endline + 1);
}
}
//m_log_label->SetLabel(old_log +"\n"+ msg);
//printf("%s\n",old_log + "\n" + msg);
m_full_log += +"\n" + msg;
//m_log_lines++;
//wxString old_log = m_log_label->GetLabel();
//if (m_log_lines > 10) {
// size_t endline = old_log.Find('\n');
// endline = old_log.find('\n', endline + 1);
// if (endline != wxString::npos) {
// old_log = "Log:\n" + old_log.substr(endline + 1);
// }
//}
////m_log_label->SetLabel(old_log +"\n"+ msg);
////printf("%s\n",old_log + "\n" + msg);
//m_full_log += +"\n" + msg;
}
void DownloadFrame::on_progress(wxCommandEvent& event)
{
//log(std::to_string(event.GetInt()) + ": " + event.GetString());
dataview->SetValue(std::stoi(boost::nowide::narrow(event.GetString())), event.GetInt() - 1, 2);
dataview->SetValue("Downloading", event.GetInt() -1, 3);
m_dataview->SetValue(std::stoi(boost::nowide::narrow(event.GetString())), event.GetInt() - 1, 2);
m_dataview->SetValue("Downloading", event.GetInt() -1, 3);
}
void DownloadFrame::on_error(wxCommandEvent& event)
{
//log(std::to_string(event.GetInt()) + ": " + event.GetString());
//SetStatusText(event.GetString().c_str());
dataview->SetValue("Error", event.GetInt() - 1, 3);
set_download_state(event.GetInt(), DownloadState::DownloadError);
m_dataview->SetValue("Error", event.GetInt() - 1, 3);
}
void DownloadFrame::on_complete(wxCommandEvent& event)
{
dataview->SetValue("Done", event.GetInt() - 1, 3);
m_instance_send->start_with_path(event.GetString());
set_download_state(event.GetInt(), DownloadState::DownloadDone);
m_dataview->SetValue("Done", event.GetInt() - 1, 3);
start_next();
}
void DownloadFrame::on_name_change(wxCommandEvent& event)
{
m_dataview->SetValue(event.GetString(), event.GetInt() - 1, 1);
}
void DownloadFrame::start_next()
{
for (size_t i = 0; i < m_downloads.size(); i++) {
if (m_downloads[i]->get_state() == DownloadState::DownloadPending) {
m_downloads[i]->start();
break;
}
}
}
void DownloadFrame::on_open_in_slicer(wxCommandEvent& event)
{
int selected = m_dataview->GetSelectedRow();
if (selected == wxNOT_FOUND) { return; }
int id = std::stoi(boost::nowide::narrow(m_dataview->GetTextValue(selected,0)));
if (is_in_state(id, DownloadState::DownloadDone)) {
m_slicer_send->start_or_send(get_path_of(id));
}
}
void DownloadFrame::on_open_in_new_slicer(wxCommandEvent& event)
{
int selected = m_dataview->GetSelectedRow();
if (selected == wxNOT_FOUND) { return; }
int id = std::stoi(boost::nowide::narrow(m_dataview->GetTextValue(selected, 0)));
if (is_in_state(id, DownloadState::DownloadDone)) {
m_slicer_send->start_with_path(get_path_of(id));
}
}
void DownloadFrame::on_open_in_explorer(wxCommandEvent& event)
{
int selected = m_dataview->GetSelectedRow();
if (selected == wxNOT_FOUND) { return; }
int id = std::stoi(boost::nowide::narrow(m_dataview->GetTextValue(selected, 0)));
if (is_in_state(id, DownloadState::DownloadDone)) {
open_folder(get_folder_path_of(id));
}
}
void DownloadFrame::on_cancel_button(wxCommandEvent& event)
{
int selected = m_dataview->GetSelectedRow();
if (selected == wxNOT_FOUND) { return; }
int id = std::stoi(boost::nowide::narrow(m_dataview->GetTextValue(selected, 0)));
if(cancel_download(id))
m_dataview->SetValue("Canceled", id - 1, 3);
}
void DownloadFrame::set_download_state(int id, DownloadState state)
{
for( size_t i = 0; i < m_downloads.size(); ++i) {
if (m_downloads[i]->get_id() == id) {
m_downloads[i]->set_state(state);
return;
}
}
}
bool DownloadFrame::is_in_state(int id, DownloadState state) const
{
for (size_t i = 0; i < m_downloads.size(); ++i) {
if (m_downloads[i]->get_id() == id) {
return m_downloads[i]->get_state();
}
}
}
bool DownloadFrame::cancel_download(int id)
{
for (size_t i = 0; i < m_downloads.size(); ++i) {
if (m_downloads[i]->get_id() == id) {
if (m_downloads[i]->get_state() == DownloadState::DownloadOngoing) {
m_downloads[i]->cancel();
return true;
}
return false;
}
}
return false;
}
wxString DownloadFrame::get_path_of(int id) const
{
for (size_t i = 0; i < m_downloads.size(); ++i) {
if (m_downloads[i]->get_id() == id) {
return m_downloads[i]->get_final_path().string();
}
}
}
wxString DownloadFrame::get_folder_path_of(int id) const
{
for (size_t i = 0; i < m_downloads.size(); ++i) {
if (m_downloads[i]->get_id() == id) {
return m_downloads[i]->get_final_path().parent_path().string();
}
}
}
void DownloadFrame::handle_message(const wxString& msg)
{
log("recieved: " + msg);
//log("recieved: " + msg);
start_download(msg);
}

View File

@ -24,8 +24,20 @@ private:
void on_progress(wxCommandEvent& event);
void on_error(wxCommandEvent& event);
void on_complete(wxCommandEvent& event);
void on_name_change(wxCommandEvent& event);
void on_open_in_slicer(wxCommandEvent& event);
void on_open_in_new_slicer(wxCommandEvent& event);
void on_open_in_explorer(wxCommandEvent& event);
void on_cancel_button(wxCommandEvent& event);
void start_next();
void set_download_state(int id, DownloadState state);
bool is_in_state(int id, DownloadState state) const;
bool cancel_download(int id);
wxString get_path_of(int id) const;
wxString get_folder_path_of(int id) const;
int m_next_id { 0 };
int get_next_id() {return ++m_next_id; }
@ -33,12 +45,12 @@ private:
size_t m_log_lines { 0 };
wxString m_full_log;
wxDataViewListCtrl* dataview;
wxDataViewListCtrl* m_dataview;
wxString m_url;
wxString m_path_to_slicer;
std::unique_ptr<SlicerSend> m_instance_send;
std::unique_ptr<SlicerSend> m_slicer_send;
boost::filesystem::path m_dest_folder;

View File

@ -8,6 +8,8 @@
namespace Downloader {
const size_t DOWNLOAD_MAX_CHUNK_SIZE = 10 * 1024 * 1024;
const size_t DOWNLOAD_SIZE_LIMIT = 1024 * 1024 * 1024;
std::string FileGet::escape_url(const std::string& unescaped)
{
@ -41,6 +43,9 @@ wxDEFINE_EVENT(EVT_FILE_COMPLETE, wxCommandEvent);
wxDEFINE_EVENT(EVT_FILE_ERROR, wxCommandEvent);
// int = DOWNLOAD ID; string = progress percent
wxDEFINE_EVENT(EVT_FILE_PROGRESS, wxCommandEvent);
// int = DOWNLOAD ID; string = name
wxDEFINE_EVENT(EVT_FILE_NAME_CHANGE, wxCommandEvent);
struct FileGet::priv
{
@ -73,23 +78,72 @@ void FileGet::priv::get_perform()
assert(!m_filename.empty());
assert(boost::filesystem::is_directory(m_dest_folder));
// open dest file
boost::filesystem::path dest_path = m_dest_folder / m_filename;
std::string extension = boost::filesystem::extension(dest_path);
std::string just_filename = m_filename.substr(0, m_filename.size() - extension.size());
std::string final_filename = just_filename;
size_t version = 0;
while (boost::filesystem::exists(m_dest_folder / (final_filename + extension)) || boost::filesystem::exists(m_dest_folder / (final_filename + extension + "." + std::to_string(get_current_pid()) + ".download")))
{
++version;
final_filename = just_filename + "(" + std::to_string(version) + ")";
}
m_filename = final_filename + extension;
boost::filesystem::path tmp_path = m_dest_folder / (m_filename + "." + std::to_string(get_current_pid()) + ".download");
dest_path = m_dest_folder / m_filename;
wxCommandEvent* evt = new wxCommandEvent(EVT_FILE_NAME_CHANGE);
evt->SetString(boost::nowide::widen(m_filename));
evt->SetInt(m_id);
m_evt_handler->QueueEvent(evt);
// open file for writting
FILE* file = fopen(tmp_path.string().c_str(), "wb");
size_t written = 0;
Downloader::Http::get(m_url)
//.size_limit(size_limit)
.size_limit(DOWNLOAD_SIZE_LIMIT) //more?
.on_progress([&](Downloader::Http::Progress progress, bool& cancel) {
if (m_cancel) {
fclose(file);
// remove canceled file
std::remove(tmp_path.string().c_str());
cancel = true;
return;
// TODO: send canceled event?
}
}
wxCommandEvent* evt = new wxCommandEvent(EVT_FILE_PROGRESS);
if (progress.dlnow == 0)
evt->SetString("0");
else
else {
if (progress.dlnow - written > DOWNLOAD_MAX_CHUNK_SIZE || progress.dlnow == progress.dltotal) {
try
{
std::string part_for_write = progress.buffer.substr(written, progress.dlnow);
fwrite(part_for_write.c_str(), 1, part_for_write.size(), file);
}
catch (const std::exception&)
{
// fclose(file); do it?
wxCommandEvent* evt = new wxCommandEvent(EVT_FILE_ERROR);
evt->SetString("Failed to write progress.");
evt->SetInt(m_id);
m_evt_handler->QueueEvent(evt);
cancel = true;
return;
}
written = progress.dlnow;
}
evt->SetString(std::to_string(progress.dlnow * 100 / progress.dltotal));
}
evt->SetInt(m_id);
m_evt_handler->QueueEvent(evt);
})
.on_error([&](std::string body, std::string error, unsigned http_status) {
fclose(file);
wxCommandEvent* evt = new wxCommandEvent(EVT_FILE_ERROR);
evt->SetString(error);
evt->SetInt(m_id);
@ -102,30 +156,18 @@ void FileGet::priv::get_perform()
//if (body_size != expected_size) {
// return;
//}
boost::filesystem::path dest_path = m_dest_folder / m_filename;
std::string extension = boost::filesystem::extension(dest_path);
std::string just_filename = m_filename.substr(0, m_filename.size() - extension.size());
std::string final_filename = just_filename;
size_t version = 0;
while (boost::filesystem::exists(m_dest_folder / (final_filename + extension)))
{
++version;
final_filename = just_filename + "("+std::to_string(version)+")";
}
m_filename = final_filename + extension;
boost::filesystem::path tmp_path = m_dest_folder / (m_filename + "." + std::to_string(get_current_pid()) + ".download");
dest_path = m_dest_folder / m_filename;
try
{
boost::nowide::fstream file(tmp_path.string(), std::ios::out | std::ios::binary | std::ios::trunc);
file.write(body.c_str(), body.size());
file.close();
if (written < body.size())
{
// this code should never be entered. As there should be on_progress call after last bit downloaded.
std::string part_for_write = body.substr(written);
fwrite(part_for_write.c_str(), 1, part_for_write.size(), file);
}
fclose(file);
boost::filesystem::rename(tmp_path, dest_path);
}
catch (const std::exception&)
catch (const std::exception& e)
{
//TODO: report?
//error_message = GUI::format("Failed to write and move %1% to %2%", tmp_path, dest_path);

View File

@ -30,6 +30,7 @@ wxDECLARE_EVENT(EVT_FILE_COMPLETE, wxCommandEvent);
wxDECLARE_EVENT(EVT_FILE_PROGRESS, wxCommandEvent);
// int = DOWNLOAD ID; string = progress percent
wxDECLARE_EVENT(EVT_FILE_ERROR, wxCommandEvent);
// int = DOWNLOAD ID; string = name
wxDECLARE_EVENT(EVT_FILE_NAME_CHANGE, wxCommandEvent);
}
#endif

View File

@ -225,7 +225,7 @@ int Http::priv::xfercb(void *userp, curl_off_t dltotal, curl_off_t dlnow, curl_o
bool cb_cancel = false;
if (self->progressfn) {
Progress progress(dltotal, dlnow, ultotal, ulnow);
Progress progress(dltotal, dlnow, ultotal, ulnow, self->buffer);
self->progressfn(progress, cb_cancel);
}
@ -370,7 +370,7 @@ void Http::priv::http_perform()
if (res == CURLE_ABORTED_BY_CALLBACK) {
if (cancel) {
// The abort comes from the request being cancelled programatically
Progress dummyprogress(0, 0, 0, 0);
Progress dummyprogress(0, 0, 0, 0, std::string());
bool cancel = true;
if (progressfn) { progressfn(dummyprogress, cancel); }
} else {

View File

@ -22,8 +22,10 @@ public:
size_t ultotal; // Total bytes to upload
size_t ulnow; // Bytes uploaded so far
Progress(size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) :
dltotal(dltotal), dlnow(dlnow), ultotal(ultotal), ulnow(ulnow)
const std::string& buffer; // reference to buffer containing all data
Progress(size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow, const std::string& buffer) :
dltotal(dltotal), dlnow(dlnow), ultotal(ultotal), ulnow(ulnow), buffer(buffer)
{}
};

View File

@ -70,9 +70,9 @@ namespace {
#ifdef _WIN32
static HWND l_prusa_slicer_hwnd;
static HWND l_downloader_hwnd;
BOOL CALLBACK EnumWindowsProcSlicer(_In_ HWND hwnd, _In_ LPARAM lParam)
BOOL CALLBACK EnumWindowsProcSlicer(_In_ HWND hwnd, _In_ LPARAM lParam)
{
//checks for other instances of prusaslicer, if found brings it to front and return false to stop enumeration and quit this instance
//checks for other instances of prusaslicer, if found brings it to front and return false to cancel enumeration and quit this instance
//search is done by classname(wxWindowNR is wxwidgets thing, so probably not unique) and name in window upper panel
//other option would be do a mutex and check for its existence
//BOOST_LOG_TRIVIAL(error) << "ewp: version: " << l_version_wstring;
@ -136,9 +136,9 @@ bool send_message_slicer(const wxString& message)
}
BOOL CALLBACK EnumWindowsProcDownloader(_In_ HWND hwnd, _In_ LPARAM lParam)
BOOL CALLBACK EnumWindowsProcDownloader(_In_ HWND hwnd, _In_ LPARAM lParam)
{
//checks for other instances of prusaslicer, if found brings it to front and return false to stop enumeration and quit this instance
//checks for other instances of prusaslicer, if found brings it to front and return false to cancel enumeration and quit this instance
//search is done by classname(wxWindowNR is wxwidgets thing, so probably not unique) and name in window upper panel
//other option would be do a mutex and check for its existence
//BOOST_LOG_TRIVIAL(error) << "ewp: version: " << l_version_wstring;
@ -153,7 +153,7 @@ BOOL CALLBACK EnumWindowsProcDownloader(_In_ HWND hwnd, _In_ LPARAM lParam)
return true;
std::wstring classNameString(className);
std::wstring wndTextString(wndText);
if (wndTextString.find(L"PrusaSlicer-Downloader") != std::wstring::npos && classNameString == L"wxWindowNR") {
if (wndTextString.find(L"Downloader") != std::wstring::npos && classNameString == L"wxWindowNR") {
//check if other instances has same instance hash
//if not it is not same version(binary) as this version
HANDLE handle = GetProp(hwnd, L"Instance_Hash_Minor");
@ -210,6 +210,10 @@ bool execute_command(const wxString& command)
#endif
}
// ------ SlicerSend ----------------
bool SlicerSend::get_instance_exists() const
{
return !EnumWindows(EnumWindowsProcSlicer, 0);
@ -219,6 +223,7 @@ bool SlicerSend::send_path(const wxString& path) const
std::string escaped = escape_strings_cstyle({ "prusa-downloader", boost::nowide::narrow(path) });
return send_message_slicer(boost::nowide::widen(escaped));
}
bool SlicerSend::start_with_path(const wxString& path) const
{
// "C:\\Users\\User\\Downloads\\PrusaSlicer-2.4.2+win64-202204251110\\prusa-slicer.exe "
@ -227,6 +232,17 @@ bool SlicerSend::start_with_path(const wxString& path) const
return execute_command("C:\\Users\\User\\Downloads\\PrusaSlicer-2.4.2+win64-202204251110\\prusa-slicer.exe " + boost::nowide::widen(escaped));
}
bool SlicerSend::start_or_send(const wxString& path) const
{
if (send_path(path))
return true;
return start_with_path(path);
}
// ------ DownloaderSend ----------------
bool DownloaderSend::get_instance_exists() const
{
return !EnumWindows(EnumWindowsProcDownloader, 0);
@ -236,4 +252,6 @@ bool DownloaderSend::send_url(const wxString& url) const
//std::string escaped = escape_strings_cstyle({ boost::nowide::narrow(url) });
return send_message_downloader(url);
}
}

View File

@ -11,6 +11,7 @@ public:
bool get_instance_exists() const;
bool send_path(const wxString& path) const;
bool start_with_path(const wxString& path) const;
bool start_or_send(const wxString& path) const;
};
class DownloaderSend