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()}, ]
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)})
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)})
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, }
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)})
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
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)
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)
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)} )
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)
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)