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() })
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, }
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)
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, }
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)
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, }
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)
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)