warnings.py 4.8 KB

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