Exemple #1
0
    def add_urls_from_datagrid(urls, datagrid, view, group=None):
        datagrid.load_state()

        datagrid_params = "view=%s" % view

        if group:
            datagrid_params += "&group=%s" % group

        datagrid_url = "%s%s?%s" % (url_prefix, reverse("dashboard"), datagrid_params)

        urls.append({"url": datagrid_url, "matchQuery": {"hasAll": datagrid_params}})

        highlighting = get_enable_highlighting(request.user)

        for obj_info in datagrid.rows:
            review_request = obj_info["object"]
            assert isinstance(review_request, ReviewRequest)

            if review_request.id in found_review_requests:
                continue

            found_review_requests[review_request.id] = True

            # Grab the latest activity timestamp.
            # TODO: Make this common between here and review_detail.
            timestamp = get_last_activity_timestamp(review_request)

            if not info["latest_timestamp"] or timestamp > info["latest_timestamp"]:
                info["latest_timestamp"] = timestamp

            urls.append({"url": url_prefix + review_request.get_absolute_url()})

            try:
                diffset = review_request.diffset_history.diffsets.latest()

                view_diff_url = url_prefix + reverse("view_diff", args=[review_request.id])

                urls += [{"url": view_diff_url}, {"url": url_prefix + reverse("raw_diff", args=[review_request.id])}]

                files = get_diff_files(diffset, None, None, highlighting, False)

                # Break the list of files into pages
                siteconfig = SiteConfiguration.objects.get_current()
                paginator = Paginator(
                    files, siteconfig.get("diffviewer_paginate_by"), siteconfig.get("diffviewer_paginate_orphans")
                )

                for pagenum in paginator.page_range:
                    urls.append({"url": "%s?page=%d" % (view_diff_url, pagenum)})
            except DiffSet.DoesNotExist:
                pass

            for screenshot in review_request.screenshots.all():
                urls += [
                    {"url": url_prefix + screenshot.get_absolute_url()},
                    {"url": url_prefix + screenshot.image.url},
                    {"url": url_prefix + screenshot.get_thumbnail_url()},
                ]
Exemple #2
0
def view_diff_fragment(
    request,
    diffset_id,
    filediff_id,
    base_url,
    interdiffset_id=None,
    chunkindex=None,
    template_name='diffviewer/diff_file_fragment.html',
    error_template_name='diffviewer/diff_fragment_error.html'):
    """View which renders a specific fragment from a diff."""

    def get_requested_diff_file(get_chunks=True):
        files = get_diff_files(diffset, filediff, interdiffset, highlighting,
                               get_chunks)

        if files:
            assert len(files) == 1
            file = files[0]

            if 'index' in request.GET:
                file['index'] = request.GET.get('index')

            return file

        return None

    diffset = get_object_or_404(DiffSet, pk=diffset_id)
    filediff = get_object_or_404(FileDiff, pk=filediff_id, diffset=diffset)
    interdiffset = get_object_or_none(DiffSet, pk=interdiffset_id)
    highlighting = get_enable_highlighting(request.user)

    if chunkindex:
        collapseall = False
    else:
        collapseall = get_collapse_diff(request)

    try:
        file = get_requested_diff_file()

        if file:
            context = {
                'standalone': chunkindex is not None,
                'base_url': base_url,
            }

            return HttpResponse(build_diff_fragment(request, file,
                                                    chunkindex,
                                                    highlighting, collapseall,
                                                    context, template_name))
        raise UserVisibleError(
            _(u"Internal error. Unable to locate file record for filediff %s") % \
            filediff.id)
    except Exception, e:
        return exception_traceback(
            request, e, error_template_name,
            extra_context={'file': get_requested_diff_file(False)})
