pollmodel.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. from datetime import timedelta
  2. from django.db import models
  3. from django.utils import timezone
  4. import base64
  5. try:
  6. import cPickle as pickle
  7. except ImportError:
  8. import pickle
  9. from misago.signals import (delete_user_content, merge_thread,
  10. move_forum_content, move_thread,
  11. rename_user)
  12. class Poll(models.Model):
  13. forum = models.ForeignKey('Forum')
  14. thread = models.OneToOneField('Thread', primary_key=True, related_name='poll_of')
  15. user = models.ForeignKey('User', null=True, blank=True, on_delete=models.SET_NULL)
  16. user_name = models.CharField(max_length=255, null=True, blank=True)
  17. user_slug = models.SlugField(max_length=255, null=True, blank=True)
  18. start_date = models.DateTimeField()
  19. length = models.PositiveIntegerField(default=0)
  20. question = models.CharField(max_length=255)
  21. max_choices = models.PositiveIntegerField(default=0)
  22. _choices_cache = models.TextField(db_column='choices_cache')
  23. votes = models.PositiveIntegerField(default=0)
  24. vote_changing = models.BooleanField(default=False)
  25. public = models.BooleanField(default=False)
  26. class Meta:
  27. app_label = 'misago'
  28. def move_to(self, forum=None, thread=None):
  29. kwargs = {}
  30. if forum:
  31. self.forum = forum
  32. kwargs['forum'] = forum
  33. if thread:
  34. self.thread = thread
  35. kwargs['thread'] = thread
  36. self.vote_set.all().update(**kwargs)
  37. self.option_set.all().update(**kwargs)
  38. self.save()
  39. @property
  40. def end_date(self):
  41. return self.start_date + timedelta(days=self.length)
  42. @property
  43. def over(self):
  44. if not self.length:
  45. return False
  46. return timezone.now() > self.end_date
  47. def make_choices_cache(self):
  48. self.choices_cache = [x for x in self.option_set.all()]
  49. @property
  50. def choices_cache(self):
  51. try:
  52. return self._cache
  53. except AttributeError:
  54. pass
  55. try:
  56. self._cache = pickle.loads(base64.decodestring(self._choices_cache))
  57. except Exception:
  58. self._cache = []
  59. return self._cache
  60. @choices_cache.setter
  61. def choices_cache(self, choices):
  62. choices_cache = []
  63. for choice in choices:
  64. choices_cache.append({
  65. 'id': choice.pk,
  66. 'pk': choice.pk,
  67. 'name': choice.name,
  68. 'votes': choice.votes
  69. })
  70. self._cache = choices_cache
  71. self._choices_cache = base64.encodestring(pickle.dumps(choices_cache, pickle.HIGHEST_PROTOCOL))
  72. def retract_votes(self, votes):
  73. options = self.option_set.all()
  74. options_dict = {}
  75. for option in options:
  76. options_dict[option.pk] = option
  77. for vote in votes:
  78. if vote.option_id in options_dict:
  79. self.votes -= 1
  80. options_dict[vote.option_id].votes -= 1
  81. self.vote_set.filter(id__in=[x.pk for x in votes]).delete()
  82. for option in options:
  83. option.save()
  84. self.choices_cache = options
  85. def make_vote(self, request, options=None):
  86. try:
  87. len(options)
  88. except TypeError:
  89. options = (options, )
  90. for option in self.option_set.all():
  91. if option.pk in options:
  92. self.votes += 1
  93. option.votes += 1
  94. option.save()
  95. self.vote_set.create(
  96. forum_id=self.forum_id,
  97. thread_id=self.thread_id,
  98. option=option,
  99. user=request.user,
  100. user_name=request.user.username,
  101. user_slug=request.user.username_slug,
  102. date=timezone.now(),
  103. ip=request.session.get_ip(request),
  104. agent=request.META.get('HTTP_USER_AGENT'),
  105. )
  106. self.make_choices_cache()
  107. def make_empty_vote(self, request):
  108. self.vote_set.create(
  109. forum_id=self.forum_id,
  110. thread_id=self.thread_id,
  111. user=request.user,
  112. user_name=request.user.username,
  113. user_slug=request.user.username_slug,
  114. date=timezone.now(),
  115. ip=request.session.get_ip(request),
  116. agent=request.META.get('HTTP_USER_AGENT'),
  117. )
  118. def rename_user_handler(sender, **kwargs):
  119. Poll.objects.filter(user=sender).update(
  120. user_name=sender.username,
  121. user_slug=sender.username_slug,
  122. )
  123. rename_user.connect(rename_user_handler, dispatch_uid="rename_user_poll")
  124. def delete_user_content_handler(sender, **kwargs):
  125. for poll in Poll.objects.filter(user=sender).iterator():
  126. poll.delete()
  127. delete_user_content.connect(delete_user_content_handler, dispatch_uid="delete_user_polls")
  128. def move_forum_content_handler(sender, **kwargs):
  129. Poll.objects.filter(forum=sender).update(forum=kwargs['move_to'])
  130. move_forum_content.connect(move_forum_content_handler, dispatch_uid="move_forum_polls")
  131. def move_thread_handler(sender, **kwargs):
  132. Poll.objects.filter(thread=sender).update(forum=kwargs['move_to'])
  133. move_thread.connect(move_thread_handler, dispatch_uid="move_thread_polls")