warnings.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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 __unicode__(self):
  53. return self.name
  54. def save(self, *args, **kwargs):
  55. if not self.pk:
  56. self.set_level()
  57. super(WarningLevel, self).save(*args, **kwargs)
  58. cache.delete(CACHE_NAME)
  59. def delete(self, *args, **kwargs):
  60. super(WarningLevel, self).delete(*args, **kwargs)
  61. cache.delete(CACHE_NAME)
  62. @property
  63. def length(self):
  64. if self.length_in_minutes:
  65. return time_amount(self.length_in_minutes * 60)
  66. else:
  67. return _("permanent")
  68. @property
  69. def has_restrictions(self):
  70. return self.restricts_posting_replies or self.restricts_posting_threads
  71. @property
  72. def is_replying_moderated(self):
  73. return self.restricts_posting_replies == RESTRICT_MODERATOR_REVIEW
  74. @property
  75. def is_replying_disallowed(self):
  76. return self.restricts_posting_replies == RESTRICT_DISALLOW
  77. @property
  78. def is_starting_threads_moderated(self):
  79. return self.restricts_posting_threads == RESTRICT_MODERATOR_REVIEW
  80. @property
  81. def is_starting_threads_disallowed(self):
  82. return self.restricts_posting_threads == RESTRICT_DISALLOW
  83. def set_level(self):
  84. try:
  85. self.level = WarningLevel.objects.latest('level').level + 1
  86. except WarningLevel.DoesNotExist:
  87. self.level = 1
  88. class UserWarning(models.Model):
  89. user = models.ForeignKey(settings.AUTH_USER_MODEL,
  90. related_name="warnings")
  91. reason = models.TextField(null=True, blank=True)
  92. given_on = models.DateTimeField(default=timezone.now)
  93. giver = models.ForeignKey(settings.AUTH_USER_MODEL,
  94. null=True, blank=True,
  95. on_delete=models.SET_NULL,
  96. related_name="warnings_given")
  97. giver_username = models.CharField(max_length=255)
  98. giver_slug = models.CharField(max_length=255)
  99. is_canceled = models.BooleanField(default=False)
  100. canceled_on = models.DateTimeField(null=True, blank=True)
  101. canceler = models.ForeignKey(settings.AUTH_USER_MODEL,
  102. null=True, blank=True,
  103. on_delete=models.SET_NULL,
  104. related_name="warnings_canceled")
  105. canceler_username = models.CharField(max_length=255)
  106. canceler_slug = models.CharField(max_length=255)
  107. def cancel(self, canceler):
  108. self.is_canceled = True
  109. self.canceled_on = timezone.now()
  110. self.canceler = canceler
  111. self.canceler_username = canceler.username
  112. self.canceler_slug = canceler.slug
  113. self.save(update_fields=(
  114. 'is_canceled',
  115. 'canceled_on',
  116. 'canceler',
  117. 'canceler_username',
  118. 'canceler_slug',
  119. ))
  120. def is_expired(self, valid_for):
  121. return timezone.now() > self.given_on + timedelta(minutes=valid_for)