Exemple #3
0
def view_diff_fragment(
        request,
        diffset_id,
        filediff_id,
        base_url,
        interdiffset_id=None,
        chunkindex=None,
        template_name='diffviewer/diff_file_fragment.html',
        error_template_name='diffviewer/diff_fragment_error.html'):
    """View which renders a specific fragment from a diff."""
    def get_requested_diff_file(get_chunks=True):
        files = get_diff_files(diffset, filediff, interdiffset, highlighting,
                               get_chunks)

        if files:
            assert len(files) == 1
            file = files[0]

            if 'index' in request.GET:
                file['index'] = request.GET.get('index')

            return file

        return None

    diffset = get_object_or_404(DiffSet, pk=diffset_id)
    filediff = get_object_or_404(FileDiff, pk=filediff_id, diffset=diffset)
    interdiffset = get_object_or_none(DiffSet, pk=interdiffset_id)
    highlighting = get_enable_highlighting(request.user)

    if chunkindex:
        collapseall = False
    else:
        collapseall = get_collapse_diff(request)

    try:
        file = get_requested_diff_file()

        if file:
            context = {
                'standalone': chunkindex is not None,
                'base_url': base_url,
            }

            return HttpResponse(
                build_diff_fragment(request, file, chunkindex, highlighting,
                                    collapseall, context, template_name))
        raise UserVisibleError(
            _(u"Internal error. Unable to locate file record for filediff %s") % \
            filediff.id)
    except Exception, e:
        return exception_traceback(
            request,
            e,
            error_template_name,
            extra_context={'file': get_requested_diff_file(False)})
Exemple #4
0
    def _get_renderer_settings(self, chunk_index=None, **kwargs):
        """Calculate the render settings for the display of a diff.

        This will calculate settings based on user preferences and URL
        parameters. It does not calculate the state of any DiffSets or
        FileDiffs.
        """
        highlighting = get_enable_highlighting(self.request.user)

        try:
            lines_of_context = self.request.GET.get('lines-of-context', '')
            lines_of_context = [int(i) for i in lines_of_context.split(',', 1)]
        except (TypeError, ValueError):
            lines_of_context = None

        if chunk_index is not None:
            try:
                chunk_index = int(chunk_index)
            except (TypeError, ValueError):
                chunk_index = None

        if lines_of_context:
            collapse_all = True
        elif chunk_index is not None:
            # If we're currently expanding part of a chunk, we want to render
            # the entire chunk without any lines collapsed. In the case of
            # showing a range of lines, we're going to get all chunks and then
            # only show the range. This is so that we won't have separate
            # cached entries for each range.
            collapse_all = False
        else:
            collapse_all = get_collapse_diff(self.request)

        show_deleted = (self.request.GET.get('show-deleted') == '1')

        return {
            'chunk_index': chunk_index,
            'collapse_all': collapse_all,
            'highlighting': highlighting,
            'lines_of_context': lines_of_context,
            'show_deleted': show_deleted,
        }
Exemple #5
0
    def _get_renderer_settings(self, chunk_index=None, **kwargs):
        """Calculate the render settings for the display of a diff.

        This will calculate settings based on user preferences and URL
        parameters. It does not calculate the state of any DiffSets or
        FileDiffs.
        """
        highlighting = get_enable_highlighting(self.request.user)

        try:
            lines_of_context = self.request.GET.get('lines-of-context', '')
            lines_of_context = [int(i) for i in lines_of_context.split(',', 1)]
        except (TypeError, ValueError):
            lines_of_context = None

        if chunk_index is not None:
            try:
                chunk_index = int(chunk_index)
            except (TypeError, ValueError):
                chunk_index = None

        if lines_of_context:
            collapse_all = True
        elif chunk_index is not None:
            # If we're currently expanding part of a chunk, we want to render
            # the entire chunk without any lines collapsed. In the case of
            # showing a range of lines, we're going to get all chunks and then
            # only show the range. This is so that we won't have separate
            # cached entries for each range.
            collapse_all = False
        else:
            collapse_all = get_collapse_diff(self.request)

        show_deleted = (self.request.GET.get('show-deleted') == '1')

        return {
            'chunk_index': chunk_index,
            'collapse_all': collapse_all,
            'highlighting': highlighting,
            'lines_of_context': lines_of_context,
            'show_deleted': show_deleted,
        }
