warnings.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. from collections import OrderedDict
  2. from datetime import timedelta
  3. from django.conf import settings
  4. from django.db import models
  5. from django.utils import timezone
  6. from django.utils.translation import ugettext_lazy as _
  7. from misago.core import threadstore
  8. from misago.core.cache import cache
  9. __all__ = [
  10. 'RESTRICT_NO', 'RESTRICT_MODERATOR_REVIEW', 'RESTRICT_DISALLOW',
  11. 'RESTRICTIONS_CHOICES', 'WarningLevel', 'UserWarning'
  12. ]
  13. CACHE_NAME = 'misago_warning_levels'
  14. RESTRICT_NO = 0
  15. RESTRICT_MODERATOR_REVIEW = 1
  16. RESTRICT_DISALLOW = 2
  17. RESTRICTIONS_CHOICES = (
  18. (RESTRICT_NO, _("No restrictions")),
  19. (RESTRICT_MODERATOR_REVIEW, _("Review by moderator")),
  20. (RESTRICT_DISALLOW, _("Disallowed")),
  21. )
  22. class WarningLevelManager(models.Manager):
  23. def dict(self):
  24. return self.get_levels_from_threadstore()
  25. def get_levels_from_threadstore(self):
  26. levels = threadstore.get(CACHE_NAME, 'nada')
  27. if levels == 'nada':
  28. levels = self.get_levels_from_cache()
  29. threadstore.set(CACHE_NAME, levels)
  30. return levels
  31. def get_levels_from_cache(self):
  32. levels = cache.get(CACHE_NAME, 'nada')
  33. if levels == 'nada':
  34. levels = self.get_levels_from_database()
  35. cache.set(CACHE_NAME, levels)
  36. return levels
  37. def get_levels_from_database(self):
  38. levels = [(0, None)]
  39. for level, obj in enumerate(self.order_by('level')):
  40. levels.append((level + 1, obj))
  41. return OrderedDict(levels)
  42. class WarningLevel(models.Model):
  43. name = models.CharField(max_length=255)
  44. level = models.PositiveIntegerField(default=1, db_index=True)
  45. length_in_minutes = models.PositiveIntegerField(default=0)
  46. restricts_posting_replies = models.PositiveIntegerField(
  47. default=RESTRICT_NO)
  48. restricts_posting_threads = models.PositiveIntegerField(
  49. default=RESTRICT_NO)
  50. objects = WarningLevelManager()
  51. def __unicode__(self):
  52. return self.name
  53. def save(self, *args, **kwargs):
  54. if not self.pk:
  55. self.set_level()
  56. super(WarningLevel, self).save(*args, **kwargs)
  57. cache.delete(CACHE_NAME)
  58. def delete(self, *args, **kwargs):
  59. super(WarningLevel, self).delete(*args, **kwargs)
  60. cache.delete(CACHE_NAME)
  61. @property
  62. def has_restrictions(self):
  63. return self.restricts_posting_replies or self.restricts_posting_threads
  64. @property
  65. def is_replying_moderated(self):
  66. return self.restricts_posting_replies == RESTRICT_MODERATOR_REVIEW
  67. @property
  68. def is_replying_disallowed(self):
  69. return self.restricts_posting_replies == RESTRICT_DISALLOW
  70. @property
  71. def is_starting_threads_moderated(self):
  72. return self.restricts_posting_threads == RESTRICT_MODERATOR_REVIEW
  73. @property
  74. def is_starting_threads_disallowed(self):
  75. return self.restricts_posting_threads == RESTRICT_DISALLOW
  76. def set_level(self):
  77. try:
  78. self.level = WarningLevel.objects.latest('level').level + 1
  79. except WarningLevel.DoesNotExist:
  80. self.level = 1
  81. class UserWarning(models.Model):
  82. user = models.ForeignKey(settings.AUTH_USER_MODEL,
  83. related_name="warnings")
  84. reason = models.TextField(null=True, blank=True)
  85. given_on = models.DateTimeField(default=timezone.now)
  86. giver = models.ForeignKey(settings.AUTH_USER_MODEL,
  87. null=True, blank=True,
  88. on_delete=models.SET_NULL,
  89. related_name="warnings_given")
  90. giver_username = models.CharField(max_length=255)
  91. giver_slug = models.CharField(max_length=255)
  92. is_canceled = models.BooleanField(default=False)
  93. canceled_on = models.DateTimeField(null=True, blank=True)
  94. canceler = models.ForeignKey(settings.AUTH_USER_MODEL,
  95. null=True, blank=True,
  96. on_delete=models.SET_NULL,
  97. related_name="warnings_canceled")
  98. canceler_username = models.CharField(max_length=255)
  99. canceler_slug = models.CharField(max_length=255)
  100. def cancel(self, canceler):
  101. self.is_canceled = True
  102. self.canceled_on = timezone.now()
  103. self.canceler = canceler
  104. self.canceler_username = canceler.username
  105. self.canceler_slug = canceler.slug
  106. self.save(update_fields=(
  107. 'is_canceled',
  108. 'canceled_on',
  109. 'canceler',
  110. 'canceler_username',
  111. 'canceler_slug',
  112. ))
  113. def is_expired(self, valid_for):
  114. return timezone.now() > self.given_on + timedelta(minutes=valid_for)