예제 #1
0
파일: json.py 프로젝트: Kamlani/reviewboard
def count_review_requests(request, func, api_format='json',
                          local_site_name=None, *args, **kwargs):
    """
    Returns the number of review requests.

    Optional parameters:

      * status: The status of the returned review requests. This defaults
                to "pending".
    """
    local_site = get_object_or_none(LocalSite, name=local_site_name)
    status = string_to_status(request.GET.get('status', 'pending'))
    return WebAPIResponse(request, {
        'count': func(user=request.user, status=status,
                      local_site=local_site, **kwargs).count()
    })
예제 #2
0
    def update(self, request, status=None, changenum=None, description=None,
               extra_fields={}, *args, **kwargs):
        """Updates the status of the review request.

        The only supported update to a review request's resource is to change
        the status, the associated server-side, change number, or to update
        information from the existing change number.

        The status can be set in order to close the review request as
        discarded or submitted, or to reopen as pending.

        For Perforce, a change number can either be changed to a new number, or
        the current change number can be passed. In either case, a new draft
        will be created or an existing one updated to include information from
        the server based on the change number. This behavior is deprecated,
        and instead, the commit_id field should be set on the draft.

        Changes to a review request's fields, such as the summary or the
        list of reviewers, is made on the Review Request Draft resource.
        This can be accessed through the ``draft`` link. Only when that
        draft is published will the changes end up back in this resource.

        Extra data can be stored on the review request for later lookup by
        passing ``extra_data.key_name=value``. The ``key_name`` and ``value``
        can be any valid strings. Passing a blank ``value`` will remove the
        key. The ``extra_data.`` prefix is required.
        """
        try:
            review_request = \
                resources.review_request.get_object(request, *args, **kwargs)
        except ObjectDoesNotExist:
            return DOES_NOT_EXIST

        is_mutating_field = (
            changenum is not None or
            extra_fields
        )

        if ((is_mutating_field and
             not self.has_modify_permissions(request, review_request)) or
            (status is not None and
             not review_request.is_status_mutable_by(request.user))):
            return self._no_access_error(request.user)

        if (status is not None and
            (review_request.status != string_to_status(status) or
             review_request.status != ReviewRequest.PENDING_REVIEW)):
            try:
                if status in self._close_type_map:
                    review_request.close(self._close_type_map[status],
                                         request.user, description)
                elif status == 'pending':
                    review_request.reopen(request.user)
                else:
                    raise AssertionError("Code path for invalid status '%s' "
                                         "should never be reached." % status)
            except PermissionError:
                return self._no_access_error(request.user)

        # Preserve the old changenum behavior.
        if changenum is not None:
            if changenum != review_request.changenum:
                review_request.commit = changenum

            try:
                draft = ReviewRequestDraftResource.prepare_draft(
                    request, review_request)
            except PermissionDenied:
                return PERMISSION_DENIED

            try:
                draft.update_from_commit_id(six.text_type(changenum))
            except InvalidChangeNumberError:
                return INVALID_CHANGE_NUMBER
            except EmptyChangeSetError:
                return EMPTY_CHANGESET

            draft.save()
            review_request.reopen()

        if extra_fields:
            self._import_extra_data(review_request.extra_data, extra_fields)
            review_request.save(update_fields=['extra_data'])

        return 200, {
            self.item_result_key: review_request,
        }
예제 #3
0
    def get_queryset(self, request, is_list=False, local_site_name=None,
                     *args, **kwargs):
        """Returns a queryset for ReviewRequest models.

        By default, this returns all published or formerly published
        review requests.

        If the queryset is being used for a list of review request
        resources, then it can be further filtered by one or more arguments
        in the URL. These are listed in @webapi_request_fields for get_list().

        Some arguments accept dates. The handling of dates is quite flexible,
        accepting a variety of date/time formats, but we recommend sticking
        with ISO8601 format.

        ISO8601 format defines a date as being in ``{yyyy}-{mm}-{dd}`` format,
        and a date/time as being in ``{yyyy}-{mm}-{dd}T{HH}:{MM}:{SS}``.
        A timezone can also be appended to this, using ``-{HH:MM}``.

        The following examples are valid dates and date/times:

            * ``2010-06-27``
            * ``2010-06-27T16:26:30``
            * ``2010-06-27T16:26:30-08:00``
        """
        local_site = self._get_local_site(local_site_name)

        if is_list:
            q = Q()

            if 'to-groups' in request.GET:
                for group_name in request.GET.get('to-groups').split(','):
                    q = q & self.model.objects.get_to_group_query(group_name,
                                                                  None)

            if 'to-users' in request.GET:
                for username in request.GET.get('to-users').split(','):
                    q = q & self.model.objects.get_to_user_query(username)

            if 'to-users-directly' in request.GET:
                to_users_directly = \
                    request.GET.get('to-users-directly').split(',')

                for username in to_users_directly:
                    q = q & self.model.objects.get_to_user_directly_query(
                        username)

            if 'to-users-groups' in request.GET:
                for username in request.GET.get('to-users-groups').split(','):
                    q = q & self.model.objects.get_to_user_groups_query(
                        username)

            if 'from-user' in request.GET:
                q = q & self.model.objects.get_from_user_query(
                    request.GET.get('from-user'))

            if 'repository' in request.GET:
                q = q & Q(repository=int(request.GET.get('repository')))

            commit_q = Q()
            if 'changenum' in request.GET:
                try:
                    commit_q = Q(changenum=int(request.GET.get('changenum')))
                except (TypeError, ValueError):
                    pass

            commit_id = request.GET.get('commit-id', None)
            if commit_id is not None:
                commit_q = commit_q | Q(commit_id=commit_id)

            if commit_q:
                q = q & commit_q

            if 'ship-it' in request.GET:
                ship_it = request.GET.get('ship-it')

                if ship_it in ('1', 'true', 'True'):
                    q = q & Q(shipit_count__gt=0)
                elif ship_it in ('0', 'false', 'False'):
                    q = q & Q(shipit_count=0)

            q = q & self.build_queries_for_int_field(
                request, 'shipit_count', 'ship-it-count')

            for issue_field in ('issue_open_count', 'issue_dropped_count',
                                'issue_resolved_count'):
                q = q & self.build_queries_for_int_field(
                    request, issue_field)

            if 'time-added-from' in request.GET:
                date = self._parse_date(request.GET['time-added-from'])

                if date:
                    q = q & Q(time_added__gte=date)

            if 'time-added-to' in request.GET:
                date = self._parse_date(request.GET['time-added-to'])

                if date:
                    q = q & Q(time_added__lt=date)

            if 'last-updated-from' in request.GET:
                date = self._parse_date(request.GET['last-updated-from'])

                if date:
                    q = q & Q(last_updated__gte=date)

            if 'last-updated-to' in request.GET:
                date = self._parse_date(request.GET['last-updated-to'])

                if date:
                    q = q & Q(last_updated__lt=date)

            status = string_to_status(request.GET.get('status', 'pending'))

            queryset = self.model.objects.public(user=request.user,
                                                 status=status,
                                                 local_site=local_site,
                                                 extra_query=q)

            return queryset
        else:
            return self.model.objects.filter(local_site=local_site)
예제 #4
0
    def update(self, request, status=None, changenum=None, commit_id=None,
               description=None, *args, **kwargs):
        """Updates the status of the review request.

        The only supported update to a review request's resource is to change
        the status, the associated server-side, change number, or to update
        information from the existing change number.

        The status can be set in order to close the review request as
        discarded or submitted, or to reopen as pending.

        The change number can either be changed to a new number, or the
        current change number can be passed. In either case, a new draft will
        be created or an existing one updated to include information from
        the server based on the change number.

        Changes to a review request's fields, such as the summary or the
        list of reviewers, is made on the Review Request Draft resource.
        This can be accessed through the ``draft`` link. Only when that
        draft is published will the changes end up back in this resource.
        """
        try:
            review_request = \
                resources.review_request.get_object(request, *args, **kwargs)
        except ObjectDoesNotExist:
            return DOES_NOT_EXIST

        if not self.has_modify_permissions(request, review_request):
            return self._no_access_error(request.user)

        if (status is not None and
            (review_request.status != string_to_status(status) or
             review_request.status != ReviewRequest.PENDING_REVIEW)):
            try:
                if status in self._close_type_map:
                    review_request.close(self._close_type_map[status],
                                         request.user, description)
                elif status == 'pending':
                    review_request.reopen(request.user)
                else:
                    raise AssertionError("Code path for invalid status '%s' "
                                         "should never be reached." % status)
            except PermissionError:
                return self._no_access_error(request.user)

        if changenum is not None and commit_id is None:
            commit_id = str(changenum)

        if commit_id is not None:
            if commit_id != review_request.commit:
                review_request.update_commit_id(commit_id, request.user)

            try:
                draft = ReviewRequestDraftResource.prepare_draft(
                    request, review_request)
            except PermissionDenied:
                return PERMISSION_DENIED

            try:
                draft.update_from_commit_id(commit_id)
            except InvalidChangeNumberError:
                return INVALID_CHANGE_NUMBER

            draft.save()
            review_request.reopen()

        return 200, {
            self.item_result_key: review_request,
        }
예제 #5
0
    def get_queryset(self, request, is_list=False, local_site_name=None,
                     *args, **kwargs):
        """Returns a queryset for ReviewRequest models.

        By default, this returns all published or formerly published
        review requests.

        If the queryset is being used for a list of review request
        resources, then it can be further filtered by one or more of the
        following arguments in the URL:

          * ``changenum``
              - The change number the review requests must be
                against. This will only return one review request
                per repository, and only works for repository
                types that support server-side changesets.

          * ``commit_id``
              - The commit_id of review requests. This will only return one
                review request per repository.

          * ``time-added-to``
              - The date/time that all review requests must be added before.
                This is compared against the review request's ``time_added``
                field. See below for information on date/time formats.

          * ``time-added-from``
              - The earliest date/time the review request could be added.
                This is compared against the review request's ``time_added``
                field. See below for information on date/time formats.

          * ``last-updated-to``
              - The date/time that all review requests must be last updated
                before. This is compared against the review request's
                ``last_updated`` field. See below for information on date/time
                formats.

          * ``last-updated-from``
              - The earliest date/time the review request could be last
                updated. This is compared against the review request's
                ``last_updated`` field. See below for information on date/time
                formats.

          * ``from-user``
              - The username that the review requests must be owned by.

          * ``repository``
              - The ID of the repository that the review requests must be on.

          * ``ship-it``
              - The review request must have at least one review with Ship It
                set, if this is 1. Otherwise, if 0, it must not have any marked
                Ship It.

          * ``status``
              - The status of the review requests. This can be ``pending``,
                ``submitted`` or ``discarded``.

          * ``to-groups``
              - A comma-separated list of review group names that the review
                requests must have in the reviewer list.

          * ``to-user-groups``
              - A comma-separated list of usernames who are in groups that the
                review requests must have in the reviewer list.

          * ``to-users``
              - A comma-separated list of usernames that the review requests
                must either have in the reviewer list specifically or by way
                of a group.

          * ``to-users-directly``
              - A comma-separated list of usernames that the review requests
                must have in the reviewer list specifically.

        Some arguments accept dates. The handling of dates is quite flexible,
        accepting a variety of date/time formats, but we recommend sticking
        with ISO8601 format.

        ISO8601 format defines a date as being in ``{yyyy}-{mm}-{dd}`` format,
        and a date/time as being in ``{yyyy}-{mm}-{dd}T{HH}:{MM}:{SS}``.
        A timezone can also be appended to this, using ``-{HH:MM}``.

        The following examples are valid dates and date/times:

            * ``2010-06-27``
            * ``2010-06-27T16:26:30``
            * ``2010-06-27T16:26:30-08:00``
        """
        local_site = self._get_local_site(local_site_name)

        if is_list:
            q = Q()

            if 'to-groups' in request.GET:
                for group_name in request.GET.get('to-groups').split(','):
                    q = q & self.model.objects.get_to_group_query(group_name,
                                                                  None)

            if 'to-users' in request.GET:
                for username in request.GET.get('to-users').split(','):
                    q = q & self.model.objects.get_to_user_query(username)

            if 'to-users-directly' in request.GET:
                to_users_directly = \
                    request.GET.get('to-users-directly').split(',')

                for username in to_users_directly:
                    q = q & self.model.objects.get_to_user_directly_query(
                        username)

            if 'to-users-groups' in request.GET:
                for username in request.GET.get('to-users-groups').split(','):
                    q = q & self.model.objects.get_to_user_groups_query(
                        username)

            if 'from-user' in request.GET:
                q = q & self.model.objects.get_from_user_query(
                    request.GET.get('from-user'))

            if 'repository' in request.GET:
                q = q & Q(repository=int(request.GET.get('repository')))

            commit_q = Q()
            if 'changenum' in request.GET:
                try:
                    commit_q = Q(changenum=int(request.GET.get('changenum')))
                except (TypeError, ValueError):
                    pass

            commit_id = request.GET.get('commit_id', None)
            if commit_id is not None:
                commit_q = commit_q | Q(commit_id=commit_id)

            if commit_q:
                q = q & commit_q

            if 'ship-it' in request.GET:
                ship_it = request.GET.get('ship-it')

                if ship_it in ('1', 'true', 'True'):
                    q = q & Q(shipit_count__gt=0)
                elif ship_it in ('0', 'false', 'False'):
                    q = q & Q(shipit_count=0)

            if 'time-added-from' in request.GET:
                date = self._parse_date(request.GET['time-added-from'])

                if date:
                    q = q & Q(time_added__gte=date)

            if 'time-added-to' in request.GET:
                date = self._parse_date(request.GET['time-added-to'])

                if date:
                    q = q & Q(time_added__lt=date)

            if 'last-updated-from' in request.GET:
                date = self._parse_date(request.GET['last-updated-from'])

                if date:
                    q = q & Q(last_updated__gte=date)

            if 'last-updated-to' in request.GET:
                date = self._parse_date(request.GET['last-updated-to'])

                if date:
                    q = q & Q(last_updated__lt=date)

            status = string_to_status(request.GET.get('status', 'pending'))

            queryset = self.model.objects.public(user=request.user,
                                                 status=status,
                                                 local_site=local_site,
                                                 extra_query=q)

            return queryset
        else:
            return self.model.objects.filter(local_site=local_site)
예제 #6
0
    def update(self,
               request,
               status=None,
               changenum=None,
               description=None,
               extra_fields={},
               *args,
               **kwargs):
        """Updates the status of the review request.

        The only supported update to a review request's resource is to change
        the status, the associated server-side, change number, or to update
        information from the existing change number.

        The status can be set in order to close the review request as
        discarded or submitted, or to reopen as pending.

        For Perforce, a change number can either be changed to a new number, or
        the current change number can be passed. In either case, a new draft
        will be created or an existing one updated to include information from
        the server based on the change number. This behavior is deprecated,
        and instead, the commit_id field should be set on the draft.

        Changes to a review request's fields, such as the summary or the
        list of reviewers, is made on the Review Request Draft resource.
        This can be accessed through the ``draft`` link. Only when that
        draft is published will the changes end up back in this resource.

        Extra data can be stored on the review request for later lookup by
        passing ``extra_data.key_name=value``. The ``key_name`` and ``value``
        can be any valid strings. Passing a blank ``value`` will remove the
        key. The ``extra_data.`` prefix is required.
        """
        try:
            review_request = \
                resources.review_request.get_object(request, *args, **kwargs)
        except ObjectDoesNotExist:
            return DOES_NOT_EXIST

        is_mutating_field = (changenum is not None or extra_fields)

        if ((is_mutating_field
             and not self.has_modify_permissions(request, review_request)) or
            (status is not None
             and not review_request.is_status_mutable_by(request.user))):
            return self._no_access_error(request.user)

        if (status is not None and
            (review_request.status != string_to_status(status)
             or review_request.status != ReviewRequest.PENDING_REVIEW)):
            try:
                if status in self._close_type_map:
                    review_request.close(self._close_type_map[status],
                                         request.user, description)
                elif status == 'pending':
                    review_request.reopen(request.user)
                else:
                    raise AssertionError("Code path for invalid status '%s' "
                                         "should never be reached." % status)
            except PermissionError:
                return self._no_access_error(request.user)

        # Preserve the old changenum behavior.
        if changenum is not None:
            if changenum != review_request.changenum:
                review_request.commit = changenum

            try:
                draft = ReviewRequestDraftResource.prepare_draft(
                    request, review_request)
            except PermissionDenied:
                return PERMISSION_DENIED

            try:
                draft.update_from_commit_id(six.text_type(changenum))
            except InvalidChangeNumberError:
                return INVALID_CHANGE_NUMBER

            draft.save()
            review_request.reopen()

        if extra_fields:
            self._import_extra_data(review_request.extra_data, extra_fields)
            review_request.save(update_fields=['extra_data'])

        return 200, {
            self.item_result_key: review_request,
        }
예제 #7
0
    def get_queryset(self,
                     request,
                     is_list=False,
                     local_site_name=None,
                     *args,
                     **kwargs):
        """Returns a queryset for ReviewRequest models.

        By default, this returns all published or formerly published
        review requests.

        If the queryset is being used for a list of review request
        resources, then it can be further filtered by one or more arguments
        in the URL. These are listed in @webapi_request_fields for get_list().

        Some arguments accept dates. The handling of dates is quite flexible,
        accepting a variety of date/time formats, but we recommend sticking
        with ISO8601 format.

        ISO8601 format defines a date as being in ``{yyyy}-{mm}-{dd}`` format,
        and a date/time as being in ``{yyyy}-{mm}-{dd}T{HH}:{MM}:{SS}``.
        A timezone can also be appended to this, using ``-{HH:MM}``.

        The following examples are valid dates and date/times:

            * ``2010-06-27``
            * ``2010-06-27T16:26:30``
            * ``2010-06-27T16:26:30-08:00``
        """
        local_site = self._get_local_site(local_site_name)

        if is_list:
            q = Q()

            if 'to-groups' in request.GET:
                for group_name in request.GET.get('to-groups').split(','):
                    q = q & self.model.objects.get_to_group_query(
                        group_name, None)

            if 'to-users' in request.GET:
                for username in request.GET.get('to-users').split(','):
                    q = q & self.model.objects.get_to_user_query(username)

            if 'to-users-directly' in request.GET:
                to_users_directly = \
                    request.GET.get('to-users-directly').split(',')

                for username in to_users_directly:
                    q = q & self.model.objects.get_to_user_directly_query(
                        username)

            if 'to-users-groups' in request.GET:
                for username in request.GET.get('to-users-groups').split(','):
                    q = q & self.model.objects.get_to_user_groups_query(
                        username)

            if 'from-user' in request.GET:
                q = q & self.model.objects.get_from_user_query(
                    request.GET.get('from-user'))

            if 'repository' in request.GET:
                q = q & Q(repository=int(request.GET.get('repository')))

            commit_q = Q()
            if 'changenum' in request.GET:
                try:
                    commit_q = Q(changenum=int(request.GET.get('changenum')))
                except (TypeError, ValueError):
                    pass

            commit_id = request.GET.get('commit-id', None)
            if commit_id is not None:
                commit_q = commit_q | Q(commit_id=commit_id)

            if commit_q:
                q = q & commit_q

            if 'ship-it' in request.GET:
                ship_it = request.GET.get('ship-it')

                if ship_it in ('1', 'true', 'True'):
                    q = q & Q(shipit_count__gt=0)
                elif ship_it in ('0', 'false', 'False'):
                    q = q & Q(shipit_count=0)

            q = q & self.build_queries_for_int_field(request, 'shipit_count',
                                                     'ship-it-count')

            for issue_field in ('issue_open_count', 'issue_dropped_count',
                                'issue_resolved_count'):
                q = q & self.build_queries_for_int_field(request, issue_field)

            if 'time-added-from' in request.GET:
                date = self._parse_date(request.GET['time-added-from'])

                if date:
                    q = q & Q(time_added__gte=date)

            if 'time-added-to' in request.GET:
                date = self._parse_date(request.GET['time-added-to'])

                if date:
                    q = q & Q(time_added__lt=date)

            if 'last-updated-from' in request.GET:
                date = self._parse_date(request.GET['last-updated-from'])

                if date:
                    q = q & Q(last_updated__gte=date)

            if 'last-updated-to' in request.GET:
                date = self._parse_date(request.GET['last-updated-to'])

                if date:
                    q = q & Q(last_updated__lt=date)

            status = string_to_status(request.GET.get('status', 'pending'))

            queryset = self.model.objects.public(user=request.user,
                                                 status=status,
                                                 local_site=local_site,
                                                 extra_query=q)

            return queryset
        else:
            return self.model.objects.filter(local_site=local_site)
예제 #8
0
    def update(self,
               request,
               status=None,
               changenum=None,
               commit_id=None,
               description=None,
               *args,
               **kwargs):
        """Updates the status of the review request.

        The only supported update to a review request's resource is to change
        the status, the associated server-side, change number, or to update
        information from the existing change number.

        The status can be set in order to close the review request as
        discarded or submitted, or to reopen as pending.

        The change number can either be changed to a new number, or the
        current change number can be passed. In either case, a new draft will
        be created or an existing one updated to include information from
        the server based on the change number.

        Changes to a review request's fields, such as the summary or the
        list of reviewers, is made on the Review Request Draft resource.
        This can be accessed through the ``draft`` link. Only when that
        draft is published will the changes end up back in this resource.
        """
        try:
            review_request = \
                resources.review_request.get_object(request, *args, **kwargs)
        except ObjectDoesNotExist:
            return DOES_NOT_EXIST

        if not self.has_modify_permissions(request, review_request):
            return self._no_access_error(request.user)

        if (status is not None and
            (review_request.status != string_to_status(status)
             or review_request.status != ReviewRequest.PENDING_REVIEW)):
            try:
                if status in self._close_type_map:
                    review_request.close(self._close_type_map[status],
                                         request.user, description)
                elif status == 'pending':
                    review_request.reopen(request.user)
                else:
                    raise AssertionError("Code path for invalid status '%s' "
                                         "should never be reached." % status)
            except PermissionError:
                return self._no_access_error(request.user)

        if changenum is not None and commit_id is None:
            commit_id = str(changenum)

        if commit_id is not None:
            if commit_id != review_request.commit:
                review_request.update_commit_id(commit_id, request.user)

            try:
                draft = ReviewRequestDraftResource.prepare_draft(
                    request, review_request)
            except PermissionDenied:
                return PERMISSION_DENIED

            try:
                draft.update_from_commit_id(commit_id)
            except InvalidChangeNumberError:
                return INVALID_CHANGE_NUMBER

            draft.save()
            review_request.reopen()

        return 200, {
            self.item_result_key: review_request,
        }
예제 #9
0
    def get_queryset(self,
                     request,
                     is_list=False,
                     local_site_name=None,
                     *args,
                     **kwargs):
        """Returns a queryset for ReviewRequest models.

        By default, this returns all published or formerly published
        review requests.

        If the queryset is being used for a list of review request
        resources, then it can be further filtered by one or more of the
        following arguments in the URL:

          * ``changenum``
              - The change number the review requests must be
                against. This will only return one review request
                per repository, and only works for repository
                types that support server-side changesets.

          * ``commit_id``
              - The commit_id of review requests. This will only return one
                review request per repository.

          * ``time-added-to``
              - The date/time that all review requests must be added before.
                This is compared against the review request's ``time_added``
                field. See below for information on date/time formats.

          * ``time-added-from``
              - The earliest date/time the review request could be added.
                This is compared against the review request's ``time_added``
                field. See below for information on date/time formats.

          * ``last-updated-to``
              - The date/time that all review requests must be last updated
                before. This is compared against the review request's
                ``last_updated`` field. See below for information on date/time
                formats.

          * ``last-updated-from``
              - The earliest date/time the review request could be last
                updated. This is compared against the review request's
                ``last_updated`` field. See below for information on date/time
                formats.

          * ``from-user``
              - The username that the review requests must be owned by.

          * ``repository``
              - The ID of the repository that the review requests must be on.

          * ``ship-it``
              - The review request must have at least one review with Ship It
                set, if this is 1. Otherwise, if 0, it must not have any marked
                Ship It.

          * ``status``
              - The status of the review requests. This can be ``pending``,
                ``submitted`` or ``discarded``.

          * ``to-groups``
              - A comma-separated list of review group names that the review
                requests must have in the reviewer list.

          * ``to-user-groups``
              - A comma-separated list of usernames who are in groups that the
                review requests must have in the reviewer list.

          * ``to-users``
              - A comma-separated list of usernames that the review requests
                must either have in the reviewer list specifically or by way
                of a group.

          * ``to-users-directly``
              - A comma-separated list of usernames that the review requests
                must have in the reviewer list specifically.

        Some arguments accept dates. The handling of dates is quite flexible,
        accepting a variety of date/time formats, but we recommend sticking
        with ISO8601 format.

        ISO8601 format defines a date as being in ``{yyyy}-{mm}-{dd}`` format,
        and a date/time as being in ``{yyyy}-{mm}-{dd}T{HH}:{MM}:{SS}``.
        A timezone can also be appended to this, using ``-{HH:MM}``.

        The following examples are valid dates and date/times:

            * ``2010-06-27``
            * ``2010-06-27T16:26:30``
            * ``2010-06-27T16:26:30-08:00``
        """
        local_site = self._get_local_site(local_site_name)

        if is_list:
            q = Q()

            if 'to-groups' in request.GET:
                for group_name in request.GET.get('to-groups').split(','):
                    q = q & self.model.objects.get_to_group_query(
                        group_name, None)

            if 'to-users' in request.GET:
                for username in request.GET.get('to-users').split(','):
                    q = q & self.model.objects.get_to_user_query(username)

            if 'to-users-directly' in request.GET:
                to_users_directly = \
                    request.GET.get('to-users-directly').split(',')

                for username in to_users_directly:
                    q = q & self.model.objects.get_to_user_directly_query(
                        username)

            if 'to-users-groups' in request.GET:
                for username in request.GET.get('to-users-groups').split(','):
                    q = q & self.model.objects.get_to_user_groups_query(
                        username)

            if 'from-user' in request.GET:
                q = q & self.model.objects.get_from_user_query(
                    request.GET.get('from-user'))

            if 'repository' in request.GET:
                q = q & Q(repository=int(request.GET.get('repository')))

            commit_q = Q()
            if 'changenum' in request.GET:
                try:
                    commit_q = Q(changenum=int(request.GET.get('changenum')))
                except (TypeError, ValueError):
                    pass

            commit_id = request.GET.get('commit_id', None)
            if commit_id is not None:
                commit_q = commit_q | Q(commit_id=commit_id)

            if commit_q:
                q = q & commit_q

            if 'ship-it' in request.GET:
                ship_it = request.GET.get('ship-it')

                if ship_it in ('1', 'true', 'True'):
                    q = q & Q(shipit_count__gt=0)
                elif ship_it in ('0', 'false', 'False'):
                    q = q & Q(shipit_count=0)

            if 'time-added-from' in request.GET:
                date = self._parse_date(request.GET['time-added-from'])

                if date:
                    q = q & Q(time_added__gte=date)

            if 'time-added-to' in request.GET:
                date = self._parse_date(request.GET['time-added-to'])

                if date:
                    q = q & Q(time_added__lt=date)

            if 'last-updated-from' in request.GET:
                date = self._parse_date(request.GET['last-updated-from'])

                if date:
                    q = q & Q(last_updated__gte=date)

            if 'last-updated-to' in request.GET:
                date = self._parse_date(request.GET['last-updated-to'])

                if date:
                    q = q & Q(last_updated__lt=date)

            status = string_to_status(request.GET.get('status', 'pending'))

            queryset = self.model.objects.public(user=request.user,
                                                 status=status,
                                                 local_site=local_site,
                                                 extra_query=q)

            return queryset
        else:
            return self.model.objects.filter(local_site=local_site)