mirror of
https://github.com/jazzband/django-avatar.git
synced 2026-05-08 15:44:45 +00:00
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
This commit is contained in:
parent
dd5ac6a8ff
commit
274a1e2f59
13 changed files with 99 additions and 92 deletions
|
|
@ -1 +1 @@
|
|||
import avatar.api.signals
|
||||
import avatar.api.signals
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class ApiConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'avatar.api'
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "avatar.api"
|
||||
|
|
|
|||
|
|
@ -189,7 +189,3 @@ API Setting
|
|||
.. py:data:: API_AVATAR_CHANGE_IMAGE
|
||||
|
||||
It Allows the user to Change the avatar image in ``PUT`` method. Default is ``False``.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,17 +6,17 @@
|
|||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
project = 'django-avatar'
|
||||
project = "django-avatar"
|
||||
copyright = "2013, django-avatar developers"
|
||||
author = 'keyvan'
|
||||
author = "keyvan"
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
extensions = []
|
||||
|
||||
templates_path = ['_templates']
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
templates_path = ["_templates"]
|
||||
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
||||
|
||||
htmlhelp_basename = "django-avatar apidoc"
|
||||
|
||||
|
|
@ -28,6 +28,6 @@ pygments_style = "sphinx"
|
|||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_static_path = ['_static']
|
||||
epub_show_urls = 'footnote'
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
html_static_path = ["_static"]
|
||||
epub_show_urls = "footnote"
|
||||
|
|
|
|||
|
|
@ -308,5 +308,3 @@ after `Installation <#installation>`_ .
|
|||
:maxdepth: 1
|
||||
|
||||
avatar
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
djangorestframework
|
||||
djangorestframework
|
||||
|
|
|
|||
|
|
@ -1,43 +1,51 @@
|
|||
import os
|
||||
from PIL import Image, ImageOps
|
||||
from avatar.models import Avatar
|
||||
from avatar.conf import settings
|
||||
from rest_framework import serializers
|
||||
from avatar.conf import settings as api_setting
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django.template.defaultfilters import filesizeformat
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from PIL import Image, ImageOps
|
||||
from rest_framework import serializers
|
||||
|
||||
from avatar.conf import settings
|
||||
from avatar.conf import settings as api_setting
|
||||
from avatar.models import Avatar
|
||||
|
||||
|
||||
class AvatarSerializer(serializers.ModelSerializer):
|
||||
avatar_url = serializers.HyperlinkedIdentityField(view_name='avatar-detail', )
|
||||
avatar_url = serializers.HyperlinkedIdentityField(
|
||||
view_name="avatar-detail",
|
||||
)
|
||||
user = serializers.HiddenField(default=serializers.CurrentUserDefault())
|
||||
|
||||
class Meta:
|
||||
model = Avatar
|
||||
fields = ['id', 'avatar_url', 'avatar', 'primary', 'user']
|
||||
extra_kwargs = {'avatar': {'required': True}}
|
||||
fields = ["id", "avatar_url", "avatar", "primary", "user"]
|
||||
extra_kwargs = {"avatar": {"required": True}}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
request = kwargs.get('context').get('request', None)
|
||||
request = kwargs.get("context").get("request", None)
|
||||
|
||||
self.user = request.user
|
||||
|
||||
def get_fields(self, *args, **kwargs):
|
||||
fields = super(AvatarSerializer, self).get_fields(*args, **kwargs)
|
||||
request = self.context.get('request', None)
|
||||
request = self.context.get("request", None)
|
||||
|
||||
# remove avatar url field in detail page
|
||||
if bool(self.context.get('view').kwargs):
|
||||
fields.pop('avatar_url')
|
||||
if bool(self.context.get("view").kwargs):
|
||||
fields.pop("avatar_url")
|
||||
|
||||
# remove avatar field in put method
|
||||
if request and getattr(request, 'method', None) == "PUT":
|
||||
if request and getattr(request, "method", None) == "PUT":
|
||||
# avatar updates only when primary=true and API_AVATAR_CHANGE_IMAGE = True
|
||||
if not api_setting.API_AVATAR_CHANGE_IMAGE or self.instance and not self.instance.primary:
|
||||
fields.pop('avatar')
|
||||
if (
|
||||
not api_setting.API_AVATAR_CHANGE_IMAGE
|
||||
or self.instance
|
||||
and not self.instance.primary
|
||||
):
|
||||
fields.pop("avatar")
|
||||
else:
|
||||
fields.get('avatar', None).required = False
|
||||
fields.get("avatar", None).required = False
|
||||
return fields
|
||||
|
||||
def validate_avatar(self, value):
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import os
|
||||
from avatar.conf import settings
|
||||
|
||||
from django.db.models import signals
|
||||
from avatar.api.shortcut import get_object_or_none
|
||||
|
||||
from avatar.api.conf import settings as api_settings
|
||||
from avatar.api.shortcut import get_object_or_none
|
||||
from avatar.conf import settings
|
||||
from avatar.models import Avatar, invalidate_avatar_cache
|
||||
|
||||
|
||||
|
|
@ -20,11 +22,12 @@ def create_default_thumbnails(sender, instance, created=False, **kwargs):
|
|||
instance.create_thumbnail(size[0], size[1])
|
||||
|
||||
|
||||
def remove_previous_avatar_images_when_update(sender, instance=None, created=False, update_main_avatar=True, **kwargs):
|
||||
def remove_previous_avatar_images_when_update(
|
||||
sender, instance=None, created=False, update_main_avatar=True, **kwargs
|
||||
):
|
||||
if not created:
|
||||
old_instance = get_object_or_none(Avatar, pk=instance.pk)
|
||||
if old_instance and not old_instance.avatar == instance.avatar:
|
||||
|
||||
base_filepath = old_instance.avatar.name
|
||||
path, filename = os.path.split(base_filepath)
|
||||
# iterate through resized avatars directories and delete resized avatars
|
||||
|
|
@ -33,10 +36,14 @@ def remove_previous_avatar_images_when_update(sender, instance=None, created=Fal
|
|||
resized_widths, _ = old_instance.avatar.storage.listdir(resized_path)
|
||||
for width in resized_widths:
|
||||
resized_width_path = os.path.join(resized_path, width)
|
||||
resized_heights, _ = old_instance.avatar.storage.listdir(resized_width_path)
|
||||
resized_heights, _ = old_instance.avatar.storage.listdir(
|
||||
resized_width_path
|
||||
)
|
||||
for height in resized_heights:
|
||||
if old_instance.thumbnail_exists(width, height):
|
||||
old_instance.avatar.storage.delete(old_instance.avatar_name(width, height))
|
||||
old_instance.avatar.storage.delete(
|
||||
old_instance.avatar_name(width, height)
|
||||
)
|
||||
if update_main_avatar:
|
||||
if old_instance.avatar.storage.exists(old_instance.avatar.name):
|
||||
old_instance.avatar.storage.delete(old_instance.avatar.name)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
from avatar.api.views import AvatarViewSets
|
||||
from rest_framework.routers import SimpleRouter
|
||||
|
||||
from avatar.api.views import AvatarViewSets
|
||||
|
||||
router = SimpleRouter()
|
||||
router.register('avatar', AvatarViewSets)
|
||||
router.register("avatar", AvatarViewSets)
|
||||
|
||||
urlpatterns = router.urls
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
from avatar.conf import settings
|
||||
from html.parser import HTMLParser
|
||||
|
||||
from avatar.conf import settings
|
||||
|
||||
|
||||
class HTMLTagParser(HTMLParser):
|
||||
"""
|
||||
URL parser for getting (url ,width ,height) from avatar templatetags
|
||||
URL parser for getting (url ,width ,height) from avatar templatetags
|
||||
"""
|
||||
|
||||
def __init__(self, output=None):
|
||||
|
|
@ -20,30 +21,27 @@ class HTMLTagParser(HTMLParser):
|
|||
|
||||
def assign_width_or_height(query_params):
|
||||
"""
|
||||
Getting width and height in url parameters and specifying them
|
||||
Getting width and height in url parameters and specifying them
|
||||
"""
|
||||
avatar_default_size = settings.AVATAR_DEFAULT_SIZE
|
||||
|
||||
width = query_params.get('width', avatar_default_size)
|
||||
height = query_params.get('height', avatar_default_size)
|
||||
width = query_params.get("width", avatar_default_size)
|
||||
height = query_params.get("height", avatar_default_size)
|
||||
|
||||
if width == '':
|
||||
if width == "":
|
||||
width = avatar_default_size
|
||||
if height == '':
|
||||
if height == "":
|
||||
height = avatar_default_size
|
||||
|
||||
if height == avatar_default_size and height != '':
|
||||
if height == avatar_default_size and height != "":
|
||||
height = width
|
||||
elif width == avatar_default_size and width != '':
|
||||
elif width == avatar_default_size and width != "":
|
||||
width = height
|
||||
|
||||
width = int(width)
|
||||
height = int(height)
|
||||
|
||||
context = {
|
||||
'width': width,
|
||||
'height': height
|
||||
}
|
||||
context = {"width": width, "height": height}
|
||||
return context
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,23 @@
|
|||
from avatar.models import Avatar
|
||||
from django.db.models import QuerySet
|
||||
from avatar.api.utils import HTMLTagParser
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.decorators import action
|
||||
from avatar.templatetags.avatar_tags import avatar
|
||||
from avatar.api.serializers import AvatarSerializer
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import viewsets, status, permissions
|
||||
from avatar.api.utils import set_new_primary, assign_width_or_height
|
||||
from avatar.utils import invalidate_cache, get_default_avatar_url, get_primary_avatar
|
||||
from rest_framework import permissions, status, viewsets
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.response import Response
|
||||
|
||||
from avatar.api.serializers import AvatarSerializer
|
||||
from avatar.api.utils import HTMLTagParser, assign_width_or_height, set_new_primary
|
||||
from avatar.models import Avatar
|
||||
from avatar.templatetags.avatar_tags import avatar
|
||||
from avatar.utils import get_default_avatar_url, get_primary_avatar, invalidate_cache
|
||||
|
||||
|
||||
class AvatarViewSets(viewsets.ModelViewSet):
|
||||
serializer_class = AvatarSerializer
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
queryset = Avatar.objects.select_related('user').order_by('-primary', '-date_uploaded')
|
||||
queryset = Avatar.objects.select_related("user").order_by(
|
||||
"-primary", "-date_uploaded"
|
||||
)
|
||||
|
||||
@property
|
||||
def parse_html_to_json(self):
|
||||
|
|
@ -26,9 +28,8 @@ class AvatarViewSets(viewsets.ModelViewSet):
|
|||
|
||||
def get_queryset(self):
|
||||
assert self.queryset is not None, (
|
||||
"'%s' should either include a `queryset` attribute, "
|
||||
"or override the `get_queryset()` method."
|
||||
% self.__class__.__name__
|
||||
"'%s' should either include a `queryset` attribute, "
|
||||
"or override the `get_queryset()` method." % self.__class__.__name__
|
||||
)
|
||||
|
||||
queryset = self.queryset
|
||||
|
|
@ -52,8 +53,9 @@ class AvatarViewSets(viewsets.ModelViewSet):
|
|||
return Response(
|
||||
{
|
||||
"message": "You haven't uploaded an avatar yet. Please upload one now.",
|
||||
"default_avatar": self.parse_html_to_json
|
||||
})
|
||||
"default_avatar": self.parse_html_to_json,
|
||||
}
|
||||
)
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
|
|
@ -62,10 +64,7 @@ class AvatarViewSets(viewsets.ModelViewSet):
|
|||
headers = self.get_success_headers(serializer.data)
|
||||
message = _("Successfully uploaded a new avatar.")
|
||||
|
||||
context_data = {
|
||||
'message': message,
|
||||
'data': serializer.data
|
||||
}
|
||||
context_data = {"message": message, "data": serializer.data}
|
||||
return Response(context_data, status=status.HTTP_201_CREATED, headers=headers)
|
||||
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
|
|
@ -78,14 +77,14 @@ class AvatarViewSets(viewsets.ModelViewSet):
|
|||
return Response(message, status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
partial = kwargs.pop('partial', False)
|
||||
partial = kwargs.pop("partial", False)
|
||||
instance = self.get_object()
|
||||
serializer = self.get_serializer(instance, data=request.data, partial=partial)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
avatar_image = serializer.validated_data.get('avatar')
|
||||
primary_avatar = serializer.validated_data.get('primary')
|
||||
avatar_image = serializer.validated_data.get("avatar")
|
||||
primary_avatar = serializer.validated_data.get("primary")
|
||||
if not primary_avatar and avatar_image:
|
||||
raise ValidationError('You cant update an avatar image that is not primary')
|
||||
raise ValidationError("You cant update an avatar image that is not primary")
|
||||
|
||||
if instance.primary is True:
|
||||
# Find the next avatar, and set it as the new primary
|
||||
|
|
@ -94,17 +93,16 @@ class AvatarViewSets(viewsets.ModelViewSet):
|
|||
self.perform_update(serializer)
|
||||
invalidate_cache(request.user)
|
||||
message = _("Successfully updated your avatar.")
|
||||
if getattr(instance, '_prefetched_objects_cache', None):
|
||||
if getattr(instance, "_prefetched_objects_cache", None):
|
||||
# If 'prefetch_related' has been applied to a queryset, we need to
|
||||
# forcibly invalidate the prefetch cache on the instance.
|
||||
instance._prefetched_objects_cache = {}
|
||||
context_data = {
|
||||
'message': message,
|
||||
'data': serializer.data
|
||||
}
|
||||
context_data = {"message": message, "data": serializer.data}
|
||||
return Response(context_data)
|
||||
|
||||
@action(['GET'], detail=False, url_path='render_primary', name='Render Primary Avatar')
|
||||
@action(
|
||||
["GET"], detail=False, url_path="render_primary", name="Render Primary Avatar"
|
||||
)
|
||||
def render_primary(self, request, *args, **kwargs):
|
||||
"""
|
||||
|
||||
|
|
@ -117,19 +115,20 @@ class AvatarViewSets(viewsets.ModelViewSet):
|
|||
context_data = {}
|
||||
avatar_size = assign_width_or_height(request.query_params)
|
||||
|
||||
width = avatar_size.get('width')
|
||||
height = avatar_size.get('height')
|
||||
width = avatar_size.get("width")
|
||||
height = avatar_size.get("height")
|
||||
|
||||
primary_avatar = get_primary_avatar(request.user, width=width, height=height)
|
||||
|
||||
if primary_avatar and primary_avatar.primary:
|
||||
|
||||
url = primary_avatar.avatar_url(width, height)
|
||||
|
||||
else:
|
||||
url = get_default_avatar_url()
|
||||
if bool(request.query_params):
|
||||
context_data.update({'message': 'Resize parameters not working for default avatar'})
|
||||
context_data.update(
|
||||
{"message": "Resize parameters not working for default avatar"}
|
||||
)
|
||||
|
||||
context_data.update({"image_url": request.build_absolute_uri(url)})
|
||||
return Response(context_data)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ INSTALLED_APPS = [
|
|||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"avatar",
|
||||
"rest_framework"
|
||||
"rest_framework",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
from django.conf import settings
|
||||
from django.conf.urls import include
|
||||
from django.contrib import admin
|
||||
from django.views.static import serve
|
||||
from django.urls import re_path
|
||||
from django.views.static import serve
|
||||
|
||||
urlpatterns = [
|
||||
re_path(r"^admin/", admin.site.urls),
|
||||
re_path(r"^avatar/", include("avatar.urls")),
|
||||
re_path(r"^api/", include('avatar.api.urls')),
|
||||
re_path(r"^api/", include("avatar.api.urls")),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue