Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- '''
- Usage:
- torrent.py [options] <file> [--url_list <url>...]
- torrent.py -h | --help
- -t, --tracker <url> Tracker address
- [default: udp://tracker.openbittorrent.com:80/announce]
- -u, --url_list <url> GetRight webseeds
- -p, --min_pieces <min> [default: 1]
- -P, --max_pieces <max> [default: 0]
- -l, --min_length <min> [default: 16]
- -L, --max_length <max> [default: 0]
- -h, --help Help file
- The lengths need to be a multiple of 16 since that is the smallest
- unit torrent transports.
- This is my hack at Robert Nitsch's code to get a command line
- torrenter that I can use. I've added webseed support, docopt,
- progress, and some piece/length control.
- http://www.robertnitsch.de/projects:py3createtorrent
- '''
- from py3bencode import bencode
- from docopt import docopt
- import os, hashlib, sys, requests
- def auto_length(length, min_p, max_p, min_l, max_l):
- assert length > 0
- piece_length = 2**((length.bit_length()+8)//2)
- pieces = length / piece_length
- assert min_p >= 1
- while pieces < min_p:
- piece_length /= 2
- pieces *= 2
- if max_p > 0:
- while pieces > max_p:
- piece_length *= 2
- pieces /= 2
- assert min_l >= 16384
- assert min_l % 16384 == 0
- assert max_l % 16384 == 0
- if piece_length < min_l:
- piece_length = min_l
- if max_l > 0 and piece_length > max_l:
- piece_length = max_l
- return piece_length
- def torrent_dict(announce, file, url_list, min_p, max_p, min_l, max_l):
- name = os.path.basename(file)
- length = os.path.getsize(file)
- piece_length = auto_length(length, min_p, max_p, min_l, max_l)
- pieces = bytearray()
- num = length // piece_length + 1
- with open(file, 'rb') as f:
- i = 0
- print('Hashing ... ')
- for piece in iter((lambda:f.read(piece_length)),b''):
- pieces += hashlib.sha1(piece).digest()
- i += 1
- sys.stdout.write('\r{}/{}'.format(i,num))
- d = {
- 'announce': announce,
- 'info':
- {
- 'name': name,
- 'length': length,
- 'piece length': piece_length,
- 'pieces': pieces
- }
- }
- if url_list:
- if len(url_list) is 1:
- d['url-list'] = url_list[0]
- else:
- d['url-list'] = url_list
- return d
- def torrent_bencode(a, f, u, p, P, l, L):
- return bencode(torrent_dict(a, f, u, p, P, l, L))
- def write_torrent(a, f, u, p=1, P=0, l=16384, L=0):
- with open(f + '.torrent', 'wb') as file:
- file.write(bencode(torrent_dict(a, f, u, p, P, l, L)))
- def try_int(s, default):
- try:
- i = int(s)
- except ValueError:
- print('[warning] pieces and length must be integers, using default values')
- i = default
- return i
- def try_file(f):
- if os.path.isfile(f):
- return os.path.abspath(f)
- else:
- sys.exit("[error] '{}' isn't a file".format(f))
- def try_url(u):
- try:
- r = requests.head(u.strip())
- r.raise_for_status()
- except Exception as e:
- print("[warning] url '{}' had an error: {}".format(u, e))
- if __name__ == '__main__':
- arguments = docopt(__doc__)
- announce = arguments['--tracker']
- file = try_file(arguments['<file>'])
- url_list = arguments['--url_list']
- min_p = try_int(arguments['--min_pieces'], 1)
- max_p = try_int(arguments['--max_pieces'], 0)
- min_l = try_int(arguments['--min_length'], 16) * 1024
- max_l = try_int(arguments['--max_length'], 0) * 1024
- write_torrent(announce, file, url_list, min_p, max_p, min_l, max_l)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement