Example #1
0
    def _build_query_params_from_request(self, request, project):
        query_kwargs = {
            'project': project,
            'sort_by': request.GET.get('sort', DEFAULT_SORT_OPTION),
        }

        limit = request.GET.get('limit')
        if limit:
            try:
                query_kwargs['limit'] = int(limit)
            except ValueError:
                raise ValidationError('invalid limit')

        # TODO: proper pagination support
        cursor = request.GET.get('cursor')
        if cursor:
            query_kwargs['cursor'] = Cursor.from_string(cursor)

        query = request.GET.get('query', 'is:unresolved').strip()
        if query:
            try:
                query_kwargs.update(parse_query(project, query, request.user))
            except InvalidQuery as e:
                raise ValidationError(
                    u'Your search query could not be parsed: {}'.format(
                        e.message)
                )

        return query_kwargs
Example #2
0
    def _get_search_query_and_tags(self, request, group, environments=None):
        raw_query = request.GET.get("query")

        if raw_query:
            query_kwargs = parse_query([group.project], raw_query,
                                       request.user, environments)
            query = query_kwargs.pop("query", None)
            tags = query_kwargs.pop("tags", {})
        else:
            query = None
            tags = {}

        if environments:
            env_names = set(env.name for env in environments)
            if "environment" in tags:
                # If a single environment was passed as part of the query, then
                # we'll just search for that individual environment in this
                # query, even if more are selected.
                if tags["environment"] not in env_names:
                    # An event can only be associated with a single
                    # environment, so if the environments associated with
                    # the request don't contain the environment provided as a
                    # tag lookup, the query cannot contain any valid results.
                    raise NoResults
            else:
                # XXX: Handle legacy backends here. Just store environment as a
                # single tag if we only have one so that we don't break existing
                # usage.
                tags["environment"] = list(
                    env_names) if len(env_names) > 1 else env_names.pop()

        return query, tags
Example #3
0
    def get(self, request, group):
        """
        List an Issue's Events
        ``````````````````````

        This endpoint lists an issue's events.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """

        events = Event.objects.filter(group_id=group.id, )

        query = request.GET.get('query')
        if query:
            query_kwargs = parse_query(group.project, query, request.user)

            if query_kwargs['query']:
                events = events.filter(
                    message__icontains=query_kwargs['query'], )

            if query_kwargs['tags']:
                events = events.filter(id__in=self._tags_to_filter(
                    group, query_kwargs['tags']), )

        return self.paginate(
            request=request,
            queryset=events,
            order_by='-datetime',
            on_results=lambda x: serialize(x, request.user),
            paginator_cls=DateTimePaginator,
        )
Example #4
0
    def _build_query_params_from_request(self, request, project):
        query_kwargs = {
            'project': project,
            'sort_by': request.GET.get('sort', DEFAULT_SORT_OPTION),
        }

        limit = request.GET.get('limit')
        if limit:
            try:
                query_kwargs['limit'] = int(limit)
            except ValueError:
                raise ValidationError('invalid limit')

        # TODO: proper pagination support
        cursor = request.GET.get('cursor')
        if cursor:
            query_kwargs['cursor'] = Cursor.from_string(cursor)

        query = request.GET.get('query', 'is:unresolved').strip()
        if query:
            try:
                query_kwargs.update(parse_query(project, query, request.user))
            except InvalidQuery as e:
                raise ValidationError(
                    u'Your search query could not be parsed: {}'.format(
                        e.message))

        return query_kwargs
Example #5
0
 def test_is_resolved(self):
     result = parse_query('is:resolved', self.user)
     assert result == {
         'status': GroupStatus.RESOLVED,
         'tags': {},
         'query': ''
     }
Example #6
0
    def _get_search_query_and_tags(self, request, group, environments=None):
        raw_query = request.GET.get('query')

        if raw_query:
            query_kwargs = parse_query([group.project], raw_query, request.user, environments)
            query = query_kwargs.pop('query', None)
            tags = query_kwargs.pop('tags', {})
        else:
            query = None
            tags = {}

        if environments:
            env_names = set(env.name for env in environments)
            if 'environment' in tags:
                # If a single environment was passed as part of the query, then
                # we'll just search for that individual environment in this
                # query, even if more are selected.
                if tags['environment'] not in env_names:
                    # An event can only be associated with a single
                    # environment, so if the environments associated with
                    # the request don't contain the environment provided as a
                    # tag lookup, the query cannot contain any valid results.
                    raise NoResults
            else:
                # XXX: Handle legacy backends here. Just store environment as a
                # single tag if we only have one so that we don't break existing
                # usage.
                tags['environment'] = list(env_names) if len(env_names) > 1 else env_names.pop()

        return query, tags
Example #7
0
    def _get_search_query_and_tags(self, request, group, environment=None):
        raw_query = request.GET.get('query')

        if raw_query:
            query_kwargs = parse_query([group.project], raw_query,
                                       request.user)
            query = query_kwargs.pop('query', None)
            tags = query_kwargs.pop('tags', {})
        else:
            query = None
            tags = {}

        if environment is not None:
            if 'environment' in tags and tags[
                    'environment'] != environment.name:
                # An event can only be associated with a single
                # environment, so if the environment associated with
                # the request is different than the environment
                # provided as a tag lookup, the query cannot contain
                # any valid results.
                raise NoResults
            else:
                tags['environment'] = environment.name

        return query, tags
    def get(self, request, group):
        """
        List an Issue's Events
        ``````````````````````

        This endpoint lists an issue's events.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """

        events = Event.objects.filter(group_id=group.id)

        query = request.GET.get("query")
        if query:
            query_kwargs = parse_query(group.project, query, request.user)

            if query_kwargs["query"]:
                events = events.filter(message__icontains=query_kwargs["query"])

            if query_kwargs["tags"]:
                events = events.filter(id__in=self._tags_to_filter(group, query_kwargs["tags"]))

        return self.paginate(
            request=request,
            queryset=events,
            order_by="-datetime",
            on_results=lambda x: serialize(x, request.user),
            paginator_cls=DateTimePaginator,
        )
Example #9
0
    def _get_search_query_and_tags(self, request):
        raw_query = request.GET.get('query')

        if raw_query:
            query_kwargs = parse_query(raw_query, request.user)
            query = query_kwargs.pop('query', None)
            tags = query_kwargs.pop('tags', {})
        else:
            query = None
            tags = {}
        return query, tags
Example #10
0
    def _build_query_params_from_request(self, request, project):
        query_kwargs = {
            'project': project,
        }

        if request.GET.get('status'):
            try:
                query_kwargs['status'] = STATUS_CHOICES[request.GET['status']]
            except KeyError:
                raise ValidationError('invalid status')

        if request.user.is_authenticated() and request.GET.get('bookmarks'):
            query_kwargs['bookmarked_by'] = request.user

        if request.user.is_authenticated() and request.GET.get('assigned'):
            query_kwargs['assigned_to'] = request.user

        sort_by = request.GET.get('sort')
        if sort_by is None:
            sort_by = DEFAULT_SORT_OPTION

        query_kwargs['sort_by'] = sort_by

        tags = {}
        for tag_key in TagKey.objects.all_keys(project):
            if request.GET.get(tag_key):
                tags[tag_key] = request.GET[tag_key]
        if tags:
            query_kwargs['tags'] = tags

        limit = request.GET.get('limit')
        if limit:
            try:
                query_kwargs['limit'] = int(limit)
            except ValueError:
                raise ValidationError('invalid limit')

        # TODO: proper pagination support
        cursor = request.GET.get('cursor')
        if cursor:
            query_kwargs['cursor'] = Cursor.from_string(cursor)

        query = request.GET.get('query', 'is:unresolved').strip()
        if query:
            try:
                query_kwargs.update(parse_query(project, query, request.user))
            except InvalidQuery as e:
                raise ValidationError(
                    u'Your search query could not be parsed: {}'.format(
                        e.message)
                )

        return query_kwargs
Example #11
0
    def get(self, request, group):
        """
        List an Issue's Events
        ``````````````````````

        This endpoint lists an issue's events.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """

        events = Event.objects.filter(group_id=group.id, )

        query = request.GET.get('query')

        if query:
            try:
                query_kwargs = parse_query(group.project, query, request.user)
            except InvalidQuery as exc:
                return Response({'detail': six.text_type(exc)}, status=400)

            if query_kwargs['query']:
                q = Q(message__icontains=query_kwargs['query'])

                if len(query) == 32:
                    q |= Q(event_id__exact=query_kwargs['query'])

                events = events.filter(q)

            if query_kwargs['tags']:
                try:
                    environment_id = self._get_environment_id_from_request(
                        request, group.project.organization_id)
                except Environment.DoesNotExist:
                    event_ids = []
                else:
                    event_ids = tagstore.get_group_event_ids(
                        group.project_id, group.id, environment_id,
                        query_kwargs['tags'])

                if event_ids:
                    events = events.filter(id__in=event_ids, )
                else:
                    events = events.none()

        return self.paginate(
            request=request,
            queryset=events,
            order_by='-datetime',
            on_results=lambda x: serialize(x, request.user),
            paginator_cls=DateTimePaginator,
        )
