Example #1
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response
        data = serialize(group, request.user)

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        first_release = group.get_first_release()

        if first_release is not None:
            last_release = group.get_last_release()
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=1),
            ), 3600
        )[group.id]
        daily_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=30),
            ), 3600 * 24
        )[group.id]

        if first_release:
            first_release = self._get_release_info(request, group, first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        tags = tagstore.get_group_tag_keys(group.id, limit=100)

        participants = list(
            User.objects.filter(
                groupsubscription__is_active=True,
                groupsubscription__group=group,
            )
        )

        data.update(
            {
                'firstRelease': first_release,
                'lastRelease': last_release,
                'activity': serialize(activity, request.user),
                'seenBy': seen_by,
                'participants': serialize(participants, request.user),
                'pluginActions': action_list,
                'pluginIssues': self._get_available_issue_plugins(request, group),
                'pluginContexts': self._get_context_plugins(request, group),
                'userReportCount': UserReport.objects.filter(group=group).count(),
                'tags': sorted(serialize(tags, request.user), key=lambda x: x['name']),
                'stats': {
                    '24h': hourly_stats,
                    '30d': daily_stats,
                }
            }
        )

        return Response(data)
Example #2
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response

        organization = group.project.organization
        environments = get_environments(request, organization)
        environment_ids = [e.id for e in environments]

        # WARNING: the rest of this endpoint relies on this serializer
        # populating the cache SO don't move this :)
        data = serialize(group, request.user,
                         GroupSerializerSnuba(environment_ids=environment_ids))

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        first_release = group.get_first_release()

        if first_release is not None:
            last_release = group.get_last_release()
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        if first_release:
            first_release = self._get_release_info(request, group,
                                                   first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        get_range = functools.partial(tsdb.get_range,
                                      environment_ids=environment_ids)

        tags = tagstore.get_group_tag_keys(group.project_id,
                                           group.id,
                                           environment_ids,
                                           limit=100)
        if not environment_ids:
            user_reports = UserReport.objects.filter(group=group)
        else:
            user_reports = UserReport.objects.filter(
                group=group, environment_id__in=environment_ids)

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            get_range(model=tsdb.models.group,
                      keys=[group.id],
                      end=now,
                      start=now - timedelta(days=1)),
            3600,
        )[group.id]
        daily_stats = tsdb.rollup(
            get_range(model=tsdb.models.group,
                      keys=[group.id],
                      end=now,
                      start=now - timedelta(days=30)),
            3600 * 24,
        )[group.id]

        participants = list(
            User.objects.filter(groupsubscription__is_active=True,
                                groupsubscription__group=group))

        data.update({
            "firstRelease":
            first_release,
            "lastRelease":
            last_release,
            "activity":
            serialize(activity, request.user),
            "seenBy":
            seen_by,
            "participants":
            serialize(participants, request.user),
            "pluginActions":
            action_list,
            "pluginIssues":
            self._get_available_issue_plugins(request, group),
            "pluginContexts":
            self._get_context_plugins(request, group),
            "userReportCount":
            user_reports.count(),
            "tags":
            sorted(serialize(tags, request.user), key=lambda x: x["name"]),
            "stats": {
                "24h": hourly_stats,
                "30d": daily_stats
            },
        })

        # the current release is the 'latest seen' release within the
        # environment even if it hasnt affected this issue
        if environments:
            try:
                current_release = GroupRelease.objects.filter(
                    group_id=group.id,
                    environment__in=[env.name for env in environments],
                    release_id=ReleaseEnvironment.objects.filter(
                        release_id__in=ReleaseProject.objects.filter(
                            project_id=group.project_id).values_list(
                                "release_id", flat=True),
                        organization_id=group.project.organization_id,
                        environment_id__in=environment_ids,
                    ).order_by("-first_seen").values_list("release_id",
                                                          flat=True)[:1],
                )[0]
            except IndexError:
                current_release = None

            data.update({
                "currentRelease":
                serialize(current_release, request.user,
                          GroupReleaseWithStatsSerializer())
            })

        return Response(data)
Example #3
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response
        data = serialize(
            group, request.user,
            GroupSerializer(environment_func=self._get_environment_func(
                request, group.project.organization_id)))

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        first_release = group.get_first_release()

        if first_release is not None:
            last_release = group.get_last_release()
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        if first_release:
            first_release = self._get_release_info(request, group,
                                                   first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        try:
            environment_id = self._get_environment_id_from_request(
                request, group.project.organization_id)
        except Environment.DoesNotExist:
            get_range = lambda model, keys, start, end, **kwargs: \
                {k: tsdb.make_series(0, start, end) for k in keys}
            tags = []
            user_reports = UserReport.objects.none()

        else:
            get_range = functools.partial(tsdb.get_range,
                                          environment_id=environment_id)
            tags = tagstore.get_group_tag_keys(group.project_id,
                                               group.id,
                                               environment_id,
                                               limit=100)
            if environment_id is None:
                user_reports = UserReport.objects.filter(group=group)
            else:
                user_reports = UserReport.objects.filter(
                    group=group, environment_id=environment_id)

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=1),
            ), 3600)[group.id]
        daily_stats = tsdb.rollup(
            get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=30),
            ), 3600 * 24)[group.id]

        participants = list(
            User.objects.filter(
                groupsubscription__is_active=True,
                groupsubscription__group=group,
            ))

        data.update({
            'firstRelease':
            first_release,
            'lastRelease':
            last_release,
            'activity':
            serialize(activity, request.user),
            'seenBy':
            seen_by,
            'participants':
            serialize(participants, request.user),
            'pluginActions':
            action_list,
            'pluginIssues':
            self._get_available_issue_plugins(request, group),
            'pluginContexts':
            self._get_context_plugins(request, group),
            'userReportCount':
            user_reports.count(),
            'tags':
            sorted(serialize(tags, request.user), key=lambda x: x['name']),
            'stats': {
                '24h': hourly_stats,
                '30d': daily_stats,
            }
        })

        # the current release is the 'latest seen' release within the
        # environment even if it hasnt affected this issue

        try:
            environment = self._get_environment_from_request(
                request,
                group.project.organization_id,
            )
        except Environment.DoesNotExist:
            environment = None

        if environment is not None:
            try:
                current_release = GroupRelease.objects.filter(
                    group_id=group.id,
                    environment=environment.name,
                    release_id=ReleaseEnvironment.objects.filter(
                        release_id__in=ReleaseProject.objects.filter(
                            project_id=group.project_id).values_list(
                                'release_id', flat=True),
                        organization_id=group.project.organization_id,
                        environment_id=environment.id,
                    ).order_by('-first_seen').values_list('release_id',
                                                          flat=True)[:1],
                )[0]
            except IndexError:
                current_release = None

            data.update({
                'currentRelease':
                serialize(current_release, request.user,
                          GroupReleaseWithStatsSerializer())
            })

        return Response(data)
Example #4
0
    def get(self, request: Request, group) -> Response:
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        from sentry.utils import snuba

        try:
            # TODO(dcramer): handle unauthenticated/public response

            organization = group.project.organization
            environments = get_environments(request, organization)
            environment_ids = [e.id for e in environments]
            expand = request.GET.getlist("expand", [])
            collapse = request.GET.getlist("collapse", [])

            # WARNING: the rest of this endpoint relies on this serializer
            # populating the cache SO don't move this :)
            data = serialize(
                group, request.user,
                GroupSerializerSnuba(environment_ids=environment_ids))

            # TODO: these probably should be another endpoint
            activity = self._get_activity(request, group, num=100)
            seen_by = self._get_seen_by(request, group)

            if "release" not in collapse:
                first_release, last_release = get_first_last_release(
                    request, group)
                data.update({
                    "firstRelease": first_release,
                    "lastRelease": last_release,
                })

            get_range = functools.partial(tsdb.get_range,
                                          environment_ids=environment_ids)

            tags = tagstore.get_group_tag_keys(group.project_id,
                                               group.id,
                                               environment_ids,
                                               limit=100)
            if not environment_ids:
                user_reports = UserReport.objects.filter(group_id=group.id)
            else:
                user_reports = UserReport.objects.filter(
                    group_id=group.id, environment_id__in=environment_ids)

            now = timezone.now()
            hourly_stats = tsdb.rollup(
                get_range(model=tsdb.models.group,
                          keys=[group.id],
                          end=now,
                          start=now - timedelta(days=1)),
                3600,
            )[group.id]
            daily_stats = tsdb.rollup(
                get_range(
                    model=tsdb.models.group,
                    keys=[group.id],
                    end=now,
                    start=now - timedelta(days=30),
                ),
                3600 * 24,
            )[group.id]

            participants = GroupSubscriptionManager.get_participating_users(
                group)

            if "inbox" in expand:
                inbox_map = get_inbox_details([group])
                inbox_reason = inbox_map.get(group.id)
                data.update({"inbox": inbox_reason})

            action_list = self._get_actions(request, group)
            data.update({
                "activity":
                serialize(activity, request.user),
                "seenBy":
                seen_by,
                "participants":
                serialize(participants, request.user),
                "pluginActions":
                action_list,
                "pluginIssues":
                self._get_available_issue_plugins(request, group),
                "pluginContexts":
                self._get_context_plugins(request, group),
                "userReportCount":
                user_reports.count(),
                "tags":
                sorted(serialize(tags, request.user), key=lambda x: x["name"]),
                "stats": {
                    "24h": hourly_stats,
                    "30d": daily_stats
                },
            })

            metrics.incr(
                "group.update.http_response",
                sample_rate=1.0,
                tags={
                    "status": 200,
                    "detail": "group_details:get:response"
                },
            )
            return Response(data)
        except snuba.RateLimitExceeded:
            metrics.incr(
                "group.update.http_response",
                sample_rate=1.0,
                tags={
                    "status": 429,
                    "detail": "group_details:get:snuba.RateLimitExceeded"
                },
            )
            raise
        except Exception:
            metrics.incr(
                "group.update.http_response",
                sample_rate=1.0,
                tags={
                    "status": 500,
                    "detail": "group_details:get:Exception"
                },
            )
            raise
