def render_change_entry_html(self, info): """Render a change entry to HTML. This function is expected to return safe, valid HTML. Any values coming from a field or any other form of user input must be properly escaped. Args: info (dict): A dictionary describing how the field has changed. This is guaranteed to have ``new`` and ``old`` keys, but may also contain ``added`` and ``removed`` keys as well. Returns: unicode: The HTML representation of the change entry. """ added_diff_info = info['added'][0] review_request = self.review_request_details.get_review_request() try: diffset = self.data.diffsets_by_id[added_diff_info[2]] except KeyError: # If a published revision of a diff has been deleted from the # database, this will explode. Just return a blank string for this, # so that it doesn't show a traceback. return '' diff_revision = diffset.revision past_revision = diff_revision - 1 diff_url = added_diff_info[1] s = [] # Fetch the total number of inserts/deletes. These will be shown # alongside the diff revision. counts = diffset.get_total_line_counts() raw_insert_count = counts.get('raw_insert_count', 0) raw_delete_count = counts.get('raw_delete_count', 0) line_counts = [] if raw_insert_count > 0: line_counts.append('<span class="insert-count">+%d</span>' % raw_insert_count) if raw_delete_count > 0: line_counts.append('<span class="delete-count">-%d</span>' % raw_delete_count) # Display the label, URL, and line counts for the diff. s.append(format_html( '<p class="diff-changes">' ' <a href="{url}">{label}</a>' ' <span class="line-counts">({line_counts})</span>' '</p>', url=diff_url, label=_('Revision %s') % diff_revision, count=_('%d files') % diffset.file_count, line_counts=mark_safe(' '.join(line_counts)))) if past_revision > 0: # This is not the first diff revision. Include an interdiff link. interdiff_url = local_site_reverse( 'view-interdiff', local_site=review_request.local_site, args=[ review_request.display_id, past_revision, diff_revision, ]) s.append(format_html( '<p><a href="{url}">{text}</a>', url=interdiff_url, text=_('Show changes'))) if diffset.file_count > 0: # Begin displaying the list of files modified in this diff. # It will be capped at a fixed number (MAX_FILES_PREVIEW). s += [ '<div class="diff-index">', ' <table>', ] # We want a sorted list of filediffs, but tagged with the order in # which they come from the database, so that we can properly link # to the respective files in the diff viewer. files = get_sorted_filediffs(enumerate(diffset.files.all()), key=lambda i: i[1]) for i, filediff in files[:self.MAX_FILES_PREVIEW]: counts = filediff.get_line_counts() data_attrs = [ 'data-%s="%s"' % (attr.replace('_', '-'), counts[attr]) for attr in ('insert_count', 'delete_count', 'replace_count', 'total_line_count') if counts.get(attr) is not None ] s.append(format_html( '<tr {data_attrs}>' ' <td class="diff-file-icon"></td>' ' <td class="diff-file-info">' ' <a href="{url}">{filename}</a>' ' </td>' '</tr>', data_attrs=mark_safe(' '.join(data_attrs)), url=diff_url + '#%d' % i, filename=filediff.source_file)) num_remaining = diffset.file_count - self.MAX_FILES_PREVIEW if num_remaining > 0: # There are more files remaining than we've shown, so show # the count. s.append(format_html( '<tr>' ' <td></td>' ' <td class="diff-file-info">{text}</td>' '</tr>', text=_('%s more') % num_remaining)) s += [ ' </table>', '</div>', ] return ''.join(s)
def render_change_entry_html(self, info): """Render a change entry to HTML. This function is expected to return safe, valid HTML. Any values coming from a field or any other form of user input must be properly escaped. Args: info (dict): A dictionary describing how the field has changed. This is guaranteed to have ``new`` and ``old`` keys, but may also contain ``added`` and ``removed`` keys as well. Returns: unicode: The HTML representation of the change entry. """ added_diff_info = info['added'][0] review_request = self.review_request_details.get_review_request() try: diffset = self.data.diffsets_by_id[added_diff_info[2]] except KeyError: # If a published revision of a diff has been deleted from the # database, this will explode. Just return a blank string for this, # so that it doesn't show a traceback. return '' diff_revision = diffset.revision past_revision = diff_revision - 1 diff_url = added_diff_info[1] s = [] # Fetch the total number of inserts/deletes. These will be shown # alongside the diff revision. counts = diffset.get_total_line_counts() raw_insert_count = counts.get('raw_insert_count', 0) raw_delete_count = counts.get('raw_delete_count', 0) line_counts = [] if raw_insert_count > 0: line_counts.append('<span class="insert-count">+%d</span>' % raw_insert_count) if raw_delete_count > 0: line_counts.append('<span class="delete-count">-%d</span>' % raw_delete_count) # Display the label, URL, and line counts for the diff. s.append( format_html( '<p class="diff-changes">' ' <a href="{url}">{label}</a>' ' <span class="line-counts">({line_counts})</span>' '</p>', url=diff_url, label=_('Revision %s') % diff_revision, count=_('%d files') % diffset.file_count, line_counts=mark_safe(' '.join(line_counts)))) if past_revision > 0: # This is not the first diff revision. Include an interdiff link. interdiff_url = local_site_reverse( 'view-interdiff', local_site=review_request.local_site, args=[ review_request.display_id, past_revision, diff_revision, ]) s.append( format_html('<p><a href="{url}">{text}</a>', url=interdiff_url, text=_('Show changes'))) if diffset.file_count > 0: # Begin displaying the list of files modified in this diff. # It will be capped at a fixed number (MAX_FILES_PREVIEW). s += [ '<div class="diff-index">', ' <table>', ] # We want a sorted list of filediffs, but tagged with the order in # which they come from the database, so that we can properly link # to the respective files in the diff viewer. files = get_sorted_filediffs(enumerate(diffset.files.all()), key=lambda i: i[1]) for i, filediff in files[:self.MAX_FILES_PREVIEW]: counts = filediff.get_line_counts() data_attrs = [ 'data-%s="%s"' % (attr.replace('_', '-'), counts[attr]) for attr in ('insert_count', 'delete_count', 'replace_count', 'total_line_count') if counts.get(attr) is not None ] s.append( format_html( '<tr {data_attrs}>' ' <td class="diff-file-icon"></td>' ' <td class="diff-file-info">' ' <a href="{url}">{filename}</a>' ' </td>' '</tr>', data_attrs=mark_safe(' '.join(data_attrs)), url=diff_url + '#%d' % i, filename=filediff.source_file)) num_remaining = diffset.file_count - self.MAX_FILES_PREVIEW if num_remaining > 0: # There are more files remaining than we've shown, so show # the count. s.append( format_html( '<tr>' ' <td></td>' ' <td class="diff-file-info">{text}</td>' '</tr>', text=_('%s more') % num_remaining)) s += [ ' </table>', '</div>', ] return ''.join(s)
def render_change_entry_html(self, info): added_diff_info = info['added'][0] review_request = self.review_request_details.get_review_request() diffset = self.diffsets_by_id[added_diff_info[2]] diff_revision = diffset.revision past_revision = diff_revision - 1 diff_url = added_diff_info[1] s = [] # Fetch the total number of inserts/deletes. These will be shown # alongside the diff revision. counts = diffset.get_total_line_counts() raw_insert_count = counts['raw_insert_count'] raw_delete_count = counts['raw_delete_count'] line_counts = [] if raw_insert_count > 0: line_counts.append('<span class="insert-count">+%d</span>' % raw_insert_count) if raw_delete_count > 0: line_counts.append('<span class="delete-count">-%d</span>' % raw_delete_count) # Display the label, URL, and line counts for the diff. s.append(format_html( '<p class="diff-changes">' ' <a href="{url}">{label}</a>' ' <span class="line-counts">({line_counts})</span>' '</p>', url=diff_url, label=_('Revision %s') % diff_revision, count=_('%d files') % diffset.file_count, line_counts=mark_safe(' '.join(line_counts)))) if past_revision > 0: # This is not the first diff revision. Include an interdiff link. interdiff_url = local_site_reverse('view-interdiff', args=[ review_request.display_id, past_revision, diff_revision, ]) s.append(format_html( '<p><a href="{url}">{text}</a>', url=interdiff_url, text=_('Show changes'))) if diffset.file_count > 0: # Begin displaying the list of files modified in this diff. # It will be capped at a fixed number (MAX_FILES_PREVIEW). s += [ '<div class="diff-index">', ' <table>', ] # We want a sorted list of filediffs, but tagged with the order in # which they come from the database, so that we can properly link # to the respective files in the diff viewer. files = get_sorted_filediffs(enumerate(diffset.files.all()), key=lambda i: i[1]) for i, filediff in files[:self.MAX_FILES_PREVIEW]: counts = filediff.get_line_counts() data_attrs = [ 'data-%s="%s"' % (attr.replace('_', '-'), counts[attr]) for attr in ('insert_count', 'delete_count', 'replace_count', 'total_line_count') if counts.get(attr) is not None ] s.append(format_html( '<tr {data_attrs}>' ' <td class="diff-file-icon"></td>' ' <td class="diff-file-info">' ' <a href="{url}">{filename}</a>' ' </td>' '</tr>', data_attrs=mark_safe(' '.join(data_attrs)), url=diff_url + '#%d' % i, filename=filediff.source_file)) num_remaining = diffset.file_count - self.MAX_FILES_PREVIEW if num_remaining > 0: # There are more files remaining than we've shown, so show # the count. s.append(format_html( '<tr>' ' <td></td>' ' <td class="diff-file-info">{text}</td>' '</tr>', text=_('%s more') % num_remaining)) s += [ ' </table>', '</div>', ] return ''.join(s)