Use piece_sizes in KiBs
Fix bug with webseeds Fix bug with multi-level directories
This commit is contained in:
parent
4014b3fba9
commit
4ca5f9a371
|
@ -72,7 +72,7 @@ class TorrentMetadata(object):
|
||||||
self.__comment = ""
|
self.__comment = ""
|
||||||
self.__private = False
|
self.__private = False
|
||||||
self.__trackers = []
|
self.__trackers = []
|
||||||
self.__web_seeds = []
|
self.__webseeds = []
|
||||||
self.__pad_files = False
|
self.__pad_files = False
|
||||||
|
|
||||||
def save(self, torrent_path, progress=None):
|
def save(self, torrent_path, progress=None):
|
||||||
|
@ -123,17 +123,19 @@ class TorrentMetadata(object):
|
||||||
|
|
||||||
datasize = get_path_size(self.data_path)
|
datasize = get_path_size(self.data_path)
|
||||||
|
|
||||||
if not self.piece_size:
|
if self.piece_size:
|
||||||
|
piece_size = piece_size * 1024
|
||||||
|
else:
|
||||||
# We need to calculate a piece size
|
# We need to calculate a piece size
|
||||||
psize = 16384
|
psize = 16384
|
||||||
while (datasize / psize) > 1024:
|
while (datasize / psize) > 1024 and psize < 8192 * 1024:
|
||||||
psize *= 2
|
psize *= 2
|
||||||
|
|
||||||
self.piece_size = psize
|
piece_size = psize / 1024
|
||||||
|
|
||||||
# Calculate the number of pieces we will require for the data
|
# Calculate the number of pieces we will require for the data
|
||||||
num_pieces = datasize / self.piece_size
|
num_pieces = datasize / piece_size
|
||||||
torrent["info"]["piece length"] = self.piece_size
|
torrent["info"]["piece length"] = piece_size
|
||||||
|
|
||||||
# Create the info
|
# Create the info
|
||||||
if os.path.isdir(self.data_path):
|
if os.path.isdir(self.data_path):
|
||||||
|
@ -144,7 +146,8 @@ class TorrentMetadata(object):
|
||||||
for (dirpath, dirnames, filenames) in os.walk(self.data_path):
|
for (dirpath, dirnames, filenames) in os.walk(self.data_path):
|
||||||
for index, filename in enumerate(filenames):
|
for index, filename in enumerate(filenames):
|
||||||
size = get_path_size(os.path.join(self.data_path, dirpath, filename))
|
size = get_path_size(os.path.join(self.data_path, dirpath, filename))
|
||||||
p = dirpath.lstrip(self.data_path)
|
p = dirpath[len(self.data_path):]
|
||||||
|
p = p.lstrip("/")
|
||||||
p = p.split("/")
|
p = p.split("/")
|
||||||
if p[0]:
|
if p[0]:
|
||||||
p += [filename]
|
p += [filename]
|
||||||
|
@ -153,14 +156,13 @@ class TorrentMetadata(object):
|
||||||
files.append((size, p))
|
files.append((size, p))
|
||||||
# Add a padding file if necessary
|
# Add a padding file if necessary
|
||||||
if self.pad_files and (index + 1) < len(filenames):
|
if self.pad_files and (index + 1) < len(filenames):
|
||||||
left = size % self.piece_size
|
left = size % piece_size
|
||||||
if left:
|
if left:
|
||||||
p = list(p)
|
p = list(p)
|
||||||
p[-1] = "_____padding_file_" + str(padding_count)
|
p[-1] = "_____padding_file_" + str(padding_count)
|
||||||
files.append((self.piece_size - left, p))
|
files.append((piece_size - left, p))
|
||||||
padding_count += 1
|
padding_count += 1
|
||||||
|
|
||||||
|
|
||||||
# Run the progress function with 0 completed pieces
|
# Run the progress function with 0 completed pieces
|
||||||
if progress:
|
if progress:
|
||||||
progress(0, num_pieces)
|
progress(0, num_pieces)
|
||||||
|
@ -179,10 +181,10 @@ class TorrentMetadata(object):
|
||||||
fs[-1]["attr"] = "p"
|
fs[-1]["attr"] = "p"
|
||||||
else:
|
else:
|
||||||
fd = open(os.path.join(self.data_path, *path), "rb")
|
fd = open(os.path.join(self.data_path, *path), "rb")
|
||||||
r = fd.read(self.piece_size - len(buf))
|
r = fd.read(piece_size - len(buf))
|
||||||
while r:
|
while r:
|
||||||
buf += r
|
buf += r
|
||||||
if len(buf) == self.piece_size:
|
if len(buf) == piece_size:
|
||||||
pieces.append(sha(buf).digest())
|
pieces.append(sha(buf).digest())
|
||||||
# Run the progress function if necessary
|
# Run the progress function if necessary
|
||||||
if progress:
|
if progress:
|
||||||
|
@ -190,7 +192,7 @@ class TorrentMetadata(object):
|
||||||
buf = ""
|
buf = ""
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
r = fd.read(self.piece_size - len(buf))
|
r = fd.read(piece_size - len(buf))
|
||||||
fd.close()
|
fd.close()
|
||||||
|
|
||||||
if buf:
|
if buf:
|
||||||
|
@ -208,13 +210,13 @@ class TorrentMetadata(object):
|
||||||
pieces = []
|
pieces = []
|
||||||
|
|
||||||
fd = open(self.data_path, "rb")
|
fd = open(self.data_path, "rb")
|
||||||
r = fd.read(self.piece_size)
|
r = fd.read(piece_size)
|
||||||
while r:
|
while r:
|
||||||
pieces.append(sha(r).digest())
|
pieces.append(sha(r).digest())
|
||||||
if progress:
|
if progress:
|
||||||
progress(len(pieces), num_pieces)
|
progress(len(pieces), num_pieces)
|
||||||
|
|
||||||
r = fd.read(self.piece_size)
|
r = fd.read(piece_size)
|
||||||
|
|
||||||
torrent["info"]["pieces"] = "".join(pieces)
|
torrent["info"]["pieces"] = "".join(pieces)
|
||||||
|
|
||||||
|
@ -238,7 +240,7 @@ class TorrentMetadata(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if os.path.exists(path) and (os.path.isdir(path) or os.path.isfile(path)):
|
if os.path.exists(path) and (os.path.isdir(path) or os.path.isfile(path)):
|
||||||
self.__data_path = path
|
self.__data_path = os.path.abspath(path)
|
||||||
else:
|
else:
|
||||||
raise InvalidPath("No such file or directory: %s" % path)
|
raise InvalidPath("No such file or directory: %s" % path)
|
||||||
|
|
||||||
|
@ -246,21 +248,22 @@ class TorrentMetadata(object):
|
||||||
"""
|
"""
|
||||||
The size of pieces in bytes. The size must be a multiple of 16KiB.
|
The size of pieces in bytes. The size must be a multiple of 16KiB.
|
||||||
If you don't set a piece size, one will be automatically selected to
|
If you don't set a piece size, one will be automatically selected to
|
||||||
produce a torrent with less than 1024 pieces.
|
produce a torrent with less than 1024 pieces or the smallest possible
|
||||||
|
with a 8192KiB piece size.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.__piece_size
|
return self.__piece_size
|
||||||
|
|
||||||
def set_piece_size(self, size):
|
def set_piece_size(self, size):
|
||||||
"""
|
"""
|
||||||
:param size: the desired piece size in bytes
|
:param size: the desired piece size in KiBs
|
||||||
:type size: int
|
:type size: int
|
||||||
|
|
||||||
:raises InvalidPieceSize: if the piece size is not a multiple of 16KiB
|
:raises InvalidPieceSize: if the piece size is not a multiple of 16 KiB
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if size % 16384 and size:
|
if size % 16 and size:
|
||||||
raise InvalidPieceSize("Piece size must be a multiple of 16384")
|
raise InvalidPieceSize("Piece size must be a multiple of 16 KiB")
|
||||||
self.__piece_size = size
|
self.__piece_size = size
|
||||||
|
|
||||||
def get_comment(self):
|
def get_comment(self):
|
||||||
|
@ -320,7 +323,7 @@ class TorrentMetadata(object):
|
||||||
If the url ends in '.php' then it will be considered Hoffman-style, if
|
If the url ends in '.php' then it will be considered Hoffman-style, if
|
||||||
not it will be considered GetRight-style.
|
not it will be considered GetRight-style.
|
||||||
"""
|
"""
|
||||||
return self.__web_seeds
|
return self.__webseeds
|
||||||
|
|
||||||
def set_webseeds(self, webseeds):
|
def set_webseeds(self, webseeds):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue