@log_calls<EOL><INDENT>def download(self, source, target, mpi=None, pos=<NUM_LIT:0>, chunk=<NUM_LIT:0>, part=<NUM_LIT:0>):<DEDENT>
s3url = S3URL(source)<EOL>obj = self.lookup(s3url)<EOL>if obj is None:<EOL><INDENT>raise Failure('<STR_LIT>' % (s3url.path,))<EOL><DEDENT>if not mpi:<EOL><INDENT>if self.opt.dry_run:<EOL><INDENT>message('<STR_LIT>', source, target)<EOL>return<EOL><DEDENT>elif self.opt.sync_check and self.sync_check(LocalMD5Cache(target), obj):<EOL><INDENT>message('<STR_LIT>', source, target)<EOL>return<EOL><DEDENT>elif not self.opt.force and os.path.exists(target):<EOL><INDENT>raise Failure('<STR_LIT>' % target)<EOL><DEDENT>fsize = int(obj['<STR_LIT>'])<EOL>if fsize < self.opt.max_singlepart_download_size:<EOL><INDENT>mpi = ThreadUtil.MultipartItem(tempfile_get(target))<EOL>mpi.total = <NUM_LIT:1><EOL>pos = <NUM_LIT:0><EOL>chunk = fsize<EOL><DEDENT>else:<EOL><INDENT>for args in self.get_file_splits(tempfile_get(target), source, target, fsize, self.opt.multipart_split_size):<EOL><INDENT>self.pool.download(*args)<EOL><DEDENT>return<EOL><DEDENT><DEDENT>tempfile = mpi.id<EOL>if self.opt.recursive:<EOL><INDENT>self.mkdirs(tempfile)<EOL><DEDENT>response = self.s3.get_object(Bucket=s3url.bucket, Key=s3url.path, Range='<STR_LIT>' % (pos, pos + chunk - <NUM_LIT:1>))<EOL>self.write_file_chunk(tempfile, pos, chunk, response['<STR_LIT>'])<EOL>if mpi.complete({'<STR_LIT>': part}):<EOL><INDENT>try:<EOL><INDENT>self.update_privilege(obj, tempfile)<EOL>self._verify_file_size(obj, tempfile)<EOL>tempfile_set(tempfile, target)<EOL>message('<STR_LIT>', source, target)<EOL><DEDENT>except Exception as e:<EOL><INDENT>tempfile_set(tempfile, None)<EOL>raise Failure('<STR_LIT>' % (e.message, source))<EOL><DEDENT><DEDENT>
Thread worker for download operation.