diff --git a/ChangeLog b/ChangeLog index 939b65ad2..b2561ddac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ * added new read_resume_data() function, initializing add_torrent_params * removed deprecated fields from add_torrent_params + * deprecate "resume_data" field in add_torrent_params * improved support for bind-to-device * deprecated ssl_listen, SSL sockets are specified in listen_interfaces now * improved support for listening on multiple sockets and interfaces diff --git a/bindings/python/src/alert.cpp b/bindings/python/src/alert.cpp index 1582ac227..83d156a5e 100644 --- a/bindings/python/src/alert.cpp +++ b/bindings/python/src/alert.cpp @@ -19,44 +19,12 @@ bytes get_buffer(read_piece_alert const& rpa) : bytes(); } -tuple endpoint_to_tuple(tcp::endpoint const& ep) -{ - return boost::python::make_tuple(ep.address().to_string(), ep.port()); -} - -tuple endpoint_to_tuple(udp::endpoint const& ep) -{ - return boost::python::make_tuple(ep.address().to_string(), ep.port()); -} - - -tuple peer_alert_ip(peer_alert const& pa) -{ - return endpoint_to_tuple(pa.ip); -} - -std::string peer_blocked_alert_ip(peer_blocked_alert const& pa) -{ - error_code ec; - return pa.ip.to_string(ec); -} - std::string dht_announce_alert_ip(dht_announce_alert const& pa) { error_code ec; return pa.ip.to_string(ec); } -tuple incoming_connection_alert_ip(incoming_connection_alert const& ica) -{ - return endpoint_to_tuple(ica.ip); -} - -tuple dht_outgoing_get_peers_alert_ip(dht_outgoing_get_peers_alert const& a) -{ - return endpoint_to_tuple(a.ip); -} - std::string external_ip_alert_ip(external_ip_alert const& eia) { return eia.external_address.to_string(); @@ -282,7 +250,8 @@ void bind_alert() class_, noncopyable>( "peer_alert", no_init) - .add_property("ip", &peer_alert_ip) + .add_property("ip", make_getter(&peer_alert::ip + , return_value_policy())) .def_readonly("pid", &peer_alert::pid) ; class_, noncopyable>( @@ -469,7 +438,8 @@ void bind_alert() class_, noncopyable>( "peer_blocked_alert", no_init) - .add_property("ip", &peer_blocked_alert_ip) + .add_property("ip", make_getter(&peer_blocked_alert::ip + , return_value_policy())) ; class_, noncopyable>( @@ -494,7 +464,9 @@ void bind_alert() class_, noncopyable>( "external_ip_alert", no_init) - .add_property("external_address", &external_ip_alert_ip) + .add_property("external_address" + , make_getter(&external_ip_alert::external_address + , return_value_policy())) ; class_, noncopyable>( @@ -667,11 +639,12 @@ void bind_alert() class_, noncopyable>( "incoming_connection_alert", no_init) .def_readonly("socket_type", &incoming_connection_alert::socket_type) - .add_property("ip", &incoming_connection_alert_ip) + .add_property("ip", make_getter(&incoming_connection_alert::ip + , return_value_policy())) ; class_, noncopyable>( "torrent_need_cert_alert", no_init) - .def_readonly("error", &torrent_need_cert_alert::error) + .def_readonly("error", &torrent_need_cert_alert::error) ; class_, noncopyable>( @@ -692,7 +665,8 @@ void bind_alert() "dht_outgoing_get_peers_alert", no_init) .def_readonly("info_hash", &dht_outgoing_get_peers_alert::info_hash) .def_readonly("obfuscated_info_hash", &dht_outgoing_get_peers_alert::obfuscated_info_hash) - .add_property("ip", &dht_outgoing_get_peers_alert_ip) + .add_property("ip", make_getter(&dht_outgoing_get_peers_alert::ip + , return_value_policy())) ; #ifndef TORRENT_DISABLE_LOGGING diff --git a/bindings/python/src/converters.cpp b/bindings/python/src/converters.cpp index b7981ce7c..7b02c873f 100644 --- a/bindings/python/src/converters.cpp +++ b/bindings/python/src/converters.cpp @@ -3,15 +3,65 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include "boost_python.hpp" +#include "libtorrent/socket.hpp" +#include "libtorrent/address.hpp" +#include "libtorrent/error_code.hpp" +#include using namespace boost::python; +namespace bp = boost::python; +namespace lt = libtorrent; + +template +struct endpoint_to_tuple +{ + static PyObject* convert(T const& ep) + { + return incref(bp::make_tuple(ep.address().to_string(), ep.port()).ptr()); + } +}; + +template +struct tuple_to_endpoint +{ + tuple_to_endpoint() + { + converter::registry::push_back( + &convertible, &construct, type_id() + ); + } + + static void* convertible(PyObject* x) + { + if (!PyTuple_Check(x)) return NULL; + if (PyTuple_Size(x) != 2) return NULL; + if (!PyString_Check(PyTuple_GetItem(x, 0))) return NULL; + if (!PyNumber_Check(PyTuple_GetItem(x, 1))) return NULL; + lt::error_code ec; + lt::address::from_string(PyString_AsString(PyTuple_GetItem(x, 0)), ec); + if (ec) return NULL; + return x; + } + + static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) + { + void* storage = ((converter::rvalue_from_python_storage*)data) + ->storage.bytes; + + object o(borrowed(x)); + new (storage) T(lt::address::from_string( + extract(o[0])) + , extract(o[1])); + data->convertible = storage; + } +}; template struct pair_to_tuple { static PyObject* convert(const std::pair& p) { - return incref(make_tuple(p.first, p.second).ptr()); + return incref(bp::make_tuple(p.first, p.second).ptr()); } }; @@ -27,7 +77,7 @@ struct tuple_to_pair static void* convertible(PyObject* x) { - return PyTuple_Check(x) ? x: 0; + return (PyTuple_Check(x) && PyTuple_Size(x) == 2) ? x: NULL; } static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) @@ -44,8 +94,78 @@ struct tuple_to_pair } }; +template +struct vector_to_list +{ + static PyObject* convert(const std::vector& v) + { + list l; + for (int i = 0; i < v.size(); ++i) + { + l.append(v[i]); + } + return incref(l.ptr()); + } +}; + +template +struct list_to_vector +{ + list_to_vector() + { + converter::registry::push_back( + &convertible, &construct, type_id >() + ); + } + + static void* convertible(PyObject* x) + { + return PyList_Check(x) ? x: 0; + } + + static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data) + { + void* storage = ((converter::rvalue_from_python_storage< + std::vector >*)data)->storage.bytes; + + std::vector p; + int const size = PyList_Size(x); + p.reserve(size); + for (int i = 0; i < size; ++i) + { + object o(borrowed(PyList_GetItem(x, i))); + p.push_back(extract(o)); + } + std::vector* ptr = new (storage) std::vector(); + ptr->swap(p); + data->convertible = storage; + } +}; + void bind_converters() { + // C++ -> python conversions to_python_converter, pair_to_tuple >(); + to_python_converter, pair_to_tuple >(); + to_python_converter >(); + to_python_converter >(); + to_python_converter, vector_to_list >(); + to_python_converter, vector_to_list >(); + to_python_converter, vector_to_list >(); + to_python_converter, vector_to_list >(); + to_python_converter, vector_to_list >(); + to_python_converter >, vector_to_list > >(); + + // python -> C++ conversions tuple_to_pair(); + tuple_to_pair(); + tuple_to_endpoint(); + tuple_to_endpoint(); + list_to_vector(); + list_to_vector(); + list_to_vector(); + list_to_vector(); + list_to_vector(); + list_to_vector >(); } + diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index cc3c79883..08292100a 100644 --- a/bindings/python/src/session.cpp +++ b/bindings/python/src/session.cpp @@ -680,17 +680,21 @@ void bind_session() #endif // TORRENT_DISABLE_DHT #endif // TORRENT_NO_DEPRECATE +#define PROP(val) \ + make_getter(val, return_value_policy()), \ + make_setter(val, return_value_policy()) + class_("add_torrent_params") .def_readwrite("version", &add_torrent_params::version) .def_readwrite("ti", &add_torrent_params::ti) - .def_readwrite("trackers", &add_torrent_params::trackers) - .def_readwrite("tracker_tiers", &add_torrent_params::tracker_tiers) - .def_readwrite("dht_nodes", &add_torrent_params::dht_nodes) + .add_property("trackers", PROP(&add_torrent_params::trackers)) + .add_property("tracker_tiers", PROP(&add_torrent_params::tracker_tiers)) + .add_property("dht_nodes", PROP(&add_torrent_params::dht_nodes)) .def_readwrite("name", &add_torrent_params::name) .def_readwrite("save_path", &add_torrent_params::save_path) .def_readwrite("storage_mode", &add_torrent_params::storage_mode) - .def_readwrite("storage", &add_torrent_params::storage) - .def_readwrite("file_priorities", &add_torrent_params::file_priorities) +// .def_readwrite("storage", &add_torrent_params::storage) + .add_property("file_priorities", PROP(&add_torrent_params::file_priorities)) .def_readwrite("trackerid", &add_torrent_params::trackerid) .def_readwrite("url", &add_torrent_params::url) .def_readwrite("flags", &add_torrent_params::flags) @@ -710,16 +714,16 @@ void bind_session() .def_readwrite("num_complete", &add_torrent_params::num_complete) .def_readwrite("num_incomplete", &add_torrent_params::num_incomplete) .def_readwrite("num_downloaded", &add_torrent_params::num_downloaded) - .def_readwrite("http_seeds", &add_torrent_params::http_seeds) - .def_readwrite("url_seeds", &add_torrent_params::url_seeds) - .def_readwrite("peers", &add_torrent_params::peers) - .def_readwrite("banned_peers", &add_torrent_params::banned_peers) - .def_readwrite("unfinished_pieces", &add_torrent_params::unfinished_pieces) - .def_readwrite("have_pieces", &add_torrent_params::have_pieces) - .def_readwrite("verified_pieces", &add_torrent_params::verified_pieces) - .def_readwrite("piece_priorities", &add_torrent_params::piece_priorities) - .def_readwrite("merkle_tree", &add_torrent_params::merkle_tree) - .def_readwrite("renamed_files", &add_torrent_params::renamed_files) + .add_property("http_seeds", PROP(&add_torrent_params::http_seeds)) + .add_property("url_seeds", PROP(&add_torrent_params::url_seeds)) + .add_property("peers", PROP(&add_torrent_params::peers)) + .add_property("banned_peers", PROP(&add_torrent_params::banned_peers)) + .add_property("unfinished_pieces", PROP(&add_torrent_params::unfinished_pieces)) + .add_property("have_pieces", PROP(&add_torrent_params::have_pieces)) + .add_property("verified_pieces", PROP(&add_torrent_params::verified_pieces)) + .add_property("piece_priorities", PROP(&add_torrent_params::piece_priorities)) + .add_property("merkle_tree", PROP(&add_torrent_params::merkle_tree)) + .add_property("renamed_files", PROP(&add_torrent_params::renamed_files)) #ifndef TORRENT_NO_DEPRECATE .def_readwrite("uuid", &add_torrent_params::uuid) diff --git a/bindings/python/src/torrent_handle.cpp b/bindings/python/src/torrent_handle.cpp index 59a269de3..1fee602dd 100644 --- a/bindings/python/src/torrent_handle.cpp +++ b/bindings/python/src/torrent_handle.cpp @@ -301,19 +301,6 @@ void set_metadata(torrent_handle& handle, std::string const& buf) handle.set_metadata(buf.c_str(), buf.size()); } -namespace -{ - tcp::endpoint tuple_to_endpoint(tuple const& t) - { - return tcp::endpoint(address::from_string(extract(t[0])), extract(t[1])); - } -} - -void connect_peer(torrent_handle& th, tuple ip, int source) -{ - th.connect_peer(tuple_to_endpoint(ip), source); -} - #ifndef TORRENT_NO_DEPRECATE #if BOOST_VERSION > 104200 @@ -336,16 +323,6 @@ boost::shared_ptr get_torrent_info(torrent_handle const& h) #endif -void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit) -{ - th.set_peer_upload_limit(tuple_to_endpoint(ip), limit); -} - -void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit) -{ - th.set_peer_download_limit(tuple_to_endpoint(ip), limit); -} - #endif // TORRENT_NO_DEPRECAE void add_piece(torrent_handle& th, int piece, char const *data, int flags) @@ -471,18 +448,18 @@ void bind_torrent_handle() .def("download_limit", _(&torrent_handle::download_limit)) .def("set_sequential_download", _(&torrent_handle::set_sequential_download)) #ifndef TORRENT_NO_DEPRECATE - .def("set_peer_upload_limit", &set_peer_upload_limit) - .def("set_peer_download_limit", &set_peer_download_limit) + .def("set_peer_upload_limit", &torrent_handle::set_peer_upload_limit) + .def("set_peer_download_limit", &torrent_handle::set_peer_download_limit) .def("set_ratio", _(&torrent_handle::set_ratio)) .def("save_path", _(&torrent_handle::save_path)) #endif - .def("connect_peer", &connect_peer) - .def("set_max_uploads", _(&torrent_handle::set_max_uploads)) + .def("connect_peer", &torrent_handle::connect_peer, (arg("endpoint"), arg("source")=0, arg("flags")=0xd)) + .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)) #ifndef TORRENT_NO_DEPRECATE - .def("set_tracker_login", _(&torrent_handle::set_tracker_login)) + .def("set_tracker_login", &torrent_handle::set_tracker_login) #endif .def("move_storage", _(move_storage0), (arg("path"), arg("flags") = 0)) .def("info_hash", _(&torrent_handle::info_hash)) diff --git a/bindings/python/test.py b/bindings/python/test.py index 9b556f444..a050d609d 100644 --- a/bindings/python/test.py +++ b/bindings/python/test.py @@ -31,15 +31,20 @@ class test_torrent_handle(unittest.TestCase): 'info-hash': 'abababababababababab', 'name': 'test', 'save_path': '.', - 'file_priorities': [0, 1, 1]}) + 'peers': '\x01\x01\x01\x01\x00\x01\x02\x02\x02\x02\x00\x02', + 'file_priority': [0, 1, 1]}) tp = lt.read_resume_data(resume_data) self.assertEqual(tp.name, 'test') self.assertEqual(tp.info_hash, lt.sha1_hash('abababababababababab')) + self.assertEqual(tp.file_priorities, [0, 1, 1]) + self.assertEqual(tp.peers, [('1.1.1.1', 1), ('2.2.2.2', 2)]) ses = lt.session({'alert_mask': lt.alert.category_t.all_categories}) h = ses.add_torrent(tp) + h.connect_peer(('3.3.3.3', 3)) + for i in range(0, 10): alerts = ses.pop_alerts() for a in alerts: diff --git a/examples/bt-get2.cpp b/examples/bt-get2.cpp index c608752c1..1b20a377d 100644 --- a/examples/bt-get2.cpp +++ b/examples/bt-get2.cpp @@ -41,6 +41,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include +#include namespace lt = libtorrent; using clk = std::chrono::steady_clock; @@ -74,14 +76,16 @@ int main(int argc, char const* argv[]) | lt::alert::status_notification); lt::session ses(pack); - lt::add_torrent_params atp; clk::time_point last_save_resume = clk::now(); // load resume data from disk and pass it in as we add the magnet link std::ifstream ifs(".resume_file", std::ios_base::binary); ifs.unsetf(std::ios_base::skipws); - atp.resume_data.assign(std::istream_iterator(ifs) - , std::istream_iterator()); + std::vector buf{std::istream_iterator(ifs) + , std::istream_iterator()}; + + lt::error_code ec; + lt::add_torrent_params atp = lt::read_resume_data(&buf[0], buf.size(), ec); atp.url = argv[1]; atp.save_path = "."; // save in current dir ses.async_add_torrent(atp); diff --git a/simulation/libsimulator b/simulation/libsimulator index 5f7cbb8bd..0151d5c17 160000 --- a/simulation/libsimulator +++ b/simulation/libsimulator @@ -1 +1 @@ -Subproject commit 5f7cbb8bd222ed0e5cfdaffc2a2f5010fb5b4a29 +Subproject commit 0151d5c17fa3f4cf0ce518d0b8f90a23792c9b24