merged python binding update from RC_0_16

This commit is contained in:
Arvid Norberg 2013-05-03 08:24:26 +00:00
parent 39e4361fff
commit f01169a68d
9 changed files with 182 additions and 13 deletions

View File

@ -20,6 +20,7 @@
* fix uTP edge case where udp socket buffer fills up * fix uTP edge case where udp socket buffer fills up
* fix nagle implementation in uTP * fix nagle implementation in uTP
* add a number of missing functions to the python binding
* fix typo in Jamfile for building shared libraries * fix typo in Jamfile for building shared libraries
* prevent tracker exchange for magnet links before metadata is received * prevent tracker exchange for magnet links before metadata is received
* fix crash in make_magnet_uri when generating links longer than 1024 characters * fix crash in make_magnet_uri when generating links longer than 1024 characters

View File

@ -17,6 +17,11 @@ namespace
c.set_hash(p, sha1_hash(hash)); c.set_hash(p, sha1_hash(hash));
} }
void set_file_hash(create_torrent& c, int f, char const* hash)
{
c.set_file_hash(f, sha1_hash(hash));
}
void call_python_object(boost::python::object const& obj, int i) void call_python_object(boost::python::object const& obj, int i)
{ {
obj(i); obj(i);
@ -120,7 +125,9 @@ void bind_create_torrent()
.def("set_comment", &create_torrent::set_comment) .def("set_comment", &create_torrent::set_comment)
.def("set_creator", &create_torrent::set_creator) .def("set_creator", &create_torrent::set_creator)
.def("set_hash", &set_hash) .def("set_hash", &set_hash)
.def("set_file_hash", &set_file_hash)
.def("add_url_seed", &create_torrent::add_url_seed) .def("add_url_seed", &create_torrent::add_url_seed)
.def("add_http_seed", &create_torrent::add_http_seed)
.def("add_node", &add_node) .def("add_node", &add_node)
.def("add_tracker", &create_torrent::add_tracker, (arg("announce_url"), arg("tier") = 0)) .def("add_tracker", &create_torrent::add_tracker, (arg("announce_url"), arg("tier") = 0))
.def("set_priv", &create_torrent::set_priv) .def("set_priv", &create_torrent::set_priv)

View File

@ -20,6 +20,11 @@ int get_last_request(peer_info const& pi)
return total_seconds(pi.last_request); return total_seconds(pi.last_request);
} }
int get_download_queue_time(peer_info const& pi)
{
return total_seconds(pi.download_queue_time);
}
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
str get_country(peer_info const& pi) str get_country(peer_info const& pi)
{ {
@ -27,6 +32,11 @@ str get_country(peer_info const& pi)
} }
#endif #endif
tuple get_local_endpoint(peer_info const& pi)
{
return make_tuple(pi.local_endpoint.address().to_string(), pi.local_endpoint.port());
}
tuple get_ip(peer_info const& pi) tuple get_ip(peer_info const& pi)
{ {
return make_tuple(pi.ip.address().to_string(), pi.ip.port()); return make_tuple(pi.ip.address().to_string(), pi.ip.port());
@ -64,8 +74,13 @@ void bind_peer_info()
.def_readonly("download_limit", &peer_info::download_limit) .def_readonly("download_limit", &peer_info::download_limit)
.add_property("last_request", get_last_request) .add_property("last_request", get_last_request)
.add_property("last_active", get_last_active) .add_property("last_active", get_last_active)
.add_property("download_queue_time", get_download_queue_time)
.def_readonly("queue_bytes", &peer_info::queue_bytes)
.def_readonly("request_timeout", &peer_info::request_timeout)
.def_readonly("send_buffer_size", &peer_info::send_buffer_size) .def_readonly("send_buffer_size", &peer_info::send_buffer_size)
.def_readonly("used_send_buffer", &peer_info::used_send_buffer) .def_readonly("used_send_buffer", &peer_info::used_send_buffer)
.def_readonly("receive_buffer_size", &peer_info::receive_buffer_size)
.def_readonly("used_receive_buffer", &peer_info::used_receive_buffer)
.def_readonly("num_hashfails", &peer_info::num_hashfails) .def_readonly("num_hashfails", &peer_info::num_hashfails)
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
.add_property("country", get_country) .add_property("country", get_country)
@ -89,7 +104,13 @@ void bind_peer_info()
.def_readonly("send_quota", &peer_info::send_quota) .def_readonly("send_quota", &peer_info::send_quota)
.def_readonly("receive_quota", &peer_info::receive_quota) .def_readonly("receive_quota", &peer_info::receive_quota)
.def_readonly("rtt", &peer_info::rtt) .def_readonly("rtt", &peer_info::rtt)
.def_readonly("num_pieces", &peer_info::num_pieces)
.def_readonly("download_rate_peak", &peer_info::download_rate_peak)
.def_readonly("upload_rate_peak", &peer_info::upload_rate_peak)
.def_readonly("progress", &peer_info::progress) .def_readonly("progress", &peer_info::progress)
.def_readonly("progress_ppm", &peer_info::progress_ppm)
.def_readonly("estimated_reciprocation_rate", &peer_info::estimated_reciprocation_rate)
.add_property("local_endpoint", get_local_endpoint)
; ;
// flags // flags
@ -104,6 +125,11 @@ void bind_peer_info()
pi.attr("queued") = (int)peer_info::queued; pi.attr("queued") = (int)peer_info::queued;
pi.attr("on_parole") = (int)peer_info::on_parole; pi.attr("on_parole") = (int)peer_info::on_parole;
pi.attr("seed") = (int)peer_info::seed; pi.attr("seed") = (int)peer_info::seed;
pi.attr("optimistic_unchoke") = (int)peer_info::optimistic_unchoke;
pi.attr("snubbed") = (int)peer_info::snubbed;
pi.attr("upload_only") = (int)peer_info::upload_only;
pi.attr("endgame_mode") = (int)peer_info::endgame_mode;
pi.attr("holepunched") = (int)peer_info::holepunched;
#ifndef TORRENT_DISABLE_ENCRYPTION #ifndef TORRENT_DISABLE_ENCRYPTION
pi.attr("rc4_encrypted") = (int)peer_info::rc4_encrypted; pi.attr("rc4_encrypted") = (int)peer_info::rc4_encrypted;
pi.attr("plaintext_encrypted") = (int)peer_info::plaintext_encrypted; pi.attr("plaintext_encrypted") = (int)peer_info::plaintext_encrypted;
@ -126,6 +152,8 @@ void bind_peer_info()
pi.attr("bw_torrent") = (int)peer_info::bw_torrent; pi.attr("bw_torrent") = (int)peer_info::bw_torrent;
pi.attr("bw_global") = (int)peer_info::bw_global; pi.attr("bw_global") = (int)peer_info::bw_global;
#endif #endif
pi.attr("bw_limit") = (int)peer_info::bw_limit;
pi.attr("bw_network") = (int)peer_info::bw_network; pi.attr("bw_network") = (int)peer_info::bw_network;
pi.attr("bw_disk") = (int)peer_info::bw_disk;
} }

View File

@ -43,6 +43,13 @@ namespace
return; return;
} }
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
void add_dht_node(session& s, tuple n)
{
std::string ip = extract<std::string>(n[0]);
int port = extract<int>(n[1]);
s.add_dht_node(std::make_pair(ip, port));
}
void add_dht_router(session& s, std::string router_, int port_) void add_dht_router(session& s, std::string router_, int port_)
{ {
allow_threading_guard guard; allow_threading_guard guard;
@ -396,6 +403,17 @@ namespace
return ret; return ret;
} }
dict get_utp_stats(session_status const& st)
{
dict ret;
ret["num_idle"] = st.utp_stats.num_idle;
ret["num_syn_sent"] = st.utp_stats.num_syn_sent;
ret["num_connected"] = st.utp_stats.num_connected;
ret["num_fin_sent"] = st.utp_stats.num_fin_sent;
ret["num_close_wait"] = st.utp_stats.num_close_wait;
return ret;
}
#ifndef TORRENT_DISABLE_GEO_IP #ifndef TORRENT_DISABLE_GEO_IP
void load_asnum_db(session& s, std::string file) void load_asnum_db(session& s, std::string file)
{ {
@ -503,7 +521,9 @@ void bind_session()
.def_readonly("dht_torrents", &session_status::dht_torrents) .def_readonly("dht_torrents", &session_status::dht_torrents)
.def_readonly("dht_global_nodes", &session_status::dht_global_nodes) .def_readonly("dht_global_nodes", &session_status::dht_global_nodes)
.def_readonly("active_requests", &session_status::active_requests) .def_readonly("active_requests", &session_status::active_requests)
.def_readonly("dht_total_allocations", &session_status::dht_total_allocations)
#endif #endif
.add_property("utp_stats", &get_utp_stats)
; ;
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
@ -573,10 +593,12 @@ void bind_session()
.def("listen_port", allow_threads(&session::listen_port)) .def("listen_port", allow_threads(&session::listen_port))
.def("status", allow_threads(&session::status)) .def("status", allow_threads(&session::status))
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
.def("add_dht_node", add_dht_node)
.def( .def(
"add_dht_router", &add_dht_router "add_dht_router", &add_dht_router
, (arg("router"), "port") , (arg("router"), "port")
) )
.def("is_dht_running", allow_threads(&session::is_dht_running))
.def("set_dht_settings", allow_threads(&session::set_dht_settings)) .def("set_dht_settings", allow_threads(&session::set_dht_settings))
.def("start_dht", allow_threads(start_dht0)) .def("start_dht", allow_threads(start_dht0))
.def("stop_dht", allow_threads(&session::stop_dht)) .def("stop_dht", allow_threads(&session::stop_dht))
@ -657,6 +679,10 @@ void bind_session()
.def("peer_proxy", allow_threads(&session::peer_proxy)) .def("peer_proxy", allow_threads(&session::peer_proxy))
.def("tracker_proxy", allow_threads(&session::tracker_proxy)) .def("tracker_proxy", allow_threads(&session::tracker_proxy))
.def("web_seed_proxy", allow_threads(&session::web_seed_proxy)) .def("web_seed_proxy", allow_threads(&session::web_seed_proxy))
#endif
#if TORRENT_USE_I2P
.def("set_i2p_proxy", allow_threads(&session::set_i2p_proxy))
.def("i2p_proxy", allow_threads(&session::i2p_proxy))
#endif #endif
.def("set_proxy", allow_threads(&session::set_proxy)) .def("set_proxy", allow_threads(&session::set_proxy))
.def("proxy", allow_threads(&session::proxy)) .def("proxy", allow_threads(&session::proxy))

View File

@ -30,6 +30,21 @@ namespace
return ret; return ret;
} }
list http_seeds(torrent_handle& handle)
{
list ret;
std::set<std::string> urls;
{
allow_threading_guard guard;
urls = handle.http_seeds();
}
for (std::set<std::string>::iterator i(urls.begin())
, end(urls.end()); i != end; ++i)
ret.append(*i);
return ret;
}
list piece_availability(torrent_handle& handle) list piece_availability(torrent_handle& handle)
{ {
list ret; list ret;
@ -158,6 +173,21 @@ void file_prioritity1(torrent_handle& h, int index, int prio)
return h.file_priority(index, prio); return h.file_priority(index, prio);
} }
void dict_to_announce_entry(dict d, announce_entry& ae)
{
ae.url = extract<std::string>(d["url"]);
if (d.has_key("tier"))
ae.tier = extract<int>(d["tier"]);
if (d.has_key("fail_limit"))
ae.fail_limit = extract<int>(d["fail_limit"]);
if (d.has_key("source"))
ae.source = extract<int>(d["source"]);
if (d.has_key("verified"))
ae.verified = extract<int>(d["verified"]);
if (d.has_key("send_stats"))
ae.send_stats = extract<int>(d["send_stats"]);
}
void replace_trackers(torrent_handle& h, object trackers) void replace_trackers(torrent_handle& h, object trackers)
{ {
object iter(trackers.attr("__iter__")()); object iter(trackers.attr("__iter__")());
@ -179,18 +209,9 @@ void replace_trackers(torrent_handle& h, object trackers)
{ {
dict d; dict d;
d = extract<dict>(object(entry)); d = extract<dict>(object(entry));
std::string url = extract<std::string>(d["url"]); announce_entry ae;
announce_entry ae(url); dict_to_announce_entry(d, ae);
if (d.has_key("tier")) result.push_back(ae);
ae.tier = extract<int>(d["tier"]);
if (d.has_key("fail_limit"))
ae.fail_limit = extract<int>(d["fail_limit"]);
if (d.has_key("source"))
ae.source = extract<int>(d["source"]);
if (d.has_key("verified"))
ae.verified = extract<int>(d["verified"]);
if (d.has_key("send_stats"))
ae.send_stats = extract<int>(d["send_stats"]);
} }
} }
@ -198,7 +219,14 @@ void replace_trackers(torrent_handle& h, object trackers)
h.replace_trackers(result); h.replace_trackers(result);
} }
list trackers(torrent_handle &h) void add_tracker(torrent_handle& h, dict d)
{
announce_entry ae;
dict_to_announce_entry(d, ae);
h.add_tracker(ae);
}
list trackers(torrent_handle& h)
{ {
list ret; list ret;
std::vector<announce_entry> const trackers = h.trackers(); std::vector<announce_entry> const trackers = h.trackers();
@ -259,6 +287,11 @@ list get_download_queue(torrent_handle& handle)
return ret; return ret;
} }
void set_metadata(torrent_handle& handle, std::string const& buf)
{
handle.set_metadata(buf.c_str(), buf.size());
}
namespace namespace
{ {
tcp::endpoint tuple_to_endpoint(tuple const& t) tcp::endpoint tuple_to_endpoint(tuple const& t)
@ -331,10 +364,15 @@ void bind_torrent_handle()
.def("file_progress", file_progress) .def("file_progress", file_progress)
.def("trackers", trackers) .def("trackers", trackers)
.def("replace_trackers", replace_trackers) .def("replace_trackers", replace_trackers)
.def("add_tracker", add_tracker)
.def("add_url_seed", _(&torrent_handle::add_url_seed)) .def("add_url_seed", _(&torrent_handle::add_url_seed))
.def("remove_url_seed", _(&torrent_handle::remove_url_seed)) .def("remove_url_seed", _(&torrent_handle::remove_url_seed))
.def("url_seeds", url_seeds) .def("url_seeds", url_seeds)
.def("add_http_seed", _(&torrent_handle::add_http_seed))
.def("remove_http_seed", _(&torrent_handle::remove_http_seed))
.def("http_seeds", http_seeds)
.def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>()) .def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
.def("set_metadata", set_metadata)
.def("is_valid", _(&torrent_handle::is_valid)) .def("is_valid", _(&torrent_handle::is_valid))
.def("pause", _(&torrent_handle::pause), arg("flags") = 0) .def("pause", _(&torrent_handle::pause), arg("flags") = 0)
.def("resume", _(&torrent_handle::resume)) .def("resume", _(&torrent_handle::resume))
@ -393,6 +431,7 @@ void bind_torrent_handle()
.def("set_upload_mode", _(&torrent_handle::set_upload_mode)) .def("set_upload_mode", _(&torrent_handle::set_upload_mode))
.def("set_share_mode", _(&torrent_handle::set_share_mode)) .def("set_share_mode", _(&torrent_handle::set_share_mode))
.def("flush_cache", &torrent_handle::flush_cache) .def("flush_cache", &torrent_handle::flush_cache)
.def("apply_ip_filter", &torrent_handle::apply_ip_filter)
.def("set_upload_limit", _(&torrent_handle::set_upload_limit)) .def("set_upload_limit", _(&torrent_handle::set_upload_limit))
.def("upload_limit", _(&torrent_handle::upload_limit)) .def("upload_limit", _(&torrent_handle::upload_limit))
.def("set_download_limit", _(&torrent_handle::set_download_limit)) .def("set_download_limit", _(&torrent_handle::set_download_limit))
@ -406,7 +445,9 @@ void bind_torrent_handle()
.def("connect_peer", &connect_peer) .def("connect_peer", &connect_peer)
.def("save_path", _(&torrent_handle::save_path)) .def("save_path", _(&torrent_handle::save_path))
.def("set_max_uploads", _(&torrent_handle::set_max_uploads)) .def("set_max_uploads", _(&torrent_handle::set_max_uploads))
.def("max_uploads", _(&torrent_handle::max_uploads))
.def("set_max_connections", _(&torrent_handle::set_max_connections)) .def("set_max_connections", _(&torrent_handle::set_max_connections))
.def("max_connections", _(&torrent_handle::max_connections))
.def("set_tracker_login", _(&torrent_handle::set_tracker_login)) .def("set_tracker_login", _(&torrent_handle::set_tracker_login))
.def("move_storage", _(move_storage0)) .def("move_storage", _(move_storage0))
.def("info_hash", _(&torrent_handle::info_hash)) .def("info_hash", _(&torrent_handle::info_hash))

View File

@ -42,6 +42,50 @@ namespace
return result; return result;
} }
list get_web_seeds(torrent_info const& ti)
{
std::vector<web_seed_entry> const& ws = ti.web_seeds();
list ret;
for (std::vector<web_seed_entry>::const_iterator i = ws.begin()
, end(ws.end()); i != end; ++i)
{
dict d;
d["url"] = i->url;
d["type"] = i->type;
d["auth"] = i->auth;
d["extra_headers"] = i->extra_headers;
d["retry"] = total_seconds(i->retry - min_time());
d["resolving"] = i->resolving;
d["removed"] = i->removed;
d["endpoint"] = make_tuple(
boost::lexical_cast<std::string>(i->endpoint.address()), i->endpoint.port());
ret.append(d);
}
return ret;
}
list get_merkle_tree(torrent_info const& ti)
{
std::vector<sha1_hash> const& mt = ti.merkle_tree();
list ret;
for (std::vector<sha1_hash>::const_iterator i = mt.begin()
, end(mt.end()); i != end; ++i)
{
ret.append(i->to_string());
}
return ret;
}
void set_merkle_tree(torrent_info& ti, list hashes)
{
std::vector<sha1_hash> h;
for (int i = 0, e = len(hashes); i < e; ++i)
h.push_back(sha1_hash(extract<char const*>(hashes[i])));
ti.set_merkle_tree(h);
}
file_storage::iterator begin_files(torrent_info& i) file_storage::iterator begin_files(torrent_info& i)
{ {
return i.begin_files(); return i.begin_files();
@ -161,6 +205,8 @@ void bind_torrent_info()
.def("remap_files", &remap_files) .def("remap_files", &remap_files)
.def("add_tracker", &torrent_info::add_tracker, arg("url")) .def("add_tracker", &torrent_info::add_tracker, arg("url"))
.def("add_url_seed", &torrent_info::add_url_seed) .def("add_url_seed", &torrent_info::add_url_seed)
.def("add_http_seed", &torrent_info::add_http_seed)
.def("web_seeds", get_web_seeds)
.def("name", &torrent_info::name, copy) .def("name", &torrent_info::name, copy)
.def("comment", &torrent_info::comment, copy) .def("comment", &torrent_info::comment, copy)
@ -172,6 +218,8 @@ void bind_torrent_info()
.def("info_hash", &torrent_info::info_hash, copy) .def("info_hash", &torrent_info::info_hash, copy)
#endif #endif
.def("hash_for_piece", &hash_for_piece) .def("hash_for_piece", &hash_for_piece)
.def("merkle_tree", get_merkle_tree)
.def("set_merkle_tree", set_merkle_tree)
.def("piece_size", &torrent_info::piece_size) .def("piece_size", &torrent_info::piece_size)
.def("num_files", &torrent_info::num_files, (arg("storage")=false)) .def("num_files", &torrent_info::num_files, (arg("storage")=false))

View File

@ -63,6 +63,7 @@ void bind_torrent_status()
.def_readonly("num_incomplete", &torrent_status::num_incomplete) .def_readonly("num_incomplete", &torrent_status::num_incomplete)
.def_readonly("list_seeds", &torrent_status::list_seeds) .def_readonly("list_seeds", &torrent_status::list_seeds)
.def_readonly("list_peers", &torrent_status::list_peers) .def_readonly("list_peers", &torrent_status::list_peers)
.def_readonly("connect_candidates", &torrent_status::connect_candidates)
.add_property("pieces", &pieces) .add_property("pieces", &pieces)
.add_property("verified_pieces", &verified_pieces) .add_property("verified_pieces", &verified_pieces)
.def_readonly("num_pieces", &torrent_status::num_pieces) .def_readonly("num_pieces", &torrent_status::num_pieces)
@ -92,6 +93,7 @@ void bind_torrent_status()
.def_readonly("seed_mode", &torrent_status::seed_mode) .def_readonly("seed_mode", &torrent_status::seed_mode)
.def_readonly("upload_mode", &torrent_status::upload_mode) .def_readonly("upload_mode", &torrent_status::upload_mode)
.def_readonly("share_mode", &torrent_status::share_mode) .def_readonly("share_mode", &torrent_status::share_mode)
.def_readonly("super_seeding", &torrent_status::super_seeding)
.def_readonly("error", &torrent_status::error) .def_readonly("error", &torrent_status::error)
.def_readonly("priority", &torrent_status::priority) .def_readonly("priority", &torrent_status::priority)
.def_readonly("added_time", &torrent_status::added_time) .def_readonly("added_time", &torrent_status::added_time)
@ -101,6 +103,7 @@ void bind_torrent_status()
.def_readonly("time_since_download", &torrent_status::time_since_download) .def_readonly("time_since_download", &torrent_status::time_since_download)
.def_readonly("queue_position", &torrent_status::queue_position) .def_readonly("queue_position", &torrent_status::queue_position)
.def_readonly("need_save_resume", &torrent_status::need_save_resume) .def_readonly("need_save_resume", &torrent_status::need_save_resume)
.def_readonly("ip_filter_applies", &torrent_status::ip_filter_applies)
; ;
enum_<torrent_status::state_t>("states") enum_<torrent_status::state_t>("states")

View File

@ -83,6 +83,7 @@ namespace libtorrent
struct TORRENT_EXPORT announce_entry struct TORRENT_EXPORT announce_entry
{ {
announce_entry(std::string const& u); announce_entry(std::string const& u);
announce_entry();
~announce_entry(); ~announce_entry();
// tracker URL as it appeared in the torrent file // tracker URL as it appeared in the torrent file

View File

@ -496,6 +496,20 @@ namespace libtorrent
, send_stats(true) , send_stats(true)
{} {}
announce_entry::announce_entry()
: next_announce(min_time())
, min_announce(min_time())
, tier(0)
, fail_limit(0)
, fails(0)
, updating(false)
, source(0)
, verified(false)
, start_sent(false)
, complete_sent(false)
, send_stats(true)
{}
announce_entry::~announce_entry() {} announce_entry::~announce_entry() {}
int announce_entry::next_announce_in() const int announce_entry::next_announce_in() const