def get(self, request, group, environment): try: environment = Environment.objects.get( project_id=group.project_id, # XXX(dcramer): we have no great way to pass the empty env name='' if environment == 'none' else environment, ) except Environment.DoesNotExist: raise ResourceDoesNotExist first_release = GroupRelease.objects.filter( group_id=group.id, environment=environment.name, ).order_by('first_seen').first() last_release = GroupRelease.objects.filter( group_id=group.id, environment=environment.name, ).order_by('-first_seen').first() # the current release is the 'latest seen' release within the # environment even if it hasnt affected this issue current_release = GroupRelease.objects.filter( group_id=group.id, environment=environment.name, release_id=ReleaseEnvironment.objects.filter( project_id=group.project_id, organization_id=group.project.organization_id, environment_id=environment.id, ).order_by('-first_seen').values_list('release_id', flat=True).first(), ).first() last_seen = GroupRelease.objects.filter( group_id=group.id, environment=environment.name, ).order_by('-last_seen').values_list('last_seen', flat=True).first() until = request.GET.get('until') if until: until = to_datetime(float(until)) context = { 'environment': serialize( environment, request.user, GroupEnvironmentWithStatsSerializer( group=group, until=until, ) ), 'firstRelease': serialize(first_release, request.user), 'lastRelease': serialize(last_release, request.user), 'currentRelease': serialize( current_release, request.user, GroupReleaseWithStatsSerializer( until=until, ) ), 'lastSeen': last_seen, 'firstSeen': first_release.first_seen if first_release else None, } return Response(context)
def get(self, request, group): """Get the current release in the group's project. Find the most recent release in the project associated with the issue being viewed, regardless of whether the issue has been reported in that release. (That is, the latest release in which the user might expect to have seen the issue.) Then, if the issue has indeed been seen in that release, provide a reference to it. If not, indicate so with a null value for "current release". If the user is filtering by environment, include only releases in those environments. If `environments` is empty, include all environments because the user is not filtering. """ environments = get_environments(request, group.project.organization) with sentry_sdk.start_span( op="CurrentReleaseEndpoint.get.current_release") as span: span.set_data("Environment Count", len(environments)) span.set_data( "Raw Parameters", { "group.id": group.id, "group.project_id": group.project_id, "group.project.organization_id": group.project.organization_id, "environments": [{ "id": e.id, "name": e.name } for e in environments], }, ) current_release = self._get_current_release(group, environments) data = { "currentRelease": serialize(current_release, request.user, GroupReleaseWithStatsSerializer()) } return Response(data)
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)
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)
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)