Use piece_sizes in KiBs

Fix bug with webseeds
Fix bug with multi-level directories
This commit is contained in:
Andrew Resch 2009-08-19 01:45:55 +00:00
parent 4014b3fba9
commit 4ca5f9a371
1 changed files with 25 additions and 22 deletions

View File

@ -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):
""" """