예제 #1
0
    def notify_digest(self, project, digest, target_type, target_identifier=None):
        metrics.incr("mail_adapter.notify_digest")
        user_ids = self.get_send_to(project, target_type, target_identifier)[
            ExternalProviders.EMAIL
        ]
        logger.info(
            "mail.adapter.notify_digest",
            extra={
                "project_id": project.id,
                "target_type": target_type.value,
                "target_identifier": target_identifier,
                "user_ids": user_ids,
            },
        )
        for user_id, digest in get_personalized_digests(target_type, project.id, digest, user_ids):
            start, end, counts = get_digest_metadata(digest)

            # If there is only one group in this digest (regardless of how many
            # rules it appears in), we should just render this using the single
            # notification template. If there is more than one record for a group,
            # just choose the most recent one.
            if len(counts) == 1:
                group = next(iter(counts))
                record = max(
                    itertools.chain.from_iterable(
                        groups.get(group, []) for groups in digest.values()
                    ),
                    key=lambda record: record.timestamp,
                )
                notification = Notification(record.value.event, rules=record.value.rules)
                return self.notify(notification, target_type, target_identifier)

            context = {
                "start": start,
                "end": end,
                "project": project,
                "digest": digest,
                "counts": counts,
            }

            headers = {
                "X-Sentry-Project": project.slug,
                "X-SMTPAPI": json.dumps({"category": "digest_email"}),
            }

            group = next(iter(counts))
            subject = self.get_digest_subject(group, counts, start)

            self.add_unsubscribe_link(context, user_id, project, "alert_digest")
            self._send_mail(
                subject=subject,
                template="sentry/emails/digests/body.txt",
                html_template="sentry/emails/digests/body.html",
                project=project,
                reference=project,
                headers=headers,
                type="notify.digest",
                context=context,
                send_to=[user_id],
            )
예제 #2
0
    def assert_get_personalized_digests(self, project, digest, user_ids, expected_result):
        result_user_ids = []
        for user_id, user_digest in get_personalized_digests(project.id, digest, user_ids):
            assert user_id in expected_result
            assert expected_result[user_id] == get_event_from_groups_in_digest(user_digest)
            result_user_ids.append(user_id)

        assert sorted(expected_result.keys()) == sorted(result_user_ids)
예제 #3
0
    def assert_get_personalized_digests(self, project, digest, user_ids, expected_result):
        result_user_ids = []
        for user_id, user_digest in get_personalized_digests(project.id, digest, user_ids):
            assert user_id in expected_result
            assert expected_result[user_id] == get_event_from_groups_in_digest(user_digest)
            result_user_ids.append(user_id)

        assert sorted(expected_result.keys()) == sorted(result_user_ids)
예제 #4
0
    def notify_digest(self,
                      project,
                      digest,
                      target_type,
                      target_identifier=None):
        user_ids = self.get_send_to(project, target_type, target_identifier)
        for user_id, digest in get_personalized_digests(
                project.id, digest, user_ids):
            start, end, counts = get_digest_metadata(digest)

            # If there is only one group in this digest (regardless of how many
            # rules it appears in), we should just render this using the single
            # notification template. If there is more than one record for a group,
            # just choose the most recent one.
            if len(counts) == 1:
                group = six.next(iter(counts))
                record = max(
                    itertools.chain.from_iterable(
                        groups.get(group, [])
                        for groups in six.itervalues(digest)),
                    key=lambda record: record.timestamp,
                )
                notification = Notification(record.value.event,
                                            rules=record.value.rules)
                return self.notify(notification, target_type,
                                   target_identifier)

            context = {
                "start": start,
                "end": end,
                "project": project,
                "digest": digest,
                "counts": counts,
            }

            headers = {"X-Sentry-Project": project.slug}

            group = six.next(iter(counts))
            subject = self.get_digest_subject(group, counts, start)

            self.add_unsubscribe_link(context, user_id, project,
                                      "alert_digest")
            self._send_mail(
                subject=subject,
                template="sentry/emails/digests/body.txt",
                html_template="sentry/emails/digests/body.html",
                project=project,
                reference=project,
                headers=headers,
                type="notify.digest",
                context=context,
                send_to=[user_id],
            )
예제 #5
0
    def assert_get_personalized_digests(
        self, project, digest, user_ids, expected_result, target_type=ActionTargetType.ISSUE_OWNERS
    ):
        result_user_ids = []
        for user_id, user_digest in get_personalized_digests(
            target_type, project.id, digest, user_ids
        ):
            assert user_id in expected_result
            assert {e.event_id for e in get_event_from_groups_in_digest(user_digest)} == {
                e.event_id for e in expected_result[user_id]
            }
            result_user_ids.append(user_id)

        assert sorted(expected_result.keys()) == sorted(result_user_ids)
