rndusr / torf

Python module to create, parse and edit torrent files and magnet links
GNU General Public License v3.0
179 stars 18 forks source link

How to modify the torrent file? #16

Closed dvector89 closed 4 years ago

dvector89 commented 4 years ago

Hi @rndusr,

Thanks for your hard working.
I want to download several files in a torrent which contains a lot of files.
Can a torrent file be modified by torf? I want to remove some files in the torrent.

a test

from torf import Torrent                                                  

torrent = Torrent.read('./temp/old.torrent')                              
torrent.files = [torrent.files[0], torrent.files[2], torrent.files[-1]]   
torrent.write('./temp/new.torrent')

but the output is:

Traceback (most recent call last): File "test.py", line 5, in torrent.write('./temp/new.torrent') File "D:\work\02work\work\009torrent\rw-torrent\venv\lib\site-packages\torf_torrent.py", line 1477, in write self.write_stream(content, validate=validate) File "D:\work\02work\work\009torrent\rw-torrent\venv\lib\site-packages\torf_torrent.py", line 1448, in write_stream content = self.dump(validate=validate) File "D:\work\02work\work\009torrent\rw-torrent\venv\lib\site-packages\torf_torrent.py", line 1435, in dump self.validate() File "D:\work\02work\work\009torrent\rw-torrent\venv\lib\site-packages\torf_torrent.py", line 1331, in validate utils.assert_type(md, ('info', 'pieces'), (abc.ByteString,), must_exist=True) File "D:\work\02work\work\009torrent\rw-torrent\venv\lib\site-packages\torf_utils.py", line 718, in assert_type raise error.MetainfoError(f'Missing {key!r} in {keychain_str}') torf._errors.MetainfoError: Invalid metainfo: Missing 'pieces' in ['info']

Looking forward to your reply.

dvector89 commented 4 years ago

@rr- @sinic @PyR8zdl

rndusr commented 4 years ago

You need to torrent.generate() before you can torrent.write().

Also, you can modify torrent.files like any regular list, so you can do stuff like del torrent.files[3] or torrent.files.remove("file/path").

dvector89 commented 4 years ago

You need to torrent.generate() before you can torrent.write(). Also, you can modify torrent.files like any regular list, so you can do stuff like del torrent.files[3] or torrent.files.remove("file/path").

Thanks for your reply. It seems that i have a wrong understanding for torf.

add torrent.generate

I tried torrent.generate() . But there are some errors. The code and error information are below:

from torf import Torrent

torrent = Torrent.read('./temp/old.torrent')
#torrent.files = [torrent.files[0], torrent.files[2], torrent.files[-1]]
del torrent.files[3]
torrent.generate()
torrent.write('./temp/new.torrent')

Traceback (most recent call last): File "test.py", line 6, in torrent.generate() File "D:\work\02work\work\009torrent\rw-torrent\venv\lib\site-packages\torf_torrent.py", line 1016, in generate raise RuntimeError('generate() called with no path specified') RuntimeError: generate() called with no path specified

add path

I add a path to torrent:

from torf import Torrent

torrent = Torrent.read('./temp/old.torrent')
#torrent.files = [torrent.files[0], torrent.files[2], torrent.files[-1]]
del torrent.files[3]
torrent.path = 'temp'
torrent.generate()
print(torrent.files)
torrent.write('./temp/new.torrent')

But the new.torrent contains the files which are in my computer, instead of the files in the old.torrent. The information is below:

λ ls temp/ k old.torrent (venv) admin@DESKTOP-ILNMBPV /d/work/02work/work/009torrent/rw-torrent λ python test.py [File('temp\k', size=95829), File('temp\old.torrent', size=95829)] (venv) admin@DESKTOP-ILNMBPV /d/work/02work/work/009torrent/rw-torrent

what's more, if the path does not exist, the code and error information are below:

from torf import Torrent

torrent = Torrent.read('./temp/old.torrent')
#torrent.files = [torrent.files[0], torrent.files[2], torrent.files[-1]]
del torrent.files[3]
torrent.path = 'temp_not_exist'
torrent.generate()
print(torrent.files)
torrent.write('./temp/new.torrent')

Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\os.py", line 350, in walk scandir_it = scandir(top) FileNotFoundError: [WinError 3] The system cannot find the specified path: 'temp_not_exist'

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "test.py", line 6, in torrent.path = 'temp_not_exist' File "D:\work\02work\work\009torrent\rw-torrent\venv\lib\site-packages\torf_torrent.py", line 178, in path for fp in utils.list_files(basepath)) File "D:\work\02work\work\009torrent\rw-torrent\venv\lib\site-packages\torf_utils.py", line 138, in list_files for dirpath, dirnames, filenames in os.walk(path, onerror=onerror): File "C:\ProgramData\Anaconda3\lib\os.py", line 353, in walk onerror(error) File "D:\work\02work\work\009torrent\rw-torrent\venv\lib\site-packages\torf_utils.py", line 136, in onerror getattr(exc, 'filename', None)) torf._errors.ReadError: temp_not_exist: No such file or directory

my goal

I want to download several files in a torrent which contains a lot of files. I want to remove some files in the torrent. So can a torrent file be modified by torf?

rndusr commented 4 years ago

You can't create a torrent from files you don't have.

If you download a torrent and remove files from it, you are creating a new torrent. That means concatenating all the file contents into a single stream, hashing torrent.piece_sized chunks of that and storing the hashes in the torrent so clients can validate downloaded chunks.

torrent.path must contain all the files in torrent.files.

https://wiki.theory.org/index.php/BitTorrentSpecification#Metainfo_File_Structure

dvector89 commented 4 years ago

Thanks @rndusr . So I can only download the specific files in the original torrent, instead of making a new torrent from the original torrent.

rndusr commented 4 years ago

Correct. You can create a new torrent after you (partially) downloaded the files in the original torrent.