From: Michael Tremer Date: Sat, 6 Jan 2024 17:02:53 +0000 (+0000) Subject: accounts: Show all initials if no avatar is available X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=27714b61f0be4b1870938482cc9bc979bff89379;p=ipfire.org.git accounts: Show all initials if no avatar is available Signed-off-by: Michael Tremer --- diff --git a/src/backend/accounts.py b/src/backend/accounts.py index be791808..beb4636d 100644 --- a/src/backend/accounts.py +++ b/src/backend/accounts.py @@ -1029,6 +1029,30 @@ class Account(LDAPObject): if self.country_code: return self.backend.get_country_name(self.country_code) + @property + def initials(self): + initials = [] + + # If a nickname is set, only use the nickname + if self.nickname: + for m in re.findall(r"(\w+)", self.nickname): + initials.append(m[0]) + + # Otherwise use the first and last name + else: + if self.first_name: + initials.append(self.first_name[0]) + + if self.last_name: + initials.append(self.last_name[0]) + + # Truncate to two initials + initials = initials[:2] + + return [i.upper() for i in initials] + + # Email + @property def email(self): return self._get_string("mail") diff --git a/src/web/users.py b/src/web/users.py index aaaca825..7867e9d6 100644 --- a/src/web/users.py +++ b/src/web/users.py @@ -10,6 +10,7 @@ import os.path import tornado.web from .. import countries +from .. import util from . import base from . import ui_modules @@ -92,7 +93,7 @@ class AvatarHandler(base.BaseHandler): self.finish(avatar) async def _get_avatar(self, account, size=None, **args): - letter = ("%s" % account)[0].upper() + letters = account.initials if size is None: size = 256 @@ -101,51 +102,59 @@ class AvatarHandler(base.BaseHandler): if size >= 2048: size = 2048 + print("LETTERS", letters) + # Cache key - key = "avatar:letter:%s:%s" % (letter, size) + key = "avatar:letter:%s:%s" % ("".join(letters), size) # Fetch avatar from the cache - avatar = await self.backend.cache.get(key) + #avatar = await self.backend.cache.get(key) + avatar = None if not avatar: - avatar = self._make_avatar(letter, size=size, **args) + avatar = self._make_avatar(letters, size=size, **args) # Cache for forever await self.backend.cache.set(key, avatar) return avatar - def _make_avatar(self, letter, format="PNG", size=None, **args): - # Generate an image of the correct size - image = PIL.Image.new("RGBA", (size, size), COLOUR_LIGHT) - - # Have a canvas - draw = PIL.ImageDraw.Draw(image) - + def _make_avatar(self, letters, format="PNG", size=None, **args): # Load font font = PIL.ImageFont.truetype(os.path.join( self.application.settings.get("static_path", ""), "fonts/Prompt-Bold.ttf" ), size, encoding="unic") - # Determine size of the printed letter - w, h = font.getsize(letter) + width = 0 + height = 0 - # Prompt seems to be very broken and the height needs to be corrected - h //= 0.7 + for letter in letters: + # Determine size of the printed letter + w, h = font.getsize(letter) - # Draw the letter in the center - draw.text(((size - w) / 2, (size - h) / 2), letter, - font=font, fill=COLOUR_DARK) + # Store the maximum height + height = max(h, height) - with io.BytesIO() as f: - # If writing out the image does not work with optimization, - # we try to write it out without any optimization. - try: - image.save(f, format, optimize=True, **args) - except: - image.save(f, format, **args) + # Add up the width + width += w + + # Add the margin + width = int(width * 1.5) + height = int(height * 1.5) + + print(width, height) + + # Generate an image of the correct size + image = PIL.Image.new("RGBA", (width, height), COLOUR_LIGHT) + + # Have a canvas + draw = PIL.ImageDraw.Draw(image) + + # Draw the letter in the center + draw.text((width // 2, height // 2), "".join(letters), + font=font, anchor="mm", fill=COLOUR_DARK) - return f.getvalue() + return util.generate_thumbnail(image, size, square=True) class EditHandler(base.BaseHandler):