1 // Copyright Daniel Wallin & Arvid Norberg 2009. 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)
4
5 #include "boost_python.hpp"
6 #include <libtorrent/create_torrent.hpp>
7 #include <libtorrent/file_storage.hpp>
8 #include "libtorrent/torrent_info.hpp"
9 #include <libtorrent/version.hpp>
10 #include "bytes.hpp"
11 #include "gil.hpp"
12
13 using namespace boost::python;
14 using namespace lt;
15
16 #ifdef _MSC_VER
17 #pragma warning(push)
18 // warning c4996: x: was declared deprecated
19 #pragma warning( disable : 4996 )
20 #endif
21
22 namespace
23 {
set_hash(create_torrent & c,piece_index_t p,bytes const & b)24 void set_hash(create_torrent& c, piece_index_t p, bytes const& b)
25 {
26 c.set_hash(p, sha1_hash(b.arr));
27 }
28
set_file_hash(create_torrent & c,file_index_t f,bytes const & b)29 void set_file_hash(create_torrent& c, file_index_t f, bytes const& b)
30 {
31 c.set_file_hash(f, sha1_hash(b.arr));
32 }
33
34 #ifndef BOOST_NO_EXCEPTIONS
set_piece_hashes_callback(create_torrent & c,std::string const & p,boost::python::object cb)35 void set_piece_hashes_callback(create_torrent& c, std::string const& p
36 , boost::python::object cb)
37 {
38 set_piece_hashes(c, p, std::function<void(piece_index_t)>(
39 [&](piece_index_t const i) { cb(i); }));
40 }
41 #else
set_piece_hashes_callback(create_torrent & c,std::string const & p,boost::python::object cb)42 void set_piece_hashes_callback(create_torrent& c, std::string const& p
43 , boost::python::object cb)
44 {
45 error_code ec;
46 set_piece_hashes(c, p, [&](piece_index_t const i) { cb(i); }, ec);
47 }
48
set_piece_hashes0(create_torrent & c,std::string const & s)49 void set_piece_hashes0(create_torrent& c, std::string const & s)
50 {
51 error_code ec;
52 set_piece_hashes(c, s, ec);
53 }
54 #endif
55
add_node(create_torrent & ct,std::string const & addr,int port)56 void add_node(create_torrent& ct, std::string const& addr, int port)
57 {
58 ct.add_node(std::make_pair(addr, port));
59 }
60
61 #if TORRENT_ABI_VERSION == 1
add_file_deprecated(file_storage & ct,file_entry const & fe)62 void add_file_deprecated(file_storage& ct, file_entry const& fe)
63 {
64 python_deprecated("this overload of add_file() is deprecated");
65 ct.add_file(fe);
66 }
67
68 struct FileIter
69 {
70 using value_type = lt::file_entry;
71 using reference = lt::file_entry;
72 using pointer = lt::file_entry*;
73 using difference_type = int;
74 using iterator_category = std::forward_iterator_tag;
75
FileIter__anon4e8d66350111::FileIter76 FileIter(file_storage const& fs, file_index_t i) : m_fs(&fs), m_i(i) {}
77 FileIter(FileIter const&) = default;
FileIter__anon4e8d66350111::FileIter78 FileIter() : m_fs(nullptr), m_i(0) {}
operator *__anon4e8d66350111::FileIter79 lt::file_entry operator*() const
80 { return m_fs->at(m_i); }
81
operator ++__anon4e8d66350111::FileIter82 FileIter operator++() { m_i++; return *this; }
operator ++__anon4e8d66350111::FileIter83 FileIter operator++(int) { return FileIter(*m_fs, m_i++); }
84
operator ==__anon4e8d66350111::FileIter85 bool operator==(FileIter const& rhs) const
86 { return m_fs == rhs.m_fs && m_i == rhs.m_i; }
87
operator -__anon4e8d66350111::FileIter88 int operator-(FileIter const& rhs) const
89 {
90 assert(rhs.m_fs == m_fs);
91 return m_i - rhs.m_i;
92 }
93
94 FileIter& operator=(FileIter const&) = default;
95
96 file_storage const* m_fs;
97 file_index_t m_i;
98 };
99
begin_files(file_storage const & self)100 FileIter begin_files(file_storage const& self)
101 {
102 python_deprecated("__iter__ is deprecated");
103 return FileIter(self, file_index_t(0));
104 }
105
end_files(file_storage const & self)106 FileIter end_files(file_storage const& self)
107 { return FileIter(self, self.end_file()); }
108
109 #ifdef TORRENT_WINDOWS
add_file_wstring(file_storage & fs,std::wstring const & file,std::int64_t size,file_flags_t const flags,std::time_t md,std::string link)110 void add_file_wstring(file_storage& fs, std::wstring const& file, std::int64_t size
111 , file_flags_t const flags, std::time_t md, std::string link)
112 {
113 fs.add_file(file, size, flags, md, link);
114 }
115 #endif
116 #endif // TORRENT_ABI_VERSION
117
add_files_callback(file_storage & fs,std::string const & file,boost::python::object cb,create_flags_t const flags)118 void add_files_callback(file_storage& fs, std::string const& file
119 , boost::python::object cb, create_flags_t const flags)
120 {
121 add_files(fs, file, [&](std::string const& i) { return cb(i); }, flags);
122 }
123
add_file(file_storage & fs,std::string const & file,std::int64_t size,file_flags_t const flags,std::time_t md,std::string link)124 void add_file(file_storage& fs, std::string const& file, std::int64_t size
125 , file_flags_t const flags, std::time_t md, std::string link)
126 {
127 fs.add_file(file, size, flags, md, link);
128 }
129
add_tracker(create_torrent & ct,std::string url,int tier)130 void add_tracker(create_torrent& ct, std::string url, int tier)
131 {
132 ct.add_tracker(url, tier);
133 }
134
135 struct dummy13 {};
136 struct dummy14 {};
137 }
138
bind_create_torrent()139 void bind_create_torrent()
140 {
141 void (file_storage::*set_name0)(std::string const&) = &file_storage::set_name;
142 void (file_storage::*rename_file0)(file_index_t, std::string const&) = &file_storage::rename_file;
143 #if TORRENT_ABI_VERSION == 1
144 #ifdef TORRENT_WINDOWS
145 void (file_storage::*set_name1)(std::wstring const&) = &file_storage::set_name;
146 void (file_storage::*rename_file1)(file_index_t, std::wstring const&) = &file_storage::rename_file;
147 #endif
148 #endif
149
150 #ifndef BOOST_NO_EXCEPTIONS
151 void (*set_piece_hashes0)(create_torrent&, std::string const&) = &set_piece_hashes;
152 #endif
153 void (*add_files0)(file_storage&, std::string const&, create_flags_t) = add_files;
154
155 std::string const& (file_storage::*file_storage_symlink)(file_index_t) const = &file_storage::symlink;
156 sha1_hash (file_storage::*file_storage_hash)(file_index_t) const = &file_storage::hash;
157 std::string (file_storage::*file_storage_file_path)(file_index_t, std::string const&) const = &file_storage::file_path;
158 string_view (file_storage::*file_storage_file_name)(file_index_t) const = &file_storage::file_name;
159 std::int64_t (file_storage::*file_storage_file_size)(file_index_t) const = &file_storage::file_size;
160 std::int64_t (file_storage::*file_storage_file_offset)(file_index_t) const = &file_storage::file_offset;
161 file_flags_t (file_storage::*file_storage_file_flags)(file_index_t) const = &file_storage::file_flags;
162
163 #if TORRENT_ABI_VERSION == 1
164 file_entry (file_storage::*at)(int) const = &file_storage::at;
165 #endif
166
167 // TODO: 3 move this to its own file
168 {
169 scope s = class_<file_storage>("file_storage")
170 .def("is_valid", &file_storage::is_valid)
171 .def("add_file", add_file, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
172 .def("num_files", &file_storage::num_files)
173 #if TORRENT_ABI_VERSION == 1
174 .def("at", depr(at))
175 .def("add_file", add_file_deprecated, arg("entry"))
176 .def("__iter__", boost::python::range(&begin_files, &end_files))
177 .def("__len__", depr(&file_storage::num_files))
178 #ifdef TORRENT_WINDOWS
179 .def("add_file", add_file_wstring, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
180 #endif
181 #endif // TORRENT_ABI_VERSION
182 .def("hash", file_storage_hash)
183 .def("symlink", file_storage_symlink, return_value_policy<copy_const_reference>())
184 .def("file_path", file_storage_file_path, (arg("idx"), arg("save_path") = ""))
185 .def("file_name", file_storage_file_name)
186 .def("file_size", file_storage_file_size)
187 .def("file_offset", file_storage_file_offset)
188 .def("file_flags", file_storage_file_flags)
189
190 .def("total_size", &file_storage::total_size)
191 .def("set_num_pieces", &file_storage::set_num_pieces)
192 .def("num_pieces", &file_storage::num_pieces)
193 .def("set_piece_length", &file_storage::set_piece_length)
194 .def("piece_length", &file_storage::piece_length)
195 .def("piece_size", &file_storage::piece_size)
196 .def("set_name", set_name0)
197 .def("rename_file", rename_file0)
198 #if TORRENT_ABI_VERSION == 1
199 #ifdef TORRENT_WINDOWS
200 .def("set_name", depr(set_name1))
201 .def("rename_file", depr(rename_file1))
202 #endif
203 #endif
204 .def("name", &file_storage::name, return_value_policy<copy_const_reference>())
205 ;
206
207 s.attr("flag_pad_file") = file_storage::flag_pad_file;
208 s.attr("flag_hidden") = file_storage::flag_hidden;
209 s.attr("flag_executable") = file_storage::flag_executable;
210 s.attr("flag_symlink") = file_storage::flag_symlink;
211 }
212
213 {
214 scope s = class_<dummy13>("file_flags_t");
215 s.attr("flag_pad_file") = file_storage::flag_pad_file;
216 s.attr("flag_hidden") = file_storage::flag_hidden;
217 s.attr("flag_executable") = file_storage::flag_executable;
218 s.attr("flag_symlink") = file_storage::flag_symlink;
219 }
220
221 {
222 scope s = class_<create_torrent>("create_torrent", no_init)
223 .def(init<file_storage&>())
224 .def(init<torrent_info const&>(arg("ti")))
225 .def(init<file_storage&, int, int, create_flags_t>((arg("storage"), arg("piece_size") = 0
226 , arg("pad_file_limit") = -1, arg("flags") = lt::create_torrent::optimize_alignment)))
227
228 .def("generate", &create_torrent::generate)
229
230 .def("files", &create_torrent::files, return_internal_reference<>())
231 .def("set_comment", &create_torrent::set_comment)
232 .def("set_creator", &create_torrent::set_creator)
233 .def("set_hash", &set_hash)
234 .def("set_file_hash", &set_file_hash)
235 .def("add_url_seed", &create_torrent::add_url_seed)
236 .def("add_http_seed", &create_torrent::add_http_seed)
237 .def("add_node", &add_node)
238 .def("add_tracker", add_tracker, (arg("announce_url"), arg("tier") = 0))
239 .def("set_priv", &create_torrent::set_priv)
240 .def("num_pieces", &create_torrent::num_pieces)
241 .def("piece_length", &create_torrent::piece_length)
242 .def("piece_size", &create_torrent::piece_size)
243 .def("priv", &create_torrent::priv)
244 .def("set_root_cert", &create_torrent::set_root_cert, (arg("pem")))
245 .def("add_collection", &create_torrent::add_collection)
246 .def("add_similar_torrent", &create_torrent::add_similar_torrent)
247
248 ;
249
250 s.attr("optimize_alignment") = create_torrent::optimize_alignment;
251 s.attr("merkle") = create_torrent::merkle;
252 s.attr("modification_time") = create_torrent::modification_time;
253 s.attr("symlinks") = create_torrent::symlinks;
254 }
255
256 {
257 scope s = class_<dummy14>("create_torrent_flags_t");
258 #if TORRENT_ABI_VERSION == 1
259 s.attr("optimize") = create_torrent::optimize;
260 #endif
261 s.attr("optimize_alignment") = create_torrent::optimize_alignment;
262 s.attr("merkle") = create_torrent::merkle;
263 s.attr("modification_time") = create_torrent::modification_time;
264 s.attr("symlinks") = create_torrent::symlinks;
265 }
266
267 def("add_files", add_files0, (arg("fs"), arg("path"), arg("flags") = 0));
268 def("add_files", add_files_callback, (arg("fs"), arg("path")
269 , arg("predicate"), arg("flags") = 0));
270 def("set_piece_hashes", set_piece_hashes0);
271 def("set_piece_hashes", set_piece_hashes_callback);
272
273 }
274
275 #ifdef _MSC_VER
276 #pragma warning(pop)
277 #endif
278
279