OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GUI::FileGet::priv Struct Reference
Collaboration diagram for Slic3r::GUI::FileGet::priv:

Public Member Functions

 priv (int ID, std::string &&url, const std::string &filename, wxEvtHandler *evt_handler, const boost::filesystem::path &dest_folder)
void get_perform ()

Public Attributes

const int m_id
std::string m_url
std::string m_filename
std::thread m_io_thread
wxEvtHandler * m_evt_handler
boost::filesystem::path m_dest_folder
boost::filesystem::path m_tmp_path
std::atomic_bool m_cancel { false }
std::atomic_bool m_pause { false }
std::atomic_bool m_stopped { false }
size_t m_written { 0 }
size_t m_absolute_size { 0 }

Detailed Description

Constructor & Destructor Documentation

◆ priv()

Slic3r::GUI::FileGet::priv::priv ( int ID,
std::string && url,
const std::string & filename,
wxEvtHandler * evt_handler,
const boost::filesystem::path & dest_folder )
121 : m_id(ID)
122 , m_url(std::move(url))
123 , m_filename(filename)
124 , m_evt_handler(evt_handler)
125 , m_dest_folder(dest_folder)
126{
127}
const int m_id
Definition DownloaderFileGet.cpp:103
std::string m_filename
Definition DownloaderFileGet.cpp:105
boost::filesystem::path m_dest_folder
Definition DownloaderFileGet.cpp:108
std::string m_url
Definition DownloaderFileGet.cpp:104
wxEvtHandler * m_evt_handler
Definition DownloaderFileGet.cpp:107

References m_dest_folder, m_evt_handler, m_filename, m_id, and m_url.

Member Function Documentation

◆ get_perform()

