ENH: [STUDIO-1868] update printer file system protocol

Change-Id: I22300fadcafc08042cbeac537d0d0e7f621db3d2
This commit is contained in:
chunmao.guo 2023-04-21 15:56:57 +08:00 committed by Lane.Wei
parent feb5dfe1ca
commit e8387b97ac
3 changed files with 82 additions and 47 deletions

View file

@ -171,11 +171,11 @@ void Slic3r::GUI::ImageGrid::DoAction(size_t index, int action)
return; return;
} }
#ifdef __WXMSW__ #ifdef __WXMSW__
auto wfile = boost::filesystem::path(file.path).wstring(); auto wfile = boost::filesystem::path(file.local_path).wstring();
SHELLEXECUTEINFO info{sizeof(info), 0, NULL, NULL, wfile.c_str(), L"", SW_HIDE}; SHELLEXECUTEINFO info{sizeof(info), 0, NULL, NULL, wfile.c_str(), L"", SW_HIDE};
::ShellExecuteEx(&info); ::ShellExecuteEx(&info);
#else #else
wxShell("open " + file.path); wxShell("open " + file.local_path);
#endif #endif
} else { } else {
m_file_sys->DownloadCancel(index); m_file_sys->DownloadCancel(index);
@ -197,9 +197,9 @@ void Slic3r::GUI::ImageGrid::DoAction(size_t index, int action)
return; return;
} }
#ifdef __WIN32__ #ifdef __WIN32__
wxExecute(L"explorer.exe /select," + from_u8(file.path)); wxExecute(L"explorer.exe /select," + from_u8(file.local_path));
#elif __APPLE__ #elif __APPLE__
openFolderForFile(from_u8(file.path)); openFolderForFile(from_u8(file.local_path));
#else #else
#endif #endif
} }

View file

