Except for `filesto`, all of these parameters are optional, so only
        bother setting the ones relevant to *this upload*.

        filesto
        :   A `werkzeug.FileUploader`.

        upload_to
        :   Relative path to where to upload

        secret
        :   If True, instead of the original filename, a random one'll
             be used.

        prefix
        :   To avoid race-conditions between users uploading files with
            the same name at the same time. If `secret` is True, this
            will be ignored.

        name
        :   If set, it'll be used as the name of the uploaded file.
            Instead of a string, this can also be a callable.

        allowed
        :   List of allowed file extensions. `None` to allow all
            of them. If the uploaded file doesn't have one of these
            extensions, an `UnsupportedMediaType` exception will be
            raised.

        denied
        :   List of forbidden extensions. Set to `None` to disable.
            If the uploaded file *does* have one of these extensions, a
            `UnsupportedMediaType` exception will be raised.

        max_size
        :   Maximum file size, in bytes, that file can have.
            Note: The attribute `max_content_length` defined in the
            `request` object has higher priority.

def save(self, filesto, upload_to=None, name=None, secret=None, prefix=None,
             allowed=None, denied=None, max_size=None, **kwargs):
        """
        Except for `filesto`, all of these parameters are optional, so only
        bother setting the ones relevant to *this upload*.

        filesto
        :   A `werkzeug.FileUploader`.

        upload_to
        :   Relative path to where to upload

        secret
        :   If True, instead of the original filename, a random one'll
             be used.

        prefix
        :   To avoid race-conditions between users uploading files with
            the same name at the same time. If `secret` is True, this
            will be ignored.

        name
        :   If set, it'll be used as the name of the uploaded file.
            Instead of a string, this can also be a callable.

        allowed
        :   List of allowed file extensions. `None` to allow all
            of them. If the uploaded file doesn't have one of these
            extensions, an `UnsupportedMediaType` exception will be
            raised.

        denied
        :   List of forbidden extensions. Set to `None` to disable.
            If the uploaded file *does* have one of these extensions, a
            `UnsupportedMediaType` exception will be raised.

        max_size
        :   Maximum file size, in bytes, that file can have.
            Note: The attribute `max_content_length` defined in the
            `request` object has higher priority.

        """
        if not filesto:
            return None
        upload_to = upload_to or self.upload_to
        secret = secret or self.secret
        prefix = prefix or self.prefix
        original_filename = filesto.filename
        allowed = allowed or self.allowed
        denied = denied or self.denied

        self.validate(filesto, allowed, denied, max_size)

        if callable(upload_to):
            filepath = upload_to(original_filename)
        else:
            filepath = upload_to

        oname, ext = os.path.splitext(original_filename)
        if name:
            new_name = name(original_filename) if callable(name) else name
        else:
            new_name = get_random_filename() if secret else prefix + oname

        filename = get_unique_filename(self.base_path, filepath, new_name, ext=ext)
        fullpath = os.path.join(
            make_dirs(self.base_path, filepath),
            filename
        )
        filesto.save(fullpath)
        filesize = os.path.getsize(fullpath)

        # Post validation
        if max_size and filesize > max_size:
            self.delete_file(fullpath)
            raise RequestEntityTooLarge

        return os.path.join(filepath, filename)