def changelist_js_model_attrs(context): """Return serialized JSON attributes for the RB.Admin.ChangeListPage model. These will all be passed to the :js:class:`RB.Admin.ChangeListPage` constructor. Args: context (django.template.Context): The context for the page. Returns: django.utils.safestring.SafeText: A string containing the JSON attributes for the page model. """ action_form = context.get('action_form') cl = context['cl'] model_data = { 'modelName': cl.opts.verbose_name, 'modelNamePlural': cl.opts.verbose_name_plural, } if action_form is not None: action_choices = action_form.fields['action'].choices model_data['actions'] = [{ 'id': action_id, 'label': action_label, } for action_id, action_label in action_choices if action_id] return json_dumps_items(model_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), '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, })