attachmentmodel.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. from datetime import date
  2. from time import time
  3. import hashlib
  4. from path import path
  5. from PIL import Image
  6. from django.conf import settings
  7. from django.db import models
  8. from django.utils import timezone
  9. from django.utils.translation import ugettext_lazy as _
  10. from floppyforms import ValidationError
  11. class AttachmentManager(models.Manager):
  12. def allow_more_orphans(self):
  13. if Attachment.objects.filter(post__isnull=True).count() > settings.ORPHAN_ATTACHMENTS_LIMIT:
  14. raise ValidationError(_("Too many users are currently uploading files. Please try agian later."))
  15. class Attachment(models.Model):
  16. filetype = models.ForeignKey('AttachmentType')
  17. forum = models.ForeignKey('Forum', null=True, blank=True, on_delete=models.SET_NULL)
  18. thread = models.ForeignKey('Thread', null=True, blank=True, on_delete=models.SET_NULL)
  19. post = models.ForeignKey('Post', null=True, blank=True, on_delete=models.SET_NULL)
  20. user = models.ForeignKey('User', null=True, blank=True, on_delete=models.SET_NULL)
  21. user_name = models.CharField(max_length=255)
  22. user_name_slug = models.CharField(max_length=255)
  23. ip = models.GenericIPAddressField()
  24. agent = models.CharField(max_length=255)
  25. date = models.DateTimeField(default=timezone.now)
  26. session = models.CharField(max_length=255, db_index=True)
  27. name = models.CharField(max_length=255)
  28. content_type = models.CharField(max_length=255)
  29. path = models.CharField(max_length=255)
  30. size = models.PositiveIntegerField(max_length=255)
  31. objects = AttachmentManager()
  32. class Meta:
  33. app_label = 'misago'
  34. def delete(self, *args, **kwargs):
  35. try:
  36. file_path = self.file_path
  37. if file_path.exists() and not file_path.isdir():
  38. file_path.unlink()
  39. except Exception:
  40. pass
  41. try:
  42. file_path = self.thumb_path
  43. if thumb_path.exists() and not thumb_path.isdir():
  44. thumb_path.unlink()
  45. except Exception:
  46. pass
  47. super(Attachment, self).delete(*args, **kwargs)
  48. @property
  49. def is_image(self):
  50. IMAGES_EXTENSIONS = ('.png', '.gif', '.jpg', '.jpeg')
  51. name = self.name.lower()
  52. for extension in IMAGES_EXTENSIONS:
  53. if name[len(extension) * -1:] == extension:
  54. return extension[1:]
  55. return False
  56. @property
  57. def file_path(self):
  58. return path(settings.ATTACHMENTS_ROOT + self.path)
  59. @property
  60. def thumb_path(self):
  61. return path(unicode(self.file_path).replace('.', '_thumb.'))
  62. def use_file(self, uploaded_file):
  63. self.name = uploaded_file.name
  64. self.content_type = uploaded_file.content_type
  65. self.size = uploaded_file.size
  66. self.store_file(uploaded_file)
  67. def store_file(self, uploaded_file):
  68. datenow = date.today()
  69. current_dir = '%s-%s-%s' % (datenow.month, datenow.day, datenow.year)
  70. full_dir = path(settings.ATTACHMENTS_ROOT + current_dir)
  71. full_dir.mkdir_p()
  72. filename = hashlib.md5('%s:%s:%s' % (self.user.pk, int(time()), settings.SECRET_KEY)).hexdigest()
  73. if self.is_image:
  74. filename += '.%s' % self.is_image
  75. self.path = '%s/%s' % (current_dir, filename)
  76. with open('%s/%s' % (full_dir, filename), 'wb+') as destination:
  77. for chunk in uploaded_file.chunks():
  78. destination.write(chunk)
  79. if self.is_image:
  80. self.make_thumb()
  81. def make_thumb(self):
  82. try:
  83. image = Image.open(self.file_path)
  84. image.thumbnail((800, 600), Image.ANTIALIAS)
  85. image.save(self.thumb_path)
  86. except IOError:
  87. pass