@ -46,7 +46,7 @@ PrinterFileSystem::PrinterFileSystem()
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 100; ++i) {
auto name = wxString::Format(L"img-%03d.jpg", i + 1); auto name = wxString::Format(L"img-%03d.jpg", i + 1);
wxImage im(L"D:\\work\\pic\\" + name); wxImage im(L"D:\\work\\pic\\" + name);
m_file_list.push_back({name.ToUTF8().data(), time.GetTicks(), 26937, i > 3 ? im : default_thumbnail, i < 20 ? FF_DOWNLOAD : 0, i * 10 - 40 - 1}); m_file_list.push_back({name.ToUTF8().data(), "", time.GetTicks(), 26937, i > 3 ? im : default_thumbnail, i < 20 ? FF_DOWNLOAD : 0, i * 10 - 40 - 1});
time.Add(wxDateSpan::Days(-1)); time.Add(wxDateSpan::Days(-1));
} }
m_file_list[0].thumbnail = default_thumbnail; m_file_list[0].thumbnail = default_thumbnail;
@ -99,10 +99,11 @@ void PrinterFileSystem::ListAllFiles()
SendRequest<FileList>(LIST_INFO, req, [this](json const& resp, FileList & list, auto) { SendRequest<FileList>(LIST_INFO, req, [this](json const& resp, FileList & list, auto) {
json files = resp["file_lists"]; json files = resp["file_lists"];
for (auto& f : files) { for (auto& f : files) {
std::string name = f["name"]; std::string name = f["name"];
time_t time = f.value("time", 0); std::string path = f.value("path", "");
time_t time = f.value("time", 0);
boost::uint64_t size = f["size"]; boost::uint64_t size = f["size"];
File ff = {name, time, size, default_thumbnail}; File ff = {name, path, time, size, default_thumbnail};
list.push_back(ff); list.push_back(ff);
} }
return 0; return 0;
@ -120,7 +121,7 @@ void PrinterFileSystem::ListAllFiles()
if (!iter1->thumbnail.IsOk()) if (!iter1->thumbnail.IsOk())
iter1->flags &= ~FF_THUMNAIL; iter1->flags &= ~FF_THUMNAIL;
iter1->progress = iter2->progress; iter1->progress = iter2->progress;
iter1->path = iter2->path; iter1->local_path = iter2->local_path;
++iter1; ++iter2; ++iter1; ++iter2;
} else if (*iter1 < *iter2) { } else if (*iter1 < *iter2) {
++iter1; ++iter1;
@ -174,7 +175,7 @@ void PrinterFileSystem::DownloadFiles(size_t index, std::string const &path)
if ((file.flags & FF_DOWNLOAD) != 0 && file.progress >= 0) continue; if ((file.flags & FF_DOWNLOAD) != 0 && file.progress >= 0) continue;
file.flags |= FF_DOWNLOAD; file.flags |= FF_DOWNLOAD;
file.progress = -1; file.progress = -1;
file.path = (boost::filesystem::path(path) / file.name).string(); file.local_path = (boost::filesystem::path(path) / file.name).string();
++n; ++n;
} }
if (n == 0) return; if (n == 0) return;
@ -186,7 +187,7 @@ void PrinterFileSystem::DownloadFiles(size_t index, std::string const &path)
return; return;
file.flags |= FF_DOWNLOAD; file.flags |= FF_DOWNLOAD;
file.progress = -1; file.progress = -1;
file.path = (boost::filesystem::path(path) / file.name).string(); file.local_path = (boost::filesystem::path(path) / file.name).string();
} }
if ((m_task_flags & FF_DOWNLOAD) == 0) if ((m_task_flags & FF_DOWNLOAD) == 0)
DownloadNextFile(); DownloadNextFile();
@ -202,7 +203,7 @@ void PrinterFileSystem::DownloadCheckFiles(std::string const &path)
if (boost::filesystem::file_size(path2, ec) == file.size) { if (boost::filesystem::file_size(path2, ec) == file.size) {
file.flags |= FF_DOWNLOAD; file.flags |= FF_DOWNLOAD;
file.progress = 100; file.progress = 100;
file.path = path2.string(); file.local_path = path2.string();
} }
} }
} }
@ -212,11 +213,11 @@ bool PrinterFileSystem::DownloadCheckFile(size_t index)
if (index >= m_file_list.size()) return false; if (index >= m_file_list.size()) return false;
auto &file = m_file_list[index]; auto &file = m_file_list[index];
if ((file.flags & FF_DOWNLOAD) == 0) return false; if ((file.flags & FF_DOWNLOAD) == 0) return false;
if (!boost::filesystem::exists(file.path)) { if (!boost::filesystem::exists(file.local_path)) {
file.flags &= ~FF_DOWNLOAD; file.flags &= ~FF_DOWNLOAD;
file.progress = 0; file.progress = 0;
file.path.clear(); file.local_path.clear();
SendChangedEvent(EVT_DOWNLOAD, index, file.path); SendChangedEvent(EVT_DOWNLOAD, index, file.local_path);
return false; return false;
} }
return true; return true;
@ -243,7 +244,7 @@ size_t PrinterFileSystem::GetCount() const
size_t PrinterFileSystem::GetIndexAtTime(boost::uint32_t time) size_t PrinterFileSystem::GetIndexAtTime(boost::uint32_t time)
{ {
auto iter = std::upper_bound(m_file_list.begin(), m_file_list.end(), File{"", time}); auto iter = std::upper_bound(m_file_list.begin(), m_file_list.end(), File{"", "", time});
size_t n = std::distance(m_file_list.begin(), iter) - 1; size_t n = std::distance(m_file_list.begin(), iter) - 1;
if (m_group_mode == G_NONE) { if (m_group_mode == G_NONE) {
return n; return n;
@ -440,27 +441,37 @@ void PrinterFileSystem::DeleteFilesContinue()
{ {
std::vector<size_t> indexes; std::vector<size_t> indexes;
std::vector<std::string> names; std::vector<std::string> names;
std::vector<std::string> paths;
for (size_t i = 0; i < m_file_list.size(); ++i) for (size_t i = 0; i < m_file_list.size(); ++i)
if ((m_file_list[i].flags & FF_DELETED) && !m_file_list[i].name.empty()) { if ((m_file_list[i].flags & FF_DELETED) && !m_file_list[i].name.empty()) {
indexes.push_back(i); indexes.push_back(i);
names.push_back(m_file_list[i].name); auto &file = m_file_list[i];
if (names.size() >= 64) if (file.path.empty())
names.push_back(file.name);
else
paths.push_back(file.path);
if (names.size() >= 64 || paths.size() >= 64)
break; break;
} }
m_task_flags &= ~FF_DELETED; m_task_flags &= ~FF_DELETED;
if (names.empty()) if (names.empty() && paths.empty())
return; return;
json req; json req;
json arr; json arr;
for (auto &name : names) arr.push_back(name); if (paths.empty()) {
req["delete"] = arr; for (auto &name : names) arr.push_back(name);
req["delete"] = arr;
} else {
for (auto &path : paths) arr.push_back(path);
req["paths"] = arr;
}
m_task_flags |= FF_DELETED; m_task_flags |= FF_DELETED;
SendRequest<Void>( SendRequest<Void>(
FILE_DEL, req, nullptr, FILE_DEL, req, nullptr,
[indexes, names, this](int, Void const &) { [indexes, names = paths.empty() ? names : paths, bypath = !paths.empty(), this](int, Void const &) {
// TODO: // TODO:
for (size_t i = indexes.size() - 1; i != size_t(-1); --i) for (size_t i = indexes.size() - 1; i != size_t(-1); --i)
FileRemoved(indexes[i], names[i]); FileRemoved(indexes[i], names[i], bypath);
SendChangedEvent(EVT_FILE_CHANGED, indexes.size()); SendChangedEvent(EVT_FILE_CHANGED, indexes.size());
DeleteFilesContinue(); DeleteFilesContinue();
}); });
@ -479,7 +490,10 @@ void PrinterFileSystem::DownloadNextFile()
if (index >= m_file_list.size()) if (index >= m_file_list.size())
return; return;
json req; json req;
req["file"] = m_file_list[index].name; if (m_file_list[index].path.empty())
req["file"] = m_file_list[index].name;
else
req["path"] = m_file_list[index].path;
m_file_list[index].progress = 0; m_file_list[index].progress = 0;
SendChangedEvent(EVT_DOWNLOAD, index, m_file_list[index].name); SendChangedEvent(EVT_DOWNLOAD, index, m_file_list[index].name);
struct Download struct Download
@ -487,13 +501,15 @@ void PrinterFileSystem::DownloadNextFile()
size_t index; size_t index;
std::string name; std::string name;
std::string path; std::string path;
std::string local_path;
boost::filesystem::ofstream ofs; boost::filesystem::ofstream ofs;
boost::uuids::detail::md5 boost_md5; boost::uuids::detail::md5 boost_md5;
}; };
std::shared_ptr<Download> download(new Download); std::shared_ptr<Download> download(new Download);
download->index = index; download->index = index;
download->name = m_file_list[index].name; download->name = m_file_list[index].name;
download->path = m_file_list[index].path; download->path = m_file_list[index].path;
download->local_path = m_file_list[index].local_path;
m_task_flags |= FF_DOWNLOAD; m_task_flags |= FF_DOWNLOAD;
m_download_seq = SendRequest<Progress>( m_download_seq = SendRequest<Progress>(
FILE_DOWNLOAD, req, FILE_DOWNLOAD, req,
@ -503,7 +519,7 @@ void PrinterFileSystem::DownloadNextFile()
prog.size = resp["offset"]; prog.size = resp["offset"];
prog.total = resp["total"]; prog.total = resp["total"];
if (prog.size == 0) { if (prog.size == 0) {
download->ofs.open(download->path, std::ios::binary); download->ofs.open(download->local_path, std::ios::binary);
if (!download->ofs) return FILE_OPEN_ERR; if (!download->ofs) return FILE_OPEN_ERR;
} }
// receive data // receive data
@ -528,13 +544,13 @@ void PrinterFileSystem::DownloadNextFile()
} }
if (result != 0) { if (result != 0) {
boost::system::error_code ec; boost::system::error_code ec;
boost::filesystem::remove(download->path, ec); boost::filesystem::remove(download->local_path, ec);
} }
return result; return result;
}, },
[this, download](int result, Progress const &data) { [this, download](int result, Progress const &data) {
if (download->index != size_t(-1)) if (download->index != size_t(-1))
download->index = FindFile(download->index, download->name); download->index = FindFile(download->index, download->path.empty() ? download->name : download->path, !download->path.empty());
if (download->index != size_t(-1)) { if (download->index != size_t(-1)) {
int progress = data.size * 100 / data.total; int progress = data.size * 100 / data.total;
auto & file = m_file_list[download->index]; auto & file = m_file_list[download->index];
@ -542,7 +558,7 @@ void PrinterFileSystem::DownloadNextFile()
file.flags &= ~FF_DOWNLOAD; file.flags &= ~FF_DOWNLOAD;
else if (file.progress != progress) { else if (file.progress != progress) {
file.progress = progress; file.progress = progress;
SendChangedEvent(EVT_DOWNLOAD, download->index, file.path, result); SendChangedEvent(EVT_DOWNLOAD, download->index, file.local_path, result);
} }
} }
if (result != CONTINUE) DownloadNextFile(); if (result != CONTINUE) DownloadNextFile();
@ -557,20 +573,29 @@ void PrinterFileSystem::UpdateFocusThumbnail()
size_t start = m_lock_start; size_t start = m_lock_start;
size_t end = std::min(m_lock_end, GetCount()); size_t end = std::min(m_lock_end, GetCount());
std::vector<std::string> names; std::vector<std::string> names;
std::vector<std::string> paths;
for (; start < end; ++start) { for (; start < end; ++start) {
auto &file = GetFile(start); auto &file = GetFile(start);
if ((file.flags & FF_THUMNAIL) == 0) { if ((file.flags & FF_THUMNAIL) == 0) {
names.push_back(file.name); if (file.path.empty())
if (names.size() >= 5) names.push_back(file.name);
else
paths.push_back(file.path + "#thumbnail");
if (names.size() >= 5 || paths.size() >= 5)
break; break;
} }
} }
if (names.empty()) if (names.empty() && paths.empty())
return; return;
json req; json req;
json arr; json arr;
for (auto &name : names) arr.push_back(name); if (paths.empty()) {
req["files"] = arr; for (auto &name : names) arr.push_back(name);
req["files"] = arr;
} else {
for (auto &path : paths) arr.push_back(path);
req["paths"] = arr;
}
m_task_flags |= FF_THUMNAIL; m_task_flags |= FF_THUMNAIL;
SendRequest<Thumbnail>( SendRequest<Thumbnail>(
THUMBNAIL, req, THUMBNAIL, req,
@ -578,9 +603,11 @@ void PrinterFileSystem::UpdateFocusThumbnail()
// in work thread, continue recv // in work thread, continue recv
// receive data // receive data
wxString mimetype = resp.value("mimetype", "image/jpeg"); wxString mimetype = resp.value("mimetype", "image/jpeg");
std::string thumbnail = resp["thumbnail"]; std::string thumbnail = resp.value("thumbnail", "");
std::string path = resp.value("path", "");
boost::uint32_t size = resp["size"]; boost::uint32_t size = resp["size"];
thumb.name = thumbnail; thumb.name = thumbnail;
thumb.path = path;
if (size > 0) { if (size > 0) {
wxMemoryInputStream mis(data, size); wxMemoryInputStream mis(data, size);
thumb.thumbnail = wxImage(mis, mimetype); thumb.thumbnail = wxImage(mis, mimetype);
@ -590,7 +617,10 @@ void PrinterFileSystem::UpdateFocusThumbnail()
[this](int result, Thumbnail const &thumb) { [this](int result, Thumbnail const &thumb) {
auto n = thumb.name.find_last_of('.'); auto n = thumb.name.find_last_of('.');
auto name = n == std::string::npos ? thumb.name : thumb.name.substr(0, n); auto name = n == std::string::npos ? thumb.name : thumb.name.substr(0, n);
auto iter = std::find_if(m_file_list.begin(), m_file_list.end(), [&name](auto &f) { return boost::algorithm::starts_with(f.name, name); }); n = thumb.path.find_last_of('#');
auto path = n == std::string::npos ? thumb.path : thumb.path.substr(0, n);
auto iter = path.empty() ? std::find_if(m_file_list.begin(), m_file_list.end(), [&name](auto &f) { return boost::algorithm::starts_with(f.name, name); }) :
std::find_if(m_file_list.begin(), m_file_list.end(), [&path](auto &f) { return f.path == path; });
if (iter != m_file_list.end()) { if (iter != m_file_list.end()) {
iter->flags |= FF_THUMNAIL; // DOTO: retry on fail iter->flags |= FF_THUMNAIL; // DOTO: retry on fail
if (thumb.thumbnail.IsOk()) { if (thumb.thumbnail.IsOk()) {
@ -604,19 +634,20 @@ void PrinterFileSystem::UpdateFocusThumbnail()
}); });
} }
size_t PrinterFileSystem::FindFile(size_t index, std::string const &name) size_t PrinterFileSystem::FindFile(size_t index, std::string const &name, bool by_path)
{ {
if (index >= m_file_list.size() || m_file_list[index].name != name) { if (index >= m_file_list.size() || (by_path ? m_file_list[index].path : m_file_list[index].name) != name) {
auto iter = std::find_if(m_file_list.begin(), m_file_list.end(), [name](File &f) { return f.name == name; }); auto iter = std::find_if(m_file_list.begin(), m_file_list.end(),
[name, by_path](File &f) { return (by_path ? f.path : f.name) == name; });
if (iter == m_file_list.end()) return -1; if (iter == m_file_list.end()) return -1;
index = std::distance(m_file_list.begin(), iter); index = std::distance(m_file_list.begin(), iter);
} }
return index; return index;
} }
void PrinterFileSystem::FileRemoved(size_t index, std::string const &name) void PrinterFileSystem::FileRemoved(size_t index, std::string const &name, bool by_path)
{ {
index = FindFile(index, name); index = FindFile(index, name, by_path);
if (index == size_t(-1)) if (index == size_t(-1))
return; return;
auto removeFromGroup = [](std::vector<size_t> &group, size_t index, int total) { auto removeFromGroup = [](std::vector<size_t> &group, size_t index, int total) {
@ -778,6 +809,8 @@ void PrinterFileSystem::RecvMessageThread()
l.lock(); l.lock();
if (n == 0) { if (n == 0) {
HandleResponse(l, sample); HandleResponse(l, sample);
} else if (n == Bambu_stream_end) {
Reconnect(l, 3);
} else if (n == Bambu_would_block) { } else if (n == Bambu_would_block) {
m_cond.timed_wait(l, boost::posix_time::milliseconds(m_messages.empty() && m_callbacks.empty() ? 1000 : 20)); m_cond.timed_wait(l, boost::posix_time::milliseconds(m_messages.empty() && m_callbacks.empty() ? 1000 : 20));
} else { } else {

View file

@ -91,12 +91,13 @@ public:
struct File struct File
{ {
std::string name; std::string name;
std::string path;
time_t time = 0; time_t time = 0;
boost::uint64_t size = 0; boost::uint64_t size = 0;
wxBitmap thumbnail; wxBitmap thumbnail;
int flags = 0; int flags = 0;
int progress = -1; // -1: waiting int progress = -1; // -1: waiting
std::string path; std::string local_path;
bool IsSelect() const { return flags & FF_SELECT; } bool IsSelect() const { return flags & FF_SELECT; }
bool IsDownload() const { return flags & FF_DOWNLOAD; } bool IsDownload() const { return flags & FF_DOWNLOAD; }
@ -111,6 +112,7 @@ public:
struct Thumbnail struct Thumbnail
{ {
std::string name; std::string name;
std::string path;
wxBitmap thumbnail; wxBitmap thumbnail;
}; };
@ -180,9 +182,9 @@ private:
void UpdateFocusThumbnail(); void UpdateFocusThumbnail();
void FileRemoved(size_t index, std::string const &name); void FileRemoved(size_t index, std::string const &name, bool by_path);
size_t FindFile(size_t index, std::string const &name); size_t FindFile(size_t index, std::string const &name, bool by_path);
void SendChangedEvent(wxEventType type, size_t index = (size_t)-1, std::string const &str = {}, long extra = 0); void SendChangedEvent(wxEventType type, size_t index = (size_t)-1, std::string const &str = {}, long extra = 0);