Browse Source

ref(notifications): Move Activities to Notifications (#25227)

Marcos Gaeta 3 years ago
parent
commit
7c7fc8203c

+ 1 - 0
mypy.ini

@@ -5,6 +5,7 @@ files = src/sentry/api/serializers/models/notification_setting.py,
         src/sentry/notifications/*.py,
         src/sentry/snuba/outcomes.py,
         src/sentry/snuba/query_subscription_consumer.py,
+        src/sentry/utils/avatar.py,
         src/sentry/utils/codecs.py,
         src/sentry/utils/kvstore,
         src/sentry/utils/snql.py

+ 0 - 20
src/sentry/mail/activity/__init__.py

@@ -1,20 +0,0 @@
-from sentry.mail.activity.assigned import AssignedActivityEmail
-from sentry.mail.activity.new_processing_issues import NewProcessingIssuesActivityEmail
-from sentry.mail.activity.note import NoteActivityEmail
-from sentry.mail.activity.regression import RegressionActivityEmail
-from sentry.mail.activity.release import ReleaseActivityEmail
-from sentry.mail.activity.resolved import ResolvedActivityEmail
-from sentry.mail.activity.resolved_in_release import ResolvedInReleaseActivityEmail
-from sentry.mail.activity.unassigned import UnassignedActivityEmail
-from sentry.models.activity import Activity
-
-emails = {
-    Activity.ASSIGNED: AssignedActivityEmail,
-    Activity.NOTE: NoteActivityEmail,
-    Activity.DEPLOY: ReleaseActivityEmail,
-    Activity.SET_REGRESSION: RegressionActivityEmail,
-    Activity.SET_RESOLVED: ResolvedActivityEmail,
-    Activity.SET_RESOLVED_IN_RELEASE: ResolvedInReleaseActivityEmail,
-    Activity.UNASSIGNED: UnassignedActivityEmail,
-    Activity.NEW_PROCESSING_ISSUES: NewProcessingIssuesActivityEmail,
-}

+ 0 - 15
src/sentry/mail/activity/note.py

@@ -1,15 +0,0 @@
-from .base import ActivityEmail
-
-
-class NoteActivityEmail(ActivityEmail):
-    def get_context(self):
-        return {}
-
-    def get_template(self):
-        return "sentry/emails/activity/note.txt"
-
-    def get_html_template(self):
-        return "sentry/emails/activity/note.html"
-
-    def get_category(self):
-        return "note_activity_email"

+ 0 - 12
src/sentry/mail/activity/resolved.py

@@ -1,12 +0,0 @@
-from .base import ActivityEmail
-
-
-class ResolvedActivityEmail(ActivityEmail):
-    def get_activity_name(self):
-        return "Resolved Issue"
-
-    def get_description(self):
-        return "{author} marked {an issue} as resolved"
-
-    def get_category(self):
-        return "resolved_activity_email"

+ 0 - 12
src/sentry/mail/activity/unassigned.py

@@ -1,12 +0,0 @@
-from .base import ActivityEmail
-
-
-class UnassignedActivityEmail(ActivityEmail):
-    def get_activity_name(self):
-        return "Unassigned"
-
-    def get_description(self):
-        return "{author} unassigned {an issue}"
-
-    def get_category(self):
-        return "unassigned_activity_email"

+ 2 - 4
src/sentry/mail/adapter.py

@@ -24,6 +24,7 @@ from sentry.models import (
     Team,
     User,
 )
+from sentry.notifications.activity import EMAIL_CLASSES_BY_TYPE
 from sentry.notifications.helpers import transform_to_notification_settings_by_user
 from sentry.notifications.types import (
     GroupSubscriptionReason,
@@ -512,10 +513,7 @@ class MailAdapter:
 
     def notify_about_activity(self, activity):
         metrics.incr("mail_adapter.notify_about_activity")
-        # TODO: We should move these into the `mail` module.
-        from sentry.mail.activity import emails
-
-        email_cls = emails.get(activity.type)
+        email_cls = EMAIL_CLASSES_BY_TYPE.get(activity.type)
         if not email_cls:
             logger.debug(f"No email associated with activity type `{activity.get_type_display()}`")
             return

+ 26 - 52
src/sentry/models/activity.py

@@ -11,67 +11,41 @@ from sentry.db.models import (
     sane_repr,
 )
 from sentry.tasks import activity
+from sentry.types.activity import CHOICES, ActivityType
 
 
 class Activity(Model):
     __core__ = False
 
-    SET_RESOLVED = 1
-    SET_UNRESOLVED = 2
-    SET_IGNORED = 3
-    SET_PUBLIC = 4
-    SET_PRIVATE = 5
-    SET_REGRESSION = 6
-    CREATE_ISSUE = 7
-    NOTE = 8
-    FIRST_SEEN = 9
-    RELEASE = 10
-    ASSIGNED = 11
-    UNASSIGNED = 12
-    SET_RESOLVED_IN_RELEASE = 13
-    MERGE = 14
-    SET_RESOLVED_BY_AGE = 15
-    SET_RESOLVED_IN_COMMIT = 16
-    DEPLOY = 17
-    NEW_PROCESSING_ISSUES = 18
-    UNMERGE_SOURCE = 19
-    UNMERGE_DESTINATION = 20
-    SET_RESOLVED_IN_PULL_REQUEST = 21
-    REPROCESS = 22
-    MARK_REVIEWED = 23
-
-    TYPE = (
-        # (TYPE, verb-slug)
-        (SET_RESOLVED, "set_resolved"),
-        (SET_RESOLVED_BY_AGE, "set_resolved_by_age"),
-        (SET_RESOLVED_IN_RELEASE, "set_resolved_in_release"),
-        (SET_RESOLVED_IN_COMMIT, "set_resolved_in_commit"),
-        (SET_RESOLVED_IN_PULL_REQUEST, "set_resolved_in_pull_request"),
-        (SET_UNRESOLVED, "set_unresolved"),
-        (SET_IGNORED, "set_ignored"),
-        (SET_PUBLIC, "set_public"),
-        (SET_PRIVATE, "set_private"),
-        (SET_REGRESSION, "set_regression"),
-        (CREATE_ISSUE, "create_issue"),
-        (NOTE, "note"),
-        (FIRST_SEEN, "first_seen"),
-        (RELEASE, "release"),
-        (ASSIGNED, "assigned"),
-        (UNASSIGNED, "unassigned"),
-        (MERGE, "merge"),
-        (DEPLOY, "deploy"),
-        (NEW_PROCESSING_ISSUES, "new_processing_issues"),
-        (UNMERGE_SOURCE, "unmerge_source"),
-        (UNMERGE_DESTINATION, "unmerge_destination"),
-        # The user has reprocessed the group, so events may have moved to new groups
-        (REPROCESS, "reprocess"),
-        (MARK_REVIEWED, "mark_reviewed"),
-    )
+    # TODO(mgaeta): Replace all usages with ActivityTypes.
+    ASSIGNED = ActivityType.ASSIGNED.value
+    CREATE_ISSUE = ActivityType.CREATE_ISSUE.value
+    DEPLOY = ActivityType.DEPLOY.value
+    FIRST_SEEN = ActivityType.FIRST_SEEN.value
+    MARK_REVIEWED = ActivityType.MARK_REVIEWED.value
+    MERGE = ActivityType.MERGE.value
+    NEW_PROCESSING_ISSUES = ActivityType.NEW_PROCESSING_ISSUES.value
+    NOTE = ActivityType.NOTE.value
+    RELEASE = ActivityType.RELEASE.value
+    REPROCESS = ActivityType.REPROCESS.value
+    SET_IGNORED = ActivityType.SET_IGNORED.value
+    SET_PRIVATE = ActivityType.SET_PRIVATE.value
+    SET_PUBLIC = ActivityType.SET_PUBLIC.value
+    SET_REGRESSION = ActivityType.SET_REGRESSION.value
+    SET_RESOLVED = ActivityType.SET_RESOLVED.value
+    SET_RESOLVED_BY_AGE = ActivityType.SET_RESOLVED_BY_AGE.value
+    SET_RESOLVED_IN_COMMIT = ActivityType.SET_RESOLVED_IN_COMMIT.value
+    SET_RESOLVED_IN_PULL_REQUEST = ActivityType.SET_RESOLVED_IN_PULL_REQUEST.value
+    SET_RESOLVED_IN_RELEASE = ActivityType.SET_RESOLVED_IN_RELEASE.value
+    SET_UNRESOLVED = ActivityType.SET_UNRESOLVED.value
+    UNASSIGNED = ActivityType.UNASSIGNED.value
+    UNMERGE_DESTINATION = ActivityType.UNMERGE_DESTINATION.value
+    UNMERGE_SOURCE = ActivityType.UNMERGE_SOURCE.value
 
     project = FlexibleForeignKey("sentry.Project")
     group = FlexibleForeignKey("sentry.Group", null=True)
     # index on (type, ident)
-    type = BoundedPositiveIntegerField(choices=TYPE)
+    type = BoundedPositiveIntegerField(choices=CHOICES)
     ident = models.CharField(max_length=64, null=True)
     # if the user is not set, it's assumed to be the system
     user = FlexibleForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)

+ 7 - 2
src/sentry/models/group.py

@@ -7,7 +7,7 @@ from datetime import timedelta
 from enum import Enum
 from functools import reduce
 from operator import or_
-from typing import List, Set
+from typing import List, Mapping, Optional, Set
 
 from django.db import models
 from django.db.models import Q
@@ -373,7 +373,12 @@ class Group(Model):
         )
         super().save(*args, **kwargs)
 
-    def get_absolute_url(self, params=None, event_id=None, organization_slug=None):
+    def get_absolute_url(
+        self,
+        params: Optional[Mapping[str, str]] = None,
+        event_id: Optional[int] = None,
+        organization_slug: Optional[str] = None,
+    ) -> str:
         # Built manually in preference to django.core.urlresolvers.reverse,
         # because reverse has a measured performance impact.
         event_path = f"events/{event_id}/" if event_id else ""

+ 1 - 1
src/sentry/models/groupsubscription.py

@@ -82,7 +82,7 @@ class GroupSubscriptionManager(BaseManager):
                 if i == 0:
                     raise e
 
-    def get_participants(self, group) -> Mapping[Any, Mapping[Any, GroupSubscriptionReason]]:
+    def get_participants(self, group) -> Mapping[Any, Mapping[Any, int]]:
         """
         Identify all users who are participating with a given issue.
         :param group: Group object

+ 22 - 0
src/sentry/notifications/activity/__init__.py

@@ -0,0 +1,22 @@
+from sentry.notifications.activity.assigned import AssignedActivityNotification
+from sentry.notifications.activity.new_processing_issues import (
+    NewProcessingIssuesActivityNotification,
+)
+from sentry.notifications.activity.note import NoteActivityNotification
+from sentry.notifications.activity.regression import RegressionActivityNotification
+from sentry.notifications.activity.release import ReleaseActivityNotification
+from sentry.notifications.activity.resolved import ResolvedActivityNotification
+from sentry.notifications.activity.resolved_in_release import ResolvedInReleaseActivityNotification
+from sentry.notifications.activity.unassigned import UnassignedActivityNotification
+from sentry.types.activity import ActivityType
+
+EMAIL_CLASSES_BY_TYPE = {
+    ActivityType.ASSIGNED.value: AssignedActivityNotification,
+    ActivityType.DEPLOY.value: ReleaseActivityNotification,
+    ActivityType.NEW_PROCESSING_ISSUES.value: NewProcessingIssuesActivityNotification,
+    ActivityType.NOTE.value: NoteActivityNotification,
+    ActivityType.SET_REGRESSION.value: RegressionActivityNotification,
+    ActivityType.SET_RESOLVED.value: ResolvedActivityNotification,
+    ActivityType.SET_RESOLVED_IN_RELEASE.value: ResolvedInReleaseActivityNotification,
+    ActivityType.UNASSIGNED.value: UnassignedActivityNotification,
+}

Some files were not shown because too many files changed in this diff