def shutdown(self): # We have to put the TestingDone field back before we shut down # in order to get the instance back to its original state. main_fieldset = get_review_request_fieldset('main') if not get_review_request_field('testing_done'): main_fieldset.add_field(TestingDoneField) info_fieldset = get_review_request_fieldset('info') if not get_review_request_field('branch'): info_fieldset.add_field(BranchField) if not get_review_request_field('depends_on'): info_fieldset.add_field(DependsOnField) if not get_review_request_field('blocks'): info_fieldset.add_field(BlocksField) super(MozReviewExtension, self).shutdown()
def reopen(self, user=None): """Reopens the review request for review.""" from reviewboard.reviews.models.review_request_draft import \ ReviewRequestDraft if (user and not self.is_mutable_by(user) and not user.has_perm("reviews.can_change_status", self.local_site)): raise PermissionError if self.status != self.PENDING_REVIEW: changedesc = ChangeDescription() status_field = get_review_request_field('status')(self) status_field.record_change_entry(changedesc, self.status, self.PENDING_REVIEW) if self.status == self.DISCARDED: # A draft is needed if reopening a discarded review request. self.public = False changedesc.save() draft = ReviewRequestDraft.create(self) draft.changedesc = changedesc draft.save() else: changedesc.public = True changedesc.save() self.changedescs.add(changedesc) self.status = self.PENDING_REVIEW self.save(update_counts=True) review_request_reopened.send(sender=self.__class__, user=user, review_request=self)
def shutdown(self): # We have to put the TestingDone field back before we shut down # in order to get the instance back to its original state. fieldset = get_review_request_fieldset('main') field = get_review_request_field('testing_done') if not field: fieldset.add_field(TestingDoneField)
def shutdown(self): # We have to put the TestingDone field back before we shut down # in order to get the instance back to its original state. main_fieldset = get_review_request_fieldset('main') testing_done_field = get_review_request_field('testing_done') if not testing_done_field: main_fieldset.add_field(TestingDoneField) super(MozReviewExtension, self).shutdown()
def close(self, type, user=None, description=None, rich_text=False): """Closes the review request. The type must be one of SUBMITTED or DISCARDED. """ if (user and not self.is_mutable_by(user) and not user.has_perm("reviews.can_change_status", self.local_site)): raise PermissionError if type not in [self.SUBMITTED, self.DISCARDED]: raise AttributeError("%s is not a valid close type" % type) draft = get_object_or_none(self.draft) if self.status != type: if (draft is not None and not self.public and type == self.DISCARDED): # Copy over the draft information if this is a private discard. draft.copy_fields_to_request(self) # TODO: Use the user's default for rich_text. changedesc = ChangeDescription(public=True, text=description or "", rich_text=rich_text or False) status_field = get_review_request_field('status')(self) status_field.record_change_entry(changedesc, self.status, type) changedesc.save() self.changedescs.add(changedesc) if type == self.SUBMITTED: if not self.public: raise PublishError("The draft must be public first.") else: self.commit_id = None self.status = type self.save(update_counts=True) review_request_closed.send(sender=self.__class__, user=user, review_request=self, type=type) else: # Update submission description. changedesc = self.changedescs.filter(public=True).latest() changedesc.timestamp = timezone.now() changedesc.text = description or "" changedesc.rich_text = rich_text changedesc.save() # Needed to renew last-update. self.save() # Delete the associated draft review request. if draft is not None: draft.delete()
def shutdown(self): # Restore the built-in opcode generator. set_diff_opcode_generator_class(self.original_opcode_generator) # We have to put the TestingDone field back before we shut down # in order to get the instance back to its original state. main_fieldset = get_review_request_fieldset('main') if not get_review_request_field('testing_done'): main_fieldset.add_field(TestingDoneField) info_fieldset = get_review_request_fieldset('info') if not get_review_request_field('branch'): info_fieldset.add_field(BranchField) if not get_review_request_field('depends_on'): info_fieldset.add_field(DependsOnField) if not get_review_request_field('blocks'): info_fieldset.add_field(BlocksField) super(MozReviewExtension, self).shutdown()
def serialize_fields_changed_field(self, obj, **kwargs): review_request = obj.review_request.get() fields_changed = {} for field_name, data in six.iteritems(obj.fields_changed): field_cls = get_review_request_field(field_name) field = field_cls(review_request) fields_changed[field.field_id] = field.serialize_change_entry(obj) return fields_changed
def initialize(self): # Start by hiding the Testing Done field in all review requests, since # Mozilla developers will not be using it. fieldset = get_review_request_fieldset('main') field = get_review_request_field('testing_done') if (field): fieldset.remove_field(field) # All of our review request styling is injected via review-stylings-css, # which in turn loads the review.css static bundle. TemplateHook(self, 'base-css', 'rbmozui/review-stylings-css.html', apply_to=review_request_url_names) TemplateHook(self, 'base-css', 'rbmozui/viewdiff-stylings-css.html', apply_to=diffviewer_url_names) TemplateHook(self, 'base-before-content', 'rbmozui/review-header.html', apply_to=review_request_url_names) TemplateHook(self, 'base-scripts-post', 'rbmozui/review-header-workaround.html', apply_to=review_request_url_names)
def reopen(self, user=None): """Reopens the review request for review.""" from reviewboard.reviews.models.review_request_draft import \ ReviewRequestDraft if (user and not self.is_mutable_by(user) and not user.has_perm( "reviews.can_change_status", self.local_site)): raise PermissionError old_status = self.status old_public = self.public if old_status != self.PENDING_REVIEW: # The reopening signal is only fired when actually making a status # change since the main consumers (extensions) probably only care # about changes. review_request_reopening.send(sender=self.__class__, user=user, review_request=self) changedesc = ChangeDescription(user=user or self.submitter) status_field = get_review_request_field('status')(self) status_field.record_change_entry(changedesc, old_status, self.PENDING_REVIEW) if old_status == self.DISCARDED: # A draft is needed if reopening a discarded review request. self.public = False changedesc.save() draft = ReviewRequestDraft.create(self) draft.changedesc = changedesc draft.save() else: changedesc.public = True changedesc.save() self.changedescs.add(changedesc) self.status = self.PENDING_REVIEW self.save(update_counts=True) review_request_reopened.send(sender=self.__class__, user=user, review_request=self, old_status=old_status, old_public=old_public)
def reopen(self, user=None): """Reopens the review request for review.""" from reviewboard.reviews.models.review_request_draft import \ ReviewRequestDraft if (user and not self.is_mutable_by(user) and not user.has_perm("reviews.can_change_status", self.local_site)): raise PermissionError old_status = self.status old_public = self.public if old_status != self.PENDING_REVIEW: # The reopening signal is only fired when actually making a status # change since the main consumers (extensions) probably only care # about changes. review_request_reopening.send(sender=self.__class__, user=user, review_request=self) changedesc = ChangeDescription(user=user or self.submitter) status_field = get_review_request_field('status')(self) status_field.record_change_entry(changedesc, old_status, self.PENDING_REVIEW) if old_status == self.DISCARDED: # A draft is needed if reopening a discarded review request. self.public = False changedesc.save() draft = ReviewRequestDraft.create(self) draft.changedesc = changedesc draft.save() else: changedesc.public = True changedesc.save() self.changedescs.add(changedesc) self.status = self.PENDING_REVIEW self.save(update_counts=True) review_request_reopened.send(sender=self.__class__, user=user, review_request=self, old_status=old_status, old_public=old_public)
def review_request_field(context, nodelist, review_request_details, field_id): """Render a block with a specific review request field. Args: context (dict): The render context. nodelist (django.template.NodeList): The contents of the template inside the blocktag. review_request_details (reviewboard.reviews.models. base_review_request_details. BaseReviewRequestDetails): The review request or draft being rendered. field_id (unicode): The ID of the field to add to the render context. Returns: unicode: The rendered block. """ request = context.get('request') try: field_cls = get_review_request_field(field_id) field = field_cls(review_request_details, request=request) except Exception as e: logging.exception('Error instantiating field %r: %s', field_id, e) return '' context.push() try: context['field'] = field return nodelist.render(context) finally: context.pop()
def close(self, close_type=None, user=None, description=None, rich_text=False, **kwargs): """Closes the review request. Args: close_type (unicode): How the close occurs. This should be one of :py:attr:`SUBMITTED` or :py:attr:`DISCARDED`. user (django.contrib.auth.models.User): The user who is closing the review request. description (unicode): An optional description that indicates why the review request was closed. rich_text (bool): Indicates whether or not that the description is rich text. Raises: ValueError: The provided close type is not a valid value. PermissionError: The user does not have permission to close the review request. TypeError: Keyword arguments were supplied to the function. .. versionchanged:: 3.0 The ``type`` argument is deprecated: ``close_type`` should be used instead. This method raises :py:exc:`ValueError` instead of :py:exc:`AttributeError` when the ``close_type`` has an incorrect value. """ if close_type is None: try: close_type = kwargs.pop('type') except KeyError: raise AttributeError('close_type must be provided') warnings.warn( 'The "type" argument was deprecated in Review Board 3.0 and ' 'will be removed in a future version. Use "close_type" ' 'instead.') if kwargs: raise TypeError('close() does not accept keyword arguments.') if (user and not self.is_mutable_by(user) and not user.has_perm( "reviews.can_change_status", self.local_site)): raise PermissionError if close_type not in [self.SUBMITTED, self.DISCARDED]: raise ValueError("%s is not a valid close type" % type) review_request_closing.send(sender=type(self), user=user, review_request=self, close_type=close_type, type=deprecated_signal_argument( signal_name='review_request_closing', old_name='type', new_name='close_type', value=close_type), description=description, rich_text=rich_text) draft = get_object_or_none(self.draft) if self.status != close_type: if (draft is not None and not self.public and close_type == self.DISCARDED): # Copy over the draft information if this is a private discard. draft.copy_fields_to_request(self) # TODO: Use the user's default for rich_text. changedesc = ChangeDescription(public=True, text=description or "", rich_text=rich_text or False, user=user or self.submitter) status_field = get_review_request_field('status')(self) status_field.record_change_entry(changedesc, self.status, close_type) changedesc.save() self.changedescs.add(changedesc) if close_type == self.SUBMITTED: if not self.public: raise PublishError("The draft must be public first.") else: self.commit_id = None self.status = close_type self.save(update_counts=True) review_request_closed.send(sender=type(self), user=user, review_request=self, close_type=close_type, type=deprecated_signal_argument( signal_name='review_request_closed', old_name='type', new_name='close_type', value=close_type), description=description, rich_text=rich_text) else: # Update submission description. changedesc = self.changedescs.filter(public=True).latest() changedesc.timestamp = timezone.now() changedesc.text = description or "" changedesc.rich_text = rich_text changedesc.save() # Needed to renew last-update. self.save() # Delete the associated draft review request. if draft is not None: draft.delete()
def close(self, close_type=None, user=None, description=None, rich_text=False, **kwargs): """Closes the review request. Args: close_type (unicode): How the close occurs. This should be one of :py:attr:`SUBMITTED` or :py:attr:`DISCARDED`. user (django.contrib.auth.models.User): The user who is closing the review request. description (unicode): An optional description that indicates why the review request was closed. rich_text (bool): Indicates whether or not that the description is rich text. Raises: ValueError: The provided close type is not a valid value. PermissionError: The user does not have permission to close the review request. TypeError: Keyword arguments were supplied to the function. .. versionchanged:: 3.0 The ``type`` argument is deprecated: ``close_type`` should be used instead. This method raises :py:exc:`ValueError` instead of :py:exc:`AttributeError` when the ``close_type`` has an incorrect value. """ if close_type is None: try: close_type = kwargs.pop('type') except KeyError: raise AttributeError('close_type must be provided') warnings.warn( 'The "type" argument was deprecated in Review Board 3.0 and ' 'will be removed in a future version. Use "close_type" ' 'instead.' ) if kwargs: raise TypeError('close() does not accept keyword arguments.') if (user and not self.is_mutable_by(user) and not user.has_perm("reviews.can_change_status", self.local_site)): raise PermissionError if close_type not in [self.SUBMITTED, self.DISCARDED]: raise ValueError("%s is not a valid close type" % type) review_request_closing.send( sender=type(self), user=user, review_request=self, close_type=close_type, type=deprecated_signal_argument( signal_name='review_request_closing', old_name='type', new_name='close_type', value=close_type), description=description, rich_text=rich_text) draft = get_object_or_none(self.draft) if self.status != close_type: if (draft is not None and not self.public and close_type == self.DISCARDED): # Copy over the draft information if this is a private discard. draft.copy_fields_to_request(self) # TODO: Use the user's default for rich_text. changedesc = ChangeDescription(public=True, text=description or "", rich_text=rich_text or False, user=user or self.submitter) status_field = get_review_request_field('status')(self) status_field.record_change_entry(changedesc, self.status, close_type) changedesc.save() self.changedescs.add(changedesc) if close_type == self.SUBMITTED: if not self.public: raise PublishError("The draft must be public first.") else: self.commit_id = None self.status = close_type self.save(update_counts=True) review_request_closed.send( sender=type(self), user=user, review_request=self, close_type=close_type, type=deprecated_signal_argument( signal_name='review_request_closed', old_name='type', new_name='close_type', value=close_type), description=description, rich_text=rich_text) else: # Update submission description. changedesc = self.changedescs.filter(public=True).latest() changedesc.timestamp = timezone.now() changedesc.text = description or "" changedesc.rich_text = rich_text changedesc.save() # Needed to renew last-update. self.save() # Delete the associated draft review request. if draft is not None: draft.delete()
def initialize(self): initialize_pulse_handlers(self) URLHook(self, patterns('', url(r'^mozreview/', include('mozreview.urls')))) HeaderDropdownActionHook(self, actions=[{ 'label': 'MozReview', 'items': [ { 'label': 'User Guide', 'url': 'https://mozilla-version-control-tools.readthedocs.org/en/latest/mozreview-user.html', }, { 'label': 'Mercurial for Mozillians', 'url': 'https://mozilla-version-control-tools.readthedocs.org/en/latest/hgmozilla/index.html', }, { 'label': 'Hacking MozReview', 'url': 'https://mozilla-version-control-tools.readthedocs.org/en/latest/hacking-mozreview.html', }, { 'label': 'File a Bug', 'url': 'https://bugzilla.mozilla.org/enter_bug.cgi?product=Developer%20Services&component=MozReview', }, ], }]) ReviewRequestDropdownActionHook(self, actions=[ { 'label': 'Automation', 'id': 'automation-menu', 'items': [ { 'id': 'autoland-try-trigger', 'label': 'Trigger a Try Build', 'url': '#', }, { 'id': 'autoland-trigger', 'label': 'Land Commits', 'url': '#', }, ], }, ]) # Hide fields from all review requests that are not used by Mozilla # developers. main_fieldset = get_review_request_fieldset('main') testing_done_field = get_review_request_field('testing_done') if testing_done_field: main_fieldset.remove_field(testing_done_field) info_fieldset = get_review_request_fieldset('info') for field_name in ('branch', 'depends_on', 'blocks'): field = get_review_request_field(field_name) if field: info_fieldset.remove_field(field) # We "monkey patch" (yes, I feel dirty) the should_render method on # the description field so that it is not rendered for parent review # requests. description_field = get_review_request_field('description') if description_field: description_field.should_render = (lambda self, value: not is_parent(self.review_request_details)) # All of our review request styling is injected via # review-stylings-css, which in turn loads the review.css static # bundle. TemplateHook(self, 'base-css', 'mozreview/review-stylings-css.html', apply_to=review_request_url_names) TemplateHook(self, 'base-css', 'mozreview/viewdiff-stylings-css.html', apply_to=diffviewer_url_names) TemplateHook(self, 'base-scripts-post', 'mozreview/review-scripts-js.html', apply_to=review_request_url_names) TemplateHook(self, 'base-extrahead', 'mozreview/base-extrahead-login-form.html', apply_to=['login']) TemplateHook(self, 'before-login-form', 'mozreview/before-login-form.html', apply_to=['login']) TemplateHook(self, 'after-login-form', 'mozreview/after-login-form.html', apply_to=['login']) TemplateHook(self, 'base-after-content', 'mozreview/scm_level.html') TemplateHook(self, 'base-after-content', 'mozreview/repository.html') ReviewRequestFieldsHook(self, 'main', [CommitsListField]) # This forces the Commits field to be the top item. main_fieldset.field_classes.insert(0, main_fieldset.field_classes.pop()) # The above hack forced Commits at the top, but the rest of these # fields are fine below the Description. ReviewRequestFieldsHook(self, 'main', [CombinedReviewersField]) ReviewRequestFieldsHook(self, 'main', [TryField]) ReviewRequestFieldsHook(self, 'main', [BaseCommitField]) ReviewRequestFieldsHook(self, 'main', [FileDiffReviewerField]) # We want pull to appear first as it is the more robust way of # retrieving changesets. ReviewRequestFieldsHook(self, 'info', [PullCommitField]) ReviewRequestFieldsHook(self, 'info', [ImportCommitField]) # Use a custom method to calculate a review approval state. MozReviewApprovalHook(self) SignalHook(self, post_save, self.on_draft_changed, sender=ReviewRequestDraft) HostingServiceHook(self, HMORepository) URLHook(self, patterns('', url(r'^import-pullrequest/(?P<user>.+)/(?P<repo>.+)/(?P<pullrequest>\d+)/$', import_pullrequest, name='import_pullrequest')))
def get_extra_data_field_supports_markdown(self, review_request, key): field_cls = get_review_request_field(key) return field_cls and getattr(field_cls, 'enable_markdown', False)
def initialize(self): AuthBackendHook(self, BugzillaBackend) self.original_opcode_generator = get_diff_opcode_generator_class() set_diff_opcode_generator_class(NoFilterDiffOpcodeGenerator) initialize_pulse_handlers(self) URLHook(self, patterns('', url(r'^mozreview/', include('mozreview.urls')))) HeaderDropdownActionHook( self, actions=[{ 'id': 'nav-mozreview-menu', 'label': 'MozReview', 'items': [ { 'label': 'User Guide', 'url': 'https://mozilla-version-control-tools.readthedocs.io/en/latest/mozreview-user.html', }, { 'label': 'Mercurial for Mozillians', 'url': 'https://mozilla-version-control-tools.readthedocs.io/en/latest/hgmozilla/index.html', }, { 'label': 'Hacking MozReview', 'url': 'https://mozilla-version-control-tools.readthedocs.io/en/latest/hacking-mozreview.html', }, { 'label': 'File a Bug', 'url': 'https://bugzilla.mozilla.org/enter_bug.cgi?product=MozReview&component=General', }, ], }]) review_request_dropdown_actions = [ { 'label': 'Automation', 'id': 'automation-menu', 'items': [ { 'id': 'autoland-try-trigger', 'label': 'Trigger a Try Build', 'url': '#', }, { 'id': 'autoland-trigger', 'label': 'Land Commits', 'url': '#', }, ], }, ] ReviewRequestDropdownActionHook( self, actions=review_request_dropdown_actions) DiffViewerDropdownActionHook(self, actions=review_request_dropdown_actions) # Hide fields from all review requests that are not used by Mozilla # developers. main_fieldset = get_review_request_fieldset('main') testing_done_field = get_review_request_field('testing_done') if testing_done_field: main_fieldset.remove_field(testing_done_field) info_fieldset = get_review_request_fieldset('info') for field_name in ('branch', 'depends_on', 'blocks'): field = get_review_request_field(field_name) if field: info_fieldset.remove_field(field) # We "monkey patch" (yes, I feel dirty) the should_render method on # the description field so that it is not rendered description_field = get_review_request_field('description') if description_field: self.old_desc_should_render = description_field.should_render description_field.should_render = lambda self, value: False # All of our review request styling is injected via # review-stylings-css, which in turn loads the review.css static # bundle. TemplateHook(self, 'base-css', 'mozreview/review-stylings-css.html', apply_to=review_request_url_names) TemplateHook(self, 'base-css', 'mozreview/viewdiff-stylings-css.html', apply_to=diffviewer_url_names) TemplateHook( self, 'base-css', 'mozreview/admin-stylings-css.html', apply_to=['reviewboard.extensions.views.configure_extension']) TemplateHook(self, 'base-scripts-post', 'mozreview/review-scripts-js.html', apply_to=review_request_url_names) TemplateHook(self, 'base-extrahead', 'mozreview/base-extrahead-login-form.html', apply_to=['login']) TemplateHook(self, 'before-login-form', 'mozreview/before-login-form.html', apply_to=['login']) TemplateHook(self, 'after-login-form', 'mozreview/after-login-form.html', apply_to=['login']) TemplateHook(self, 'base-after-content', 'mozreview/user-data.html') TemplateHook(self, 'base-after-content', 'mozreview/repository.html') TemplateHook(self, 'base-after-content', 'mozreview/user_review_flag.html', apply_to=review_request_url_names) TemplateHook(self, 'base-after-content', 'mozreview/diff-data.html', apply_to=diffviewer_url_names) TemplateHook(self, 'review-summary-body', 'mozreview/review_summary_flag_info.html') ReviewRequestFieldsHook(self, 'main', [CommitsListField]) ReviewRequestFieldsHook(self, 'main', [CommitDetailField]) CommitContextTemplateHook(self, 'mozreview-pre-review-request-box', 'mozreview/commits.html', apply_to=review_request_url_names) # The above hack forced Commits at the top, but the rest of these # fields are fine below the Description. ReviewRequestFieldsHook(self, 'main', [CombinedReviewersField]) ReviewRequestFieldsHook(self, 'main', [TryField]) ReviewRequestFieldsHook(self, 'main', [BaseCommitField]) ReviewRequestFieldsHook(self, 'main', [FileDiffReviewerField]) ReviewRequestFieldsHook(self, 'info', [CommitAuthorField]) # Use a custom method to calculate a review approval state. MozReviewApprovalHook(self) # Instantiate the various signal handlers initialize_signal_handlers(self) HostingServiceHook(self, HMORepository) HostingServiceHook(self, BMOBugTracker)