def comment_diff_fragments( request, review_request_id, comment_ids, template_name='reviews/load_diff_comment_fragments.js', comment_template_name='reviews/diff_comment_fragment.html', error_template_name='diffviewer/diff_fragment_error.html'): """ Returns the fragment representing the parts of a diff referenced by the specified list of comment IDs. This is used to allow batch lazy-loading of these diff fragments based on filediffs, since they may not be cached and take time to generate. """ comments = get_list_or_404(Comment, pk__in=comment_ids.split(",")) latest_timestamp = get_latest_timestamp([comment.timestamp for comment in comments]) if get_modified_since(request, latest_timestamp): return HttpResponseNotModified() context = RequestContext(request, { 'comment_entries': [], 'container_prefix': request.GET.get('container_prefix'), 'queue_name': request.GET.get('queue'), }) had_error = False for comment in comments: try: content = render_to_string(comment_template_name, RequestContext(request, { 'comment': comment, 'chunks': list(get_file_chunks_in_range(context, comment.filediff, comment.interfilediff, comment.first_line, comment.num_lines)) })) except Exception, e: content = exception_traceback_string(request, e, error_template_name, { 'comment': comment, 'file': { 'depot_filename': comment.filediff.source_file, 'index': None, 'filediff': comment.filediff, }, }) # It's bad that we failed, and we'll return a 500, but we'll # still return content for anything we have. This will prevent any # caching. had_error = True context['comment_entries'].append({ 'comment': comment, 'html': content, })
def are_cache_headers_current(self, request, last_modified=None, etag=None): """Determines if cache headers from the client are current. This will compare the optionally-provided timestamp and ETag against any conditional cache headers sent by the client to determine if the headers are current. If they are, the caller can return HttpResponseNotModified instead of a payload. """ return ((last_modified and get_modified_since(request, last_modified)) or (etag and etag_if_none_match(request, etag)))
def get(self, request, api_format, *args, **kwargs): """Handles HTTP GETs to individual object resources. By default, this will check for access permissions and query for the object. It will then return a serialized form of the object. This may need to be overridden if needing more complex logic. """ if (not self.model or (self.uri_object_key is None and not self.singleton)): return HttpResponseNotAllowed(self.allowed_methods) try: obj = self.get_object(request, *args, **kwargs) except self.model.DoesNotExist: return DOES_NOT_EXIST if not self.has_access_permissions(request, obj, *args, **kwargs): if request.user.is_authenticated(): return PERMISSION_DENIED else: return NOT_LOGGED_IN last_modified_timestamp = self.get_last_modified(request, obj) if (last_modified_timestamp and get_modified_since(request, last_modified_timestamp)): return HttpResponseNotModified() etag = self.get_etag(request, obj) if etag and etag_if_none_match(request, etag): return HttpResponseNotModified() data = { self.item_result_key: self.serialize_object(obj, request=request, *args, **kwargs), } response = WebAPIResponse(request, status=200, obj=data, api_format=api_format, **self.build_response_args(request)) if last_modified_timestamp: set_last_modified(response, last_modified_timestamp) if etag: set_etag(response, etag) return response
def comment_diff_fragments( request, review_request_id, comment_ids, template_name='reviews/load_diff_comment_fragments.js', comment_template_name='reviews/diff_comment_fragment.html', error_template_name='diffviewer/diff_fragment_error.html', local_site_name=None): """ Returns the fragment representing the parts of a diff referenced by the specified list of comment IDs. This is used to allow batch lazy-loading of these diff fragments based on filediffs, since they may not be cached and take time to generate. """ # While we don't actually need the review request, we still want to do this # lookup in order to get the permissions checking. review_request, response = \ _find_review_request(request, review_request_id, local_site_name) if not review_request: return response comments = get_list_or_404(Comment, pk__in=comment_ids.split(",")) latest_timestamp = get_latest_timestamp( [comment.timestamp for comment in comments]) if get_modified_since(request, latest_timestamp): return HttpResponseNotModified() context = RequestContext( request, { 'comment_entries': [], 'container_prefix': request.GET.get('container_prefix'), 'queue_name': request.GET.get('queue'), }) had_error, context['comment_entries'] = \ build_diff_comment_fragments(comments, context, comment_template_name, error_template_name) page_content = render_to_string(template_name, context) if had_error: return HttpResponseServerError(page_content) response = HttpResponse(page_content) set_last_modified(response, comment.timestamp) response['Expires'] = http_date(time.time() + 60 * 60 * 24 * 365) # 1 year return response
def comment_diff_fragments( request, review_request_id, comment_ids, template_name='reviews/load_diff_comment_fragments.js', comment_template_name='reviews/diff_comment_fragment.html', error_template_name='diffviewer/diff_fragment_error.html', local_site_name=None): """ Returns the fragment representing the parts of a diff referenced by the specified list of comment IDs. This is used to allow batch lazy-loading of these diff fragments based on filediffs, since they may not be cached and take time to generate. """ # While we don't actually need the review request, we still want to do this # lookup in order to get the permissions checking. review_request, response = \ _find_review_request(request, review_request_id, local_site_name) if not review_request: return response comments = get_list_or_404(Comment, pk__in=comment_ids.split(",")) latest_timestamp = get_latest_timestamp([comment.timestamp for comment in comments]) if get_modified_since(request, latest_timestamp): return HttpResponseNotModified() context = RequestContext(request, { 'comment_entries': [], 'container_prefix': request.GET.get('container_prefix'), 'queue_name': request.GET.get('queue'), }) had_error, context['comment_entries'] = \ build_diff_comment_fragments(comments, context, comment_template_name, error_template_name) page_content = render_to_string(template_name, context) if had_error: return HttpResponseServerError(page_content) response = HttpResponse(page_content) set_last_modified(response, comment.timestamp) response['Expires'] = http_date(time.time() + 60 * 60 * 24 * 365) # 1 year return response
def comment_diff_fragments( request, review_request_id, comment_ids, template_name="reviews/load_diff_comment_fragments.js", comment_template_name="reviews/diff_comment_fragment.html", error_template_name="diffviewer/diff_fragment_error.html", ): """ Returns the fragment representing the parts of a diff referenced by the specified list of comment IDs. This is used to allow batch lazy-loading of these diff fragments based on filediffs, since they may not be cached and take time to generate. """ comments = get_list_or_404(Comment, pk__in=comment_ids.split(",")) latest_timestamp = get_latest_timestamp([comment.timestamp for comment in comments]) if get_modified_since(request, latest_timestamp): return HttpResponseNotModified() context = RequestContext( request, { "comment_entries": [], "container_prefix": request.GET.get("container_prefix"), "queue_name": request.GET.get("queue"), }, ) had_error, context["comment_entries"] = build_diff_comment_fragments( comments, context, comment_template_name, error_template_name ) page_content = render_to_string(template_name, context) if had_error: return HttpResponseServerError(page_content) response = HttpResponse(page_content) set_last_modified(response, comment.timestamp) response["Expires"] = http_date(time.time() + 60 * 60 * 24 * 365) # 1 year return response
def get(self, request, *args, **kwargs): """Returns the last update made to the review request. This shows the type of update that was made, the user who made the update, and when the update was made. Clients can use this to inform the user that the review request was updated, or automatically update it in the background. This does not take into account changes to a draft review request, as that's generally not update information that the owner of the draft is interested in. Only public updates are represented. """ try: review_request = \ resources.review_request.get_object(request, *args, **kwargs) except ObjectDoesNotExist: return DOES_NOT_EXIST if not resources.review_request.has_access_permissions( request, review_request): return self._no_access_error(request.user) timestamp, updated_object = review_request.get_last_activity() if get_modified_since(request, timestamp): return HttpResponseNotModified() user = None summary = None update_type = None if isinstance(updated_object, ReviewRequest): user = updated_object.submitter if updated_object.status == ReviewRequest.SUBMITTED: summary = _("Review request submitted") elif updated_object.status == ReviewRequest.DISCARDED: summary = _("Review request discarded") else: summary = _("Review request updated") update_type = "review-request" elif isinstance(updated_object, DiffSet): summary = _("Diff updated") update_type = "diff" elif isinstance(updated_object, Review): user = updated_object.user if updated_object.is_reply(): summary = _("New reply") update_type = "reply" else: summary = _("New review") update_type = "review" else: # Should never be able to happen. The object will always at least # be a ReviewRequest. assert False return 200, { self.item_result_key: { 'timestamp': timestamp, 'user': user, 'summary': summary, 'type': update_type, } }, { 'Last-Modified': http_date(timestamp) }
def get(self, request, *args, **kwargs): """Returns the last update made to the review request. This shows the type of update that was made, the user who made the update, and when the update was made. Clients can use this to inform the user that the review request was updated, or automatically update it in the background. This does not take into account changes to a draft review request, as that's generally not update information that the owner of the draft is interested in. Only public updates are represented. """ try: review_request = \ resources.review_request.get_object(request, *args, **kwargs) except ObjectDoesNotExist: return DOES_NOT_EXIST if not resources.review_request.has_access_permissions(request, review_request): return self._no_access_error(request.user) timestamp, updated_object = review_request.get_last_activity() if get_modified_since(request, timestamp): return HttpResponseNotModified() user = None summary = None update_type = None if isinstance(updated_object, ReviewRequest): user = updated_object.submitter if updated_object.status == ReviewRequest.SUBMITTED: summary = _("Review request submitted") elif updated_object.status == ReviewRequest.DISCARDED: summary = _("Review request discarded") else: summary = _("Review request updated") update_type = "review-request" elif isinstance(updated_object, DiffSet): summary = _("Diff updated") update_type = "diff" elif isinstance(updated_object, Review): user = updated_object.user if updated_object.is_reply(): summary = _("New reply") update_type = "reply" else: summary = _("New review") update_type = "review" else: # Should never be able to happen. The object will always at least # be a ReviewRequest. assert False return 200, { self.item_result_key: { 'timestamp': timestamp, 'user': user, 'summary': summary, 'type': update_type, } }, { 'Last-Modified': http_date(timestamp) }