Exemple #6
0
def view_diff_fragment(
    request,
    diffset_or_id,
    filediff_id,
    base_url,
    interdiffset_or_id=None,
    chunkindex=None,
    template_name='diffviewer/diff_file_fragment.html',
    error_template_name='diffviewer/diff_fragment_error.html'):
    """View which renders a specific fragment from a diff."""

    def get_requested_diff_file(get_chunks=True):
        files = get_diff_files(diffset, filediff, interdiffset,
                               request=request)

        if get_chunks:
            populate_diff_chunks(files, highlighting, request=request)

        if files:
            assert len(files) == 1
            file = files[0]

            if 'index' in request.GET:
                file['index'] = request.GET.get('index')

            return file

        return None

    # Depending on whether we're invoked from a URL or from a wrapper
    # with precomputed diffsets, we may be working with either IDs or
    # actual objects. If they're objects, just use them as-is. Otherwise,
    # if they're IDs, we want to grab them both (if both are provided)
    # in one go, to save on an SQL query.
    diffset_ids = []
    diffset = None
    interdiffset = None

    if isinstance(diffset_or_id, DiffSet):
        diffset = diffset_or_id
    else:
        diffset_ids.append(diffset_or_id)

    if interdiffset_or_id:
        if isinstance(interdiffset_or_id, DiffSet):
            interdiffset = interdiffset_or_id
        else:
            diffset_ids.append(interdiffset_or_id)

    if diffset_ids:
        diffsets = DiffSet.objects.filter(pk__in=diffset_ids)

        if len(diffsets) != len(diffset_ids):
            raise Http404

        for temp_diffset in diffsets:
            if temp_diffset.pk == diffset_or_id:
                diffset = temp_diffset
            elif temp_diffset.pk == interdiffset_or_id:
                interdiffset = temp_diffset
            else:
                assert False

    filediff = get_object_or_404(FileDiff, pk=filediff_id, diffset=diffset)

    # Store this so we don't end up causing an SQL query later when looking
    # this up.
    filediff.diffset = diffset

    highlighting = get_enable_highlighting(request.user)

    try:
        lines_of_context = request.GET.get('lines-of-context', '')
        lines_of_context = [int(i) for i in lines_of_context.split(',', 1)]
    except (TypeError, ValueError):
        lines_of_context = None

    if lines_of_context:
        collapseall = True
    elif chunkindex:
        # If we're currently expanding part of a chunk, we want to render
        # the entire chunk without any lines collapsed. In the case of showing
        # a range of lines, we're going to get all chunks and then only show
        # the range. This is so that we won't have separate cached entries for
        # each range.
        collapseall = False
    else:
        collapseall = get_collapse_diff(request)

    try:
        file = get_requested_diff_file()

        if file:
            return HttpResponse(
                build_diff_fragment(request, file,
                                    chunkindex,
                                    highlighting, collapseall,
                                    lines_of_context,
                                    chunkindex is not None,
                                    context={
                                        'base_url': base_url,
                                    },
                                    template_name=template_name))

        raise UserVisibleError(
            _(u"Internal error. Unable to locate file record for filediff %s") % \
            filediff.id)
    except Exception, e:
        return exception_traceback(
            request, e, error_template_name,
            extra_context={'file': get_requested_diff_file(False)})