Example #12
0
def build_query_params_from_request(request, organization, projects,
                                    environments):
    query_kwargs = {
        'projects': projects,
        'sort_by': request.GET.get('sort', DEFAULT_SORT_OPTION),
    }

    limit = request.GET.get('limit')
    if limit:
        try:
            query_kwargs['limit'] = int(limit)
        except ValueError:
            raise ValidationError('invalid limit')

    # TODO: proper pagination support
    cursor = request.GET.get('cursor')
    if cursor:
        query_kwargs['cursor'] = Cursor.from_string(cursor)

    query = request.GET.get('query', 'is:unresolved').strip()
    use_new_filters = request.GET.get('use_new_filters', '1') == '1'
    if query:
        try:
            query_kwargs.update(
                parse_query(projects, query, request.user, environments))
        except InvalidQuery as e:
            raise ValidationError(
                u'Your search query could not be parsed: {}'.format(e.message))
        try:
            search_filters = convert_query_values(
                parse_search_query(query),
                projects,
                request.user,
                environments,
            )
        except Exception:
            # TODO: Catch less broad exceptions when we're confident in these
            # new filters
            logging.exception(
                'Error occurred while parsing new style search query')
            search_filters = []
            # If something goes wrong here we just want to use the working
            # filters
            use_new_filters = False
        if use_new_filters:
            validate_search_filter_permissions(organization, search_filters)
        query_kwargs['search_filters'] = search_filters

    query_kwargs['use_new_filters'] = use_new_filters
    return query_kwargs
Example #13
0
    def _build_query_params_from_request(self, request, project):
        query_kwargs = {
            'project': project,
        }

        if request.GET.get('status'):
            try:
                query_kwargs['status'] = STATUS_CHOICES[request.GET['status']]
            except KeyError:
                raise ValidationError('invalid status')

        if request.user.is_authenticated() and request.GET.get('bookmarks'):
            query_kwargs['bookmarked_by'] = request.user

        if request.user.is_authenticated() and request.GET.get('assigned'):
            query_kwargs['assigned_to'] = request.user

        sort_by = request.GET.get('sort')
        if sort_by is None:
            sort_by = DEFAULT_SORT_OPTION

        query_kwargs['sort_by'] = sort_by

        tags = {}
        for tag_key in TagKey.objects.all_keys(project):
            if request.GET.get(tag_key):
                tags[tag_key] = request.GET[tag_key]
        if tags:
            query_kwargs['tags'] = tags

        limit = request.GET.get('limit')
        if limit:
            try:
                query_kwargs['limit'] = int(limit)
            except ValueError:
                raise ValidationError('invalid limit')

        # TODO: proper pagination support
        cursor = request.GET.get('cursor')
        if cursor:
            query_kwargs['cursor'] = Cursor.from_string(cursor)

        query = request.GET.get('query', 'is:unresolved').strip()
        if query:
            try:
                query_kwargs.update(parse_query(project, query, request.user))
            except InvalidQuery as e:
                raise ValidationError(u'Your search query could not be parsed: {}'.format(e.message))

        return query_kwargs
Example #14
0
    def get(self, request, group):
        """
        List an Issue's Events
        ``````````````````````

        This endpoint lists an issue's events.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """

        events = Event.objects.filter(
            group_id=group.id,
        )

        query = request.GET.get('query')
        if query:
            try:
                query_kwargs = parse_query(group.project, query, request.user)
            except InvalidQuery as exc:
                return Response({'detail': six.text_type(exc)}, status=400)

            if query_kwargs['query']:
                events = events.filter(
                    message__icontains=query_kwargs['query'],
                )

            if query_kwargs['tags']:
                event_ids = tagstore.get_group_event_ids(
                    group.project_id, group.id, query_kwargs['tags'])
                if event_ids:
                    events = events.filter(
                        id__in=event_ids,
                    )
                else:
                    events = events.none()

        return self.paginate(
            request=request,
            queryset=events,
            order_by='-datetime',
            on_results=lambda x: serialize(x, request.user),
            paginator_cls=DateTimePaginator,
        )
Example #15
0
def build_query_params_from_request(request, organization, projects,
                                    environments):
    query_kwargs = {
        'projects': projects,
        'sort_by': request.GET.get('sort', DEFAULT_SORT_OPTION),
    }

    limit = request.GET.get('limit')
    if limit:
        try:
            query_kwargs['limit'] = int(limit)
        except ValueError:
            raise ValidationError('invalid limit')

    # TODO: proper pagination support
    cursor = request.GET.get('cursor')
    if cursor:
        query_kwargs['cursor'] = Cursor.from_string(cursor)

    query = request.GET.get('query', 'is:unresolved').strip()
    if query:
        try:
            query_kwargs.update(
                parse_query(projects, query, request.user, environments))
        except InvalidQuery as e:
            raise ValidationError(
                u'Your search query could not be parsed: {}'.format(e.message))
        try:
            search_filters = convert_query_values(
                parse_search_query(query),
                projects,
                request.user,
                environments,
            )
        except InvalidSearchQuery as e:
            raise ValidationError(
                u'Your search query could not be parsed: {}'.format(e.message))

        validate_search_filter_permissions(organization, search_filters)
        query_kwargs['search_filters'] = search_filters

    return query_kwargs
Example #16
0
    def get(self, request, group):
        """
        List an Issue's Events
        ``````````````````````

        This endpoint lists an issue's events.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """

        events = Event.objects.filter(group_id=group.id, )

        query = request.GET.get('query')
        if query:
            try:
                query_kwargs = parse_query(group.project, query, request.user)
            except InvalidQuery as exc:
                return Response({'detail': six.text_type(exc)}, status=400)

            if query_kwargs['query']:
                events = events.filter(
                    message__icontains=query_kwargs['query'], )

            if query_kwargs['tags']:
                matches = self._tags_to_filter(group, query_kwargs['tags'])
                if matches:
                    events = events.filter(id__in=matches, )
                else:
                    events = events.none()

        return self.paginate(
            request=request,
            queryset=events,
            order_by='-datetime',
            on_results=lambda x: serialize(x, request.user),
            paginator_cls=DateTimePaginator,
        )
Example #17
0
 def test_single_tag_with_quotes(self):
     result = parse_query('foo:"bar"', self.user)
     assert result == {'tags': {'foo': 'bar'}, 'query': ''}
Example #18
0
 def test_multiple_tags(self):
     result = parse_query('foo:bar key:value', self.user)
     assert result == {'tags': {'key': 'value', 'foo': 'bar'}, 'query': ''}
Example #19
0
 def test_tag_with_colon_in_value(self):
     result = parse_query('url:http://example.com', self.user)
     assert result == {'tags': {'url': 'http://example.com'}, 'query': ''}
Example #20
0
 def test_single_tag(self):
     result = parse_query('key:value', self.user)
     assert result == {'tags': {'key': 'value'}, 'query': ''}
Example #21
0
 def test_mix_tag_and_query(self):
     result = parse_query('foo bar key:value', self.user)
     assert result == {'tags': {'key': 'value'}, 'query': 'foo bar'}
Example #22
0
 def test_useless_prefix(self):
     result = parse_query('foo: bar', self.user)
     assert result == {'tags': {}, 'query': 'foo: bar'}
Example #23
0
    def get(self, request, group):
        """
        List an Issue's Events
        ``````````````````````

        This endpoint lists an issue's events.

        :pparam string issue_id: the ID of the issue to retrieve.
        :auth: required
        """

        def respond(queryset):
            return self.paginate(
                request=request,
                queryset=queryset,
                order_by='-datetime',
                on_results=lambda x: serialize(x, request.user),
                paginator_cls=DateTimePaginator,
            )

        events = Event.objects.filter(group_id=group.id)

        try:
            environment = self._get_environment_from_request(
                request,
                group.project.organization_id,
            )
        except Environment.DoesNotExist:
            return respond(events.none())

        raw_query = request.GET.get('query')

        if raw_query:
            try:
                query_kwargs = parse_query(group.project, raw_query, request.user)
            except InvalidQuery as exc:
                return Response({'detail': six.text_type(exc)}, status=400)
            else:
                query = query_kwargs.pop('query', None)
                tags = query_kwargs.pop('tags', {})
        else:
            query = None
            tags = {}

        if environment is not None:
            if 'environment' in tags and tags['environment'] != environment.name:
                # An event can only be associated with a single
                # environment, so if the environment associated with
                # the request is different than the environment
                # provided as a tag lookup, the query cannot contain
                # any valid results.
                return respond(events.none())
            else:
                tags['environment'] = environment.name

        if query:
            q = Q(message__icontains=query)

            if len(query) == 32:
                q |= Q(event_id__exact=query)

            events = events.filter(q)

        if tags:
            event_ids = tagstore.get_group_event_ids(
                group.project_id,
                group.id,
                environment.id if environment is not None else None,
                tags,
            )

            if not event_ids:
                return respond(events.none())

            events = events.filter(id__in=event_ids)

        # filter out events which are beyond the retention period
        retention = quotas.get_event_retention(organization=group.project.organization)
        if retention:
            events = events.filter(
                datetime__gte=timezone.now() - timedelta(days=retention)
            )

        return respond(events)
Example #24
0
 def parse_query(self, query):
     return parse_query(self.project, query, self.user)
Example #25
0
 def parse_query(self, query):
     return parse_query([self.project], query, self.user, None)
Example #26
0
 def test_assigned_me(self):
     result = parse_query('assigned:me', self.user)
     assert result == {'assigned_to': self.user, 'tags': {}, 'query': ''}
Example #27
0
 def test_simple(self):
     result = parse_query('foo bar', self.user)
     assert result == {'tags': {}, 'query': 'foo bar'}
