Search code examples
pythonbittorrentlibtorrentmagnet-urilibtorrent-rasterbar

Python libtorrent creates empty torrent with magnet link


I tried to download a torrent (the specific .torrent file) given only an info_hash. I know this was discussed here before, I even searched and modified my code accordingly. The result is the following:

import libtorrent as lt
import time
import sys
import bencode

ses = lt.session()
ses.listen_on(6881, 6891)
params = {
    'save_path': '.',
    'storage_mode': lt.storage_mode_t(2),
    'paused': False,
    'auto_managed': True,
    'duplicate_is_error': True
    }

info_hash = "2B3AF3B4977EB5485D39F96FE414729530F48386"
link = "magnet:?xt=urn:btih:" + info_hash

h = lt.add_magnet_uri(ses, link, params)

ses.add_dht_router("router.utorrent.com", 6881)
ses.add_dht_router("router.bittorrent.com", 6881)
ses.add_dht_router("dht.transmissionbt.com", 6881)
ses.start_dht()

while (not h.has_metadata()):
    time.sleep(1)

torinfo = h.get_torrent_info()

fs = lt.file_storage()
for f in torinfo.files():
  fs.add_file(f)
torfile = lt.create_torrent(fs)
torfile.set_comment(torinfo.comment())
torfile.set_creator(torinfo.creator())

f = open("torrentfile.torrent", "wb")
f.write(lt.bencode(torfile.generate()))
f.close()

This produces a torrent file, that cannot be loaded by transmission. It lacks trackers as well as the real pieces (creates \x00 instead of the actual pieces).
The following line would save the pieces, but still lacks the trackers and is not able to be opened by transmission:

f = open("torrentfile.torrent", "wb")
f.write(lt.bencode(torinfo.metadata()))
f.close()

How can I create a torrent, that looks like the actual torrent, by just using the magnet link (as stated in the code)?
(I am using Ubuntu 15.04 x64 with libtorrent 0.16.18-1)

I am not illegally downloading the file behind the torrent- however, I have the torrent to be compared to the torrent downloaded by my script.


Solution

  • You're not setting piece hashes and the piece size (of the file_storage object). See the documentation.

    However, a simpler and more robust way of creating a .torrent file is to use the create_torrent constructor that directly takes a torrent_info object. i.e.:

    torfile = lt.create_torrent(h.get_torrent_info())
    f = open("torrentfile.torrent", "wb")
    f.write(lt.bencode(torfile.generate()))
    f.close()