Exemple #7
0
def view_diff(request, diffset, interdiffset=None, extra_context={},
              template_name='diffviewer/view_diff.html'):
    highlighting = get_enable_highlighting(request.user)

    try:
        if interdiffset:
            logging.debug("Generating diff viewer page for interdiffset ids "
                          "%s-%s",
                          diffset.id, interdiffset.id, request=request)
        else:
            logging.debug("Generating diff viewer page for filediff id %s",
                          diffset.id, request=request)

        files = get_diff_files(diffset, None, interdiffset, request=request)

        # Break the list of files into pages
        siteconfig = SiteConfiguration.objects.get_current()

        paginator = Paginator(files,
                              siteconfig.get("diffviewer_paginate_by"),
                              siteconfig.get("diffviewer_paginate_orphans"))

        page_num = int(request.GET.get('page', 1))

        if request.GET.get('file', False):
            file_id = int(request.GET['file'])

            for i, f in enumerate(files):
                if f['filediff'].id == file_id:
                    page_num = i // paginator.per_page + 1
                    if page_num > paginator.num_pages:
                        page_num = paginator.num_pages
                    break

        page = paginator.page(page_num)

        collapse_diffs = get_collapse_diff(request)

        context = {
            'diffset': diffset,
            'interdiffset': interdiffset,
            'diffset_pair': (diffset, interdiffset),
            'files': page.object_list,
            'collapseall': collapse_diffs,

            # Add the pagination context
            'is_paginated': page.has_other_pages(),
            'page': page.number,
            'pages': paginator.num_pages,
            'page_numbers': paginator.page_range,
            'has_next': page.has_next(),
            'next_page': page.next_page_number(),
            'has_previous': page.has_previous(),
            'previous_page': page.previous_page_number(),
            'page_start_index': page.start_index(),
        }
        context.update(extra_context)

        # Attempt to preload the first file before rendering any part of
        # the page. This helps to remove the perception that the diff viewer
        # takes longer to load now that we have progressive diffs. Users were
        # seeing the page itself load quickly, but didn't see that first
        # diff immediately and instead saw a spinner, making them feel it was
        # taking longer than it used to to load a page. We just trick the
        # user by providing that first file.
        if page.object_list:
            first_file = page.object_list[0]
        else:
            first_file = None

        if first_file:
            filediff = first_file['filediff']

            if filediff.diffset == interdiffset:
                temp_files = get_diff_files(interdiffset, filediff, None,
                                            request=request)
            else:
                temp_files = get_diff_files(diffset, filediff, interdiffset,
                                            request=request)

            if temp_files:
                try:
                    populate_diff_chunks(temp_files, highlighting,
                                         request=request)
                except Exception, e:
                    file_temp = temp_files[0]
                    file_temp['index'] = first_file['index']
                    first_file['fragment'] = \
                        exception_traceback(request, e,
                                            'diffviewer/diff_fragment_error.html',
                                            extra_context={'file': file_temp})
                else:
                    file_temp = temp_files[0]
                    file_temp['index'] = first_file['index']
                    first_file['fragment'] = build_diff_fragment(
                        request, file_temp, None, highlighting,
                        collapse_diffs, None,
                        context=context,
                        template_name='diffviewer/diff_file_fragment.html')

        response = render_to_response(template_name,
                                      RequestContext(request, context))
        response.set_cookie('collapsediffs', collapse_diffs)

        if interdiffset:
            logging.debug("Done generating diff viewer page for interdiffset "
                          "ids %s-%s",
                          diffset.id, interdiffset.id, request=request)
        else:
            logging.debug("Done generating diff viewer page for filediff "
                          "id %s",
                          diffset.id, request=request)

        return response
Exemple #8
0
    def create_renderer(self, context, diffset_or_id, filediff_id,
                        interdiffset_or_id=None, chunkindex=None,
                        *args, **kwargs):
        """Creates the renderer for the diff.

        This calculates all the state and data needed for rendering, and
        constructs a DiffRenderer with that data. That renderer is then
        returned, ready for rendering.

        If there's an error in looking up the necessary information, this
        may raise a UserVisibleError (best case), or some other form of
        Exception.
        """
        # Depending on whether we're invoked from a URL or from a wrapper
        # with precomputed diffsets, we may be working with either IDs or
        # actual objects. If they're objects, just use them as-is. Otherwise,
        # if they're IDs, we want to grab them both (if both are provided)
        # in one go, to save on an SQL query.
        self.diffset = None
        self.interdiffset = None

        diffset_ids = []

        if isinstance(diffset_or_id, DiffSet):
            self.diffset = diffset_or_id
        else:
            diffset_ids.append(diffset_or_id)

        if interdiffset_or_id:
            if isinstance(interdiffset_or_id, DiffSet):
                self.interdiffset = interdiffset_or_id
            else:
                diffset_ids.append(interdiffset_or_id)

        if diffset_ids:
            diffsets = DiffSet.objects.filter(pk__in=diffset_ids)

            if len(diffsets) != len(diffset_ids):
                raise Http404

            for temp_diffset in diffsets:
                if temp_diffset.pk == diffset_or_id:
                    self.diffset = temp_diffset
                elif temp_diffset.pk == interdiffset_or_id:
                    self.interdiffset = temp_diffset
                else:
                    assert False

        self.highlighting = get_enable_highlighting(self.request.user)
        self.filediff = get_object_or_404(FileDiff, pk=filediff_id,
                                          diffset=self.diffset)

        # Store this so we don't end up causing an SQL query later when looking
        # this up.
        self.filediff.diffset = self.diffset

        try:
            lines_of_context = self.request.GET.get('lines-of-context', '')
            lines_of_context = [int(i) for i in lines_of_context.split(',', 1)]
        except (TypeError, ValueError):
            lines_of_context = None

        if chunkindex is not None:
            try:
                chunkindex = int(chunkindex)
            except (TypeError, ValueError):
                chunkindex = None

        if lines_of_context:
            collapseall = True
        elif chunkindex is not None:
            # If we're currently expanding part of a chunk, we want to render
            # the entire chunk without any lines collapsed. In the case of
            # showing a range of lines, we're going to get all chunks and then
            # only show the range. This is so that we won't have separate
            # cached entries for each range.
            collapseall = False
        else:
            collapseall = get_collapse_diff(self.request)

        self.diff_file = self._get_requested_diff_file()

        if not self.diff_file:
            raise UserVisibleError(
                _('Internal error. Unable to locate file record for '
                  'filediff %s')
                % self.filediff.pk)

        return get_diff_renderer(
            self.diff_file,
            chunk_index=chunkindex,
            highlighting=self.highlighting,
            collapse_all=collapseall,
            lines_of_context=lines_of_context,
            extra_context=context,
            template_name=self.template_name)
