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