c++pythonlibtorrent

Libtorrent - Given a magnet link, how do you generate a torrent file?


I have read through the manual and I cannot find the answer. Given a magnet link I would like to generate a torrent file so that it can be loaded on the next startup to avoid redownloading the metadata. I have tried the fast resume feature, but I still have to fetch meta data when I do it and that can take quite a bit of time. Examples that I have seen are for creating torrent files for a new torrent, where as I would like to create one matching a magnet uri.


Solution

  • Solution found here:

    http://code.google.com/p/libtorrent/issues/detail?id=165#c5

    See creating torrent:

    http://www.rasterbar.com/products/libtorrent/make_torrent.html

    Modify first lines:

    file_storage fs;
    
    // recursively adds files in directories
    add_files(fs, "./my_torrent");
    
    create_torrent t(fs);
    

    To this:

    torrent_info ti = handle.get_torrent_info()
    
    create_torrent t(ti)
    

    "handle" is from here:

    torrent_handle add_magnet_uri(session& ses, std::string const& uri add_torrent_params p);
    

    Also before creating torrent you have to make sure that metadata has been downloaded, do this by calling handle.has_metadata().

    UPDATE

    Seems like libtorrent python api is missing some of important c++ api that is required to create torrent from magnets, the example above won't work in python cause create_torrent python class does not accept torrent_info as parameter (c++ has it available).

    So I tried it another way, but also encountered a brick wall that makes it impossible, here is the code:

    if handle.has_metadata():
    
        torinfo = handle.get_torrent_info()
    
        fs = libtorrent.file_storage()
        for file in torinfo.files():
            fs.add_file(file)
    
        torfile = libtorrent.create_torrent(fs)
        torfile.set_comment(torinfo.comment())
        torfile.set_creator(torinfo.creator())
    
        for i in xrange(0, torinfo.num_pieces()):
            hash = torinfo.hash_for_piece(i)
            torfile.set_hash(i, hash)
    
        for url_seed in torinfo.url_seeds():
            torfile.add_url_seed(url_seed)
    
        for http_seed in torinfo.http_seeds():
            torfile.add_http_seed(http_seed)
    
        for node in torinfo.nodes():
            torfile.add_node(node)
    
        for tracker in torinfo.trackers():
            torfile.add_tracker(tracker)
    
        torfile.set_priv(torinfo.priv())
    
        f = open(magnet_torrent, "wb")
        f.write(libtorrent.bencode(torfile.generate()))
        f.close()
    

    There is an error thrown on this line:

    torfile.set_hash(i, hash)
    

    It expects hash to be const char* but torrent_info.hash_for_piece(int) returns class big_number which has no api to convert it back to const char*.

    When I find some time I will report this missing api bug to libtorrent developers, as currently it is impossible to create a .torrent file from a magnet uri when using python bindings.

    torrent_info.orig_files() is also missing in python bindings, I'm not sure whether torrent_info.files() is sufficient.

    UPDATE 2

    I've created an issue on this, see it here: http://code.google.com/p/libtorrent/issues/detail?id=294

    Star it so they fix it fast.

    UPDATE 3

    It is fixed now, there is a 0.16.0 release. Binaries for windows are also available.