MCPcopy Index your code
hub / github.com/fluentpython/example-code-2e / FileUpload

Class FileUpload

21-async/mojifinder/bottle.py:2350–2414  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2348
2349
2350class FileUpload(object):
2351
2352 def __init__(self, fileobj, name, filename, headers=None):
2353 ''' Wrapper for file uploads. '''
2354 #: Open file(-like) object (BytesIO buffer or temporary file)
2355 self.file = fileobj
2356 #: Name of the upload form field
2357 self.name = name
2358 #: Raw filename as sent by the client (may contain unsafe characters)
2359 self.raw_filename = filename
2360 #: A :class:`HeaderDict` with additional headers (e.g. content-type)
2361 self.headers = HeaderDict(headers) if headers else HeaderDict()
2362
2363 content_type = HeaderProperty('Content-Type')
2364 content_length = HeaderProperty('Content-Length', reader=int, default=-1)
2365
2366 def get_header(self, name, default=None):
2367 """ Return the value of a header within the mulripart part. """
2368 return self.headers.get(name, default)
2369
2370 @cached_property
2371 def filename(self):
2372 ''' Name of the file on the client file system, but normalized to ensure
2373 file system compatibility. An empty filename is returned as 'empty'.
2374
2375 Only ASCII letters, digits, dashes, underscores and dots are
2376 allowed in the final filename. Accents are removed, if possible.
2377 Whitespace is replaced by a single dash. Leading or tailing dots
2378 or dashes are removed. The filename is limited to 255 characters.
2379 '''
2380 fname = self.raw_filename
2381 if not isinstance(fname, unicode):
2382 fname = fname.decode('utf8', 'ignore')
2383 fname = normalize('NFKD', fname).encode('ASCII', 'ignore').decode('ASCII')
2384 fname = os.path.basename(fname.replace('\\', os.path.sep))
2385 fname = re.sub(r'[^a-zA-Z0-9-_.\s]', '', fname).strip()
2386 fname = re.sub(r'[-\s]+', '-', fname).strip('.-')
2387 return fname[:255] or 'empty'
2388
2389 def _copy_file(self, fp, chunk_size=2**16):
2390 read, write, offset = self.file.read, fp.write, self.file.tell()
2391 while 1:
2392 buf = read(chunk_size)
2393 if not buf: break
2394 write(buf)
2395 self.file.seek(offset)
2396
2397 def save(self, destination, overwrite=False, chunk_size=2**16):
2398 ''' Save file to disk or copy its content to an open file(-like) object.
2399 If *destination* is a directory, :attr:`filename` is added to the
2400 path. Existing files are not overwritten by default (IOError).
2401
2402 :param destination: File path, directory or file(-like) object.
2403 :param overwrite: If True, replace existing files. (default: False)
2404 :param chunk_size: Bytes to read at a time. (default: 64kb)
2405 '''
2406 if isinstance(destination, basestring): # Except file-likes here
2407 if os.path.isdir(destination):

Callers 1

POSTMethod · 0.85

Calls 1

HeaderPropertyClass · 0.85

Tested by

no test coverage detected