warnings.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. from collections import OrderedDict
  2. from datetime import timedelta
  3. from django.conf import settings
  4. from django.contrib.auth import get_user_model
  5. from django.db import models
  6. from django.utils import timezone
  7. from django.utils.translation import ugettext_lazy as _
  8. from misago.core import threadstore
  9. from misago.core.cache import cache
  10. from misago.core.utils import time_amount
  11. __all__ = [
  12. 'RESTRICT_NO', 'RESTRICT_MODERATOR_REVIEW', 'RESTRICT_DISALLOW',
  13. 'RESTRICTIONS_CHOICES', 'WarningLevel', 'UserWarning'
  14. ]
  15. CACHE_NAME = 'misago_warning_levels'
  16. RESTRICT_NO = 0
  17. RESTRICT_MODERATOR_REVIEW = 1
  18. RESTRICT_DISALLOW = 2
  19. RESTRICTIONS_CHOICES = (
  20. (RESTRICT_NO, _("No restrictions")),
  21. (RESTRICT_MODERATOR_REVIEW, _("Review by moderator")),
  22. (RESTRICT_DISALLOW, _("Disallowed")),
  23. )
  24. class WarningLevelManager(models.Manager):
  25. def dict(self):
  26. return self.get_levels_from_threadstore()
  27. def get_levels_from_threadstore(self):
  28. levels = threadstore.get(CACHE_NAME, 'nada')
  29. if levels == 'nada':
  30. levels = self.get_levels_from_cache()
  31. threadstore.set(CACHE_NAME, levels)
  32. return levels
  33. def get_levels_from_cache(self):
  34. levels = cache.get(CACHE_NAME, 'nada')
  35. if levels == 'nada':
  36. levels = self.get_levels_from_database()
  37. cache.set(CACHE_NAME, levels)
  38. return levels
  39. def get_levels_from_database(self):
  40. levels = [(0, None)]
  41. for level, obj in enumerate(self.order_by('level')):
  42. levels.append((level + 1, obj))
  43. return OrderedDict(levels)
  44. class WarningLevel(models.Model):
  45. name = models.CharField(max_length=255)
  46. description = models.TextField(null=True, blank=True)
  47. level = models.PositiveIntegerField(default=1, db_index=True)
  48. length_in_minutes = models.PositiveIntegerField(default=0)
  49. restricts_posting_replies = models.PositiveIntegerField(
  50. default=RESTRICT_NO)
  51. restricts_posting_threads = models.PositiveIntegerField(
  52. default=RESTRICT_NO)
  53. objects = WarningLevelManager()
  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="+")
  97. giver_username = models.CharField(max_length=255)
  98. giver_slug = models.CharField(max_length=255)
  99. 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="+")
  105. canceler_username = models.CharField(max_length=255)
  106. canceler_slug = models.CharField(max_length=255)
  107. def cancel(self, canceler):
  108. self.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. '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)