tasks.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from typing import List
  2. from celery import shared_task
  3. from django.db.models import Count, DurationField, F, Func, Q
  4. from django.utils import timezone
  5. from issues.models import Issue
  6. from .models import Notification
  7. def process_alert(project_alert_id: int, issue_ids: List[int]):
  8. notification = Notification.objects.create(project_alert_id=project_alert_id)
  9. notification.issues.add(*issue_ids)
  10. send_notification.delay(notification.pk)
  11. @shared_task
  12. def process_event_alerts():
  13. """Inspect alerts and determine if new notifications need sent"""
  14. now = timezone.now()
  15. issues = (
  16. Issue.objects.filter(
  17. project__projectalert__quantity__isnull=False,
  18. project__projectalert__timespan_minutes__isnull=False,
  19. notification__isnull=True,
  20. )
  21. .annotate(
  22. num_events=Count(
  23. "event",
  24. filter=Q(
  25. event__created__gte=now
  26. - Func(
  27. 0,
  28. 0,
  29. 0,
  30. 0,
  31. 0,
  32. F("project__projectalert__timespan_minutes"),
  33. function="make_interval",
  34. output_field=DurationField(),
  35. ),
  36. ),
  37. distinct=True,
  38. ),
  39. )
  40. .filter(num_events__gte=F("project__projectalert__quantity"))
  41. .order_by("project__projectalert")
  42. .values("pk", "project__projectalert__id")
  43. )
  44. project_alert_id = None
  45. for issue in issues:
  46. if issue["project__projectalert__id"] != project_alert_id:
  47. if project_alert_id: # If not the first in loop
  48. process_alert(project_alert_id, issue_ids)
  49. project_alert_id = issue["project__projectalert__id"]
  50. issue_ids = []
  51. issue_ids.append(issue["pk"])
  52. if project_alert_id and issue_ids:
  53. process_alert(project_alert_id, issue_ids)
  54. @shared_task
  55. def send_notification(notification_id: int):
  56. notification = Notification.objects.get(pk=notification_id)
  57. notification.send_notifications()