Example #5
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response
        data = serialize(group, request.user)

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        # find first seen release
        if group.first_release is None:
            try:
                first_release = GroupTagValue.objects.filter(
                    group=group,
                    key__in=('sentry:release', 'release'),
                ).order_by('first_seen')[0]
            except IndexError:
                first_release = None
            else:
                first_release = first_release.value
        else:
            first_release = group.first_release.version

        if first_release is not None:
            # find last seen release
            try:
                last_release = GroupTagValue.objects.filter(
                    group=group,
                    key__in=('sentry:release', 'release'),
                ).order_by('-last_seen')[0]
            except IndexError:
                last_release = None
            else:
                last_release = last_release.value
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=1),
            ), 3600)[group.id]
        daily_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=30),
            ), 3600 * 24)[group.id]

        if first_release:
            first_release = self._get_release_info(request, group,
                                                   first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        tags = list(GroupTagKey.objects.filter(group=group, )[:100])

        participants = list(
            User.objects.filter(
                groupsubscription__is_active=True,
                groupsubscription__group=group,
            ))

        data.update({
            'firstRelease':
            first_release,
            'lastRelease':
            last_release,
            'activity':
            serialize(activity, request.user),
            'seenBy':
            seen_by,
            'participants':
            serialize(participants, request.user),
            'pluginActions':
            action_list,
            'pluginIssues':
            self._get_available_issue_plugins(request, group),
            'pluginContexts':
            self._get_context_plugins(request, group),
            'userReportCount':
            UserReport.objects.filter(group=group).count(),
            'tags':
            sorted(serialize(tags, request.user), key=lambda x: x['name']),
            'stats': {
                '24h': hourly_stats,
                '30d': daily_stats,
            }
        })

        return Response(data)
Example #6
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response
        data = serialize(group, request.user)

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        first_release = group.get_first_release()

        if first_release is not None:
            last_release = group.get_last_release()
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=1),
            ), 3600)[group.id]
        daily_stats = tsdb.rollup(
            tsdb.get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=30),
            ), 3600 * 24)[group.id]

        if first_release:
            first_release = self._get_release_info(request, group,
                                                   first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        try:
            environment_id = self._get_environment_id_from_request(
                request, group.project.organization_id)
        except Environment.DoesNotExist:
            tags = []
        else:
            tags = tagstore.get_group_tag_keys(group.project_id,
                                               group.id,
                                               environment_id,
                                               limit=100)

        participants = list(
            User.objects.filter(
                groupsubscription__is_active=True,
                groupsubscription__group=group,
            ))

        data.update({
            'firstRelease':
            first_release,
            'lastRelease':
            last_release,
            'activity':
            serialize(activity, request.user),
            'seenBy':
            seen_by,
            'participants':
            serialize(participants, request.user),
            'pluginActions':
            action_list,
            'pluginIssues':
            self._get_available_issue_plugins(request, group),
            'pluginContexts':
            self._get_context_plugins(request, group),
            'userReportCount':
            UserReport.objects.filter(group=group).count(),
            'tags':
            sorted(serialize(tags, request.user), key=lambda x: x['name']),
            'stats': {
                '24h': hourly_stats,
                '30d': daily_stats,
            }
        })

        return Response(data)
Example #7
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response
        data = serialize(
            group,
            request.user,
            GroupSerializer(
                environment_func=self._get_environment_func(
                    request, group.project.organization_id)
            )
        )

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        first_release = group.get_first_release()

        if first_release is not None:
            last_release = group.get_last_release()
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        if first_release:
            first_release = self._get_release_info(request, group, first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        try:
            environment_id = self._get_environment_id_from_request(
                request, group.project.organization_id)
        except Environment.DoesNotExist:
            get_range = lambda model, keys, start, end, **kwargs: \
                {k: tsdb.make_series(0, start, end) for k in keys}
            tags = []
            user_reports = UserReport.objects.none()

        else:
            get_range = functools.partial(tsdb.get_range,
                                          environment_ids=environment_id and [environment_id])
            tags = tagstore.get_group_tag_keys(
                group.project_id, group.id, environment_id, limit=100)
            if environment_id is None:
                user_reports = UserReport.objects.filter(group=group)
            else:
                user_reports = UserReport.objects.filter(group=group, environment_id=environment_id)

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=1),
            ), 3600
        )[group.id]
        daily_stats = tsdb.rollup(
            get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=30),
            ), 3600 * 24
        )[group.id]

        participants = list(
            User.objects.filter(
                groupsubscription__is_active=True,
                groupsubscription__group=group,
            )
        )

        data.update(
            {
                'firstRelease': first_release,
                'lastRelease': last_release,
                'activity': serialize(activity, request.user),
                'seenBy': seen_by,
                'participants': serialize(participants, request.user),
                'pluginActions': action_list,
                'pluginIssues': self._get_available_issue_plugins(request, group),
                'pluginContexts': self._get_context_plugins(request, group),
                'userReportCount': user_reports.count(),
                'tags': sorted(serialize(tags, request.user), key=lambda x: x['name']),
                'stats': {
                    '24h': hourly_stats,
                    '30d': daily_stats,
                }
            }
        )

        # the current release is the 'latest seen' release within the
        # environment even if it hasnt affected this issue

        try:
            environment = self._get_environment_from_request(
                request,
                group.project.organization_id,
            )
        except Environment.DoesNotExist:
            environment = None

        if environment is not None:
            try:
                current_release = GroupRelease.objects.filter(
                    group_id=group.id,
                    environment=environment.name,
                    release_id=ReleaseEnvironment.objects.filter(
                        release_id__in=ReleaseProject.objects.filter(project_id=group.project_id
                                                                     ).values_list('release_id', flat=True),
                        organization_id=group.project.organization_id,
                        environment_id=environment.id,
                    ).order_by('-first_seen').values_list('release_id', flat=True)[:1],
                )[0]
            except IndexError:
                current_release = None

            data.update({
                'currentRelease': serialize(
                    current_release, request.user, GroupReleaseWithStatsSerializer()
                )
            })

        return Response(data)
Example #8
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response

        # TODO(jess): This can be removed when tagstore v2 is deprecated
        use_snuba = request.GET.get('enable_snuba') == '1'
        environments = get_environments(request, group.project.organization)
        environment_ids = [e.id for e in environments]

        if use_snuba:
            # WARNING: the rest of this endpoint relies on this serializer
            # populating the cache SO don't move this :)
            data = serialize(
                group,
                request.user,
                GroupSerializerSnuba(
                    environment_ids=environment_ids,
                )
            )
        else:
            # TODO(jess): This is just to ensure we're not breaking the old
            # issue page somehow -- non-snuba tagstore versions will raise
            # if more than one env is passed
            if environments:
                environments = environments[:1]
                environment_ids = environment_ids[:1]

            data = serialize(
                group,
                request.user,
                GroupSerializer(
                    # Just in case multiple envs are passed, let's make
                    # sure we're using the same one for all the stats
                    environment_func=lambda: environments[0] if environments else None
                )
            )

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        first_release = group.get_first_release()

        if first_release is not None:
            last_release = group.get_last_release()
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        if first_release:
            first_release = self._get_release_info(request, group, first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        get_range = functools.partial(tsdb.get_range,
                                      environment_ids=environment_ids)

        tags = tagstore.get_group_tag_keys(
            group.project_id, group.id, environment_ids, limit=100)
        if not environment_ids:
            user_reports = UserReport.objects.filter(group=group)
        else:
            user_reports = UserReport.objects.filter(
                group=group, environment_id__in=environment_ids
            )

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=1),
            ), 3600
        )[group.id]
        daily_stats = tsdb.rollup(
            get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=30),
            ), 3600 * 24
        )[group.id]

        participants = list(
            User.objects.filter(
                groupsubscription__is_active=True,
                groupsubscription__group=group,
            )
        )

        data.update(
            {
                'firstRelease': first_release,
                'lastRelease': last_release,
                'activity': serialize(activity, request.user),
                'seenBy': seen_by,
                'participants': serialize(participants, request.user),
                'pluginActions': action_list,
                'pluginIssues': self._get_available_issue_plugins(request, group),
                'pluginContexts': self._get_context_plugins(request, group),
                'userReportCount': user_reports.count(),
                'tags': sorted(serialize(tags, request.user), key=lambda x: x['name']),
                'stats': {
                    '24h': hourly_stats,
                    '30d': daily_stats,
                }
            }
        )

        # the current release is the 'latest seen' release within the
        # environment even if it hasnt affected this issue
        if environments:
            try:
                current_release = GroupRelease.objects.filter(
                    group_id=group.id,
                    environment__in=[env.name for env in environments],
                    release_id=ReleaseEnvironment.objects.filter(
                        release_id__in=ReleaseProject.objects.filter(project_id=group.project_id
                                                                     ).values_list('release_id', flat=True),
                        organization_id=group.project.organization_id,
                        environment_id__in=environment_ids,
                    ).order_by('-first_seen').values_list('release_id', flat=True)[:1],
                )[0]
            except IndexError:
                current_release = None

            data.update({
                'currentRelease': serialize(
                    current_release, request.user, GroupReleaseWithStatsSerializer()
                )
            })

        return Response(data)