Exemple #9
0
    def create_renderer(self,
                        context,
                        diffset_or_id,
                        filediff_id,
                        interdiffset_or_id=None,
                        chunkindex=None,
                        *args,
                        **kwargs):
        """Creates the renderer for the diff.

        This calculates all the state and data needed for rendering, and
        constructs a DiffRenderer with that data. That renderer is then
        returned, ready for rendering.

        If there's an error in looking up the necessary information, this
        may raise a UserVisibleError (best case), or some other form of
        Exception.
        """
        # Depending on whether we're invoked from a URL or from a wrapper
        # with precomputed diffsets, we may be working with either IDs or
        # actual objects. If they're objects, just use them as-is. Otherwise,
        # if they're IDs, we want to grab them both (if both are provided)
        # in one go, to save on an SQL query.
        self.diffset = None
        self.interdiffset = None

        diffset_ids = []

        if isinstance(diffset_or_id, DiffSet):
            self.diffset = diffset_or_id
        else:
            diffset_ids.append(diffset_or_id)

        if interdiffset_or_id:
            if isinstance(interdiffset_or_id, DiffSet):
                self.interdiffset = interdiffset_or_id
            else:
                diffset_ids.append(interdiffset_or_id)

        if diffset_ids:
            diffsets = DiffSet.objects.filter(pk__in=diffset_ids)

            if len(diffsets) != len(diffset_ids):
                raise Http404

            for temp_diffset in diffsets:
                if temp_diffset.pk == diffset_or_id:
                    self.diffset = temp_diffset
                elif temp_diffset.pk == interdiffset_or_id:
                    self.interdiffset = temp_diffset
                else:
                    assert False

        self.highlighting = get_enable_highlighting(self.request.user)
        self.filediff = get_object_or_404(FileDiff,
                                          pk=filediff_id,
                                          diffset=self.diffset)

        # Store this so we don't end up causing an SQL query later when looking
        # this up.
        self.filediff.diffset = self.diffset

        try:
            lines_of_context = self.request.GET.get('lines-of-context', '')
            lines_of_context = [int(i) for i in lines_of_context.split(',', 1)]
        except (TypeError, ValueError):
            lines_of_context = None

        if chunkindex is not None:
            try:
                chunkindex = int(chunkindex)
            except (TypeError, ValueError):
                chunkindex = None

        if lines_of_context:
            collapseall = True
        elif chunkindex is not None:
            # If we're currently expanding part of a chunk, we want to render
            # the entire chunk without any lines collapsed. In the case of showing
            # a range of lines, we're going to get all chunks and then only show
            # the range. This is so that we won't have separate cached entries for
            # each range.
            collapseall = False
        else:
            collapseall = get_collapse_diff(self.request)

        self.diff_file = self._get_requested_diff_file()

        if not self.diff_file:
            raise UserVisibleError(
                _('Internal error. Unable to locate file record for '
                  'filediff %s') % self.filediff.pk)

        return get_diff_renderer(self.diff_file,
                                 chunk_index=chunkindex,
                                 highlighting=self.highlighting,
                                 collapse_all=collapseall,
                                 lines_of_context=lines_of_context,
                                 extra_context=context,
                                 template_name=self.template_name)