Example #28
0
 def test_release(self):
     result = parse_query('release:bar', self.user)
     assert result == {'tags': {'sentry:release': 'bar'}, 'query': ''}
Example #29
0
 def test_assigned_unknown_user(self):
     result = parse_query('assigned:[email protected]', self.user)
     assert result['assigned_to'].id == 0
Example #30
0
 def test_tag_with_quotes_and_query(self):
     result = parse_query('key:"a value" hello', self.user)
     assert result == {'tags': {'key': 'a value'}, 'query': 'hello'}
Example #31
0
    def _build_query_params_from_request(self, request, project):
        query_kwargs = {
            'project': project,
        }

        if request.GET.get('status'):
            try:
                query_kwargs['status'] = STATUS_CHOICES[request.GET['status']]
            except KeyError:
                raise ValidationError('invalid status')

        if request.user.is_authenticated() and request.GET.get('bookmarks'):
            query_kwargs['bookmarked_by'] = request.user

        if request.user.is_authenticated() and request.GET.get('assigned'):
            query_kwargs['assigned_to'] = request.user

        sort_by = request.GET.get('sort')
        if sort_by is None:
            sort_by = DEFAULT_SORT_OPTION

        query_kwargs['sort_by'] = sort_by

        tags = {}
        for tag_key in TagKey.objects.all_keys(project):
            if request.GET.get(tag_key):
                tags[tag_key] = request.GET[tag_key]
        if tags:
            query_kwargs['tags'] = tags

        # TODO: dates should include timestamps
        date_from = request.GET.get('since')
        date_to = request.GET.get('until')
        date_filter = request.GET.get('date_filter')

        limit = request.GET.get('limit')
        if limit:
            try:
                query_kwargs['limit'] = int(limit)
            except ValueError:
                raise ValidationError('invalid limit')

        if date_from:
            date_from = self._parse_date(date_from)

        if date_to:
            date_to = self._parse_date(date_to)

        query_kwargs['date_from'] = date_from
        query_kwargs['date_to'] = date_to
        if date_filter:
            query_kwargs['date_filter'] = date_filter

        # TODO: proper pagination support
        cursor = request.GET.get('cursor')
        if cursor:
            query_kwargs['cursor'] = Cursor.from_string(cursor)

        query = request.GET.get('query', 'is:unresolved').strip()
        if query:
            query_kwargs.update(parse_query(project, query, request.user))

        return query_kwargs
Example #32
0
 def test_is_resolved(self):
     result = parse_query('is:resolved', self.user)
     assert result == {'status': GroupStatus.RESOLVED, 'tags': {}, 'query': ''}
Example #33
0
    def get(self, request, project):
        """
        List a project's aggregates

        Return a list of aggregates bound to a project.

            {method} {path}

        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).

        Any standard Sentry structured search query can be passed via the
        ``query`` parameter.

        The ``statsPeriod`` parameter can be used to select the timeline stats
        which should be present. Possible values are: '' (disable), '24h', '14d'
        """
        query_kwargs = {
            'project': project,
        }

        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

        if request.GET.get('status'):
            try:
                query_kwargs['status'] = STATUS_CHOICES[request.GET['status']]
            except KeyError:
                return Response('{"detail": "invalid status"}', status=400)

        if request.user.is_authenticated() and request.GET.get('bookmarks'):
            query_kwargs['bookmarked_by'] = request.user

        if request.user.is_authenticated() and request.GET.get('assigned'):
            query_kwargs['assigned_to'] = request.user

        sort_by = request.GET.get('sort')
        if sort_by is None:
            sort_by = DEFAULT_SORT_OPTION

        query_kwargs['sort_by'] = sort_by

        tags = {}
        for tag_key in TagKey.objects.all_keys(project):
            if request.GET.get(tag_key):
                tags[tag_key] = request.GET[tag_key]
        if tags:
            query_kwargs['tags'] = tags

        # TODO: dates should include timestamps
        date_from = request.GET.get('since')
        date_to = request.GET.get('until')
        date_filter = request.GET.get('date_filter')

        limit = request.GET.get('limit')
        if limit:
            try:
                query_kwargs['limit'] = int(limit)
            except ValueError:
                return Response('{"detail": "invalid limit"}', status=400)

        if date_from:
            date_from = self._parse_date(date_from)

        if date_to:
            date_to = self._parse_date(date_to)

        query_kwargs['date_from'] = date_from
        query_kwargs['date_to'] = date_to
        if date_filter:
            query_kwargs['date_filter'] = date_filter

        # TODO: proper pagination support
        cursor = request.GET.get('cursor')
        if cursor:
            query_kwargs['cursor'] = Cursor.from_string(cursor)

        query = request.GET.get('query', 'is:unresolved').strip()
        if len(query) == 32:
            # check to see if we've got an event ID
            try:
                matching_event = EventMapping.objects.filter(
                    project=project,
                    event_id=query,
                ).select_related('group')[0]
            except IndexError:
                pass
            else:
                return Response(serialize(
                    [matching_event.group], request.user, StreamGroupSerializer(
                        stats_period=stats_period
                    )
                ))

        if query is not None:
            query_kwargs.update(parse_query(query, request.user))

        cursor_result = search.query(**query_kwargs)

        results = list(cursor_result)

        # HACK: remove auto resolved entries
        if query_kwargs.get('status') == STATUS_UNRESOLVED:
            results = [
                r for r in results
                if not r.is_resolved()
            ]

        response = Response(serialize(
            results, request.user, StreamGroupSerializer(
                stats_period=stats_period
            )
        ))
        response['Link'] = ', '.join([
            self.build_cursor_link(request, 'previous', cursor_result.prev),
            self.build_cursor_link(request, 'next', cursor_result.next),
        ])

        return response
