weast
weast

Reputation: 1

How can i extract the name of the directory a given `.torrent` would create from the underlying bencode data?

What is the simplest way to parse bencode in python to get the directory name that a .torrent file produces?

.torrent files names and the directory names they produce are rarely if ever the same. I am working on an app that hands over a .torrent file to a server and to retrieve it when it has completed. I need to know the name of the file the .torrent file creates without actually initiating the download. I cannot perform any operations server-side.

previously I achieved this with the rather bulky dependency of a full torrent client (libtorrent). This is no longer feasible. I am sadly not smart enough to understand how libtorrent solves this, but the command to get the filename is:

import libtorrent as lt

TORRENT = <direntry item that is a .torrent file>


def getFileNamefromTorrent(torrent):
    """must be a direntry item. Gets the name of the torrent's finished folder from the .torrent file."""
    torrent_info = lt.torrent_info(torrent.path)
    return torrent_info.name()

print(getFileNameFromTorrent(TORRENT)

My first attempts have been parsing the bencode, where i can get the file names :

import bencode
import itertools

TORRENT = "path to .torrent file"

def getTorrentFilenames(filename):
    with open(filename, "rb") as fin:
        torrent = bencode.bdecode(fin.read())
        
    return itertools.chain(*(f["path"] for f in torrent["info"]["files"]))

for file in getTorrentFilenames(TORRENT) 

this gives me the files that are inside the torrent, but does not provide the name of the directory it puts them in.

i tried access different elements in the dict(like name instead of files but that produce a typeError

Traceback (most recent call last):
  File "torrent_management.py", line 65, in <module>
    test = listTorrent(TESTTORRENT)
  File "torrent_management.py", line 63, in listTorrent
    return itertools.chain(*(f["path"] for f in torrent["info"]["name"]))
  File "torrent_management.py", line 63, in <genexpr>
    return itertools.chain(*(f["path"] for f in torrent["info"]["name"]))
TypeError: string indices must be integers

I apologize if I am overlooking something very obvious. The BitTorrent .torrent metainfo file structure mentions there is a "name" in the dictionary.

I have provided a minimum working example in the above code section that runs in python. the dictonary should provide the name of the torrent encoded in bencode, but it is not a valid dict item.

Upvotes: -1

Views: 769

Answers (1)

weast
weast

Reputation: 1

I found out where I was going wrong.

the correct, minimal solution is as follows: (if you are having problems with using the bencode library, make sure you use bencode.py and not bencode .

import bencode

def getTorrentName(filename):
    """List name of a torrent from the corresponding .torrent file."""
    with open(filename, "rb") as fin:
        torrent = bencode.bdecode(fin.read())
    
    return torrent["info"]["name"]

torrent = <location of .torrent>

torrentName = getTorrentName(torrent)

Also, apparently the "name" key is strictly advisory. I am not sure if the "name" key is used to produce the corresponding directory or it just correlates with it. would love to know!

Upvotes: 0

Related Questions