diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index ee07929a..972d1b6a 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -44,6 +44,7 @@ #include #include #include +#include #include "utils/variable_generic.h" @@ -186,6 +187,13 @@ DownloadFactory::receive_success() { if (!m_session && m_variables.get("tied_to_file").as_value()) download->variable()->set("tied_to_file", m_uri); + torrent::Object& resumeObject = root->has_key_map("libtorrent_resume") + ? root->get_key("libtorrent_resume") + : root->insert_key("libtorrent_resume", torrent::Object(torrent::Object::TYPE_MAP)); + + torrent::resume_load_addresses(*download->download(), resumeObject); + torrent::resume_load_file_priorities(*download->download(), resumeObject); + // The action of inserting might cause the torrent to be // opened/started or such. Figure out a nicer way of handling this. if (m_manager->download_list()->insert(download) == m_manager->download_list()->end()) { diff --git a/src/core/download_list.cc b/src/core/download_list.cc index dff39b14..4db22365 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "rak/functional.h" @@ -304,7 +305,7 @@ DownloadList::resume(Download* download) { // on non-complete downloads after a crash. This shouldn't be // needed, but for some reason linux 2.6 is very lazy about // updating mtime. - download->download()->hash_resume_clear(); + torrent::resume_clear_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume")); } // Update the priority to ensure it has the correct @@ -333,7 +334,7 @@ DownloadList::pause(Download* download) { return; download->download()->stop(); - download->download()->hash_resume_save(); + torrent::resume_save_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume")); std::for_each(slot_map_stop().begin(), slot_map_stop().end(), download_list_call(download)); std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download)); @@ -409,7 +410,7 @@ DownloadList::hash_done(Download* download) { // Save resume data so we update time-stamps and priorities if // they were invalid/changed while loading/hashing. download->variable()->set("complete", (int64_t)download->is_done()); - download->download()->hash_resume_save(); + torrent::resume_save_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume")); if (download->variable()->get_value("state") == 1) resume(download); @@ -443,7 +444,7 @@ DownloadList::hash_queue(Download* download, int type) { throw torrent::client_error("DownloadList::hash_queue(...) hashing already queued."); close_throw(download); - download->download()->hash_resume_clear(); + torrent::resume_clear_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume")); download->set_hash_failed(false); download->variable()->set_value("hashing", type); @@ -482,8 +483,8 @@ DownloadList::confirm_finished(Download* download) { // Do this before the slots are called in case one of them closes // the download. - if (!download->is_active() && control->variable()->get_value("session_on_completion") == 1) { - download->download()->hash_resume_save(); + if (!download->is_active() && control->variable()->get_value("session_on_completion") != 0) { + torrent::resume_save_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume")); control->core()->download_store()->save(download); } diff --git a/src/core/download_store.cc b/src/core/download_store.cc index f64d6a68..04418eff 100644 --- a/src/core/download_store.cc +++ b/src/core/download_store.cc @@ -48,6 +48,7 @@ #include #include #include +#include #include #include "download.h" @@ -108,6 +109,9 @@ DownloadStore::save(Download* d) { d->bencode()->get_key("rtorrent").insert_key("total_uploaded", d->download()->up_rate()->total()); d->bencode()->get_key("rtorrent").insert_key("chunks_done", d->download()->chunks_done()); + torrent::resume_save_addresses(*d->download(), d->download()->bencode()->get_key("libtorrent_resume")); + torrent::resume_save_file_priorities(*d->download(), d->download()->bencode()->get_key("libtorrent_resume")); + f << *d->bencode(); if (!f.good()) diff --git a/src/core/manager.cc b/src/core/manager.cc index 0dd0681f..f77c6440 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -52,6 +52,7 @@ #include #include #include +#include #include #include "utils/variable_map.h" @@ -104,9 +105,9 @@ receive_tracker_dump(const std::string& url, const char* data, size_t size) { } // Hmm... find some better place for all this. -static void -delete_tied(Download* d) { - const std::string tie = d->variable()->get_string("tied_to_file"); +void +Manager::delete_tied(Download* d) { + const std::string& tie = d->variable()->get_string("tied_to_file"); // This should be configurable, need to wait for the variable // thingie to be implemented. @@ -114,7 +115,9 @@ delete_tied(Download* d) { return; if (::unlink(rak::path_expand(tie).c_str()) == -1) - control->core()->push_log("Could not unlink tied file: " + std::string(rak::error_number::current().c_str())); + push_log("Could not unlink tied file: " + std::string(rak::error_number::current().c_str())); + + d->variable()->set("tied_to_file", std::string()); } Manager::Manager() : @@ -173,7 +176,7 @@ Manager::initialize_second() { m_downloadList->slot_map_insert()["1_connect_storage_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_storage_log), sigc::mem_fun(m_logComplete, &Log::push_front)); m_downloadList->slot_map_insert()["1_connect_tracker_dump"] = sigc::bind(sigc::ptr_fun(&connect_signal_tracker_dump), sigc::ptr_fun(&receive_tracker_dump)); - m_downloadList->slot_map_erase()["1_delete_tied"] = sigc::ptr_fun(&delete_tied); + m_downloadList->slot_map_erase()["1_delete_tied"] = sigc::mem_fun(this, &Manager::delete_tied); } void @@ -215,7 +218,7 @@ Manager::listen_open() { int boundary = m_portFirst + random() % (m_portLast - m_portFirst + 1); if (torrent::connection_manager()->listen_open(boundary, m_portLast) || - torrent::connection_manager()->listen_open(m_portFirst, boundary)) + torrent::connection_manager()->listen_open(m_portFirst, boundary)) return; } else { @@ -396,6 +399,8 @@ Manager::receive_hashing_changed() { continue; m_downloadList->open_throw(*itr); + + torrent::resume_load_progress(*(*itr)->download(), (*itr)->download()->bencode()->get_key("libtorrent_resume")); (*itr)->download()->hash_check(); return; diff --git a/src/core/manager.h b/src/core/manager.h index a7644cf2..6916a6b1 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -97,6 +97,8 @@ public: void try_create_download(const std::string& uri, bool start, bool printLog = true, bool tied = false); void try_create_download_expand(const std::string& uri, bool start, bool printLog = true, bool tied = false); + void delete_tied(Download* d); + private: void create_http(const std::string& uri); void create_final(std::istream* s); diff --git a/src/display/window_download_chunks_seen.cc b/src/display/window_download_chunks_seen.cc index c3b58a5e..ef6935db 100644 --- a/src/display/window_download_chunks_seen.cc +++ b/src/display/window_download_chunks_seen.cc @@ -73,7 +73,7 @@ WindowDownloadChunksSeen::redraw() { const uint8_t* seen = m_download->download()->chunks_seen(); - if (seen == NULL) { + if (seen == NULL || m_download->download()->bitfield()->empty()) { m_canvas->print(2, 2, "Not available."); return; } diff --git a/src/main.cc b/src/main.cc index 66f339b1..dfcd657f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -141,7 +141,7 @@ main(int argc, char** argv) { try { // Temporary. - //setlocale(LC_ALL, ""); + setlocale(LC_ALL, ""); cachedTime = rak::timer::current(); diff --git a/src/ui/download.cc b/src/ui/download.cc index f8844b7f..a9f6252c 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -284,6 +284,7 @@ Download::bind_keys() { m_uiArray[DISPLAY_FILE_LIST]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); m_uiArray[DISPLAY_TRACKER_LIST]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); m_uiArray[DISPLAY_CHUNKS_SEEN]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_TRANSFER_LIST]->get_bindings()[KEY_LEFT]= sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); // Doesn't belong here. m_uiArray[DISPLAY_PEER_LIST]->get_bindings()['*'] = sigc::mem_fun(this, &Download::receive_snub_peer); diff --git a/src/ui/download_list.cc b/src/ui/download_list.cc index 81983f65..ceced36a 100644 --- a/src/ui/download_list.cc +++ b/src/ui/download_list.cc @@ -301,8 +301,11 @@ DownloadList::receive_clear_tied() { if (m_view->focus() == m_view->end_visible()) return; - if (!(*m_view->focus())->variable()->get_string("tied_to_file").empty()) { - (*m_view->focus())->variable()->set("tied_to_file", std::string()); + const std::string& tiedFile = (*m_view->focus())->variable()->get_string("tied_to_file"); + + if (!tiedFile.empty()) { + // Move this into core? + m_control->core()->delete_tied(*m_view->focus()); m_control->core()->push_log("Cleared tied to file association for download."); }