diff --git a/Makefile.am b/Makefile.am index c3978e913..031c860ae 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,6 +11,7 @@ docs/python_binding.rst docs/python_binding.html \ docs/udp_tracker_protocol.rst docs/udp_tracker_protocol.html \ docs/client_test.rst docs/client_test.html \ docs/dht_extensions.html docs/dht_extensions.rst \ +docs/make_torrent.html docs/make_torrent.rst \ docs/examples.html docs/examples.rst \ docs/features.html docs/features.rst \ docs/arctic_thumb.png \ diff --git a/docs/make_torrent.html b/docs/make_torrent.html new file mode 100644 index 000000000..f6ea66331 --- /dev/null +++ b/docs/make_torrent.html @@ -0,0 +1,267 @@ + + + + + + +creating torrents + + + + + + + +
+
+
+ +
+ +
+

creating torrents

+ +
+ + +
+ + +++ + + + +
Author:Arvid Norberg, arvid@rasterbar.com
+ +
+

overview

+

This section describes the functions and classes that are used +to create torrent files. It is a layered API with low level classes +and higher level convenience functions. A torrent is created in 4 +steps:

+
    +
  1. first the files that will be part of the torrent are determined.
  2. +
  3. the torrent properties are set, such as tracker url, web seeds, +DHT nodes etc.
  4. +
  5. Read through all the files in the torrent, SHA-1 all the data +and set the piece hashes.
  6. +
  7. The torrent is bencoded into a file or buffer.
  8. +
+

If there are a lot of files and or deep directoy hierarchies to +traverse, step one can be time consuming.

+

Typically step 3 is by far the most time consuming step, since it +requires to read all the bytes from all the files in the torrent.

+

All of these classes and functions are declared by including +libtorrent/create_torrent.hpp.

+
+
+

high level example

+
+file_storage fs;
+
+// recursively adds files in directories
+add_files(fs, "./my_torrent");
+
+create_torrent t(fs);
+t.add_tracker("http://my.tracker.com/announce");
+t.set_creator("libtorrent example");
+
+// reads the files and calculates the hashes
+set_piece_hashes(t, ".");
+
+ofstream out("my_torrent.torrent", std::ios_base::binary);
+bencode(std::ostream_iterator<char>(out), t.generate());
+
+
+
+

add_files

+
+
+template <class Pred>
+void add_files(file_storage& fs, boost::filesystem::path const& path, Pred p);
+
+void add_files(file_storage& fs, boost::filesystem::path const& path);
+
+
+

Adds the file specified by path to the file_storage object. In case path +refers to a diretory, files will be added recursively from the directory.

+

If specified, the predicate p is called once for every file and directory that +is encountered. files for which p returns true are added, and directories for +which p returns true are traversed. p must have the following signature:

+
+bool Pred(boost::filesystem::path const& p);
+
+

The path that is passed in to the predicate is the full path of the file or +directory. If no predicate is specified, all files are added, and all directories +are traveresed.

+

The ".." directory is never traversed.

+
+
+

set_piece_hashes()

+
+
+template <class Fun>
+void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, Fun f);
+
+void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p);
+
+
+

This function will assume that the files added to the torrent file exists at path +p, read those files and hash the content and set the hashes in the create_torrent +object. The optional function f is called in between every hash that is set. f +must have the following signature:

+
+void Fun(int);
+
+
+
+

file_storage

+

The file_storage class represents a file list and the piece +size. Everything necessary to interpret a regular bittorrent storage +file structure. Its synopsis:

+
+class file_storage
+{
+public:
+
+        bool is_valid() const;
+
+        void add_file(file_entry const& e);
+        void add_file(fs::path const& p, size_type size);
+        void rename_file(int index, std::string const& new_filename);
+
+        std::vector<file_slice> map_block(int piece, size_type offset
+                , int size) const;
+        peer_request map_file(int file, size_type offset, int size) const;
+
+        typedef std::vector<file_entry>::const_iterator iterator;
+        typedef std::vector<file_entry>::const_reverse_iterator reverse_iterator;
+
+        iterator begin() const;
+        iterator end() const;
+        reverse_iterator rbegin();
+        reverse_iterator rend() const;
+        int num_files() const;
+
+        file_entry const& at(int index) const;
+
+        size_type total_size() const;
+        void set_num_pieces(int n);
+        int num_pieces() const;
+        void set_piece_length(int l);
+        int piece_length() const;
+        int piece_size(int index) const;
+
+        void set_name(std::string const& n);
+        const std::string& name() const;
+
+        void swap(file_storage& ti);
+}
+
+
+
+

create_torrent

+

The create_torrent class has the following synopsis:

+
+struct create_torrent
+{
+        create_torrent(file_storage& fs, int piece_size);
+        create_torrent(file_storage& fs);
+        create_torrent(torrent_info const& ti);
+
+        entry generate() const;
+
+        file_storage const& files() const;
+
+        void set_comment(char const* str);
+        void set_creator(char const* str);
+        void set_hash(int index, sha1_hash const& h);
+        void add_url_seed(std::string const& url);
+        void add_node(std::pair<std::string, int> const& node);
+        void add_tracker(std::string const& url, int tier = 0);
+
+        int num_pieces() const;
+        int piece_length() const;
+        int piece_size(int i) const;
+};
+
+
+

create_torrent()

+
+
+create_torrent(file_storage& fs, int piece_size);
+create_torrent(file_storage& fs);
+create_torrent(torrent_info const& ti);
+
+
+

The contrstructor that does not take a piece_size will calculate +a piece size such that the torrent file is roughly 40 kB.

+

The overlad that takes a torrent_info object will make a verbatim +copy of its info dictionary (to preserve the info-hash). The copy of +the info dictionary will be used by generate(). This means +that none of the member functions of create_torrent that affects +the content of the info dictionary (such as set_hash()), will not +have any affect.

+
+
+

generate()

+
+
+entry generate() const;
+
+
+

This function will generate the .torrent file as a bencode tree. In order to +generate the flat file, use the bencode() function.

+

It may be useful to add custom entries to the torrent file before bencoding it +and saving it to disk.

+
+
+
+ +
+ + +
+ + diff --git a/docs/makefile b/docs/makefile index 86d2f5cbe..4c97a8de9 100644 --- a/docs/makefile +++ b/docs/makefile @@ -11,6 +11,7 @@ TARGETS = index \ features \ examples \ extension_protocol \ + make_torrent \ dht_extensions \ libtorrent_plugins \ python_binding \ diff --git a/docs/python_binding.html b/docs/python_binding.html index 7d7f6ce08..1e3a225a4 100644 --- a/docs/python_binding.html +++ b/docs/python_binding.html @@ -85,6 +85,9 @@ python setup.py install +

This requires that you have built and install libtorrent first. The setup.py relies +on pkg-config to be installed as well. It invokes pkg-config in order to link +against libtorrent.

building using boost build