def download(self, sm, target_file, overwrite = False):
remote_chunk = "chunks/%s" % self.get_filename()
tmp_file = target_file + ".download"
# if file exists, try
if os.path.exists(target_file):
# overwrite check
if not overwrite:
raise ChirriException("Chunk file '%s' already exists." % target_file)
# yep! chunk is already on disk.. decide what to do...
eh = chirribackup.crypto.hash_file(target_file)
if eh.hash != h:
# hashes doesn't match... it is surely an old partial chunk of
# a previous restore operation (cancelled), delete it from disk
logger.warning("Old tmp download '%s' found but corrupt. Reloading again.")
os.unlink(target_file)
else:
# hashes match, so it is the file that we need -- continue as
# usual without downloading anything
logger.info("Found previous temp download '%s' with matching hash. Recycling it.")
return
# ok... download raw chunk
sm.download_file(remote_chunk, tmp_file)
# decompress it
if self.compression is None:
os.rename(tmp_file, target_file)
else:
try:
decompressor = chirribackup.compression.Decompressor(self.compression, target_file)
sh = chirribackup.crypto.ChirriHasher()
with open(tmp_file, 'rb') as ifile:
buf = ifile.read(READ_BLOCKSIZE)
while len(buf) > 0:
sh.update(decompressor.decompress(buf))
buf = ifile.read(READ_BLOCKSIZE)
sh.update(decompressor.close())
if sh.hash != self.hash:
raise ChirriException("Bad data recovered (%s, %s)" \
% (target_file, self.first_seen_as))
except exceptions.IOError, ex:
os.unlink(target_file)
raise ChirriException("Cannot hash & copy file '%s': %s" % (source_file, ex))
finally:
os.unlink(tmp_file)
评论列表
文章目录