diff --git a/attributions.md b/attributions.md index 5afc9f9d46..611b9b1d9a 100644 --- a/attributions.md +++ b/attributions.md @@ -11,6 +11,7 @@ The following 3rd-party software packages may be used by or distributed with ### Icon Fonts diff --git a/frappe/utils/__init__.py b/frappe/utils/__init__.py index db176a5c0b..9f25b33266 100644 --- a/frappe/utils/__init__.py +++ b/frappe/utils/__init__.py @@ -283,12 +283,7 @@ def get_gravatar_url(email): def get_gravatar(email): from frappe.utils.identicon import Identicon - gravatar_url = has_gravatar(email) - - if not gravatar_url: - gravatar_url = Identicon(email).base64() - - return gravatar_url + return has_gravatar(email) or Identicon(email).base64() def get_traceback(with_context=False) -> str: diff --git a/frappe/utils/identicon.py b/frappe/utils/identicon.py index 1267b8f9c3..645898f23b 100644 --- a/frappe/utils/identicon.py +++ b/frappe/utils/identicon.py @@ -1,7 +1,13 @@ -import base64 -import random +""" +This module provides a class Identicon that can be used to generate identicons +from strings. + +It provides a (slighltly modified) version of https://github.com/evuez/identicons +which has been released under the MIT license, as described in attributions.md. +""" +from base64 import b64encode from hashlib import md5 -from io import StringIO +from io import BytesIO from PIL import Image, ImageDraw @@ -33,32 +39,7 @@ class Identicon: First three bytes are used to generate the color, remaining bytes are used to create the drawing """ - # color = (self.hash & 0xff, self.hash >> 8 & 0xff, self.hash >> 16 & 0xff) - color = random.choice( - ( - (254, 196, 197), - (253, 138, 139), - (254, 231, 206), - (254, 208, 159), - (210, 211, 253), - (163, 165, 252), - (247, 213, 247), - (242, 172, 238), - (235, 247, 206), - (217, 241, 157), - (211, 248, 237), - (167, 242, 221), - (255, 249, 207), - (254, 245, 161), - (211, 241, 254), - (168, 228, 254), - (207, 245, 210), - (159, 235, 164), - ) - ) - # print color - # color = (254, 232, 206) - + color = (self.hash & 0xFF, self.hash >> 8 & 0xFF, self.hash >> 16 & 0xFF) self.hash >>= 24 # skip first three bytes square_x = square_y = 0 # init square position for x in range(GRID_SIZE * (GRID_SIZE + 1) // 2): @@ -86,22 +67,17 @@ class Identicon: def base64(self, format="PNG"): """ - usage: i = Identicon('xx') - print(i.base64()) - return: this image's base64 code - created by: liuzheng712 - bug report: https://github.com/liuzheng712/identicons/issues + Return the identicon's base64 + + Created by: liuzheng712 + Bug report: https://github.com/liuzheng712/identicons/issues """ self.calculate() - fp = StringIO() + self.image.encoderinfo = {} self.image.encoderconfig = () - if format.upper() not in Image.SAVE: - Image.init() - save_handler = Image.SAVE[format.upper()] - try: - save_handler(self.image, fp, "") - finally: - fp.seek(0) - return f"data:image/png;base64,{base64.b64encode(fp.read())}" # noqa + buff = BytesIO() + self.image.save(buff, format=format.upper()) + + return f"data:image/png;base64,{b64encode(buff.getvalue()).decode()}"