def get_by_short_id(organization_id, is_short_id_lookup, query): if is_short_id_lookup == '1' and \ looks_like_short_id(query): try: return Group.objects.by_qualified_short_id(organization_id, query) except Group.DoesNotExist: pass
def get_by_short_id(organization_id, is_short_id_lookup, query): if is_short_id_lookup == '1' and \ looks_like_short_id(query): try: return Group.objects.by_qualified_short_id( organization_id, query ) except Group.DoesNotExist: pass
def get_by_short_id( organization_id: int, is_short_id_lookup: str, query: str, ) -> Optional["Group"]: if is_short_id_lookup == "1" and looks_like_short_id(query): try: return Group.objects.by_qualified_short_id(organization_id, query) except Group.DoesNotExist: pass return None
def get(self, request, project): """ List a Project's Issues ``````````````````````` Return a list of issues (groups) bound to a project. All parameters are supplied as query string parameters. A default query of ``is:unresolved`` is applied. To return results with other statuses send an new query value (i.e. ``?query=`` for all results). The ``statsPeriod`` parameter can be used to select the timeline stats which should be present. Possible values are: '' (disable), '24h', '14d' :qparam string statsPeriod: an optional stat period (can be one of ``"24h"``, ``"14d"``, and ``""``). :qparam bool shortIdLookup: if this is set to true then short IDs are looked up by this function as well. This can cause the return value of the function to return an event issue of a different project which is why this is an opt-in. Set to `1` to enable. :qparam querystring query: an optional Sentry structured search query. If not provided an implied ``"is:unresolved"`` is assumed.) :pparam string organization_slug: the slug of the organization the issues belong to. :pparam string project_slug: the slug of the project the issues belong to. :auth: required """ stats_period = request.GET.get('statsPeriod') if stats_period not in (None, '', '24h', '14d'): return Response({"detail": ERR_INVALID_STATS_PERIOD}, status=400) elif stats_period is None: # default stats_period = '24h' elif stats_period == '': # disable stats stats_period = None serializer = functools.partial( StreamGroupSerializer, environment_func=self._get_environment_func( request, project.organization_id), stats_period=stats_period, ) query = request.GET.get('query', '').strip() if query: matching_group = None matching_event = None if len(query) == 32: # check to see if we've got an event ID try: matching_group = Group.objects.from_event_id( project, query) except Group.DoesNotExist: pass else: try: matching_event = Event.objects.get( event_id=query, project_id=project.id) except Event.DoesNotExist: pass else: Event.objects.bind_nodes([matching_event], 'data') # If the query looks like a short id, we want to provide some # information about where that is. Note that this can return # results for another project. The UI deals with this. elif request.GET.get('shortIdLookup') == '1' and \ looks_like_short_id(query): try: matching_group = Group.objects.by_qualified_short_id( project.organization_id, query) except Group.DoesNotExist: matching_group = None if matching_group is not None: matching_event_environment = None try: matching_event_environment = matching_event.get_environment( ).name if matching_event else None except Environment.DoesNotExist: pass response = Response( serialize([matching_group], request.user, serializer( matching_event_id=getattr( matching_event, 'id', None), matching_event_environment= matching_event_environment, ))) response['X-Sentry-Direct-Hit'] = '1' return response try: cursor_result, query_kwargs = self._search(request, project, {'count_hits': True}) except ValidationError as exc: return Response({'detail': six.text_type(exc)}, status=400) results = list(cursor_result) context = serialize(results, request.user, serializer()) # HACK: remove auto resolved entries if query_kwargs.get('status') == GroupStatus.UNRESOLVED: context = [r for r in context if r['status'] == 'unresolved'] response = Response(context) self.add_cursor_headers(request, response, cursor_result) if results and query not in SAVED_SEARCH_QUERIES: advanced_search.send(project=project, sender=request.user) analytics.record('project_issue.searched', user_id=request.user.id, organization_id=project.organization_id, project_id=project.id, query=query) return response
def get(self, request, project): """ List a Project's Issues ``````````````````````` Return a list of issues (groups) bound to a project. All parameters are supplied as query string parameters. A default query of ``is:unresolved`` is applied. To return results with other statuses send an new query value (i.e. ``?query=`` for all results). The ``statsPeriod`` parameter can be used to select the timeline stats which should be present. Possible values are: '' (disable), '24h', '14d' :qparam string statsPeriod: an optional stat period (can be one of ``"24h"``, ``"14d"``, and ``""``). :qparam bool shortIdLookup: if this is set to true then short IDs are looked up by this function as well. This can cause the return value of the function to return an event issue of a different project which is why this is an opt-in. Set to `1` to enable. :qparam querystring query: an optional Sentry structured search query. If not provided an implied ``"is:unresolved"`` is assumed.) :pparam string organization_slug: the slug of the organization the issues belong to. :pparam string project_slug: the slug of the project the issues belong to. :auth: required """ stats_period = request.GET.get('statsPeriod') if stats_period not in (None, '', '24h', '14d'): return Response({"detail": ERR_INVALID_STATS_PERIOD}, status=400) elif stats_period is None: # default stats_period = '24h' elif stats_period == '': # disable stats stats_period = None query = request.GET.get('query', '').strip() if query: matching_group = None matching_event = None if len(query) == 32: # check to see if we've got an event ID try: mapping = EventMapping.objects.get( project_id=project.id, event_id=query, ) except EventMapping.DoesNotExist: pass else: matching_group = Group.objects.get(id=mapping.group_id) try: matching_event = Event.objects.get( event_id=query, project_id=project.id) except Event.DoesNotExist: pass # If the query looks like a short id, we want to provide some # information about where that is. Note that this can return # results for another project. The UI deals with this. elif request.GET.get('shortIdLookup') == '1' and \ looks_like_short_id(query): try: matching_group = Group.objects.by_qualified_short_id( project.organization_id, query) except Group.DoesNotExist: matching_group = None if matching_group is not None: response = Response( serialize([matching_group], request.user, StreamGroupSerializer(stats_period=stats_period, matching_event_id=getattr( matching_event, 'id', None)))) response['X-Sentry-Direct-Hit'] = '1' return response try: query_kwargs = self._build_query_params_from_request( request, project) except ValidationError as exc: return Response({'detail': six.text_type(exc)}, status=400) cursor_result = search.query(**query_kwargs) results = list(cursor_result) context = serialize(results, request.user, StreamGroupSerializer(stats_period=stats_period)) # HACK: remove auto resolved entries if query_kwargs.get('status') == GroupStatus.UNRESOLVED: context = [r for r in context if r['status'] == 'unresolved'] response = Response(context) response['Link'] = ', '.join([ self.build_cursor_link(request, 'previous', cursor_result.prev), self.build_cursor_link(request, 'next', cursor_result.next), ]) return response
def get(self, request, project): """ List a Project's Issues ``````````````````````` Return a list of issues (groups) bound to a project. All parameters are supplied as query string parameters. A default query of ``is:resolved`` is applied. To return results with other statuses send an new query value (i.e. ``?query=`` for all results). The ``statsPeriod`` parameter can be used to select the timeline stats which should be present. Possible values are: '' (disable), '24h', '14d' :qparam string statsPeriod: an optional stat period (can be one of ``"24h"``, ``"14d"``, and ``""``). :qparam bool shortIdLookup: if this is set to true then short IDs are looked up by this function as well. This can cause the return value of the function to return an event issue of a different project which is why this is an opt-in. Set to `1` to enable. :qparam querystring query: an optional Sentry structured search query. If not provided an implied ``"is:resolved"`` is assumed.) :pparam string organization_slug: the slug of the organization the issues belong to. :pparam string project_slug: the slug of the project the issues belong to. :auth: required """ stats_period = request.GET.get('statsPeriod') if stats_period not in (None, '', '24h', '14d'): return Response({"detail": ERR_INVALID_STATS_PERIOD}, status=400) elif stats_period is None: # default stats_period = '24h' elif stats_period == '': # disable stats stats_period = None query = request.GET.get('query', '').strip() if query: matching_group = None if len(query) == 32: # check to see if we've got an event ID try: mapping = EventMapping.objects.get( project_id=project.id, event_id=query, ) except EventMapping.DoesNotExist: pass else: matching_group = Group.objects.get(id=mapping.group_id) # If the query looks like a short id, we want to provide some # information about where that is. Note that this can return # results for another project. The UI deals with this. elif request.GET.get('shortIdLookup') == '1' and \ looks_like_short_id(query): try: matching_group = Group.objects.by_qualified_short_id( project.organization, query) except Group.DoesNotExist: matching_group = None if matching_group is not None: response = Response(serialize( [matching_group], request.user, StreamGroupSerializer( stats_period=stats_period ) )) response['X-Sentry-Direct-Hit'] = '1' return response try: query_kwargs = self._build_query_params_from_request(request, project) except ValidationError as exc: return Response({'detail': six.text_type(exc)}, status=400) cursor_result = search.query(**query_kwargs) results = list(cursor_result) context = serialize( results, request.user, StreamGroupSerializer( stats_period=stats_period ) ) # HACK: remove auto resolved entries if query_kwargs.get('status') == GroupStatus.UNRESOLVED: context = [ r for r in context if r['status'] == 'unresolved' ] response = Response(context) response['Link'] = ', '.join([ self.build_cursor_link(request, 'previous', cursor_result.prev), self.build_cursor_link(request, 'next', cursor_result.next), ]) return response
def get(self, request, project): """ List a Project's Issues ``````````````````````` Return a list of issues (groups) bound to a project. All parameters are supplied as query string parameters. A default query of ``is:unresolved`` is applied. To return results with other statuses send an new query value (i.e. ``?query=`` for all results). The ``statsPeriod`` parameter can be used to select the timeline stats which should be present. Possible values are: '' (disable), '24h', '14d' :qparam string statsPeriod: an optional stat period (can be one of ``"24h"``, ``"14d"``, and ``""``). :qparam bool shortIdLookup: if this is set to true then short IDs are looked up by this function as well. This can cause the return value of the function to return an event issue of a different project which is why this is an opt-in. Set to `1` to enable. :qparam querystring query: an optional Sentry structured search query. If not provided an implied ``"is:unresolved"`` is assumed.) :pparam string organization_slug: the slug of the organization the issues belong to. :pparam string project_slug: the slug of the project the issues belong to. :auth: required """ stats_period = request.GET.get('statsPeriod') if stats_period not in (None, '', '24h', '14d'): return Response({"detail": ERR_INVALID_STATS_PERIOD}, status=400) elif stats_period is None: # default stats_period = '24h' elif stats_period == '': # disable stats stats_period = None serializer = functools.partial( StreamGroupSerializer, environment_func=self._get_environment_func(request, project.organization_id), stats_period=stats_period, ) query = request.GET.get('query', '').strip() if query: matching_group = None matching_event = None if len(query) == 32: # check to see if we've got an event ID try: matching_group = Group.objects.from_event_id(project, query) except Group.DoesNotExist: pass else: try: matching_event = Event.objects.get( event_id=query, project_id=project.id) except Event.DoesNotExist: pass else: Event.objects.bind_nodes([matching_event], 'data') # If the query looks like a short id, we want to provide some # information about where that is. Note that this can return # results for another project. The UI deals with this. elif request.GET.get('shortIdLookup') == '1' and \ looks_like_short_id(query): try: matching_group = Group.objects.by_qualified_short_id( project.organization_id, query ) except Group.DoesNotExist: matching_group = None if matching_group is not None: matching_event_environment = None try: matching_event_environment = matching_event.get_environment().name if matching_event else None except Environment.DoesNotExist: pass response = Response( serialize( [matching_group], request.user, serializer( matching_event_id=getattr(matching_event, 'id', None), matching_event_environment=matching_event_environment, ) ) ) response['X-Sentry-Direct-Hit'] = '1' return response try: cursor_result, query_kwargs = self._search(request, project, {'count_hits': True}) except ValidationError as exc: return Response({'detail': six.text_type(exc)}, status=400) results = list(cursor_result) context = serialize(results, request.user, serializer()) # HACK: remove auto resolved entries if query_kwargs.get('status') == GroupStatus.UNRESOLVED: context = [r for r in context if r['status'] == 'unresolved'] response = Response(context) self.add_cursor_headers(request, response, cursor_result) if results and query not in SAVED_SEARCH_QUERIES: advanced_search.send(project=project, sender=request.user) analytics.record('project_issue.searched', user_id=request.user.id, organization_id=project.organization_id, project_id=project.id, query=query) return response