0

Would like to get this script working with python3 (Python 3.10.4): https://stackoverflow.com/a/2573715/2394635

It would be where it says Full code bellow:

I don't put the code directly because I get the stackoverflow notification It looks like your post is mostly code; please add some more details.

I've used the pip script 2to3, with this resulting code:

import sys, os, hashlib, io, bencode

def pieces_generator(info):
    """Yield pieces from download file(s)."""
    piece_length = info['piece length']
    if 'files' in info: # yield pieces from a multi-file torrent
        piece = ""
        for file_info in info['files']:
            path = os.sep.join([info['name']] + file_info['path'])
            print(path)
            sfile = open(path.decode('UTF-8'), "rb")
            while True:
                piece += sfile.read(piece_length-len(piece))
                if len(piece) != piece_length:
                    sfile.close()
                    break
                yield piece
                piece = ""
        if piece != "":
            yield piece
    else: # yield pieces from a single file torrent
        path = info['name']
        print(path)
        sfile = open(path.decode('UTF-8'), "rb")
        while True:
            piece = sfile.read(piece_length)
            if not piece:
                sfile.close()
                return
            yield piece

def corruption_failure():
    """Display error message and exit"""
    print("download corrupted")
    exit(1)

def main():
    # Open torrent file
    torrent_file = open(sys.argv[1], "rb")
    metainfo = bencode.bdecode(torrent_file.read())
    info = metainfo['info']
    pieces = io.StringIO(info['pieces'])
    # Iterate through pieces
    for piece in pieces_generator(info):
        # Compare piece hash with expected hash
        piece_hash = hashlib.sha1(piece).digest()
        if (piece_hash != pieces.read(20)):
            corruption_failure()
    # ensure we've read all pieces 
    if pieces.read():
        corruption_failure()

if __name__ == "__main__":
    main()

However, keeps failing:

% python3 extract-torrent.py archive.torrent 
Traceback (most recent call last):
  File "/home/smt/Documents/extract-torrent-py3.py", line 1, in <module>
    import sys, os, hashlib, io, bencode
  File "/home/smt/.local/lib/python3.10/site-packages/bencode.py", line 73, in <module>
    from types import StringType, IntType, LongType, DictType, ListType, TupleType
ImportError: cannot import name 'StringType' from 'types' (/usr/lib/python3.10/types.py)

Any help?

2
  • 2
    You're importing a package or module, bencode, that is not Python 3.10 compatible. That is causing your error. Given that that package latest release dates from 2010, that is not surprising. Note that the linked answer (& code) is also from 2010. Commented Aug 20, 2022 at 5:00
  • @9769953 thanks a lot, with python2 it works. I had to install python-pip instead of default python3-pip to get it working, also run pip2 install bencode. Commented Aug 20, 2022 at 11:55

1 Answer 1

1

As @9769953 pointed out, bencode is not compatible with Python 3.10. You could try bencodepy which claims to be compatible with both Python 2 and 3.

From the website:

  1. Install with pip install bencode.py
  2. Import with import bencodepy
Sign up to request clarification or add additional context in comments.

1 Comment

bencodepy does not work straightforward, however the python2 version work, however it only test if hash matches for those files from the torrent that are already downloaded, otherwise throws error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.