Esempio n. 1
0
def process_upload(upload, collection='uploads', image_size=(1280, 720),
                   thumbnail=True):
    """Processes the uploaded images in the posts and also the users avatars.
    This should be extensible in future to support the uploading of videos,
    audio, etc...

    :param _id: The ID for the post, user or anything you want as the filename
    :type _id: str
    :param upload: The uploaded Werkzeug FileStorage object
    :type upload: ``Werkzeug.datastructures.FileStorage``
    :param collection: The GridFS collection to upload the file too.
    :type collection: str
    :param image_size: The max height and width for the upload
    :type image_size: Tuple length 2 of int
    :param thumbnail: Is the image to have it's aspect ration kept?
    :type thumbnail: bool
    """
    try:
        # StringIO to take the uploaded image to transport to GridFS
        output = io.BytesIO()

        # All images are passed through PIL and turned in to PNG files.
        # Will change if they need thumbnailing or resizing.
        img = PILImage.open(upload)
        if thumbnail:
            img.thumbnail(image_size, PILImage.ANTIALIAS)
        else:
            # Pillow `resize` returns an image unlike thumbnail
            img = img.resize(image_size, PILImage.ANTIALIAS)

        img.save(output, format='PNG', quality=100)

        # Return the file pointer to the start
        output.seek(0)

        # Create a new file name <uuid>.<upload_extension>
        filename = '{0}.{1}'.format(get_uuid(), 'png')

        # Place file inside GridFS
        m.save_file(filename, output, base=collection)

        return filename
    except (IOError):
        # File will not have been uploaded
        return None
Esempio n. 2
0
File: uploads.py Progetto: hnk/pjuu
def process_upload(_id, upload, collection='uploads', image_size=(1280, 720)):
    """Processes the uploaded images in the posts and also the users avatars.
    This should be extensible in future to support the uploading of videos,
    audio, etc...

    :param _id: The ID for the post, user or anything you want as the filename
    :type _id: str
    :param upload: The uploaded Werkzeug FileStorage object
    :type upload: ``Werkzeug.datastructures.FileStorage``
    :param collection: The GridFS collection to upload the file too.
    :type collection: str
    :param image_size: The max height and width for the upload
    :type image_size: Tuple length 2 of int

    """

    try:
        # StringIO to take the uploaded image to transport to GridFS
        output = io.BytesIO()

        # All images are passed through PIL and turned in to PNG files.
        img = PILImage.open(upload)
        img.thumbnail(image_size, PILImage.ANTIALIAS)
        img.save(output, format='PNG', quality=100)

        # Return the file pointer to the start
        output.seek(0)

        # Create file name <post_id>.<upload_extension>
        # Example: ab592809052325df927523952.png
        filename = '{0}.{1}'.format(_id, 'png')

        # Place file inside GridFS
        m.save_file(filename, output, base=collection)

        return filename
    except (IOError):
        # File will not have been uploaded
        return None
