structure du projet + docker, back: mise en place BD et apps, front: début de dev pour le header et mise en place du thème et css global (override des variables bootstrap)
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# users/signals.py
|
||||
import io
|
||||
import random
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.files.base import ContentFile
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
|
||||
from .models import User
|
||||
|
||||
PALETTE = ["#34344A", "#845A6D", "#D47386", "#C89B7B", "#32746D"]
|
||||
|
||||
def initials_for(user: User) -> str:
|
||||
if getattr(user, "initials", None):
|
||||
return user.initials[:2].upper()
|
||||
|
||||
first = (user.first_name or "").strip()
|
||||
last = (user.last_name or "").strip()
|
||||
|
||||
if first and last:
|
||||
return (first[0] + last[0]).upper()
|
||||
if first:
|
||||
return first[:2].upper()
|
||||
# fallback: email
|
||||
return (user.email or "U")[:2].upper()
|
||||
|
||||
def generate_avatar_png(text: str, bg_hex: str, size: int = 256) -> bytes:
|
||||
img = Image.new("RGBA", (size, size), bg_hex)
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
font_path = getattr(settings, "AVATAR_FONT_PATH", None)
|
||||
if font_path:
|
||||
font = ImageFont.truetype(font_path, int(size * 0.42))
|
||||
else:
|
||||
font = ImageFont.load_default()
|
||||
|
||||
bbox = draw.textbbox((0, 0), text, font=font)
|
||||
tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
|
||||
x = (size - tw) / 2
|
||||
y = (size - th) / 2 - (size * 0.05)
|
||||
|
||||
draw.text((x, y), text, font=font, fill="white")
|
||||
|
||||
out = io.BytesIO()
|
||||
img.save(out, format="PNG", optimize=True)
|
||||
return out.getvalue()
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def set_default_avatar(sender, instance: User, created: bool, **kwargs):
|
||||
if not created:
|
||||
return
|
||||
if instance.image:
|
||||
return
|
||||
|
||||
text = initials_for(instance)
|
||||
bg = random.choice(PALETTE)
|
||||
|
||||
png_bytes = generate_avatar_png(text=text, bg_hex=bg, size=256)
|
||||
filename = f"user_{instance.pk}_avatar.png"
|
||||
instance.image.save(filename, ContentFile(png_bytes), save=False)
|
||||
User.objects.filter(pk=instance.pk).update(
|
||||
image=instance.image.name,
|
||||
)
|
||||
Reference in New Issue
Block a user