store.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import os
  2. from hashlib import md5
  3. from io import BytesIO
  4. from django.core.files.base import ContentFile
  5. from django.utils.crypto import get_random_string
  6. from PIL import Image
  7. from ...conf import settings
  8. def normalize_image(image):
  9. """strip image of animation, convert to RGBA"""
  10. image.seek(0)
  11. return image.copy().convert("RGBA")
  12. def delete_avatar(user, delete_tmp=True, delete_src=True):
  13. if delete_tmp and user.avatar_tmp:
  14. user.avatar_tmp.delete(save=False)
  15. if delete_src and user.avatar_src:
  16. user.avatar_src.delete(save=False)
  17. for avatar in user.avatar_set.all():
  18. avatar.image.delete(save=False)
  19. user.avatar_set.all().delete()
  20. def store_avatar(user, image):
  21. from ..models import Avatar
  22. image = normalize_image(image)
  23. avatars = []
  24. for size in sorted(settings.MISAGO_AVATARS_SIZES, reverse=True):
  25. image_stream = BytesIO()
  26. image = image.resize((size, size), Image.ANTIALIAS)
  27. image.save(image_stream, "PNG")
  28. avatars.append(
  29. Avatar.objects.create(
  30. user=user,
  31. size=size,
  32. image=ContentFile(image_stream.getvalue(), "avatar"),
  33. )
  34. )
  35. user.avatars = [{"size": a.size, "url": a.url} for a in avatars]
  36. user.save(update_fields=["avatars"])
  37. def store_new_avatar(user, image, delete_tmp=True, delete_src=True):
  38. delete_avatar(user, delete_tmp=delete_tmp, delete_src=delete_src)
  39. store_avatar(user, image)
  40. def store_temporary_avatar(user, image):
  41. image_stream = BytesIO()
  42. normalize_image(image)
  43. image.save(image_stream, "PNG")
  44. if user.avatar_tmp:
  45. user.avatar_tmp.delete(save=False)
  46. user.avatar_tmp = ContentFile(image_stream.getvalue(), "avatar")
  47. user.save(update_fields=["avatar_tmp"])
  48. def store_original_avatar(user):
  49. if user.avatar_src:
  50. user.avatar_src.delete(save=False)
  51. user.avatar_src = user.avatar_tmp
  52. user.avatar_tmp = None
  53. user.save(update_fields=["avatar_tmp", "avatar_src"])
  54. def upload_to(instance, filename):
  55. spread_path = md5(get_random_string(64).encode()).hexdigest()
  56. secret = get_random_string(32)
  57. filename_clean = "%s.png" % get_random_string(32)
  58. return os.path.join(
  59. "avatars", spread_path[:2], spread_path[2:4], secret, filename_clean
  60. )