attachment.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. from io import BytesIO
  2. from django.conf import settings
  3. from django.core.files import File
  4. from django.core.files.base import ContentFile
  5. from django.core.urlresolvers import reverse
  6. from django.db import models
  7. from django.utils import timezone
  8. from django.utils.crypto import get_random_string
  9. from PIL import Image
  10. class Attachment(models.Model):
  11. secret = models.CharField(max_length=64)
  12. filetype = models.ForeignKey('AttachmentType')
  13. post = models.ForeignKey(
  14. 'Post',
  15. blank=True,
  16. null=True,
  17. on_delete=models.SET_NULL
  18. )
  19. uploaded_on = models.DateTimeField(default=timezone.now)
  20. uploader = models.ForeignKey(
  21. settings.AUTH_USER_MODEL,
  22. blank=True,
  23. null=True,
  24. on_delete=models.SET_NULL
  25. )
  26. uploader_name = models.CharField(max_length=255)
  27. uploader_slug = models.CharField(max_length=255)
  28. uploader_ip = models.GenericIPAddressField()
  29. filename = models.CharField(max_length=255)
  30. size = models.PositiveIntegerField(default=0)
  31. thumbnail = models.ImageField(blank=True, null=True, upload_to='attachments')
  32. image = models.ImageField(blank=True, null=True, upload_to='attachments')
  33. file = models.FileField(blank=True, null=True, upload_to='attachments')
  34. @classmethod
  35. def generate_new_secret(cls):
  36. return get_random_string(settings.MISAGO_ATTACHMENT_SECRET_LENGTH)
  37. @property
  38. def is_image(self):
  39. return bool(self.image)
  40. @property
  41. def is_file(self):
  42. return not self.is_image
  43. def get_absolute_url(self):
  44. return reverse('misago:attachment', kwargs={
  45. 'pk': self.pk,
  46. 'secret': self.secret,
  47. })
  48. def get_thumbnail_url(self):
  49. if self.is_image:
  50. return reverse('misago:attachment-thumbnail', kwargs={
  51. 'pk': self.pk,
  52. 'secret': self.secret,
  53. })
  54. else:
  55. return None
  56. def set_file(self, upload):
  57. file_secret = get_random_string(settings.MISAGO_ATTACHMENT_SECRET_LENGTH)
  58. self.file = File(upload, '.'.join([file_secret, self.filetype.extensions_list[0]]))
  59. def set_image(self, upload):
  60. fileformat = self.filetype.extensions_list[0]
  61. image_secret = get_random_string(settings.MISAGO_ATTACHMENT_SECRET_LENGTH)
  62. image_filename = '.'.join([image_secret, fileformat])
  63. self.image = File(upload, image_filename)
  64. thumbnail = Image.open(upload)
  65. thumbnail.thumbnail((500, 500))
  66. thumb_stream = BytesIO()
  67. if fileformat == 'jpg':
  68. # normalize jpg to jpeg for Pillow
  69. thumbnail.save(thumb_stream, 'jpeg')
  70. else:
  71. thumbnail.save(thumb_stream, fileformat)
  72. thumb_secret = get_random_string(settings.MISAGO_ATTACHMENT_SECRET_LENGTH)
  73. thumb_filename = '.'.join([thumb_secret, fileformat])
  74. self.thumbnail = ContentFile(thumb_stream.getvalue(), thumb_filename)