fixes bug where priorities where lost when force-rechecking.
[libtorrent.git] / bindings / python / src / torrent_handle.cpp
blobde9ba014c1e62e119bd71d146792ffbb4b0f16fb
1 // Copyright Daniel Wallin 2006. Use, modification and distribution is
2 // subject to the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 #include <libtorrent/torrent_handle.hpp>
6 #include <boost/python.hpp>
7 #include <boost/python/tuple.hpp>
8 #include <boost/lexical_cast.hpp>
9 #include "gil.hpp"
11 using namespace boost::python;
12 using namespace libtorrent;
14 namespace
17 list url_seeds(torrent_handle& handle)
19 list ret;
20 std::set<std::string> urls;
22 allow_threading_guard guard;
23 urls = handle.url_seeds();
26 for (std::set<std::string>::iterator i(urls.begin())
27 , end(urls.end()); i != end; ++i)
28 ret.append(*i);
29 return ret;
32 list piece_availability(torrent_handle& handle)
34 list ret;
35 std::vector<int> avail;
37 allow_threading_guard guard;
38 handle.piece_availability(avail);
41 for (std::vector<int>::iterator i(avail.begin())
42 , end(avail.end()); i != end; ++i)
43 ret.append(*i);
44 return ret;
47 list piece_priorities(torrent_handle& handle)
49 list ret;
50 std::vector<int> prio;
52 allow_threading_guard guard;
53 prio = handle.piece_priorities();
56 for (std::vector<int>::iterator i(prio.begin())
57 , end(prio.end()); i != end; ++i)
58 ret.append(*i);
59 return ret;
62 std::vector<announce_entry>::const_iterator begin_trackers(torrent_handle& i)
64 allow_threading_guard guard;
65 return i.trackers().begin();
68 std::vector<announce_entry>::const_iterator end_trackers(torrent_handle& i)
70 allow_threading_guard guard;
71 return i.trackers().end();
74 } // namespace unnamed
76 list file_progress(torrent_handle& handle)
78 std::vector<size_type> p;
81 allow_threading_guard guard;
82 p.reserve(handle.get_torrent_info().num_files());
83 handle.file_progress(p);
86 list result;
88 for (std::vector<size_type>::iterator i(p.begin()), e(p.end()); i != e; ++i)
89 result.append(*i);
91 return result;
94 list get_peer_info(torrent_handle const& handle)
96 std::vector<peer_info> pi;
99 allow_threading_guard guard;
100 handle.get_peer_info(pi);
103 list result;
105 for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
106 result.append(*i);
108 return result;
111 void prioritize_pieces(torrent_handle& info, object o)
113 std::vector<int> result;
116 object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
117 while( 1 )
119 object obj = extract<object>( iter_obj.attr( "next" )() );
120 result.push_back(extract<int const>( obj ));
123 catch( error_already_set )
125 PyErr_Clear();
126 info.prioritize_pieces(result);
127 return;
131 void prioritize_files(torrent_handle& info, object o)
133 std::vector<int> result;
136 object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
137 while( 1 )
139 object obj = extract<object>( iter_obj.attr( "next" )() );
140 result.push_back(extract<int const>( obj ));
143 catch( error_already_set )
145 PyErr_Clear();
146 info.prioritize_files(result);
147 return;
152 void replace_trackers(torrent_handle& info, object trackers)
154 object iter(trackers.attr("__iter__")());
156 std::vector<announce_entry> result;
158 for (;;)
160 handle<> entry(allow_null(PyIter_Next(iter.ptr())));
162 if (entry == handle<>())
163 break;
165 result.push_back(extract<announce_entry const&>(object(entry)));
168 allow_threading_guard guard;
169 info.replace_trackers(result);
172 list get_download_queue(torrent_handle& handle)
174 using boost::python::make_tuple;
176 list ret;
178 std::vector<partial_piece_info> downloading;
181 allow_threading_guard guard;
182 handle.get_download_queue(downloading);
185 for (std::vector<partial_piece_info>::iterator i = downloading.begin()
186 , end(downloading.end()); i != end; ++i)
188 dict partial_piece;
189 partial_piece["piece_index"] = i->piece_index;
190 partial_piece["blocks_in_piece"] = i->blocks_in_piece;
191 list block_list;
192 for (int k = 0; k < i->blocks_in_piece; ++k)
194 dict block_info;
195 block_info["state"] = i->blocks[k].state;
196 block_info["num_peers"] = i->blocks[k].num_peers;
197 block_info["bytes_progress"] = i->blocks[k].bytes_progress;
198 block_info["block_size"] = i->blocks[k].block_size;
199 block_info["peer"] = make_tuple(
200 boost::lexical_cast<std::string>(i->blocks[k].peer.address()), i->blocks[k].peer.port());
201 block_list.append(block_info);
203 partial_piece["blocks"] = block_list;
205 ret.append(partial_piece);
208 return ret;
211 namespace
213 tcp::endpoint tuple_to_endpoint(tuple const& t)
215 return tcp::endpoint(address::from_string(extract<std::string>(t[0])), extract<int>(t[1]));
219 void force_reannounce(torrent_handle& th, int s)
221 th.force_reannounce(boost::posix_time::seconds(s));
224 void connect_peer(torrent_handle& th, tuple ip, int source)
226 th.connect_peer(tuple_to_endpoint(ip), source);
229 void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit)
231 th.set_peer_upload_limit(tuple_to_endpoint(ip), limit);
234 void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit)
236 th.set_peer_download_limit(tuple_to_endpoint(ip), limit);
239 void bind_torrent_handle()
241 void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;
243 int (torrent_handle::*piece_priority0)(int) const = &torrent_handle::piece_priority;
244 void (torrent_handle::*piece_priority1)(int, int) const = &torrent_handle::piece_priority;
246 #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
247 bool (torrent_handle::*resolve_countries0)() const = &torrent_handle::resolve_countries;
248 void (torrent_handle::*resolve_countries1)(bool) = &torrent_handle::resolve_countries;
249 #endif
251 return_value_policy<copy_const_reference> copy;
253 #define _ allow_threads
255 class_<torrent_handle>("torrent_handle")
256 .def("get_peer_info", get_peer_info)
257 .def("status", _(&torrent_handle::status))
258 .def("get_download_queue", get_download_queue)
259 .def("file_progress", file_progress)
260 .def("trackers", range(begin_trackers, end_trackers))
261 .def("replace_trackers", replace_trackers)
262 .def("add_url_seed", _(&torrent_handle::add_url_seed))
263 .def("remove_url_seed", _(&torrent_handle::remove_url_seed))
264 .def("url_seeds", url_seeds)
265 .def("has_metadata", _(&torrent_handle::has_metadata))
266 .def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
267 .def("is_valid", _(&torrent_handle::is_valid))
268 .def("is_seed", _(&torrent_handle::is_seed))
269 .def("is_finished", _(&torrent_handle::is_finished))
270 .def("is_paused", _(&torrent_handle::is_paused))
271 .def("pause", _(&torrent_handle::pause))
272 .def("resume", _(&torrent_handle::resume))
273 .def("clear_error", _(&torrent_handle::clear_error))
275 .def("is_auto_managed", _(&torrent_handle::is_auto_managed))
276 .def("auto_managed", _(&torrent_handle::auto_managed))
277 .def("queue_position", _(&torrent_handle::queue_position))
278 .def("queue_position_up", _(&torrent_handle::queue_position_up))
279 .def("queue_position_down", _(&torrent_handle::queue_position_down))
280 .def("queue_position_top", _(&torrent_handle::queue_position_top))
281 .def("queue_position_bottom", _(&torrent_handle::queue_position_bottom))
283 #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
284 .def("resolve_countries", _(resolve_countries0))
285 .def("resolve_countries", _(resolve_countries1))
286 #endif
287 // deprecated
288 .def("filter_piece", _(&torrent_handle::filter_piece))
289 .def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))
291 .def("piece_availability", piece_availability)
292 .def("piece_priority", _(piece_priority0))
293 .def("piece_priority", _(piece_priority1))
294 .def("prioritize_pieces", prioritize_pieces)
295 .def("piece_prioritize", piece_priorities)
296 .def("prioritize_files", prioritize_files)
297 .def("use_interface", &torrent_handle::use_interface)
298 .def("write_resume_data", _(&torrent_handle::write_resume_data))
299 .def("save_resume_data", _(&torrent_handle::save_resume_data))
300 .def("force_reannounce", _(force_reannounce0))
301 .def("force_reannounce", force_reannounce)
302 .def("scrape_tracker", _(&torrent_handle::scrape_tracker))
303 .def("name", _(&torrent_handle::name))
304 .def("set_upload_limit", _(&torrent_handle::set_upload_limit))
305 .def("upload_limit", _(&torrent_handle::upload_limit))
306 .def("set_download_limit", _(&torrent_handle::set_download_limit))
307 .def("download_limit", _(&torrent_handle::download_limit))
308 .def("set_sequential_download", _(&torrent_handle::set_sequential_download))
309 .def("set_peer_upload_limit", set_peer_upload_limit)
310 .def("set_peer_download_limit", set_peer_download_limit)
311 .def("connect_peer", connect_peer)
312 .def("set_ratio", _(&torrent_handle::set_ratio))
313 .def("save_path", _(&torrent_handle::save_path))
314 .def("set_max_uploads", _(&torrent_handle::set_max_uploads))
315 .def("set_max_connections", _(&torrent_handle::set_max_connections))
316 .def("set_tracker_login", _(&torrent_handle::set_tracker_login))
317 .def("move_storage", _(&torrent_handle::move_storage))
318 .def("info_hash", _(&torrent_handle::info_hash))
319 .def("force_recheck", _(&torrent_handle::force_recheck))