warnings.py 4.8 KB

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