Exemple #10
0
def view_diff_fragment(
    request,
    diffset_or_id,
    filediff_id,
    base_url,
    interdiffset_or_id=None,
    chunkindex=None,
    template_name="diffviewer/diff_file_fragment.html",
    error_template_name="diffviewer/diff_fragment_error.html",
):
    """View which renders a specific fragment from a diff."""

    def get_requested_diff_file(get_chunks=True):
        files = get_diff_files(diffset, filediff, interdiffset)

        if get_chunks:
            populate_diff_chunks(files, highlighting)

        if files:
            assert len(files) == 1
            file = files[0]

            if "index" in request.GET:
                file["index"] = request.GET.get("index")

            return file

        return None

    # Depending on whether we're invoked from a URL or from a wrapper
    # with precomputed diffsets, we may be working with either IDs or
    # actual objects. If they're objects, just use them as-is. Otherwise,
    # if they're IDs, we want to grab them both (if both are provided)
    # in one go, to save on an SQL query.
    diffset_ids = []
    diffset = None
    interdiffset = None

    if isinstance(diffset_or_id, DiffSet):
        diffset = diffset_or_id
    else:
        diffset_ids.append(diffset_or_id)

    if interdiffset_or_id:
        if isinstance(interdiffset_or_id, DiffSet):
            interdiffset = interdiffset_or_id
        else:
            diffset_ids.append(interdiffset_or_id)

    if diffset_ids:
        diffsets = DiffSet.objects.filter(pk__in=diffset_ids)

        if len(diffsets) != len(diffset_ids):
            raise Http404

        for temp_diffset in diffsets:
            if temp_diffset.pk == diffset_or_id:
                diffset = temp_diffset
            elif temp_diffset.pk == interdiffset_or_id:
                interdiffset = temp_diffset
            else:
                assert False

    filediff = get_object_or_404(FileDiff, pk=filediff_id, diffset=diffset)

    # Store this so we don't end up causing an SQL query later when looking
    # this up.
    filediff.diffset = diffset

    highlighting = get_enable_highlighting(request.user)

    if chunkindex:
        collapseall = False
    else:
        collapseall = get_collapse_diff(request)

    try:
        file = get_requested_diff_file()

        if file:
            context = {"standalone": chunkindex is not None, "base_url": base_url}

            return HttpResponse(
                build_diff_fragment(request, file, chunkindex, highlighting, collapseall, context, template_name)
            )
        raise UserVisibleError(_(u"Internal error. Unable to locate file record for filediff %s") % filediff.id)
    except Exception, e:
        return exception_traceback(
            request, e, error_template_name, extra_context={"file": get_requested_diff_file(False)}
        )
