From bf3775d401e14e1f4b69622f423213570cafc6d6 Mon Sep 17 00:00:00 2001 From: m5ka Date: Mon, 25 Mar 2024 14:11:21 +0000 Subject: [PATCH] =?UTF-8?q?feature:=20=F0=9F=96=BC=EF=B8=8F=20add=20user?= =?UTF-8?q?=20avatars?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- moku/config/settings.py | 2 +- moku/filters.py | 5 +++++ moku/forms/user.py | 4 ++-- moku/images.py | 21 +++++++++++++++++++++ moku/migrations/0003_user_avatar.py | 19 +++++++++++++++++++ moku/models/post.py | 12 ++---------- moku/models/user.py | 10 ++++++++++ moku/static/css/moku.css | 10 +++++++++- moku/templates/moku/feed.jinja | 2 +- moku/templates/moku/profile/edit.jinja | 10 +++++++++- moku/templates/moku/profile/show.jinja | 5 +++++ moku/utils.py | 18 ------------------ moku/views/post.py | 3 +++ moku/views/user.py | 3 +++ 15 files changed, 92 insertions(+), 35 deletions(-) create mode 100644 moku/filters.py create mode 100644 moku/images.py create mode 100644 moku/migrations/0003_user_avatar.py delete mode 100644 moku/utils.py diff --git a/.gitignore b/.gitignore index 20509ff..7f2a8b8 100644 --- a/.gitignore +++ b/.gitignore @@ -75,4 +75,5 @@ dmypy.json .pyre/ .pytype/ cython_debug/ -.idea/ \ No newline at end of file +.idea/ +media/ \ No newline at end of file diff --git a/moku/config/settings.py b/moku/config/settings.py index 25c5402..8cf482a 100644 --- a/moku/config/settings.py +++ b/moku/config/settings.py @@ -71,7 +71,7 @@ TEMPLATES = [ "django.contrib.messages.context_processors.messages", ], "filters": { - "unemoji": "moku.utils.unemoji", + "unemoji": "moku.filters.unemoji", }, "policies": {"ext.i18n.trimmed": True}, }, diff --git a/moku/filters.py b/moku/filters.py new file mode 100644 index 0000000..fa5c66d --- /dev/null +++ b/moku/filters.py @@ -0,0 +1,5 @@ +from emoji import demojize + + +def unemoji(txt: str): + return demojize(txt, delimiters=("", "")) diff --git a/moku/forms/user.py b/moku/forms/user.py index 9ac4f2d..08500ab 100644 --- a/moku/forms/user.py +++ b/moku/forms/user.py @@ -1,5 +1,4 @@ from django import forms -from django.contrib.auth import password_validation from django.contrib.auth.forms import UserCreationForm from django.utils.translation import gettext_lazy as _ @@ -35,8 +34,9 @@ class UserForm(UserCreationForm): class ProfileForm(forms.ModelForm): class Meta: model = User - fields = ("pronouns", "location", "bio") + fields = ("avatar", "pronouns", "location", "bio") labels = { + "avatar": _("avatar"), "pronouns": _("pronouns"), "location": _("location"), "bio": _("about me"), diff --git a/moku/images.py b/moku/images.py new file mode 100644 index 0000000..6d8f69f --- /dev/null +++ b/moku/images.py @@ -0,0 +1,21 @@ +from io import BytesIO + +from django.core.files import File +from PIL import Image + + +def _convert_image_to_webp(image_file): + image = Image.open(image_file) + image.convert("RGB") + image.thumbnail((486, 486)) + thumb_io = BytesIO() + image.save(thumb_io, "WEBP") + return File(thumb_io, name=image_file.name) + + +def process_avatar_image(image_file): + return _convert_image_to_webp(image_file) + + +def process_post_image(image_file): + return _convert_image_to_webp(image_file) diff --git a/moku/migrations/0003_user_avatar.py b/moku/migrations/0003_user_avatar.py new file mode 100644 index 0000000..fd75b9c --- /dev/null +++ b/moku/migrations/0003_user_avatar.py @@ -0,0 +1,19 @@ +# Generated by Django 5.0.3 on 2024-03-25 13:49 + +import moku.models.user +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('moku', '0002_post'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='avatar', + field=models.ImageField(blank=True, help_text='a little picture to show up on your profile.', upload_to=moku.models.user.user_avatar_filename, verbose_name='avatar'), + ), + ] diff --git a/moku/models/post.py b/moku/models/post.py index 9c4b8af..0c43a42 100644 --- a/moku/models/post.py +++ b/moku/models/post.py @@ -4,14 +4,11 @@ from django.utils.translation import gettext_lazy as _ from shortuuid.django_fields import ShortUUIDField from moku.constants import Verbs -from moku.utils import process_image from moku.validators import validate_emoji -def post_image_filename(instance, filename): - fn = filename.split(".") - ext = "png" if len(fn) < 2 else fn[-1] - return f"posts/{instance.created_by.username}__{instance.uuid}.{ext}" +def post_image_filename(instance, _): + return f"posts/{instance.created_by.username}__{instance.uuid}.webp" class Post(models.Model): @@ -63,11 +60,6 @@ class Post(models.Model): def __str__(self): return self.uuid - def save(self, *args, **kwargs): - if not self.id and self.image: - self.image = process_image(self.image) - super().save(*args, **kwargs) - @property def text(self): return self.get_verb_display() % { diff --git a/moku/models/user.py b/moku/models/user.py index 731dbe6..efce68f 100644 --- a/moku/models/user.py +++ b/moku/models/user.py @@ -6,6 +6,10 @@ from django.urls import reverse from moku.validators import validate_username_regex, validate_username_length +def user_avatar_filename(instance, _): + return f"avatars/{instance.username}.webp" + + class User(AbstractUser): username = models.CharField( verbose_name=_("username"), @@ -48,6 +52,12 @@ class User(AbstractUser): blank=True, help_text=_("write something about yourself!"), ) + avatar = models.ImageField( + verbose_name=_("avatar"), + blank=True, + upload_to=user_avatar_filename, + help_text=_("a little picture to show up on your profile."), + ) last_seen_at = models.DateTimeField( verbose_name=_("last seen at"), blank=True, diff --git a/moku/static/css/moku.css b/moku/static/css/moku.css index f188f83..c0d1c47 100644 --- a/moku/static/css/moku.css +++ b/moku/static/css/moku.css @@ -87,6 +87,14 @@ a:hover, button.logout:hover { color: var(--orange); } +.avatar { + border-radius: 8px; +} + +aside .avatar { + max-width: 100%; +} + dl { display: grid; grid-template-columns: 1fr 1fr; @@ -148,7 +156,7 @@ form .field .help { font-size: 1.4rem; } -form input, +form input:not([name$="-clear"]), form select { width: 100%; } diff --git a/moku/templates/moku/feed.jinja b/moku/templates/moku/feed.jinja index c41f39c..daba1a2 100644 --- a/moku/templates/moku/feed.jinja +++ b/moku/templates/moku/feed.jinja @@ -4,7 +4,7 @@