From 6ed95d7f82d4b0a8f31914d383c489e24ce46e33 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 12 Jun 2014 22:39:41 +0000 Subject: [PATCH] support storing save_path in resume data --- ChangeLog | 1 + bindings/python/src/session.cpp | 3 +++ docs/manual.rst | 4 ++++ include/libtorrent/add_torrent_params.hpp | 16 +++++++++++++--- include/libtorrent/torrent.hpp | 4 ++++ src/torrent.cpp | 23 +++++++++++++++++++++++ 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19bd679a1..d08a82c6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 1.0 release + * support storing save_path in resume data * don't use full allocation on network drives (on windows) * added clear_piece_deadlines() to remove all piece deadlines * improve queuing logic of inactive torrents (dont_count_slow_torrents) diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index ab51154a9..308ef87e1 100644 --- a/bindings/python/src/session.cpp +++ b/bindings/python/src/session.cpp @@ -604,6 +604,9 @@ void bind_session() .value("flag_duplicate_is_error", add_torrent_params::flag_duplicate_is_error) .value("flag_merge_resume_trackers", add_torrent_params::flag_merge_resume_trackers) .value("flag_update_subscribe", add_torrent_params::flag_update_subscribe) + .value("flag_super_seeding", add_torrent_params::flag_super_seeding) + .value("flag_sequential_download", add_torrent_params::flag_sequential_download) + .value("flag_use_resume_save_path", add_torrent_params::flag_use_resume_save_path) ; class_("cache_status") .def_readonly("blocks_written", &cache_status::blocks_written) diff --git a/docs/manual.rst b/docs/manual.rst index a84bcb9fd..24418334e 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -354,6 +354,10 @@ The file format is a bencoded dictionary containing the following fields: | | necessarily complete, but complete enough to be able to send | | | any piece that we have, indicated by the have bitmask. | +--------------------------+--------------------------------------------------------------+ +| ``save_path`` | string. The save path where this torrent was saved. This is | +| | especially useful when moving torrents with move_storage() | +| | since this will be updated. | ++--------------------------+--------------------------------------------------------------+ | ``peers`` | list of dictionaries. Each dictionary has the following | | | layout: | | | | diff --git a/include/libtorrent/add_torrent_params.hpp b/include/libtorrent/add_torrent_params.hpp index e5c2cd353..1d3a9027d 100644 --- a/include/libtorrent/add_torrent_params.hpp +++ b/include/libtorrent/add_torrent_params.hpp @@ -147,9 +147,9 @@ namespace libtorrent // in there will override the seed mode you set here. flag_seed_mode = 0x001, - // If ``flag_override_resume_data`` is set, the ``paused`` and - // ``auto_managed`` state of the torrent are not loaded from the - // resume data, but the states requested by the flags in + // If ``flag_override_resume_data`` is set, the ``paused``, + // ``auto_managed`` and ``save_path`` of the torrent are not loaded + // from the resume data, but the states requested by the flags in // ``add_torrent_params`` will override them. // // If you pass in resume data, the paused state of the torrent when @@ -244,6 +244,11 @@ namespace libtorrent // the torrent handle immediately after adding it. flag_sequential_download = 0x800, + // if this flag is set, the save path from the resume data file, if + // present, is honored. This defaults to not being set, in which + // case the save_path specified in add_torrent_params is always used. + flag_use_resume_save_path = 0x1000, + // internal default_flags = flag_update_subscribe | flag_auto_managed | flag_paused | flag_apply_ip_filter #ifndef TORRENT_NO_DEPRECATE @@ -273,6 +278,11 @@ namespace libtorrent // to the session (if DHT is enabled). The hostname may be an IP address. std::vector > dht_nodes; std::string name; + + // the path where the torrent is or will be stored. Note that this may + // alos be stored in resume data. If you which the save path saved in + // the resume data to be used, you need to set the + // flag_use_resume_save_path flag. std::string save_path; // The optional parameter, ``resume_data`` can be given if up to date diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index a5a3c8985..7ed639f5f 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -1420,6 +1420,10 @@ namespace libtorrent // queued, torrent. Every second it's above the threshold boost::int16_t m_inactive_counter; + // if this is set, accept the save path saved in the resume data, if + // present + bool m_use_resume_save_path:1; + #if TORRENT_USE_ASSERTS public: // set to false until we've loaded resume data diff --git a/src/torrent.cpp b/src/torrent.cpp index d1b842827..708445413 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -249,6 +249,7 @@ namespace libtorrent , m_interface_index(0) , m_progress_ppm(0) , m_inactive_counter(0) + , m_use_resume_save_path(p.flags & add_torrent_params::flag_use_resume_save_path) { // if there is resume data already, we don't need to trigger the initial save // resume data @@ -1487,6 +1488,17 @@ namespace libtorrent return; } + // Chicken-and-egg: need to load resume data to get last save_path + // before constructing m_owning_storage, but need storage before + // loading resume data. So peek ahead in this case. + // only do this if the user is willing to have the resume data + // settings override the settings set in add_torrent_params + if (!m_use_resume_save_path && m_resume_entry.type() == lazy_entry::dict_t) + { + std::string p = m_resume_entry.dict_find_string_value("save_path"); + if (!p.empty()) m_save_path = p; + } + // the shared_from_this() will create an intentional // cycle of ownership, se the hpp file for description. m_owning_storage = new piece_manager(shared_from_this(), m_torrent_file @@ -5197,6 +5209,12 @@ namespace libtorrent m_last_download = rd.dict_find_int_value("last_download", 0); m_last_upload = rd.dict_find_int_value("last_upload", 0); + if (!m_use_resume_save_path) + { + std::string p = rd.dict_find_string_value("save_path"); + if (!p.empty()) m_save_path = p; + } + m_url = rd.dict_find_string_value("url"); m_uuid = rd.dict_find_string_value("uuid"); m_source_feed_url = rd.dict_find_string_value("feed"); @@ -5396,6 +5414,8 @@ namespace libtorrent ret["last_download"] = m_last_download; ret["last_upload"] = m_last_upload; + ret["save_path"] = m_save_path; + if (!m_url.empty()) ret["url"] = m_url; if (!m_uuid.empty()) ret["uuid"] = m_uuid; if (!m_source_feed_url.empty()) ret["feed"] = m_source_feed_url; @@ -6676,6 +6696,8 @@ namespace libtorrent m_save_path = save_path; #endif + m_need_save_resume_data = true; + if (alerts().should_post()) { alerts().post_alert(storage_moved_alert(get_handle(), m_save_path)); @@ -6694,6 +6716,7 @@ namespace libtorrent if (alerts().should_post()) alerts().post_alert(storage_moved_alert(get_handle(), j.str)); m_save_path = j.str; + m_need_save_resume_data = true; if (ret == piece_manager::need_full_check) force_recheck(); }