From 2330520c51732fa0aa86bebb76c0959a3de0cb95 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Tue, 8 Nov 2011 05:36:22 +0000 Subject: [PATCH] change the add_torrent_params API to use flags instead of a bunch of bools (but leave it backwards compatible) --- bindings/python/src/magnet_uri.cpp | 37 +---- bindings/python/src/session.cpp | 43 ++++-- docs/manual.rst | 165 ++++++++++++---------- examples/client_test.cpp | 24 ++-- include/libtorrent/add_torrent_params.hpp | 65 +++++++-- src/rss.cpp | 9 +- src/session_impl.cpp | 5 +- src/torrent.cpp | 22 +-- 8 files changed, 215 insertions(+), 155 deletions(-) diff --git a/bindings/python/src/magnet_uri.cpp b/bindings/python/src/magnet_uri.cpp index c072e51b0..610626d9d 100644 --- a/bindings/python/src/magnet_uri.cpp +++ b/bindings/python/src/magnet_uri.cpp @@ -11,47 +11,22 @@ using namespace boost::python; using namespace libtorrent; +extern void dict_to_add_torrent_params(dict params + , add_torrent_params& p, std::vector& rd); + namespace { torrent_handle _add_magnet_uri(session& s, std::string uri, dict params) { add_torrent_params p; - std::string url; - if (params.has_key("tracker_url")) - { - url = extract(params["tracker_url"]); - p.tracker_url = url.c_str(); - } - std::string name; - if (params.has_key("name")) - { - name = extract(params["name"]); - p.name = name.c_str(); - } - p.save_path = extract(params["save_path"]); - std::vector resume_buf; - if (params.has_key("resume_data")) - { - std::string resume = extract(params["resume_data"]); - resume_buf.resize(resume.size()); - std::memcpy(&resume_buf[0], &resume[0], resume.size()); - p.resume_data = &resume_buf; - } - if (params.has_key("storage_mode")) - p.storage_mode = extract(params["storage_mode"]); - if (params.has_key("paused")) - p.paused = params["paused"]; - if (params.has_key("auto_managed")) - p.auto_managed = params["auto_managed"]; - if (params.has_key("duplicate_is_error")) - p.duplicate_is_error = params["duplicate_is_error"]; - + dict_to_add_torrent_params(params, p, resume_buf); + #ifndef BOOST_NO_EXCEPTIONS return add_magnet_uri(s, uri, p); #else - error_code ec; + error_code ec; return add_magnet_uri(s, uri, p, ec); #endif } diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index 54e887945..94cc075ab 100644 --- a/bindings/python/src/session.cpp +++ b/bindings/python/src/session.cpp @@ -143,6 +143,7 @@ namespace } #endif #endif +} void dict_to_add_torrent_params(dict params, add_torrent_params& p, std::vector& rd) { @@ -175,12 +176,8 @@ namespace } if (params.has_key("storage_mode")) p.storage_mode = extract(params["storage_mode"]); - if (params.has_key("paused")) - p.paused = params["paused"]; - if (params.has_key("auto_managed")) - p.auto_managed = params["auto_managed"]; - if (params.has_key("duplicate_is_error")) - p.duplicate_is_error = params["duplicate_is_error"]; + +#ifndef TORRENT_NO_DEPRECATE if (params.has_key("seed_mode")) p.seed_mode = params["seed_mode"]; if (params.has_key("upload_mode")) @@ -189,14 +186,33 @@ namespace p.upload_mode = params["share_mode"]; if (params.has_key("override_resume_data")) p.override_resume_data = params["override_resume_data"]; + if (params.has_key("apply_ip_filter")) + p.apply_ip_filter = params["apply_ip_filter"]; + if (params.has_key("paused")) + p.paused = params["paused"]; + if (params.has_key("auto_managed")) + p.auto_managed = params["auto_managed"]; + if (params.has_key("duplicate_is_error")) + p.duplicate_is_error = params["duplicate_is_error"]; + if (params.has_key("merge_resume_trackers")) + p.merge_resume_trackers = params["merge_resume_trackers"]; +#endif + if (params.has_key("flags")) + p.flags = extract(params["flags"]); + if (params.has_key("trackerid")) p.trackerid = extract(params["trackerid"]); if (params.has_key("url")) p.url = extract(params["url"]); - if (params.has_key("merge_resume_trackers")) - p.merge_resume_trackers = params["merge_resume_trackers"]; + if (params.has_key("source_feed_url")) + p.source_feed_url = extract(params["source_feed_url"]); + if (params.has_key("uuid")) + p.uuid = extract(params["uuid"]); } +namespace +{ + torrent_handle add_torrent(session& s, dict params) { add_torrent_params p; @@ -446,6 +462,17 @@ void bind_session() .value("start_default_features", session::start_default_features) ; + enum_("add_torrent_params_flags_t") + .value("flag_seed_mode", add_torrent_params::flag_seed_mode) + .value("flag_override_resume_data", add_torrent_params::flag_override_resume_data) + .value("flag_upload_mode", add_torrent_params::flag_upload_mode) + .value("flag_share_mode", add_torrent_params::flag_share_mode) + .value("flag_apply_ip_filter", add_torrent_params::flag_apply_ip_filter) + .value("flag_paused", add_torrent_params::flag_paused) + .value("flag_auto_managed", add_torrent_params::flag_auto_managed) + .value("flag_duplicate_is_error", add_torrent_params::flag_duplicate_is_error) + .value("flag_merge_resume_trackers", add_torrent_params::flag_merge_resume_trackers) + ; class_("cache_status") .def_readonly("blocks_written", &cache_status::blocks_written) .def_readonly("writes", &cache_status::writes) diff --git a/docs/manual.rst b/docs/manual.rst index 96ba46818..28f3afff6 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -382,6 +382,19 @@ add_torrent() { add_torrent_params(storage_constructor_type s); + enum flags_t + { + flag_seed_mode = 0x001, + flag_override_resume_data = 0x002, + flag_upload_mode = 0x004, + flag_share_mode = 0x008, + flag_apply_ip_filter = 0x010, + flag_paused = 0x020, + flag_auto_managed = 0x040. + flag_duplicate_is_error = 0x080, + flag_merge_resume_trackers = 0x100 + }; + int version; boost::intrusive_ptr ti; char const* tracker_url; @@ -390,22 +403,14 @@ add_torrent() fs::path save_path; std::vector* resume_data; storage_mode_t storage_mode; - bool paused; - bool auto_managed; - bool duplicate_is_error; storage_constructor_type storage; void* userdata; - bool seed_mode; - bool override_resume_data; - bool upload_mode; std::vector const* file_priorities; - bool share_mode; std::string trackerid; std::string url; std::string uuid; std::string source_feed_url; - bool apply_ip_filter; - bool merge_resume_trackers; + boost::uint64_t flags; }; torrent_handle add_torrent(add_torrent_params const& params); @@ -469,24 +474,6 @@ storage_mode_compact For more information, see `storage allocation`_. -``paused`` is a boolean that specifies whether or not the torrent is to be started in -a paused state. I.e. it won't connect to the tracker or any of the peers until it's -resumed. This is typically a good way of avoiding race conditions when setting -configuration options on torrents before starting them. - -If you pass in resume data, the paused state of the torrent when the resume data -was saved will override the paused state you pass in here. You can override this -by setting ``override_resume_data``. - -If ``auto_managed`` is true, this torrent will be queued, started and seeded -automatically by libtorrent. When this is set, the torrent should also be started -as paused. The default queue order is the order the torrents were added. They -are all downloaded in that order. For more details, see queuing_. - -If you pass in resume data, the auto_managed state of the torrent when the resume data -was saved will override the auto_managed state you pass in here. You can override this -by setting ``override_resume_data``. - ``storage`` can be used to customize how the data is stored. The default storage will simply write the data to the files it belongs to, but it could be overridden to save everything to a single file at a specific location or encrypt the @@ -496,49 +483,9 @@ that needs to be implemented for a custom storage, see `storage_interface`_. The ``userdata`` parameter is optional and will be passed on to the extension constructor functions, if any (see `add_extension()`_). -If ``seed_mode`` is set to true, libtorrent will assume that all files are present -for this torrent and that they all match the hashes in the torrent file. Each time -a peer requests to download a block, the piece is verified against the hash, unless -it has been verified already. If a hash fails, the torrent will automatically leave -the seed mode and recheck all the files. The use case for this mode is if a torrent -is created and seeded, or if the user already know that the files are complete, this -is a way to avoid the initial file checks, and significantly reduce the startup time. - -Setting ``seed_mode`` on a torrent without metadata (a .torrent file) is a no-op -and will be ignored. - -If resume data is passed in with this torrent, the seed mode saved in there will -override the seed mode you set here. - The torrent_handle_ returned by ``add_torrent()`` can be used to retrieve information about the torrent's progress, its peers etc. It is also used to abort a torrent. -If ``override_resume_data`` is set to true, the ``paused`` and ``auto_managed`` -state of the torrent are not loaded from the resume data, but the states requested -by this ``add_torrent_params`` will override it. - -If ``upload_mode`` is set to true, the torrent will be initialized in upload-mode, -which means it will not make any piece requests. This state is typically entered -on disk I/O errors, and if the torrent is also auto managed, it will be taken out -of this state periodically. This mode can be used to avoid race conditions when -adjusting priorities of pieces before allowing the torrent to start downloading. - -``share_mode`` determines if the torrent should be added in *share mode* or not. -Share mode indicates that we are not interested in downloading the torrent, but -merlely want to improve our share ratio (i.e. increase it). A torrent started in -share mode will do its best to never download more than it uploads to the swarm. -If the swarm does not have enough demand for upload capacity, the torrent will -not download anything. This mode is intended to be safe to add any number of torrents -to, without manual screening, without the risk of downloading more than is uploaded. - -A torrent in share mode sets the priority to all pieces to 0, except for the pieces -that are downloaded, when pieces are decided to be downloaded. This affects the progress -bar, which might be set to "100% finished" most of the time. Do not change file or piece -priorities for torrents in share mode, it will make it not work. - -The share mode has one setting, the share ratio target, see ``session_settings::share_mode_target`` -for more info. - ``file_priorities`` can be set to control the initial file priorities when adding a torrent. The semantics are the same as for ``torrent_handle::prioritize_files()``. @@ -556,13 +503,89 @@ is mainly useful for RSS feed items which has UUIDs specified. ``source_feed_url`` should point to the URL of the RSS feed this torrent comes from, if it comes from an RSS feed. -``apply_ip_filter`` determines if the IP filter should apply to this torrent or not. By -default all torrents are subject to filtering by the IP filter. This is useful if certain -torrents needs to be excempt for some reason, being an auto-update torrent for instance. +``flags`` is a 64 bit integer used for flags controlling aspects of this torrent +and how it's added. These are the flags:: -``merge_resume_trackers`` defaults to false and specifies whether tracker URLs loaded from + enum flags_t + { + flag_seed_mode = 0x001, + flag_override_resume_data = 0x002, + flag_upload_mode = 0x004, + flag_share_mode = 0x008, + flag_apply_ip_filter = 0x010, + flag_paused = 0x020, + flag_auto_managed = 0x040. + flag_duplicate_is_error = 0x080, + flag_merge_resume_trackers = 0x100 + } + +``flag_apply_ip_filter`` determines if the IP filter should apply to this torrent or not. By +default all torrents are subject to filtering by the IP filter (i.e. this flag is set by +default). This is useful if certain torrents needs to be excempt for some reason, being +an auto-update torrent for instance. + +``flag_merge_resume_trackers`` defaults to off and specifies whether tracker URLs loaded from resume data should be added to the trackers in the torrent or replace the trackers. +``flag_paused`` specifies whether or not the torrent is to be started in a paused +state. I.e. it won't connect to the tracker or any of the peers until it's +resumed. This is typically a good way of avoiding race conditions when setting +configuration options on torrents before starting them. + +If you pass in resume data, the paused state of the torrent when the resume data +was saved will override the paused state you pass in here. You can override this +by setting ``flag_override_resume_data``. + +If ``flag_auto_managed`` is set, the torrent will be queued, started and seeded +automatically by libtorrent. When this is set, the torrent should also be started +as paused. The default queue order is the order the torrents were added. They +are all downloaded in that order. For more details, see queuing_. + +If you pass in resume data, the auto_managed state of the torrent when the resume data +was saved will override the auto_managed state you pass in here. You can override this +by setting ``override_resume_data``. + +If ``flag_seed_mode`` is set, libtorrent will assume that all files are present +for this torrent and that they all match the hashes in the torrent file. Each time +a peer requests to download a block, the piece is verified against the hash, unless +it has been verified already. If a hash fails, the torrent will automatically leave +the seed mode and recheck all the files. The use case for this mode is if a torrent +is created and seeded, or if the user already know that the files are complete, this +is a way to avoid the initial file checks, and significantly reduce the startup time. + +Setting ``flag_seed_mode`` on a torrent without metadata (a .torrent file) is a no-op +and will be ignored. + +If resume data is passed in with this torrent, the seed mode saved in there will +override the seed mode you set here. + +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 ``add_torrent_params`` will override them. + +If ``flag_upload_mode`` is set, the torrent will be initialized in upload-mode, +which means it will not make any piece requests. This state is typically entered +on disk I/O errors, and if the torrent is also auto managed, it will be taken out +of this state periodically. This mode can be used to avoid race conditions when +adjusting priorities of pieces before allowing the torrent to start downloading. + +``flag_share_mode`` determines if the torrent should be added in *share mode* or not. +Share mode indicates that we are not interested in downloading the torrent, but +merlely want to improve our share ratio (i.e. increase it). A torrent started in +share mode will do its best to never download more than it uploads to the swarm. +If the swarm does not have enough demand for upload capacity, the torrent will +not download anything. This mode is intended to be safe to add any number of torrents +to, without manual screening, without the risk of downloading more than is uploaded. + +A torrent in share mode sets the priority to all pieces to 0, except for the pieces +that are downloaded, when pieces are decided to be downloaded. This affects the progress +bar, which might be set to "100% finished" most of the time. Do not change file or piece +priorities for torrents in share mode, it will make it not work. + +The share mode has one setting, the share ratio target, see ``session_settings::share_mode_target`` +for more info. + + remove_torrent() ---------------- diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 3631b0dca..9d6901d10 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -685,9 +685,9 @@ void add_torrent(libtorrent::session& ses printf("%s\n", t->name().c_str()); add_torrent_params p; - p.seed_mode = seed_mode; + if (seed_mode) p.flags |= add_torrent_params::flag_seed_mode; if (disable_storage) p.storage = disabled_storage_constructor; - p.share_mode = share_mode; + if (share_mode) p.flags |= add_torrent_params::flag_share_mode; lazy_entry resume_data; std::string filename = combine_path(save_path, ".resume/" + to_hex(t->info_hash().to_string()) + ".resume"); @@ -699,9 +699,9 @@ void add_torrent(libtorrent::session& ses p.ti = t; p.save_path = save_path; p.storage_mode = (storage_mode_t)allocation_mode; - p.paused = true; - p.duplicate_is_error = false; - p.auto_managed = true; + p.flags |= add_torrent_params::flag_paused; + p.flags &= ~add_torrent_params::flag_duplicate_is_error; + p.flags |= add_torrent_params::flag_auto_managed; if (monitored_dir) { p.userdata = (void*)strdup(torrent.c_str()); @@ -1173,16 +1173,16 @@ int main(int argc, char* argv[]) from_hex(argv[i], 40, (char*)&info_hash[0]); add_torrent_params p; - p.seed_mode = seed_mode; + if (seed_mode) p.flags |= add_torrent_params::flag_seed_mode; if (disable_storage) p.storage = disabled_storage_constructor; - p.share_mode = share_mode; + if (share_mode) p.flags |= add_torrent_params::flag_share_mode; p.tracker_url = argv[i] + 41; p.info_hash = info_hash; p.save_path = save_path; p.storage_mode = (storage_mode_t)allocation_mode; - p.paused = true; - p.duplicate_is_error = false; - p.auto_managed = true; + p.flags |= add_torrent_params::flag_paused; + p.flags &= ~add_torrent_params::flag_duplicate_is_error; + p.flags |= add_torrent_params::flag_auto_managed; magnet_links.push_back(p); continue; } @@ -1397,9 +1397,9 @@ int main(int argc, char* argv[]) || std::strstr(i->c_str(), "magnet:") == i->c_str()) { add_torrent_params p; - p.seed_mode = seed_mode; + if (seed_mode) p.flags |= add_torrent_params::flag_seed_mode; if (disable_storage) p.storage = disabled_storage_constructor; - p.share_mode = share_mode; + if (share_mode) p.flags |= add_torrent_params::flag_share_mode; p.save_path = save_path; p.storage_mode = (storage_mode_t)allocation_mode; p.url = *i; diff --git a/include/libtorrent/add_torrent_params.hpp b/include/libtorrent/add_torrent_params.hpp index ee06f444d..b7076b0b8 100644 --- a/include/libtorrent/add_torrent_params.hpp +++ b/include/libtorrent/add_torrent_params.hpp @@ -53,20 +53,58 @@ namespace libtorrent , name(0) , resume_data(0) , storage_mode(storage_mode_sparse) - , paused(true) - , auto_managed(true) - , duplicate_is_error(false) , storage(sc) , userdata(0) + , file_priorities(0) +#ifndef TORRENT_NO_DEPRECATE + , flags(flag_ignore_flags) , seed_mode(false) , override_resume_data(false) , upload_mode(false) - , file_priorities(0) , share_mode(false) , apply_ip_filter(true) + , paused(true) + , auto_managed(true) + , duplicate_is_error(false) , merge_resume_trackers(false) - {} +#else + , flags(flag_apply_ip_filter | flag_paused | flag_auto_managed) +#endif + { +#ifndef TORRENT_NO_DEPRECATE + if (flags == flag_ignore_flags) + { + flags = 0; + if (seed_mode) flags |= flag_seed_mode; + if (override_resume_data) flags |= flag_override_resume_data; + if (upload_mode) flags |= flag_upload_mode; + if (share_mode) flags |= flag_share_mode; + if (apply_ip_filter) flags |= flag_apply_ip_filter; + if (paused) flags |= flag_paused; + if (auto_managed) flags |= flag_auto_managed; + if (duplicate_is_error) flags |= flag_duplicate_is_error; + if (merge_resume_trackers) flags |= flag_merge_resume_trackers; + } +#endif + } + enum flags_t + { + flag_seed_mode = 0x001, + flag_override_resume_data = 0x002, + flag_upload_mode = 0x004, + flag_share_mode = 0x008, + flag_apply_ip_filter = 0x010, + flag_paused = 0x020, + flag_auto_managed = 0x040, + flag_duplicate_is_error = 0x080, + flag_merge_resume_trackers = 0x100 + +#ifndef TORRENT_NO_DEPRECATE + , flag_ignore_flags = 0x80000000 +#endif + }; + // libtorrent version. Used for forward binary compatibility int version; boost::intrusive_ptr ti; @@ -76,22 +114,25 @@ namespace libtorrent std::string save_path; std::vector* resume_data; storage_mode_t storage_mode; - bool paused; - bool auto_managed; - bool duplicate_is_error; storage_constructor_type storage; void* userdata; - bool seed_mode; - bool override_resume_data; - bool upload_mode; std::vector const* file_priorities; - bool share_mode; std::string trackerid; std::string url; std::string uuid; std::string source_feed_url; + boost::uint64_t flags; +#ifndef TORRENT_NO_DEPRECATE + bool seed_mode; + bool override_resume_data; + bool upload_mode; + bool share_mode; bool apply_ip_filter; + bool paused; + bool auto_managed; + bool duplicate_is_error; bool merge_resume_trackers; +#endif }; } diff --git a/src/rss.cpp b/src/rss.cpp index cc3332cec..6f06e63f9 100644 --- a/src/rss.cpp +++ b/src/rss.cpp @@ -429,14 +429,7 @@ void feed::on_feed(error_code const& ec bencode_map_entry add_torrent_map[] = { TORRENT_SETTING(std_string, save_path) - TORRENT_SETTING(boolean, paused) - TORRENT_SETTING(boolean, auto_managed) - TORRENT_SETTING(boolean, duplicate_is_error) - TORRENT_SETTING(boolean, seed_mode) - TORRENT_SETTING(boolean, override_resume_data) - TORRENT_SETTING(boolean, upload_mode) - TORRENT_SETTING(boolean, share_mode) - TORRENT_SETTING(std_string, trackerid) + TORRENT_SETTING(size_integer, flags) }; #undef TORRENT_SETTING diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 8b0f5b72e..a237be69b 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -4408,7 +4408,7 @@ namespace aux { if (torrent_ptr) { - if (!params.duplicate_is_error) + if ((params.flags & add_torrent_params::flag_duplicate_is_error) == 0) { if (!params.uuid.empty() && torrent_ptr->uuid().empty()) torrent_ptr->set_uuid(params.uuid); @@ -4471,7 +4471,8 @@ namespace aux { m_alerts.post_alert(torrent_added_alert(torrent_ptr->get_handle())); // recalculate auto-managed torrents sooner - if (params.auto_managed && m_auto_manage_time_scaler > 1) + if ((params.flags && add_torrent_params::flag_auto_managed) + && m_auto_manage_time_scaler > 1) m_auto_manage_time_scaler = 1; return torrent_handle(torrent_ptr); diff --git a/src/torrent.cpp b/src/torrent.cpp index f4b7c7855..367cbe3da 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -383,7 +383,7 @@ namespace libtorrent , m_got_tracker_response(false) , m_connections_initialized(false) , m_super_seeding(false) - , m_override_resume_data(p.override_resume_data) + , m_override_resume_data(p.flags & add_torrent_params::flag_override_resume_data) #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES , m_resolving_country(false) , m_resolve_countries(false) @@ -406,13 +406,13 @@ namespace libtorrent , m_incomplete(0xffffff) , m_progress_ppm(0) , m_abort(false) - , m_announce_to_dht(!p.paused) - , m_announce_to_trackers(!p.paused) - , m_announce_to_lsd(!p.paused) - , m_allow_peers(!p.paused) - , m_upload_mode(p.upload_mode) - , m_auto_managed(p.auto_managed) - , m_share_mode(p.share_mode) + , m_announce_to_dht((p.flags & add_torrent_params::flag_paused) == 0) + , m_announce_to_trackers((p.flags & add_torrent_params::flag_paused) == 0) + , m_announce_to_lsd((p.flags & add_torrent_params::flag_paused) == 0) + , m_allow_peers((p.flags & add_torrent_params::flag_paused) == 0) + , m_upload_mode(p.flags & add_torrent_params::flag_upload_mode) + , m_auto_managed(p.flags & add_torrent_params::flag_auto_managed) + , m_share_mode(p.flags & add_torrent_params::flag_share_mode) , m_num_verified(0) , m_last_scrape(0) , m_last_download(0) @@ -424,8 +424,8 @@ namespace libtorrent , m_need_connect_boost(true) , m_lsd_seq(0) , m_magnet_link(false) - , m_apply_ip_filter(p.apply_ip_filter) - , m_merge_resume_trackers(p.merge_resume_trackers) + , m_apply_ip_filter(p.flags & add_torrent_params::flag_apply_ip_filter) + , m_merge_resume_trackers(p.flags & add_torrent_params::flag_merge_resume_trackers) , m_in_encrypted_list(false) { #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS @@ -511,7 +511,7 @@ namespace libtorrent m_trackers = m_torrent_file->trackers(); if (m_torrent_file->is_valid()) { - m_seed_mode = p.seed_mode; + m_seed_mode = p.flags & add_torrent_params::flag_seed_mode; m_connections_initialized = true; m_block_size_shift = root2((std::min)(block_size, m_torrent_file->piece_length())); }