def file_attachment_comments(context, file_attachment): """Returns a JSON array of current comments for a file attachment.""" review_ui = file_attachment.review_ui if not review_ui: # For the purposes of serialization, we'll create a dummy ReviewUI. review_ui = FileAttachmentReviewUI(file_attachment.review_request, file_attachment) # NOTE: We're setting this here because file attachments serialization # requires this to be set, but we don't necessarily have it set # by this time. We should rethink parts of this down the road, but # it requires dealing with some compatibility issues for subclasses. review_ui.request = context["request"] return json.dumps(review_ui.serialize_comments(file_attachment.get_comments()))
def review_ui(self): """Return the review UI for this file.""" if not hasattr(self, '_review_ui'): from reviewboard.reviews.ui.base import FileAttachmentReviewUI self._review_ui = FileAttachmentReviewUI.for_type(self) return self._review_ui
def test_for_type_with_exception(self): """Testing FileAttachmentReviewUI.for_type sandboxes ReviewUI instantiation """ class BrokenReviewUI(FileAttachmentReviewUI): supported_mimetypes = ['image/broken'] def __init__(self, *args, **kwargs): raise Exception('Oh no') self.spy_on(BrokenReviewUI.__init__, owner=BrokenReviewUI) register_ui(BrokenReviewUI) try: attachment = self.create_file_attachment(self.review_request, mimetype='image/broken') review_ui = FileAttachmentReviewUI.for_type(attachment) self.assertIsNone(review_ui) self.assertTrue( BrokenReviewUI.__init__.called_with(self.review_request, attachment)) finally: unregister_ui(BrokenReviewUI)
def review_ui(self): """Return the review UI for this file.""" if not hasattr(self, '_review_ui'): from reviewboard.reviews.ui.base import FileAttachmentReviewUI self._review_ui = FileAttachmentReviewUI.for_type(self) return self._review_ui
def review_ui(self): if not hasattr(self, "_review_ui"): from reviewboard.reviews.ui.base import FileAttachmentReviewUI self._review_ui = FileAttachmentReviewUI.for_type(self) return self._review_ui
def file_attachment_comments(context, file_attachment): """Returns a JSON array of current comments for a file attachment.""" review_ui = file_attachment.review_ui if not review_ui: # For the purposes of serialization, we'll create a dummy ReviewUI. review_ui = FileAttachmentReviewUI(file_attachment.review_request, file_attachment) # NOTE: We're setting this here because file attachments serialization # requires this to be set, but we don't necessarily have it set # by this time. We should rethink parts of this down the road, but # it requires dealing with some compatibility issues for subclasses. review_ui.request = context['request'] return json.dumps( review_ui.serialize_comments(file_attachment.get_comments()))
def review_ui(self): """Return a ReviewUI appropriate for this comment. If a ReviewUI is available for this type of file, an instance of one will be returned that's associated with this comment's FileAttachment and the one being diffed against (if any). """ from reviewboard.reviews.ui.base import FileAttachmentReviewUI # Note that we need to create our own instance here, so that we don't # end up altering the state of another ReviewUI's file attachment # (particularly with calling set_diff_against below). review_ui = FileAttachmentReviewUI.for_type(self.file_attachment) if not review_ui: return None if review_ui.supports_diffing and self.diff_against_file_attachment: review_ui.set_diff_against(self.diff_against_file_attachment) return review_ui
def review_ui(self): """Return a ReviewUI appropriate for this comment. If a ReviewUI is available for this type of file, an instance of one will be returned that's associated with this comment's FileAttachment and the one being diffed against (if any). """ from reviewboard.reviews.ui.base import FileAttachmentReviewUI # Note that we need to create our own instance here, so that we don't # end up altering the state of another ReviewUI's file attachment # (particularly with calling set_diff_against below). review_ui = FileAttachmentReviewUI.for_type(self.file_attachment) if not review_ui: return None if review_ui.supports_diffing and self.diff_against_file_attachment: review_ui.set_diff_against(self.diff_against_file_attachment) return review_ui
def reviewable_page_model_data(context): """Output JSON-serialized data for a RB.ReviewablePage model. The data will be used by :js:class:`RB.ReviewablePage` in order to populate the review request and editor with the necessary state. Args: context (django.template.RequestContext): The current template context. Returns: unicode: The resulting JSON-serialized data. This consists of keys that are meant to be injected into an existing dictionary. """ request = context['request'] user = request.user review_request = context['review_request'] review_request_details = context['review_request_details'] draft = context['draft'] close_description = context['close_description'] close_description_rich_text = context['close_description_rich_text'] if review_request.local_site: local_site_prefix = 's/%s/' % review_request.local_site.name else: local_site_prefix = '' # Build data for the RB.ReviewRequest if review_request.status == review_request.PENDING_REVIEW: state_data = 'PENDING' elif review_request.status == review_request.SUBMITTED: state_data = 'CLOSE_SUBMITTED' elif review_request.status == review_request.DISCARDED: state_data = 'CLOSE_DISCARDED' else: raise ValueError('Unexpected ReviewRequest.status value "%s"' % review_request.status) review_request_data = { 'id': review_request.display_id, 'localSitePrefix': local_site_prefix, 'branch': review_request_details.branch, 'bugsClosed': review_request_details.get_bug_list(), 'closeDescription': normalize_text_for_edit(user=user, text=close_description, rich_text=close_description_rich_text, escape_html=False), 'closeDescriptionRichText': close_description_rich_text, 'description': normalize_text_for_edit( user=user, text=review_request_details.description, rich_text=review_request_details.description_rich_text, escape_html=False), 'descriptionRichText': review_request_details.description_rich_text, 'hasDraft': draft is not None, 'lastUpdatedTimestamp': review_request.last_updated, 'public': review_request.public, 'reviewURL': review_request.get_absolute_url(), 'state': state_data, 'summary': review_request_details.summary, 'targetGroups': [{ 'name': group.name, 'url': group.get_absolute_url(), } for group in review_request_details.target_groups.all()], 'targetPeople': [{ 'username': target_user.username, 'url': local_site_reverse('user', args=[target_user], request=request) } for target_user in review_request_details.target_people.all()], 'testingDone': normalize_text_for_edit( user=user, text=review_request_details.testing_done, rich_text=review_request_details.testing_done_rich_text, escape_html=False), 'testingDoneRichText': review_request_details.testing_done_rich_text, } if user.is_authenticated(): review_request_visit = context['review_request_visit'] if review_request_visit.visibility == review_request_visit.VISIBLE: visibility_data = 'VISIBLE' elif review_request_visit.visibility == review_request_visit.ARCHIVED: visibility_data = 'ARCHIVED' elif review_request_visit.visibility == review_request_visit.MUTED: visibility_data = 'MUTED' else: raise ValueError( 'Unexpected ReviewRequestVisit.visibility value "%s"' % review_request_visit.visibility) review_request_data['visibility'] = visibility_data repository = review_request.repository if repository: scmtool = repository.get_scmtool() review_request_data['repository'] = { 'id': repository.pk, 'name': repository.name, 'scmtoolName': scmtool.name, 'requiresBasedir': not scmtool.diffs_use_absolute_paths, 'requiresChangeNumber': scmtool.supports_pending_changesets, 'supportsPostCommit': repository.supports_post_commit, } if repository.bug_tracker: review_request_data['bugTrackerURL'] = \ local_site_reverse( 'bug_url', args=[review_request.display_id, '--bug_id--'], request=request) if draft: review_request_data['submitter'] = { 'title': draft.submitter.username, 'url': draft.submitter.get_absolute_url(), } # Build the data for the RB.ReviewRequestEditor. editor_data = { 'closeDescriptionRenderedText': _render_markdown(close_description, close_description_rich_text), 'commits': None, 'hasDraft': draft is not None, 'mutableByUser': context['mutable_by_user'], 'showSendEmail': context['send_email'], 'statusMutableByUser': context['status_mutable_by_user'], } if review_request.created_with_history: diffset = review_request_details.get_latest_diffset() editor_data['commits'] = [ commit.serialize() for commit in diffset.commits.all() ] # Build extra data for the RB.ReviewRequest. extra_review_request_draft_data = {} if draft and draft.changedesc: extra_review_request_draft_data.update({ 'changeDescription': normalize_text_for_edit(user=user, text=draft.changedesc.text, rich_text=draft.changedesc.rich_text, escape_html=False), 'changeDescriptionRichText': draft.changedesc.rich_text, }) editor_data['changeDescriptionRenderedText'] = _render_markdown( draft.changedesc.text, draft.changedesc.rich_text) if draft.diffset: extra_review_request_draft_data['interdiffLink'] = \ local_site_reverse( 'view-interdiff', args=[ review_request.display_id, draft.diffset.revision - 1, draft.diffset.revision ], request=request) # Build the file attachments data for the editor data. file_attachments_data = [] for file_attachment in context.get('file_attachments', []): if draft: caption = file_attachment.draft_caption else: caption = file_attachment.caption file_attachment_data = { 'id': file_attachment.pk, 'loaded': True, 'caption': caption, 'downloadURL': file_attachment.get_absolute_url(), 'filename': file_attachment.filename, 'revision': file_attachment.attachment_revision, 'thumbnailHTML': file_attachment.thumbnail, } if file_attachment.attachment_history_id: file_attachment_data['attachmentHistoryID'] = \ file_attachment.attachment_history_id if _has_usable_review_ui(user, review_request, file_attachment): file_attachment_data['reviewURL'] = \ local_site_reverse( 'file-attachment', args=[review_request.display_id, file_attachment.pk], request=request) file_attachments_data.append(file_attachment_data) if file_attachments_data: editor_data['fileAttachments'] = file_attachments_data # Build the file attachment comments data for the editor data. file_attachment_comments_data = {} for file_attachment in context.get('all_file_attachments', []): review_ui = file_attachment.review_ui if not review_ui: # For the purposes of serialization, we'll create a dummy ReviewUI. review_ui = FileAttachmentReviewUI(file_attachment.review_request, file_attachment) # NOTE: We're setting this here because file attachments serialization # requires this to be set, but we don't necessarily have it set # by this time. We should rethink parts of this down the road, # but it requires dealing with some compatibility issues for # subclasses. review_ui.request = request file_attachment_comments_data[file_attachment.pk] = \ review_ui.serialize_comments(file_attachment.get_comments()) if file_attachment_comments_data: editor_data['fileAttachmentComments'] = file_attachment_comments_data # And we're done! Assemble it together and chop off the outer dictionary # so it can be injected correctly. return json_dumps_items({ 'checkForUpdates': True, 'reviewRequestData': review_request_data, 'extraReviewRequestDraftData': extra_review_request_draft_data, 'editorData': editor_data, })
def reviewable_page_model_data(context): """Output JSON-serialized data for a RB.ReviewablePage model. The data will be used by :js:class:`RB.ReviewablePage` in order to populate the review request and editor with the necessary state. Args: context (django.template.RequestContext): The current template context. Returns: unicode: The resulting JSON-serialized data. This consists of keys that are meant to be injected into an existing dictionary. """ request = context['request'] user = request.user review_request = context['review_request'] review_request_details = context['review_request_details'] draft = context['draft'] close_description = context['close_description'] close_description_rich_text = context['close_description_rich_text'] if review_request.local_site: local_site_prefix = 's/%s/' % review_request.local_site.name else: local_site_prefix = '' # Build data for the RB.ReviewRequest if review_request.status == review_request.PENDING_REVIEW: state_data = 'PENDING' elif review_request.status == review_request.SUBMITTED: state_data = 'CLOSE_SUBMITTED' elif review_request.status == review_request.DISCARDED: state_data = 'CLOSE_DISCARDED' else: raise ValueError('Unexpected ReviewRequest.status value "%s"' % review_request.status) review_request_data = { 'id': review_request.display_id, 'localSitePrefix': local_site_prefix, 'branch': review_request_details.branch, 'bugsClosed': review_request_details.get_bug_list(), 'closeDescription': normalize_text_for_edit( user=user, text=close_description, rich_text=close_description_rich_text, escape_html=False), 'closeDescriptionRichText': close_description_rich_text, 'description': normalize_text_for_edit( user=user, text=review_request_details.description, rich_text=review_request_details.description_rich_text, escape_html=False), 'descriptionRichText': review_request_details.description_rich_text, 'hasDraft': draft is not None, 'lastUpdatedTimestamp': review_request.last_updated, 'public': review_request.public, 'reviewURL': review_request.get_absolute_url(), 'state': state_data, 'summary': review_request_details.summary, 'targetGroups': [ { 'name': group.name, 'url': group.get_absolute_url(), } for group in review_request_details.target_groups.all() ], 'targetPeople': [ { 'username': target_user.username, 'url': local_site_reverse('user', args=[target_user], request=request) } for target_user in review_request_details.target_people.all() ], 'testingDone': normalize_text_for_edit( user=user, text=review_request_details.testing_done, rich_text=review_request_details.testing_done_rich_text, escape_html=False), 'testingDoneRichText': review_request_details.testing_done_rich_text, } if user.is_authenticated(): review_request_visit = context['review_request_visit'] if review_request_visit.visibility == review_request_visit.VISIBLE: visibility_data = 'VISIBLE' elif review_request_visit.visibility == review_request_visit.ARCHIVED: visibility_data = 'ARCHIVED' elif review_request_visit.visibility == review_request_visit.MUTED: visibility_data = 'MUTED' else: raise ValueError( 'Unexpected ReviewRequestVisit.visibility value "%s"' % review_request_visit.visibility) review_request_data['visibility'] = visibility_data repository = review_request.repository if repository: scmtool = repository.get_scmtool() review_request_data['repository'] = { 'id': repository.pk, 'name': repository.name, 'scmtoolName': scmtool.name, 'requiresBasedir': not scmtool.diffs_use_absolute_paths, 'requiresChangeNumber': scmtool.supports_pending_changesets, 'supportsPostCommit': repository.supports_post_commit, } if repository.bug_tracker: review_request_data['bugTrackerURL'] = \ local_site_reverse( 'bug_url', args=[review_request.display_id, '--bug_id--'], request=request) if draft: review_request_data['submitter'] = { 'title': draft.submitter.username, 'url': draft.submitter.get_absolute_url(), } # Build the data for the RB.ReviewRequestEditor. editor_data = { 'closeDescriptionRenderedText': _render_markdown( close_description, close_description_rich_text), 'hasDraft': draft is not None, 'mutableByUser': context['mutable_by_user'], 'showSendEmail': context['send_email'], 'statusMutableByUser': context['status_mutable_by_user'], } # Build extra data for the RB.ReviewRequest. extra_review_request_draft_data = {} if draft and draft.changedesc: extra_review_request_draft_data.update({ 'changeDescription': normalize_text_for_edit( user=user, text=draft.changedesc.text, rich_text=draft.changedesc.rich_text, escape_html=False), 'changeDescriptionRichText': draft.changedesc.rich_text, }) editor_data['changeDescriptionRenderedText'] = _render_markdown( draft.changedesc.text, draft.changedesc.rich_text) if draft.diffset: extra_review_request_draft_data['interdiffLink'] = \ local_site_reverse( 'view-interdiff', args=[ review_request.display_id, draft.diffset.revision - 1, draft.diffset.revision ], request=request) # Build the file attachments data for the editor data. file_attachments_data = [] for file_attachment in context.get('file_attachments', []): if draft: caption = file_attachment.draft_caption else: caption = file_attachment.caption file_attachment_data = { 'id': file_attachment.pk, 'loaded': True, 'caption': caption, 'downloadURL': file_attachment.get_absolute_url(), 'filename': file_attachment.filename, 'revision': file_attachment.attachment_revision, 'thumbnailHTML': file_attachment.thumbnail, } if file_attachment.attachment_history_id: file_attachment_data['attachmentHistoryID'] = \ file_attachment.attachment_history_id if _has_usable_review_ui(user, review_request, file_attachment): file_attachment_data['reviewURL'] = \ local_site_reverse( 'file-attachment', args=[review_request.display_id, file_attachment.pk], request=request) file_attachments_data.append(file_attachment_data) if file_attachments_data: editor_data['fileAttachments'] = file_attachments_data # Build the file attachment comments data for the editor data. file_attachment_comments_data = {} for file_attachment in context.get('all_file_attachments', []): review_ui = file_attachment.review_ui if not review_ui: # For the purposes of serialization, we'll create a dummy ReviewUI. review_ui = FileAttachmentReviewUI(file_attachment.review_request, file_attachment) # NOTE: We're setting this here because file attachments serialization # requires this to be set, but we don't necessarily have it set # by this time. We should rethink parts of this down the road, # but it requires dealing with some compatibility issues for # subclasses. review_ui.request = request file_attachment_comments_data[file_attachment.pk] = \ review_ui.serialize_comments(file_attachment.get_comments()) if file_attachment_comments_data: editor_data['fileAttachmentComments'] = file_attachment_comments_data # And we're done! Assemble it together and chop off the outer dictionary # so it can be injected correctly. return json_dumps_items({ 'checkForUpdates': True, 'reviewRequestData': review_request_data, 'extraReviewRequestDraftData': extra_review_request_draft_data, 'editorData': editor_data, })