void Slic3r::GUI::FileGet::priv::get_perform ( )
138{
139 assert(m_evt_handler);
140 assert(!m_url.empty());
141 assert(!m_filename.empty());
142 assert(boost::filesystem::is_directory(m_dest_folder));
143
144 m_stopped = false;
145
146 // open dest file
147 std::string extension;
148 if (m_written == 0)
149 {
150 std::string final_filename;
151 bool found = false;
152 try {
153 found = find_unused_filename(m_dest_folder, m_filename, m_tmp_path, final_filename);
154 } catch (const boost::filesystem::filesystem_error& e)
155 {
156 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
157 evt->SetString(e.what());
158 evt->SetInt(m_id);
159 m_evt_handler->QueueEvent(evt);
160 return;
161 }
162 if (!found) {
163 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
164 evt->SetString(GUI::format_wxstr(_L("Failed to find suitable filename. Last name: %1%."), (m_dest_folder / final_filename).string()));
165 evt->SetInt(m_id);
166 m_evt_handler->QueueEvent(evt);
167 return;
168 }
169
170 m_filename = final_filename;
171 extension = boost::filesystem::path(m_filename).extension().string();
172
174
175 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE);
176 evt->SetString(boost::nowide::widen(m_filename));
177 evt->SetInt(m_id);
178 m_evt_handler->QueueEvent(evt);
179 }
180
181 boost::filesystem::path dest_path;
182 if(!extension.empty())
183 dest_path = m_dest_folder / m_filename;
184
185 wxString temp_path_wstring(m_tmp_path.wstring());
186
187 //std::cout << "dest_path: " << dest_path.string() << std::endl;
188 //std::cout << "m_tmp_path: " << m_tmp_path.string() << std::endl;
189
190 BOOST_LOG_TRIVIAL(info) << GUI::format("Starting download from %1% to %2%. Temp path is %3%",m_url, dest_path, m_tmp_path);
191
192 FILE* file;
193 // open file for writting
194 if (m_written == 0)
195 file = fopen(temp_path_wstring.c_str(), "wb");
196 else
197 file = fopen(temp_path_wstring.c_str(), "ab");
198
199 //assert(file != NULL);
200 if (file == NULL) {
201 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
202 // TRN %1% = file path
203 evt->SetString(GUI::format_wxstr(_L("Can't create file at %1%"), temp_path_wstring));
204 evt->SetInt(m_id);
205 m_evt_handler->QueueEvent(evt);
206 return;
207 }
208
209 std:: string range_string = std::to_string(m_written) + "-";
210
211 size_t written_previously = m_written;
212 size_t written_this_session = 0;
215 .set_range(range_string)
216 .on_header_callback([&](std::string header) {
217 if(dest_path.empty()) {
218 std::string filename = extract_remote_filename(header);
219 if (!filename.empty()) {
220 // The name comes from the server: keep it inside the destination folder and never
221 // replace an existing file. Keep the current name if nothing usable remains.
222 filename = sanitize_file_basename(filename);
223 std::string unused;
224 try {
225 if (filename.empty() || !find_unused_filename(m_dest_folder, filename, m_tmp_path, unused))
226 unused.clear();
227 } catch (const boost::filesystem::filesystem_error&) {
228 unused.clear();
229 }
230 const boost::filesystem::path tmp_path = unused.empty() ? m_tmp_path : download_marker_path(m_dest_folder, unused);
231 if (tmp_path != m_tmp_path) {
232 // Move the marker to the adopted name so that other downloads see the name as taken.
233 // Only before anything is written, so that no downloaded data has to be carried over.
234 FILE* tmp_file = m_written == 0 ? fopen(wxString(tmp_path.wstring()).c_str(), "wb") : nullptr;
235 if (tmp_file != nullptr) {
236 fclose(file);
237 boost::system::error_code ec;
238 boost::filesystem::remove(m_tmp_path, ec);
239 file = tmp_file;
240 m_tmp_path = tmp_path;
241 } else
242 unused.clear();
243 }
244 if (!unused.empty())
245 m_filename = unused;
246 dest_path = m_dest_folder / m_filename;
247 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE);
248 evt->SetString(boost::nowide::widen(m_filename));
249 evt->SetInt(m_id);
250 m_evt_handler->QueueEvent(evt);
251 }
252 }
253 })
254 .on_progress([&](Http::Progress progress, bool& cancel) {
255 // to prevent multiple calls into following ifs (m_cancel / m_pause)
256 if (m_stopped){
257 cancel = true;
258 return;
259 }
260 if (m_cancel) {
261 m_stopped = true;
262 fclose(file);
263 // remove canceled file
264 std::remove(m_tmp_path.string().c_str());
265 m_written = 0;
266 cancel = true;
267 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_CANCELED);
268 evt->SetInt(m_id);
269 m_evt_handler->QueueEvent(evt);
270 return;
271 // TODO: send canceled event?
272 }
273 if (m_pause) {
274 m_stopped = true;
275 fclose(file);
276 cancel = true;
277 if (m_written == 0)
278 std::remove(m_tmp_path.string().c_str());
279 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_PAUSED);
280 evt->SetInt(m_id);
281 m_evt_handler->QueueEvent(evt);
282 return;
283 }
284
285 if (m_absolute_size < progress.dltotal) {
286 m_absolute_size = progress.dltotal;
287 }
288
289 if (progress.dlnow != 0) {
290 if (progress.dlnow - written_this_session > DOWNLOAD_MAX_CHUNK_SIZE || progress.dlnow == progress.dltotal) {
291 try
292 {
293 std::string part_for_write = progress.buffer.substr(written_this_session, progress.dlnow);
294 fwrite(part_for_write.c_str(), 1, part_for_write.size(), file);
295 }
296 catch (const std::exception& e)
297 {
298 // fclose(file); do it?
299 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
300 evt->SetString(e.what());
301 evt->SetInt(m_id);
302 m_evt_handler->QueueEvent(evt);
303 cancel = true;
304 return;
305 }
306 written_this_session = progress.dlnow;
307 m_written = written_previously + written_this_session;
308 }
309 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_PROGRESS);
310 int percent_total = m_absolute_size == 0 ? 0 : (written_previously + progress.dlnow) * 100 / m_absolute_size;
311 evt->SetString(std::to_string(percent_total));
312 evt->SetInt(m_id);
313 m_evt_handler->QueueEvent(evt);
314 }
315
316 })
317 .on_error([&](std::string body, std::string error, unsigned http_status) {
318 if (file != NULL)
319 fclose(file);
320 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
321 if (!error.empty())
322 evt->SetString(GUI::from_u8(error));
323 else
324 evt->SetString(GUI::from_u8(body));
325 evt->SetInt(m_id);
326 m_evt_handler->QueueEvent(evt);
327 })
328 .on_complete([&](std::string body, unsigned /* http_status */) {
329
330 // TODO: perform a body size check
331 //
332 //size_t body_size = body.size();
333 //if (body_size != expected_size) {
334 // return;
335 //}
336 try
337 {
338 // Orca: thingiverse need this
339 if (m_written < body.size())
340 {
341 // this code should never be entered. As there should be on_progress call after last bit downloaded.
342 std::string part_for_write = body.substr(m_written);
343 fwrite(part_for_write.c_str(), 1, part_for_write.size(), file);
344
345 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_PROGRESS);
346 evt->SetString(std::to_string(100));
347 evt->SetInt(m_id);
348 m_evt_handler->QueueEvent(evt);
349 }
350 fclose(file);
351 // Another file may have taken the name while downloading.
352 if (!dest_path.empty() && boost::filesystem::exists(dest_path)) {
353 std::string unused;
355 throw std::runtime_error("No unused file name.");
356 m_filename = unused;
357 dest_path = m_dest_folder / m_filename;
358 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE);
359 evt->SetString(boost::nowide::widen(m_filename));
360 evt->SetInt(m_id);
361 m_evt_handler->QueueEvent(evt);
362 }
363 boost::filesystem::rename(m_tmp_path, dest_path);
364 }
365 catch (const std::exception& /*e*/)
366 {
367 //TODO: report?
368 //error_message = GUI::format("Failed to write and move %1% to %2%", tmp_path, dest_path);
369 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
370 evt->SetString(_L("Failed to write and move."));
371 evt->SetInt(m_id);
372 m_evt_handler->QueueEvent(evt);
373 return;
374 }
375
376 wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_COMPLETE);
377 evt->SetString(dest_path.wstring());
378 evt->SetInt(m_id);
379 m_evt_handler->QueueEvent(evt);
380 })
381 .perform_sync();
382
383}
#define _L(s)
Definition OBJ.cpp:34
void cancel()
Definition DownloaderFileGet.cpp:415
Http & size_limit(size_t sizeLimit)
Definition Http.cpp:576
Http & on_header_callback(HeaderCallbackFn fn)
Definition Http.cpp:788
Http & set_range(const std::string &range)
Definition Http.cpp:582
static Http get(std::string url)
Definition Http.cpp:886
wxString format_wxstr(const char *fmt, TArgs &&... args)
Definition format.hpp:22
const size_t DOWNLOAD_MAX_CHUNK_SIZE
Definition DownloaderFileGet.cpp:34
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:36
wxString from_u8(const std::string &str)
Definition GUI.cpp:544
std::string extract_remote_filename(const std::string &str)
Definition DownloaderFileGet.cpp:128
const size_t DOWNLOAD_SIZE_LIMIT
Definition DownloaderFileGet.cpp:35
bool find_unused_filename(const boost::filesystem::path &dest_folder, const std::string &filename, const boost::filesystem::path &ignored_marker, std::string &result)
Definition utils.cpp:1494
std::string sanitize_file_basename(const std::string &name)
Definition Utils.hpp:326
boost::filesystem::path download_marker_path(const boost::filesystem::path &dest_folder, const std::string &filename)
Definition utils.cpp:1489
std::atomic_bool m_cancel
Definition DownloaderFileGet.cpp:110
boost::filesystem::path m_tmp_path
Definition DownloaderFileGet.cpp:109
size_t m_absolute_size
Definition DownloaderFileGet.cpp:114
std::atomic_bool m_pause
Definition DownloaderFileGet.cpp:111
size_t m_written
Definition DownloaderFileGet.cpp:113
std::atomic_bool m_stopped
Definition DownloaderFileGet.cpp:112