예제 #6
0
파일: models.py 프로젝트: alexandrul/sentry
    def notify_digest(self, project, digest):
        user_ids = self.get_send_to(project)
        for user_id, digest in get_personalized_digests(project.id, digest, user_ids):
            start, end, counts = get_digest_metadata(digest)

            # If there is only one group in this digest (regardless of how many
            # rules it appears in), we should just render this using the single
            # notification template. If there is more than one record for a group,
            # just choose the most recent one.
            if len(counts) == 1:
                group = six.next(iter(counts))
                record = max(
                    itertools.chain.from_iterable(
                        groups.get(group, []) for groups in six.itervalues(digest)
                    ),
                    key=lambda record: record.timestamp,
                )
                notification = Notification(record.value.event, rules=record.value.rules)
                return self.notify(notification)

            context = {
                'start': start,
                'end': end,
                'project': project,
                'digest': digest,
                'counts': counts,
            }

            headers = {
                'X-Sentry-Project': project.slug,
            }

            group = six.next(iter(counts))
            subject = self.get_digest_subject(group, counts, start)

            self.add_unsubscribe_link(context, user_id, project)
            self._send_mail(
                subject=subject,
                template='sentry/emails/digests/body.txt',
                html_template='sentry/emails/digests/body.html',
                project=project,
                reference=project,
                headers=headers,
                type='notify.digest',
                context=context,
                send_to=[user_id],
            )
예제 #7
0
파일: digest.py 프로젝트: waterdrops/sentry
    def get_extra_context(self, recipient_ids: Iterable[int]) -> Mapping[int, Mapping[str, Any]]:
        extra_context = {}
        for user_id, digest in get_personalized_digests(
            self.target_type, self.project.id, self.digest, recipient_ids
        ):
            start, end, counts = get_digest_metadata(digest)
            group = next(iter(counts))

            extra_context[user_id] = {
                "counts": counts,
                "digest": digest,
                "group": group,
                "end": end,
                "start": start,
            }

        return extra_context
예제 #8
0
 def test_team_without_members(self):
     team = self.create_team()
     project = self.create_project(teams=[team], fire_project_created=True)
     ProjectOwnership.objects.create(
         project_id=project.id,
         schema=dump_schema([Rule(Matcher("path", "*.cpp"), [Owner("team", team.slug)])]),
         fallthrough=True,
     )
     rule = project.rule_set.all()[0]
     records = [
         event_to_record(event, (rule,))
         for event in self.create_events_from_filenames(
             project, ["hello.py", "goodbye.py", "hola.py", "adios.py"]
         )
     ]
     digest = build_digest(project, sort_records(records))
     user_ids = [member.user_id for member in team.member_set]
     assert not user_ids
     for user_id, user_digest in get_personalized_digests(project.id, digest, user_ids):
         assert False  # no users in this team no digests should be processed
예제 #9
0
 def test_team_without_members(self):
     team = self.create_team()
     project = self.create_project(teams=[team])
     ProjectOwnership.objects.create(
         project_id=project.id,
         schema=dump_schema([
             Rule(Matcher('path', '*.cpp'), [
                 Owner('team', team.slug),
             ]),
         ]),
         fallthrough=True,
     )
     rule = project.rule_set.all()[0]
     records = [
         event_to_record(event, (rule, )) for event in self.create_events(timezone.now(), project, [
             'hello.py', 'goodbye.py', 'hola.py', 'adios.py'])
     ]
     digest = build_digest(project, sort_records(records))
     user_ids = [member.user_id for member in team.member_set]
     assert not user_ids
     for user_id, user_digest in get_personalized_digests(project.id, digest, user_ids):
         assert False  # no users in this team no digests should be processed
예제 #10
0
 def test_team_without_members(self):
     team = self.create_team()
     project = self.create_project(teams=[team])
     ProjectOwnership.objects.create(
         project_id=project.id,
         schema=dump_schema([
             Rule(Matcher('path', '*.cpp'), [
                 Owner('team', team.slug),
             ]),
         ]),
         fallthrough=True,
     )
     rule = project.rule_set.all()[0]
     records = [
         event_to_record(event, (rule, ))
         for event in self.create_events(timezone.now(
         ), project, ['hello.py', 'goodbye.py', 'hola.py', 'adios.py'])
     ]
     digest = build_digest(project, sort_records(records))
     user_ids = [member.user_id for member in team.member_set]
     assert not user_ids
     for user_id, user_digest in get_personalized_digests(
             project.id, digest, user_ids):
         assert False  # no users in this team no digests should be processed