Exemple #11
0
def view_diff(request, diffset_id, interdiffset_id=None, extra_context={}, template_name="diffviewer/view_diff.html"):
    diffset = get_object_or_404(DiffSet, pk=diffset_id)
    interdiffset = get_object_or_none(DiffSet, pk=interdiffset_id)
    highlighting = get_enable_highlighting(request.user)

    try:
        if interdiffset_id:
            logging.debug("Generating diff viewer page for interdiffset ids " "%s-%s", diffset_id, interdiffset_id)
        else:
            logging.debug("Generating diff viewer page for filediff id %s", diffset_id)

        files = get_diff_files(diffset, None, interdiffset, highlighting, False)

        # Break the list of files into pages
        siteconfig = SiteConfiguration.objects.get_current()

        paginator = Paginator(
            files, siteconfig.get("diffviewer_paginate_by"), siteconfig.get("diffviewer_paginate_orphans")
        )

        page_num = int(request.GET.get("page", 1))

        if request.GET.get("file", False):
            file_id = int(request.GET["file"])

            for i, f in enumerate(files):
                if f["filediff"].id == file_id:
                    page_num = i // paginator.per_page + 1
                    if page_num > paginator.num_pages:
                        page_num = paginator.num_pages
                    break

        page = paginator.page(page_num)

        collapse_diffs = get_collapse_diff(request)

        context = {
            "diffset": diffset,
            "interdiffset": interdiffset,
            "diffset_pair": (diffset, interdiffset),
            "files": page.object_list,
            "collapseall": collapse_diffs,
            # Add the pagination context
            "is_paginated": page.has_other_pages(),
            "page": page.number,
            "pages": paginator.num_pages,
            "page_numbers": paginator.page_range,
            "has_next": page.has_next(),
            "next_page": page.next_page_number(),
            "has_previous": page.has_previous(),
            "previous_page": page.previous_page_number(),
            "page_start_index": page.start_index(),
        }
        context.update(extra_context)

        # Attempt to preload the first file before rendering any part of
        # the page. This helps to remove the perception that the diff viewer
        # takes longer to load now that we have progressive diffs. Users were
        # seeing the page itself load quickly, but didn't see that first
        # diff immediately and instead saw a spinner, making them feel it was
        # taking longer than it used to to load a page. We just trick the
        # user by providing that first file.
        if page.object_list:
            first_file = page.object_list[0]
        else:
            first_file = None

        if first_file:
            filediff = first_file["filediff"]

            if filediff.diffset == interdiffset:
                temp_files = get_diff_files(interdiffset, filediff, None, highlighting, True)
            else:
                temp_files = get_diff_files(diffset, filediff, interdiffset, highlighting, True)

            if temp_files:
                file_temp = temp_files[0]
                file_temp["index"] = first_file["index"]
                first_file["fragment"] = build_diff_fragment(
                    request,
                    file_temp,
                    None,
                    highlighting,
                    collapse_diffs,
                    context,
                    "diffviewer/diff_file_fragment.html",
                )

        response = render_to_response(template_name, RequestContext(request, context))
        response.set_cookie("collapsediffs", collapse_diffs)

        if interdiffset_id:
            logging.debug("Done generating diff viewer page for interdiffset " "ids %s-%s", diffset_id, interdiffset_id)
        else:
            logging.debug("Done generating diff viewer page for filediff " "id %s", diffset_id)

        return response

    except Exception, e:
        return exception_traceback(request, e, template_name)
Exemple #12
0
def view_diff_fragment(
        request, diffset_id, filediff_id, interdiffset_id=None,
        chunkindex=None,
        template_name='diffviewer/diff_file_fragment.html',
        error_template_name='diffviewer/diff_fragment_error.html'):

    def get_requested_diff_file(get_chunks=True):
        files = get_diff_files(diffset, filediff, interdiffset, highlighting,
                               get_chunks)

        if files:
            assert len(files) == 1
            file = files[0]

            if 'index' in request.GET:
                file['index'] = request.GET.get('index')

            return file

        return None

    diffset = get_object_or_404(DiffSet, pk=diffset_id)
    filediff = get_object_or_404(FileDiff, pk=filediff_id, diffset=diffset)
    interdiffset = get_object_or_none(DiffSet, pk=interdiffset_id)
    highlighting = get_enable_highlighting(request.user)

    if chunkindex:
        collapseall = False
    else:
        collapseall = get_collapse_diff(request)

    etag = ""

    if collapseall:
        etag += "collapseall-"

    if highlighting:
        etag += "highlighting-"

    etag += str(settings.AJAX_SERIAL)

    if etag_if_none_match(request, etag):
        return HttpResponseNotModified()

    try:
        file = get_requested_diff_file()

        if file:
            context = {
                'standalone': chunkindex is not None,
            }

            response = HttpResponse(
                build_diff_fragment(request, file, chunkindex,
                                    highlighting, collapseall,
                                    context, template_name))
            set_etag(response, etag)
            return response
        raise UserVisibleError(
            _(u"Internal error. Unable to locate file record for filediff %s") % \
            filediff.id)
    except Exception, e:
        extra_context = {}

        file = get_requested_diff_file(False)
        extra_context['file'] = file

        return exception_traceback(request, e, error_template_name,
                                   extra_context)