Example #34
0
 def test_assigned_email(self):
     result = parse_query('assigned:%s' % (self.user.email,), self.user)
     assert result == {'assigned_to': self.user, 'tags': {}, 'query': ''}
Example #35
0
    def _build_query_params_from_request(self, request, project):
        query_kwargs = {
            'project': project,
        }

        if request.GET.get('status'):
            try:
                query_kwargs['status'] = STATUS_CHOICES[request.GET['status']]
            except KeyError:
                raise ValidationError('invalid status')

        if request.user.is_authenticated() and request.GET.get('bookmarks'):
            query_kwargs['bookmarked_by'] = request.user

        if request.user.is_authenticated() and request.GET.get('assigned'):
            query_kwargs['assigned_to'] = request.user

        sort_by = request.GET.get('sort')
        if sort_by is None:
            sort_by = DEFAULT_SORT_OPTION

        query_kwargs['sort_by'] = sort_by

        tags = {}
        for tag_key in TagKey.objects.all_keys(project):
            if request.GET.get(tag_key):
                tags[tag_key] = request.GET[tag_key]
        if tags:
            query_kwargs['tags'] = tags

        # TODO: dates should include timestamps
        date_from = request.GET.get('since')
        date_to = request.GET.get('until')
        date_filter = request.GET.get('date_filter')

        limit = request.GET.get('limit')
        if limit:
            try:
                query_kwargs['limit'] = int(limit)
            except ValueError:
                raise ValidationError('invalid limit')

        if date_from:
            date_from = self._parse_date(date_from)

        if date_to:
            date_to = self._parse_date(date_to)

        query_kwargs['date_from'] = date_from
        query_kwargs['date_to'] = date_to
        if date_filter:
            query_kwargs['date_filter'] = date_filter

        # TODO: proper pagination support
        cursor = request.GET.get('cursor')
        if cursor:
            query_kwargs['cursor'] = Cursor.from_string(cursor)

        query = request.GET.get('query', 'is:unresolved').strip()
        if query:
            query_kwargs.update(parse_query(project, query, request.user))

        return query_kwargs
Example #36
0
 def test_first_release(self):
     result = parse_query('first-release:bar', self.user)
     assert result == {'first_release': 'bar', 'tags': {}, 'query': ''}
Example #37
0
 def parse_query(self, query):
     return parse_query(self.project, query, self.user)
Example #38
0
 def test_padded_spacing(self):
     result = parse_query('release:bar  foo   bar', self.user)
     assert result == {'tags': {'sentry:release': 'bar'}, 'query': 'foo bar'}
Example #39
0
def _get_group_list(request, project):
    query_kwargs = {"project": project}

    status = request.GET.get("status", "0")
    if status:
        query_kwargs["status"] = int(status)

    if request.user.is_authenticated() and request.GET.get("bookmarks"):
        query_kwargs["bookmarked_by"] = request.user

    if request.user.is_authenticated() and request.GET.get("assigned"):
        query_kwargs["assigned_to"] = request.user

    sort_by = request.GET.get("sort") or request.session.get("streamsort")
    if sort_by is None:
        sort_by = DEFAULT_SORT_OPTION

    # Save last sort in session
    if sort_by != request.session.get("streamsort"):
        request.session["streamsort"] = sort_by

    query_kwargs["sort_by"] = sort_by

    tags = {}
    for tag_key in TagKey.objects.all_keys(project):
        if request.GET.get(tag_key):
            tags[tag_key] = request.GET[tag_key]

    if tags:
        query_kwargs["tags"] = tags
    else:
        query_kwargs["tags"] = {}

    date_from = request.GET.get("df")
    time_from = request.GET.get("tf")
    date_to = request.GET.get("dt")
    time_to = request.GET.get("tt")
    date_filter = request.GET.get("date_type")

    today = timezone.now()
    # date format is Y-m-d
    if any(x is not None for x in [date_from, time_from, date_to, time_to]):
        date_from, date_to = parse_date(date_from, time_from), parse_date(date_to, time_to)
    else:
        date_from = today - datetime.timedelta(days=5)
        date_to = None

    query_kwargs["date_from"] = date_from
    query_kwargs["date_to"] = date_to
    if date_filter:
        query_kwargs["date_filter"] = date_filter

    cursor = request.GET.get("cursor")
    if cursor:
        try:
            query_kwargs["cursor"] = Cursor.from_string(cursor)
        except ValueError:
            # XXX(dcramer): ideally we'd error, but this is an internal API so
            # we'd rather just throw it away
            logging.info("Throwing away invalid cursor: %s", cursor)
    query_kwargs["limit"] = EVENTS_PER_PAGE

    query = request.GET.get("query", "")
    if query is not None:
        query_result = parse_query(query, request.user)
        # Disclaimer: the following code is disgusting
        if query_result.get("query"):
            query_kwargs["query"] = query_result["query"]
        if query_result.get("tags"):
            query_kwargs["tags"].update(query_result["tags"])

    results = app.search.query(**query_kwargs)

    return {
        "event_list": results[:EVENTS_PER_PAGE],
        "date_from": date_from,
        "date_to": date_to,
        "today": today,
        "sort": sort_by,
        "date_type": date_filter,
        "next_cursor": results.next,
        "prev_cursor": results.prev,
    }
Example #40
0
    def get(self, request, project_id):
        """
        List a project's aggregates

        Return a list of aggregates bound to a project.

            {method} {path}?id=1&id=2&id=3

        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).

        Any standard Sentry structured search query can be passed via the
        ``query`` parameter.
        """
        project = Project.objects.get_from_cache(
            id=project_id,
        )

        assert_perm(project, request.user, request.auth)

        query_kwargs = {
            'project': project,
        }

        if request.GET.get('status'):
            try:
                query_kwargs['status'] = STATUS_CHOICES[request.GET['status']]
            except KeyError:
                return Response('{"error": "invalid status"}', status=400)

        if request.user.is_authenticated() and request.GET.get('bookmarks'):
            query_kwargs['bookmarked_by'] = request.user

        if request.user.is_authenticated() and request.GET.get('assigned'):
            query_kwargs['assigned_to'] = request.user

        sort_by = request.GET.get('sort')
        if sort_by is None:
            sort_by = DEFAULT_SORT_OPTION

        query_kwargs['sort_by'] = sort_by

        tags = {}
        for tag_key in TagKey.objects.all_keys(project):
            if request.GET.get(tag_key):
                tags[tag_key] = request.GET[tag_key]
        if tags:
            query_kwargs['tags'] = tags

        # TODO: dates should include timestamps
        date_from = request.GET.get('since')
        time_from = request.GET.get('until')
        date_filter = request.GET.get('date_filter')

        date_to = request.GET.get('dt')
        time_to = request.GET.get('tt')
        limit = request.GET.get('limit')
        if limit:
            try:
                query_kwargs['limit'] = int(limit)
            except ValueError:
                return Response('{"error": "invalid limit"}', status=400)

        today = timezone.now()
        # date format is Y-m-d
        if any(x is not None for x in [date_from, time_from, date_to, time_to]):
            date_from, date_to = parse_date(date_from, time_from), parse_date(date_to, time_to)
        else:
            date_from = today - timedelta(days=5)
            date_to = None

        query_kwargs['date_from'] = date_from
        query_kwargs['date_to'] = date_to
        if date_filter:
            query_kwargs['date_filter'] = date_filter

        # TODO: proper pagination support
        cursor = request.GET.get('cursor')
        if cursor:
            query_kwargs['cursor'] = Cursor.from_string(cursor)

        query = request.GET.get('query', 'is:unresolved')
        if query is not None:
            query_kwargs.update(parse_query(query, request.user))

        cursor_result = search.query(**query_kwargs)

        context = list(cursor_result)

        GroupMeta.objects.populate_cache(context)

        response = Response(serialize(context, request.user))
        response['Link'] = ', '.join([
            self.build_cursor_link(request, 'previous', cursor_result.prev),
            self.build_cursor_link(request, 'next', cursor_result.next),
        ])

        return response
Example #41
0
def _get_group_list(request, project):
    query_kwargs = {
        'project': project,
    }

    status = request.GET.get('status', '0')
    if status:
        query_kwargs['status'] = int(status)

    if request.user.is_authenticated() and request.GET.get('bookmarks'):
        query_kwargs['bookmarked_by'] = request.user

    if request.user.is_authenticated() and request.GET.get('assigned'):
        query_kwargs['assigned_to'] = request.user

    sort_by = request.GET.get('sort') or request.session.get('streamsort')
    if sort_by is None:
        sort_by = DEFAULT_SORT_OPTION

    # Save last sort in session
    if sort_by != request.session.get('streamsort'):
        request.session['streamsort'] = sort_by

    query_kwargs['sort_by'] = sort_by

    tags = {}
    for tag_key in TagKey.objects.all_keys(project):
        if request.GET.get(tag_key):
            tags[tag_key] = request.GET[tag_key]

    if tags:
        query_kwargs['tags'] = tags
    else:
        query_kwargs['tags'] = {}

    date_from = request.GET.get('df')
    time_from = request.GET.get('tf')
    date_to = request.GET.get('dt')
    time_to = request.GET.get('tt')
    date_filter = request.GET.get('date_type')

    today = timezone.now()
    # date format is Y-m-d
    if any(x is not None for x in [date_from, time_from, date_to, time_to]):
        date_from, date_to = parse_date(date_from, time_from), parse_date(date_to, time_to)
    else:
        date_from = today - datetime.timedelta(days=5)
        date_to = None

    query_kwargs['date_from'] = date_from
    query_kwargs['date_to'] = date_to
    if date_filter:
        query_kwargs['date_filter'] = date_filter

    cursor = request.GET.get('cursor')
    if cursor:
        try:
            query_kwargs['cursor'] = Cursor.from_string(cursor)
        except ValueError:
            # XXX(dcramer): ideally we'd error, but this is an internal API so
            # we'd rather just throw it away
            logging.info('Throwing away invalid cursor: %s', cursor)
    query_kwargs['limit'] = EVENTS_PER_PAGE

    query = request.GET.get('query', '')
    if query is not None:
        query_result = parse_query(query, request.user)
        # Disclaimer: the following code is disgusting
        if query_result.get('query'):
            query_kwargs['query'] = query_result['query']
        if query_result.get('tags'):
            query_kwargs['tags'].update(query_result['tags'])

    results = app.search.query(**query_kwargs)

    return {
        'event_list': results[:EVENTS_PER_PAGE],
        'date_from': date_from,
        'date_to': date_to,
        'today': today,
        'sort': sort_by,
        'date_type': date_filter,
        'next_cursor': results.next,
        'prev_cursor': results.prev,
    }
Example #42
0
 def parse_query(self, query):
     return parse_query([self.project], query, self.user, None)
Example #43
0
    def get(self, request, project):
        """
        List a Project's Aggregates
        ```````````````````````````

        Return a list of aggregates 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 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
                                          groups belong to.
        :pparam string project_slug: the slug of the project the groups
                                     belong to.
        :auth: required
        """
        query_kwargs = {
            'project': project,
        }

        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

        if request.GET.get('status'):
            try:
                query_kwargs['status'] = STATUS_CHOICES[request.GET['status']]
            except KeyError:
                return Response('{"detail": "invalid status"}', status=400)

        if request.user.is_authenticated() and request.GET.get('bookmarks'):
            query_kwargs['bookmarked_by'] = request.user

        if request.user.is_authenticated() and request.GET.get('assigned'):
            query_kwargs['assigned_to'] = request.user

        sort_by = request.GET.get('sort')
        if sort_by is None:
            sort_by = DEFAULT_SORT_OPTION

        query_kwargs['sort_by'] = sort_by

        tags = {}
        for tag_key in TagKey.objects.all_keys(project):
            if request.GET.get(tag_key):
                tags[tag_key] = request.GET[tag_key]
        if tags:
            query_kwargs['tags'] = tags

        # TODO: dates should include timestamps
        date_from = request.GET.get('since')
        date_to = request.GET.get('until')
        date_filter = request.GET.get('date_filter')

        limit = request.GET.get('limit')
        if limit:
            try:
                query_kwargs['limit'] = int(limit)
            except ValueError:
                return Response('{"detail": "invalid limit"}', status=400)

        if date_from:
            date_from = self._parse_date(date_from)

        if date_to:
            date_to = self._parse_date(date_to)

        query_kwargs['date_from'] = date_from
        query_kwargs['date_to'] = date_to
        if date_filter:
            query_kwargs['date_filter'] = date_filter

        # TODO: proper pagination support
        cursor = request.GET.get('cursor')
        if cursor:
            query_kwargs['cursor'] = Cursor.from_string(cursor)

        query = request.GET.get('query', 'is:unresolved').strip()
        if len(query) == 32:
            # check to see if we've got an event ID
            try:
                matching_event = EventMapping.objects.filter(
                    project=project,
                    event_id=query,
                ).select_related('group')[0]
            except IndexError:
                pass
            else:
                return Response(
                    serialize(
                        [matching_event.group], request.user,
                        StreamGroupSerializer(stats_period=stats_period)))

        if query is not None:
            query_kwargs.update(parse_query(project, query, request.user))

        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