post.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. from django.core.urlresolvers import reverse
  2. from django.db import models
  3. from django.dispatch import receiver
  4. from django.utils import timezone
  5. from misago.conf import settings
  6. from misago.threads.checksums import update_post_checksum, is_post_valid
  7. class Post(models.Model):
  8. forum = models.ForeignKey('misago_forums.Forum')
  9. thread = models.ForeignKey('misago_threads.Thread')
  10. poster = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,
  11. on_delete=models.SET_NULL)
  12. poster_name = models.CharField(max_length=255)
  13. poster_ip = models.GenericIPAddressField()
  14. original = models.TextField()
  15. parsed = models.TextField()
  16. checksum = models.CharField(max_length=64, default='-')
  17. mentions = models.ManyToManyField(settings.AUTH_USER_MODEL,
  18. related_name="mention_set")
  19. has_attachments = models.BooleanField(default=False)
  20. pickled_attachments = models.TextField(null=True, blank=True)
  21. posted_on = models.DateTimeField()
  22. updated_on = models.DateTimeField()
  23. edits = models.PositiveIntegerField(default=0)
  24. last_editor = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='+',
  25. null=True, blank=True,
  26. on_delete=models.SET_NULL)
  27. last_editor_name = models.CharField(max_length=255, null=True, blank=True)
  28. last_editor_slug = models.SlugField(max_length=255, null=True, blank=True)
  29. hidden_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='+',
  30. null=True, blank=True,
  31. on_delete=models.SET_NULL)
  32. hidden_by_name = models.CharField(max_length=255, null=True, blank=True)
  33. hidden_by_slug = models.SlugField(max_length=255, null=True, blank=True)
  34. hidden_on = models.DateTimeField(default=timezone.now)
  35. is_reported = models.BooleanField(default=False)
  36. is_moderated = models.BooleanField(default=False, db_index=True)
  37. is_hidden = models.BooleanField(default=False)
  38. is_protected = models.BooleanField(default=False)
  39. def __unicode__(self):
  40. return '%s...' % self.original[10:].strip()
  41. def get_absolute_url(self):
  42. return reverse(self.thread.get_url_name('post'), kwargs={
  43. 'thread_slug': self.thread.slug,
  44. 'thread_id': self.thread.id,
  45. 'post_id': self.id
  46. })
  47. def delete(self, *args, **kwargs):
  48. from misago.threads.signals import delete_post
  49. delete_post.send(sender=self)
  50. super(Post, self).delete(*args, **kwargs)
  51. def merge(self, other_post):
  52. if self.thread_id != other_post.thread_id:
  53. message = "only posts belonging to same thread can be merged"
  54. raise ValueError(message)
  55. message = "posts made by different authors can't be merged"
  56. if self.poster_id and other_post.poster_id:
  57. if self.poster_id != other_post.poster_id:
  58. raise ValueError(message)
  59. else:
  60. raise ValueError(message)
  61. if self.pk == other_post.pk:
  62. raise ValueError("post can't be merged with itself")
  63. other_post.original = '%s\n\n%s' % (other_post.original, self.original)
  64. other_post.parsed = '%s\n%s' % (other_post.parsed, self.parsed)
  65. update_post_checksum(other_post)
  66. from misago.threads.signals import merge_post
  67. merge_post.send(sender=self, other_thread=other_post)
  68. def move(self, new_thread):
  69. from misago.threads.signals import move_post
  70. self.forum = new_thread.forum
  71. self.thread = new_thread
  72. move_post.send(sender=self)
  73. def get_absolute_url(self):
  74. return reverse(self.thread.get_url_name('post'), kwargs={
  75. 'thread_slug': self.thread.slug,
  76. 'thread_id': self.thread.id,
  77. 'post_id': self.id
  78. })
  79. def get_edit_url(self):
  80. return reverse('misago:edit_post', kwargs={
  81. 'forum_id': self.forum_id,
  82. 'thread_id': self.thread_id,
  83. 'post_id': self.id
  84. })
  85. def get_quote_url(self):
  86. return reverse('misago:quote_post', kwargs={'post_id': self.id})
  87. @property
  88. def short(self):
  89. if self.is_valid:
  90. if len(self.original) > 150:
  91. return '%s...' % self.original[:150].strip()
  92. else:
  93. return self.original
  94. else:
  95. return ''
  96. @property
  97. def is_valid(self):
  98. return is_post_valid(self)