def get(self, request, group):
        """Get the first and last release for a group.

        This data used to be returned by default in group_details.py, but now that we
        can collapse it, we're providing this endpoint to fetch the data separately.
        """
        first_release, last_release = get_first_last_release(request, group)
        data = {
            "id": str(group.id),
            "firstRelease": first_release,
            "lastRelease": last_release,
        }
        return Response(data)
Esempio n. 2
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