Skip to content

Commit

Permalink
feat: support for resizing in avatar routes
Browse files Browse the repository at this point in the history
  • Loading branch information
joamag committed May 2, 2022
1 parent ef18bdf commit 1fccfac
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 5 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

*
* Support for resizing in the avatar routes

### Changed

Expand Down
25 changes: 21 additions & 4 deletions src/appier_extras/parts/admin/models/account.py
Expand Up @@ -38,10 +38,13 @@
""" The license for the module """

import time
import appier
import hashlib
import binascii

import appier

from appier_extras import utils

from appier_extras.parts.admin.models import base
from appier_extras.parts.admin.models import role
from appier_extras.parts.admin.partials import authenticable
Expand Down Expand Up @@ -784,7 +787,14 @@ def encrypt(self, value):
cls = self.__class__
return cls.generate(value)

def _send_avatar(self, image = "avatar.png", strict = False, cache = False):
def _send_avatar(
self,
image = "avatar.png",
width = None,
height = None,
strict = False,
cache = False
):
admin_part = self.owner.admin_part
avatar = self.avatar if hasattr(self, "avatar") else None
if not avatar:
Expand All @@ -795,10 +805,17 @@ def _send_avatar(self, image = "avatar.png", strict = False, cache = False):
"images/" + image,
static_path = admin_part.static_path
)
return self.owner.send_file(
resized = bool(width or height)
avatar_data, avatar_etag = utils.resize_image(
avatar.data,
content_type = avatar.mime,
etag = avatar.etag,
width = width,
height = height
) if resized else (avatar.data, avatar.etag)
return self.owner.send_file(
avatar_data,
content_type = avatar.mime,
etag = avatar_etag,
cache = cache
)

Expand Down
5 changes: 5 additions & 0 deletions src/appier_extras/parts/admin/part.py
Expand Up @@ -741,6 +741,9 @@ def mail_account(self, username):
raise appier.NotImplementedError()

def avatar_account(self, username):
size = self.field("size", None, cast = int)
width = self.field("width", None, cast = int)
height = self.field("height", None, cast = int)
strict = self.field("strict", False, cast = bool)
cache = self.field("cache", False, cast = bool)
account_c = self._get_cls(self.account_c)
Expand All @@ -749,6 +752,8 @@ def avatar_account(self, username):
rules = False
)
return account._send_avatar(
width = width or size,
height = height or size,
strict = strict,
cache = cache
)
Expand Down
2 changes: 2 additions & 0 deletions src/appier_extras/utils/__init__.py
Expand Up @@ -35,9 +35,11 @@
""" The license for the module """

from . import format
from . import image
from . import markdown
from . import net

from .format import SafeFormatter
from .image import resize_image
from .markdown import MarkdownParser, MarkdownGenerator, MarkdownDebug, MarkdownHTML, has_regex
from .net import size_round_unit
79 changes: 79 additions & 0 deletions src/appier_extras/utils/image.py
@@ -0,0 +1,79 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# Hive Appier Framework
# Copyright (c) 2008-2021 Hive Solutions Lda.
#
# This file is part of Hive Appier Framework.
#
# Hive Appier Framework is free software: you can redistribute it and/or modify
# it under the terms of the Apache License as published by the Apache
# Foundation, either version 2.0 of the License, or (at your option) any
# later version.
#
# Hive Appier Framework is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Apache License for more details.
#
# You should have received a copy of the Apache License along with
# Hive Appier Framework. If not, see <http://www.apache.org/licenses/>.

__author__ = "João Magalhães <joamag@hive.pt>"
""" The author(s) of the module """

__version__ = "1.0.0"
""" The version of the module """

__revision__ = "$LastChangedRevision$"
""" The revision number of the module """

__date__ = "$LastChangedDate$"
""" The last change date of the module """

__copyright__ = "Copyright (c) 2008-2021 Hive Solutions Lda."
""" The copyright for the module """

__license__ = "Apache License, Version 2.0"
""" The license for the module """

import appier

def resize_image(
data,
etag = None,
width = None,
height = None,
format = None,
quality = None
):
import PIL.Image

input_stream = appier.legacy.BytesIO(data)
output_stream = appier.legacy.BytesIO()

image = PIL.Image.open(input_stream)

try:
format = format if format else image.format

image_width, image_height = image.size
if width: ratio = float(image_width) / float(width)
elif height: ratio = float(image_height) / float(height)
else: ratio = 1.0

if not width: width = int(image_width * ratio)
if not height: height = int(image_height * ratio)

image.thumbnail((width, height), PIL.Image.ANTIALIAS)
image.save(output_stream, format, quality = quality)

output_data = output_stream.getvalue()
finally:
input_stream.close()
output_stream.close()
image.close()

etag = "%s-w%s-h%s" % (etag, str(width), str(height)) if etag else etag

return (output_data, etag)

0 comments on commit 1fccfac

Please sign in to comment.