72 lines
2.1 KiB
Python
72 lines
2.1 KiB
Python
import time
|
|
import hashlib
|
|
|
|
import bencode
|
|
import resumablehashlib
|
|
|
|
from app import app
|
|
|
|
|
|
TRACKER_ANNOUNCE_URL = app.config.get('BT_TRACKER_ANNOUNCE_URL')
|
|
NAMING_SALT = app.config.get('BT_NAMING_SALT')
|
|
|
|
def private_torrent_name(user_uuid, blob_uuid):
|
|
return hashlib.sha256(blob_uuid + user_uuid + NAMING_SALT).hexdigest()
|
|
|
|
|
|
def make_torrent(name, webseed, length, piece_length, pieces):
|
|
return bencode.bencode({
|
|
'announce': TRACKER_ANNOUNCE_URL,
|
|
'url-list': webseed,
|
|
'encoding': 'UTF-8',
|
|
'created by': 'Quay Container Registry',
|
|
'creation date': int(time.time()),
|
|
'info': {
|
|
'name': name,
|
|
'length': length,
|
|
'piece length': piece_length,
|
|
'pieces': pieces,
|
|
},
|
|
})
|
|
|
|
|
|
class PieceHasher(object):
|
|
def __init__(self, piece_size, starting_offset, starting_piece_hash_bytes, hash_fragment_to_resume):
|
|
if not isinstance(starting_offset, (int, long)):
|
|
raise TypeError('starting_offset must be an integer')
|
|
elif not isinstance(piece_size, (int, long)):
|
|
raise TypeError('piece_size must be an integer')
|
|
|
|
self._current_offset = starting_offset
|
|
self._piece_size = piece_size
|
|
self._hash_fragment = hash_fragment_to_resume
|
|
self._piece_hashes = bytearray(starting_piece_hash_bytes)
|
|
|
|
def update(self, buf):
|
|
buf_offset = 0
|
|
while buf_offset < len(buf):
|
|
buf_bytes_to_hash = buf[0:self._piece_length_remaining()]
|
|
to_hash_len = len(buf_bytes_to_hash)
|
|
|
|
if self._piece_offset() == 0 and to_hash_len > 0 and self._current_offset > 0:
|
|
# We are opening a new piece
|
|
self._piece_hashes.extend(self._hash_fragment.digest())
|
|
self._hash_fragment = resumablehashlib.sha1()
|
|
|
|
self._hash_fragment.update(buf_bytes_to_hash)
|
|
self._current_offset += to_hash_len
|
|
buf_offset += to_hash_len
|
|
|
|
def _piece_length_remaining(self):
|
|
return self._piece_size - (self._current_offset % self._piece_size)
|
|
|
|
def _piece_offset(self):
|
|
return self._current_offset % self._piece_size
|
|
|
|
@property
|
|
def piece_hashes(self):
|
|
return self._piece_hashes
|
|
|
|
@property
|
|
def hash_fragment(self):
|
|
return self._hash_fragment
|