floodprotection.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. from datetime import timedelta
  2. from django.utils import timezone
  3. from django.utils.translation import gettext as _
  4. from . import PostingEndpoint, PostingInterrupt, PostingMiddleware
  5. MIN_POSTING_INTERVAL = 3
  6. class FloodProtectionMiddleware(PostingMiddleware):
  7. def use_this_middleware(self):
  8. return (
  9. not self.user_acl["can_omit_flood_protection"]
  10. and self.mode != PostingEndpoint.EDIT
  11. )
  12. def interrupt_posting(self, serializer):
  13. now = timezone.now()
  14. if self.user.last_posted_on:
  15. previous_post = now - self.user.last_posted_on
  16. if previous_post.total_seconds() < MIN_POSTING_INTERVAL:
  17. raise PostingInterrupt(
  18. _("You can't post message so quickly after previous one.")
  19. )
  20. self.user.last_posted_on = timezone.now()
  21. self.user.update_fields.append("last_posted_on")
  22. if self.settings.hourly_post_limit:
  23. cutoff = now - timedelta(hours=24)
  24. if self.is_limit_exceeded(cutoff, self.settings.hourly_post_limit):
  25. raise PostingInterrupt(
  26. _("Your account has exceed an hourly post limit.")
  27. )
  28. if self.settings.daily_post_limit:
  29. cutoff = now - timedelta(hours=1)
  30. if self.is_limit_exceeded(cutoff, self.settings.daily_post_limit):
  31. raise PostingInterrupt(_("Your account has exceed a daily post limit."))
  32. def is_limit_exceeded(self, cutoff, limit):
  33. return self.user.post_set.filter(posted_on__gte=cutoff).count() >= limit