Example #9
0
    def get(self, request, group):
        """
        Retrieve an Issue
        `````````````````

        Return details on an individual issue. This returns the basic stats for
        the issue (title, last seen, first seen), some overall numbers (number
        of comments, user reports) as well as the summarized event data.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """
        # TODO(dcramer): handle unauthenticated/public response

        # TODO(jess): This can be removed when tagstore v2 is deprecated
        use_snuba = request.GET.get('enable_snuba') == '1'
        environments = get_environments(request, group.project.organization)
        environment_ids = [e.id for e in environments]

        if use_snuba:
            # WARNING: the rest of this endpoint relies on this serializer
            # populating the cache SO don't move this :)
            data = serialize(
                group, request.user,
                GroupSerializerSnuba(environment_ids=environment_ids, ))
        else:
            # TODO(jess): This is just to ensure we're not breaking the old
            # issue page somehow -- non-snuba tagstore versions will raise
            # if more than one env is passed
            if environments:
                environments = environments[:1]
                environment_ids = environment_ids[:1]

            data = serialize(
                group,
                request.user,
                GroupSerializer(
                    # Just in case multiple envs are passed, let's make
                    # sure we're using the same one for all the stats
                    environment_func=lambda: environments[0]
                    if environments else None))

        # TODO: these probably should be another endpoint
        activity = self._get_activity(request, group, num=100)
        seen_by = self._get_seen_by(request, group)

        first_release = group.get_first_release()

        if first_release is not None:
            last_release = group.get_last_release()
        else:
            last_release = None

        action_list = self._get_actions(request, group)

        if first_release:
            first_release = self._get_release_info(request, group,
                                                   first_release)
        if last_release:
            last_release = self._get_release_info(request, group, last_release)

        get_range = functools.partial(tsdb.get_range,
                                      environment_ids=environment_ids)

        tags = tagstore.get_group_tag_keys(group.project_id,
                                           group.id,
                                           environment_ids,
                                           limit=100)
        if not environment_ids:
            user_reports = UserReport.objects.filter(group=group)
        else:
            user_reports = UserReport.objects.filter(
                group=group, environment_id__in=environment_ids)

        now = timezone.now()
        hourly_stats = tsdb.rollup(
            get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=1),
            ), 3600)[group.id]
        daily_stats = tsdb.rollup(
            get_range(
                model=tsdb.models.group,
                keys=[group.id],
                end=now,
                start=now - timedelta(days=30),
            ), 3600 * 24)[group.id]

        participants = list(
            User.objects.filter(
                groupsubscription__is_active=True,
                groupsubscription__group=group,
            ))

        data.update({
            'firstRelease':
            first_release,
            'lastRelease':
            last_release,
            'activity':
            serialize(activity, request.user),
            'seenBy':
            seen_by,
            'participants':
            serialize(participants, request.user),
            'pluginActions':
            action_list,
            'pluginIssues':
            self._get_available_issue_plugins(request, group),
            'pluginContexts':
            self._get_context_plugins(request, group),
            'userReportCount':
            user_reports.count(),
            'tags':
            sorted(serialize(tags, request.user), key=lambda x: x['name']),
            'stats': {
                '24h': hourly_stats,
                '30d': daily_stats,
            }
        })

        # the current release is the 'latest seen' release within the
        # environment even if it hasnt affected this issue
        if environments:
            try:
                current_release = GroupRelease.objects.filter(
                    group_id=group.id,
                    environment__in=[env.name for env in environments],
                    release_id=ReleaseEnvironment.objects.filter(
                        release_id__in=ReleaseProject.objects.filter(
                            project_id=group.project_id).values_list(
                                'release_id', flat=True),
                        organization_id=group.project.organization_id,
                        environment_id__in=environment_ids,
                    ).order_by('-first_seen').values_list('release_id',
                                                          flat=True)[:1],
                )[0]
            except IndexError:
                current_release = None

            data.update({
                'currentRelease':
                serialize(current_release, request.user,
                          GroupReleaseWithStatsSerializer())
            })

        return Response(data)