Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a max_size parameter to save and _copy_file #1326

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 11 additions & 4 deletions bottle.py
Expand Up @@ -2776,32 +2776,39 @@ def filename(self):
fname = re.sub(r'[-\s]+', '-', fname).strip('.-')
return fname[:255] or 'empty'

def _copy_file(self, fp, chunk_size=2 ** 16):
def _copy_file(self, fp, chunk_size=2 ** 16, max_size=None):
read, write, offset = self.file.read, fp.write, self.file.tell()
while 1:
buf = read(chunk_size)
if not buf: break
if max_size is not None:
max_size -= len(buf) # Last chunk may be smaller than chunk_size
if max_size < 0:
raise IOError('File size exceeds maximum size.')
write(buf)
self.file.seek(offset)

def save(self, destination, overwrite=False, chunk_size=2 ** 16):
def save(self, destination, overwrite=False, chunk_size=2 ** 16,
max_size=None):
""" Save file to disk or copy its content to an open file(-like) object.
If *destination* is a directory, :attr:`filename` is added to the
path. Existing files are not overwritten by default (IOError).

:param destination: File path, directory or file(-like) object.
:param overwrite: If True, replace existing files. (default: False)
:param chunk_size: Bytes to read at a time. (default: 64kb)
:param max_size: If not None: Maximum number of bytes to write.
If exceeded by file size, raise IOError. (default: None)
"""
if isinstance(destination, basestring): # Except file-likes here
if os.path.isdir(destination):
destination = os.path.join(destination, self.filename)
if not overwrite and os.path.exists(destination):
raise IOError('File exists.')
with open(destination, 'wb') as fp:
self._copy_file(fp, chunk_size)
self._copy_file(fp, chunk_size, max_size)
else:
self._copy_file(destination, chunk_size)
self._copy_file(destination, chunk_size, max_size)

###############################################################################
# Application Helper ###########################################################
Expand Down