Esempio n. 3
0
File: uploads.py Progetto: pjuu/pjuu
def process_upload(upload, collection='uploads', image_size=(1280, 720),
                   thumbnail=True):
    """Processes the uploaded images in the posts and also the users avatars.
    This should be extensible in future to support the uploading of videos,
    audio, etc...

    :param _id: The ID for the post, user or anything you want as the filename
    :type _id: str
    :param upload: The uploaded Werkzeug FileStorage object
    :type upload: ``Werkzeug.datastructures.FileStorage``
    :param collection: The GridFS collection to upload the file too.
    :type collection: str
    :param image_size: The max height and width for the upload
    :type image_size: Tuple length 2 of int
    :param thumbnail: Is the image to have it's aspect ration kept?
    :type thumbnail: bool
    """
    try:
        # StringIO to take the uploaded image to transport to GridFS
        output = io.BytesIO()

        # All images are passed through Wand and turned in to PNG files.
        # Unless the image is a GIF and its format is kept
        # Will change if they need thumbnailing or resizing.
        img = Image(file=upload)

        # If the input file if a GIF then we need to know
        gif = True if img.format == 'GIF' else False
        animated_gif = True if gif and len(img.sequence) > 1 else False

        # Check the exif data.
        # If there is an orientation then transform the image so that
        # it is always looking up.
        try:
            exif_data = {
                k[5:]: v
                for k, v in img.metadata.items()
                if k.startswith('exif:')
            }

            orientation = exif_data.get('Orientation')

            orientation = int(orientation)

            if orientation:  # pragma: no branch
                if orientation == 2:
                    img.flop()
                elif orientation == 3:
                    img.rotate(180)
                elif orientation == 4:
                    img.flip()
                elif orientation == 5:
                    img.flip()
                    img.rotate(90)
                elif orientation == 6:
                    img.rotate(90)
                elif orientation == 7:
                    img.flip()
                    img.rotate(270)
                elif orientation == 8:
                    img.rotate(270)

        except (AttributeError, TypeError, AttributeError):
            pass

        if thumbnail:
            # If the GIF was known to be animated then save the animated
            # then cycle through the frames, transforming them and save the
            # output
            if animated_gif:
                animated_image = Image()
                for frame in img.sequence:
                    frame.transform(resize='{0}x{1}>'.format(*image_size))
                    # Directly append the frame to the output image
                    animated_image.sequence.append(frame)

                animated_output = io.BytesIO()
                animated_output.format = 'GIF'
                animated_image.save(file=animated_output)
                animated_output.seek(0)

            img.transform(resize='{0}x{1}>'.format(*image_size))
        else:
            # Just sample the image to the correct size
            img.sample(*image_size)
            # Turn off animated GIF
            animated_gif = False

        img.format = 'PNG'
        uuid = get_uuid()
        filename = '{0}.{1}'.format(uuid, 'png')

        # Return the file pointer to the start
        img.save(file=output)
        output.seek(0)

        # Place file inside GridFS
        m.save_file(filename, output, base=collection)

        animated_filename = ''
        if animated_gif:
            animated_filename = '{0}.{1}'.format(uuid, 'gif')
            m.save_file(animated_filename, animated_output, base=collection)

        return filename, animated_filename
    except (IOError, MissingDelegateError):
        # File will not have been uploaded
        return None, None
Esempio n. 4
0
def process_upload(upload,
                   collection='uploads',
                   image_size=(1280, 720),
                   thumbnail=True):
    """Processes the uploaded images in the posts and also the users avatars.
    This should be extensible in future to support the uploading of videos,
    audio, etc...

    :param _id: The ID for the post, user or anything you want as the filename
    :type _id: str
    :param upload: The uploaded Werkzeug FileStorage object
    :type upload: ``Werkzeug.datastructures.FileStorage``
    :param collection: The GridFS collection to upload the file too.
    :type collection: str
    :param image_size: The max height and width for the upload
    :type image_size: Tuple length 2 of int
    :param thumbnail: Is the image to have it's aspect ration kept?
    :type thumbnail: bool
    """
    try:
        # StringIO to take the uploaded image to transport to GridFS
        output = io.BytesIO()

        # All images are passed through PIL and turned in to PNG files.
        # Will change if they need thumbnailing or resizing.
        img = PILImage.open(upload)

        # Check the exif data.
        # If there is an orientation then transform the image so that
        # it is always looking up.
        try:
            exif_data = {
                ExifTags.TAGS[k]: v
                for k, v in img._getexif().items() if k in ExifTags.TAGS
            }

            orientation = exif_data.get('Orientation')

            if orientation:  # pragma: no branch
                if orientation == 2:
                    img = img.transpose(PILImage.FLIP_LEFT_RIGHT)
                if orientation == 3:
                    img = img.transpose(PILImage.ROTATE_180)
                elif orientation == 4:
                    img = img.transpose(PILImage.FLIP_TOP_BOTTOM)
                elif orientation == 5:
                    img = img.transpose(PILImage.FLIP_TOP_BOTTOM)
                    img = img.transpose(PILImage.ROTATE_270)
                elif orientation == 6:
                    img = img.transpose(PILImage.ROTATE_270)
                elif orientation == 7:
                    img = img.transpose(PILImage.FLIP_TOP_BOTTOM)
                    img = img.transpose(PILImage.ROTATE_90)
                elif orientation == 8:
                    img = img.transpose(PILImage.ROTATE_90)

        except AttributeError:
            pass

        if thumbnail:
            img.thumbnail(image_size, PILImage.ANTIALIAS)
        else:
            # Pillow `resize` returns an image unlike thumbnail
            img = img.resize(image_size, PILImage.ANTIALIAS)

        img.save(output, format='PNG', quality=100)

        # Return the file pointer to the start
        output.seek(0)

        # Create a new file name <uuid>.<upload_extension>
        filename = '{0}.{1}'.format(get_uuid(), 'png')

        # Place file inside GridFS
        m.save_file(filename, output, base=collection)

        return filename
    except (IOError):
        # File will not have been uploaded
        return None