References _L, Slic3r::Http::Progress::buffer, Slic3r::GUI::FileGet::cancel(), Slic3r::Http::Progress::dlnow, Slic3r::Http::Progress::dltotal, Slic3r::download_marker_path(), Slic3r::GUI::DOWNLOAD_MAX_CHUNK_SIZE, Slic3r::GUI::DOWNLOAD_SIZE_LIMIT, Slic3r::GUI::extract_remote_filename(), Slic3r::find_unused_filename(), Slic3r::GUI::format(), Slic3r::GUI::format_wxstr(), Slic3r::GUI::from_u8(), Slic3r::Http::get(), m_absolute_size, m_cancel, m_dest_folder, m_evt_handler, m_filename, m_id, m_pause, m_stopped, m_tmp_path, m_url, m_written, Slic3r::Http::on_header_callback(), Slic3r::sanitize_file_basename(), Slic3r::Http::set_range(), and Slic3r::Http::size_limit().

Here is the call graph for this function:

Member Data Documentation

◆ m_absolute_size

size_t Slic3r::GUI::FileGet::priv::m_absolute_size { 0 }
114{ 0 };

Referenced by get_perform().

◆ m_cancel

std::atomic_bool Slic3r::GUI::FileGet::priv::m_cancel { false }
110{ false };

Referenced by get_perform().

◆ m_dest_folder

boost::filesystem::path Slic3r::GUI::FileGet::priv::m_dest_folder

Referenced by priv(), and get_perform().

◆ m_evt_handler

wxEvtHandler* Slic3r::GUI::FileGet::priv::m_evt_handler

Referenced by priv(), and get_perform().

◆ m_filename

std::string Slic3r::GUI::FileGet::priv::m_filename

Referenced by priv(), and get_perform().

◆ m_id

const int Slic3r::GUI::FileGet::priv::m_id

Referenced by priv(), and get_perform().

◆ m_io_thread

std::thread Slic3r::GUI::FileGet::priv::m_io_thread

◆ m_pause

std::atomic_bool Slic3r::GUI::FileGet::priv::m_pause { false }
111{ false };

Referenced by get_perform().

◆ m_stopped

std::atomic_bool Slic3r::GUI::FileGet::priv::m_stopped { false }
112{ false }; // either canceled or paused - download is not running

Referenced by get_perform().

◆ m_tmp_path

boost::filesystem::path Slic3r::GUI::FileGet::priv::m_tmp_path

Referenced by get_perform().

◆ m_url

std::string Slic3r::GUI::FileGet::priv::m_url

Referenced by priv(), and get_perform().

◆ m_written

size_t Slic3r::GUI::FileGet::priv::m_written { 0 }
113{ 0 };

Referenced by get_perform().


The documentation for this struct was generated from the following file: