Esempio n. 1
0
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()))
Esempio n. 2
0
    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)
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
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
Esempio n. 9
0
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,
    })
Esempio n. 10
0
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,
    })