def process_request(self, request): # https://bugzil.la/1189222 # Don't redirect POST $subscribe requests to GET zone url if request.method == "POST" and ("$subscribe" in request.path or "$files" in request.path): return None remaps = DocumentZoneURLRemapsJob().get(request.LANGUAGE_CODE) for original_path, new_path in remaps: if request.path_info == original_path or request.path_info.startswith(u"".join([original_path, "/"])): # Is this a request for the "original" wiki path? Redirect to # new URL root, if so. new_path = request.path_info.replace(original_path, new_path, 1) new_path = "/%s%s" % (request.LANGUAGE_CODE, new_path) query = request.GET.copy() new_path = urlparams(new_path, query_dict=query) return HttpResponseRedirect(new_path) elif request.path_info == u"/docs{}".format(new_path): # Is this a request for a DocumentZone, but with /docs/ wedged # in the url path between the language code and the zone's url_root? new_path = u"/{}{}".format(request.LANGUAGE_CODE, new_path) query = request.GET.copy() new_path = urlparams(new_path, query_dict=query) return HttpResponsePermanentRedirect(new_path) elif request.path_info.startswith(new_path): # Is this a request for the relocated wiki path? If so, rewrite # the path as a request for the proper wiki view. request.path_info = request.path_info.replace(new_path, original_path, 1) break
def test_known_authors_filter(self): # There are a total of 11 revisions url = urlparams(reverse('dashboards.revisions', locale='en-US'), authors=RevisionDashboardForm.ALL_AUTHORS) response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') eq_(response.status_code, 200) page = pq(response.content) revisions = page.find('.dashboard-row') eq_(11, revisions.length) # Only testuser01 is in the Known Authors group, and has 2 revisions url = urlparams(reverse('dashboards.revisions', locale='en-US'), authors=RevisionDashboardForm.KNOWN_AUTHORS) response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') eq_(response.status_code, 200) page = pq(response.content) revisions = page.find('.dashboard-row') eq_(2, revisions.length) # Of the 11 revisions, 9 are by users not in the Known Authors group url = urlparams(reverse('dashboards.revisions', locale='en-US'), authors=RevisionDashboardForm.UNKNOWN_AUTHORS) response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') eq_(response.status_code, 200) page = pq(response.content) revisions = page.find('.dashboard-row') eq_(9, revisions.length)
def test_compare_revisions_missing_query_param(self): """Try to compare two revisions, with a missing query string param.""" url = reverse('wiki.compare_revisions', args=[self.document.slug]) query = {'from': self.revision1.id} url = urlparams(url, **query) response = self.client.get(url) eq_(404, response.status_code) url = reverse('wiki.compare_revisions', args=[self.document.slug]) query = {'to': self.revision1.id} url = urlparams(url, **query) response = self.client.get(url) eq_(404, response.status_code)
def process_request(self, request): # https://bugzil.la/1189222 # Don't redirect POST $subscribe requests to GET zone url if (request.method == 'POST' and ('$subscribe' in request.path or '$files' in request.path)): return None # Skip slugs that don't have locales, and won't be in a zone request_slug = request.path_info.lstrip('/') if any(request_slug.startswith(slug) for slug in settings.LANGUAGE_URL_IGNORED_PATHS): return None remaps = DocumentZoneURLRemapsJob().get(request.LANGUAGE_CODE) for original_path, new_path in remaps: if ( request.path_info == original_path or request.path_info.startswith(u''.join([original_path, '/'])) ): # Is this a request for the "original" wiki path? Redirect to # new URL root, if so. new_path = request.path_info.replace(original_path, new_path, 1) new_path = '/%s%s' % (request.LANGUAGE_CODE, new_path) query = request.GET.copy() new_path = urlparams(new_path, query_dict=query) return HttpResponseRedirect(new_path) elif request.path_info == u'/docs{}'.format(new_path): # Is this a request for a DocumentZone, but with /docs/ wedged # in the url path between the language code and the zone's url_root? new_path = u'/{}{}'.format(request.LANGUAGE_CODE, new_path) query = request.GET.copy() new_path = urlparams(new_path, query_dict=query) return HttpResponsePermanentRedirect(new_path) elif request.path_info.startswith(new_path): # Is this a request for the relocated wiki path? If so, rewrite # the path as a request for the proper wiki view. request.path_info = request.path_info.replace(new_path, original_path, 1) break
def revisions(self, obj): """HTML link to user's revisions with count""" link = urlparams(reverse('dashboards.revisions'), user=obj.username) count = obj.created_revisions.count() return ('<a href="%(link)s"><strong>%(count)s</strong></a>' % {'link': link, 'count': count})
def test_compare_revisions_only_one_param(create_revision, client, param): """If a compare query parameter is missing, a 404 is returned.""" doc = create_revision.document url = urlparams(reverse('wiki.compare_revisions', args=[doc.slug]), **{param: create_revision.id}) response = client.get(url) assert response.status_code == 404
def test_spam_submission_filled(self): admin = User.objects.get(username='******') revision = admin.created_revisions.all()[0] url = urlparams( reverse('admin:wiki_revisionakismetsubmission_add'), revision=revision.id, type='ham', ) self.client.login(username='******', password='******') response = self.client.get(url) self.assertEqual(response.status_code, 200) page = pq(response.content) revision_inputs = page.find('input#id_revision') self.assertEqual(len(revision_inputs), 1) self.assertEqual(revision_inputs[0].value, str(revision.id)) type_inputs = page.find('input[name=type]') self.assertEqual(len(type_inputs), 2) for type_input in type_inputs: if type_input.value == 'spam': self.assertTrue(not type_input.checked) elif type_input.value == 'ham': self.assertTrue(type_input.checked)
def test_revisions_all_params_as_anon_user_is_forbidden(root_doc, client): """Anonymous users are forbidden to request all revisions.""" url = reverse('wiki.document_revisions', args=(root_doc.slug,)) all_url = urlparams(url, limit='all') resp = client.get(all_url) assert resp.status_code == 403 assert_shared_cache_header(resp)
def test_bad_parameters(self): """Ensure badly-formed revision parameters do not cause errors""" url = reverse('wiki.compare_revisions', args=[self.document.slug]) query = {'from': '1e309', 'to': u'1e309'} url = urlparams(url, **query) response = self.client.get(url) eq_(404, response.status_code)
def test_bad_parameters(self): """Ensure badly-formed revision parameters do not cause errors""" url = reverse("wiki.compare_revisions", args=[self.document.slug]) query = {"from": "1e309", "to": u"1e309"} url = urlparams(url, **query) response = self.client.get(url) eq_(404, response.status_code)
def _default_locale_fallback(request, document_slug, document_locale): """ If we're falling back to a Document in the default locale, figure out why and whether we can redirect to a translation in the requested locale. """ fallback_doc = None redirect_url = None fallback_reason = None try: fallback_doc = Document.objects.get(locale=settings.WIKI_DEFAULT_LANGUAGE, slug=document_slug) # If there's a translation to the requested locale, take it: translation = fallback_doc.translated_to(document_locale) if translation and translation.current_revision: url = translation.get_absolute_url() redirect_url = urlparams(url, query_dict=request.GET) elif translation and fallback_doc.current_revision: # Found a translation but its current_revision is None # and OK to fall back to parent (parent is approved). fallback_reason = 'translation_not_approved' elif fallback_doc.current_revision: # There is no translation # and OK to fall back to parent (parent is approved). fallback_reason = 'no_translation' except Document.DoesNotExist: pass return fallback_doc, fallback_reason, redirect_url
def test_compare_revisions_invalid_to_int(self): """Provide invalid 'to' int for revision ids.""" url = reverse("wiki.compare_revisions", args=[self.document.slug]) query = {"from": "", "to": "invalid"} url = urlparams(url, **query) response = self.client.get(url) eq_(404, response.status_code)
def revisions(self, obj): """HTML link to user's revisions with count""" link = urlparams(reverse('dashboards.revisions'), user=obj.username) count = obj.created_revisions.count() return ('<a href="{link!s}"><strong>{count!s}</strong></a>'.format(** {'link': link, 'count': count}))
def test_compare_revisions_invalid_ids(root_doc, client, id1, id2): """Comparing badly-formed revision parameters return 404, not error.""" url = urlparams(reverse('wiki.compare_revisions', args=[root_doc.slug], locale=root_doc.locale), **{'from': id1, 'to': id2}) response = client.get(url) assert response.status_code == 404
def test_intermediate(self): """ Test that the intermediate DocumentAttachment gets created correctly when adding an Attachment with a document_id. """ doc = document(locale='en', slug='attachment-test-intermediate') doc.save() rev = revision(document=doc, is_approved=True) rev.save() file_for_upload = make_test_file( content='A file for testing intermediate attachment model.') post_data = { 'title': 'Intermediate test file', 'description': 'Intermediate test file', 'comment': 'Initial upload', 'file': file_for_upload, } add_url = urlparams(reverse('attachments.new_attachment'), document_id=doc.id) resp = self.client.post(add_url, data=post_data) eq_(302, resp.status_code) eq_(1, doc.files.count()) intermediates = DocumentAttachment.objects.filter(document__pk=doc.id) eq_(1, intermediates.count()) intermediate = intermediates[0] eq_('admin', intermediate.attached_by.username) eq_(file_for_upload.name.split('/')[-1], intermediate.name)
def process_request(self, request): # https://bugzil.la/1189222 # Don't redirect POST $subscribe requests to GET zone url if request.method == 'POST' and '$subscribe' in request.path: return None remaps = DocumentZoneURLRemapsJob().get(request.LANGUAGE_CODE) for original_path, new_path in remaps: if ( request.path_info == original_path or request.path_info.startswith(u''.join([original_path, '/'])) ): # Is this a request for the "original" wiki path? Redirect to # new URL root, if so. new_path = request.path_info.replace(original_path, new_path, 1) new_path = '/{0!s}{1!s}'.format(request.LANGUAGE_CODE, new_path) query = request.GET.copy() if 'lang' in query: query.pop('lang') new_path = urlparams(new_path, query_dict=query) return HttpResponseRedirect(new_path) elif request.path_info.startswith(new_path): # Is this a request for the relocated wiki path? If so, rewrite # the path as a request for the proper wiki view. request.path_info = request.path_info.replace(new_path, original_path, 1) break
def test_intermediate(self): """ Test that the intermediate DocumentAttachment gets created correctly when adding an Attachment with a document_id. """ doc = document(locale="en", slug="attachment-test-intermediate") doc.save() rev = revision(document=doc, is_approved=True) rev.save() file_for_upload = make_test_file(content="A file for testing intermediate attachment model.") post_data = { "title": "Intermediate test file", "description": "Intermediate test file", "comment": "Initial upload", "file": file_for_upload, } add_url = urlparams(reverse("attachments.new_attachment"), document_id=doc.id) resp = self.client.post(add_url, data=post_data) eq_(302, resp.status_code) eq_(1, doc.files.count()) intermediates = DocumentAttachment.objects.filter(document__pk=doc.id) eq_(1, intermediates.count()) intermediate = intermediates[0] eq_("admin", intermediate.attached_by.username) eq_(file_for_upload.name.split("/")[-1], intermediate.name)
def test_compare_revisions_invalid_from_int(self): """Provide invalid 'from' int for revision ids.""" url = reverse('wiki.compare_revisions', args=[self.document.slug]) query = {'from': 'invalid', 'to': ''} url = urlparams(url, **query) response = self.client.get(url) eq_(404, response.status_code)
def _document_redirect_to_create(document_slug, document_locale, slug_dict): """ When a Document doesn't exist but the user can create it, return the creation URL to redirect to. """ url = reverse('wiki.create', locale=document_locale) if slug_dict['length'] > 1: parent_doc = get_object_or_404(Document, locale=document_locale, slug=slug_dict['parent'], is_template=0) url = urlparams(url, parent=parent_doc.id, slug=slug_dict['specific']) else: # This is a "base level" redirect, i.e. no parent url = urlparams(url, slug=document_slug) return url
def test_compare_unmatched_document_url(self): """Comparing two revisions of unlinked document should cause error.""" unmatched_document = _create_document(title='Invalid document') url = reverse('wiki.compare_revisions', args=[unmatched_document.slug]) query = {'from': self.revision1.id, 'to': self.revision2.id} url = urlparams(url, **query) response = self.client.get(url) eq_(404, response.status_code)
def test_revisions_request_large_pages(root_doc, client): """$history?limit=(more than revisions) works, removes pagination.""" rev_count = root_doc.revisions.count() url = reverse('wiki.document_revisions', args=(root_doc.slug,)) limit_url = urlparams(url, limit=rev_count + 1) resp = client.get(limit_url) assert resp.status_code == 200 page = pq(resp.content) assert len(page.find('ol.pagination')) == 0
def test_compare_revisions(self): """Compare two revisions""" url = reverse("wiki.compare_revisions", args=[self.document.slug]) query = {"from": self.revision1.id, "to": self.revision2.id} url = urlparams(url, **query) response = self.client.get(url) eq_(200, response.status_code) doc = pq(response.content) eq_("Dolor", doc("span.diff_add").text())
def test_revisions_all_params_as_user_is_allowed(root_doc, wiki_user, client): """Users are allowed to request all revisions.""" url = reverse('wiki.document_revisions', args=(root_doc.slug,)) all_url = urlparams(url, limit='all') wiki_user.set_password('password') wiki_user.save() client.login(username=wiki_user.username, password='******') resp = client.get(all_url) assert resp.status_code == 200
def test_create_no_revision(self): url = urlparams( reverse('admin:wiki_revisionakismetsubmission_add'), type='ham', ) self.client.login(username='******', password='******') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertIn(SUBMISSION_NOT_AVAILABLE, response.content)
def test_compare_revisions(self): """Compare two revisions""" url = reverse('wiki.compare_revisions', args=[self.document.slug]) query = {'from': self.revision1.id, 'to': self.revision2.id} url = urlparams(url, **query) response = self.client.get(url) eq_(200, response.status_code) doc = pq(response.content) eq_('Dolor', doc('span.diff_add').text())
def test_revisions_request_tiny_pages(edit_revision, client): """$history will paginate the revisions.""" doc = edit_revision.document assert doc.revisions.count() > 1 url = reverse('wiki.document_revisions', args=(doc.slug,)) limit_url = urlparams(url, limit=1) resp = client.get(limit_url) assert resp.status_code == 200 page = pq(resp.content) assert len(page.find('ol.pagination')) == 1
def test_compare_revisions_wrong_document(edit_revision, client): """If the revision is for the wrong document, a 404 is returned.""" doc = edit_revision.document first_revision = doc.revisions.first() other_doc = Document.objects.create(locale='en-US', slug='Other', title='Other Document') url = urlparams(reverse('wiki.compare_revisions', args=[other_doc.slug]), **{'from': first_revision.id, 'to': edit_revision.id}) response = client.get(url) assert response.status_code == 404
def test_topic_filter(self): url = urlparams(reverse("dashboards.revisions", locale="en-US"), topic="article-with-revisions") response = self.client.get(url, HTTP_X_REQUESTED_WITH="XMLHttpRequest") eq_(response.status_code, 200) page = pq(response.content) revisions = page.find(".dashboard-row") eq_(revisions.length, 7) for revision in revisions: ok_("lorem" not in pq(revision).find(".dashboard-title").html())
def test_topic_filter(self): url = urlparams(reverse('dashboards.revisions', locale='en-US'), topic='article-with-revisions') response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') eq_(response.status_code, 200) page = pq(response.content) revisions = page.find('.dashboard-row') eq_(revisions.length, 7) for revision in revisions: ok_('lorem' not in pq(revision).find('.dashboard-title').html())
def test_compare_revisions(edit_revision, client, raw): """Comparing two valid revisions of the same document works.""" doc = edit_revision.document first_revision = doc.revisions.first() params = {'from': first_revision.id, 'to': edit_revision.id} if raw: params['raw'] = '1' url = urlparams(reverse('wiki.compare_revisions', args=[doc.slug], locale=doc.locale), **params) response = client.get(url) assert response.status_code == 200
def react_document(request, document_slug, document_locale): """ View a wiki document. """ slug_dict = split_slug(document_slug) # Is there a document at this slug, in this locale? doc, _ = _get_doc_and_fallback_reason(document_locale, document_slug) if doc is None: # We can throw a 404 immediately if the request type is HEAD. # TODO: take a shortcut if the document was found? if request.method == 'HEAD': raise Http404 # Check if we should fall back to default locale. fallback_doc, _, redirect_url = _default_locale_fallback( request, document_slug, document_locale) if fallback_doc is not None: doc = fallback_doc if redirect_url is not None: return redirect(redirect_url) else: raise Http404 # We found a Document. Now we need to figure out how we're going # to display it. # If we're a redirect, and redirecting hasn't been disabled, redirect. # Obey explicit redirect pages: # Don't redirect on redirect=no (like Wikipedia), so we can link from a # redirected-to-page back to a "Redirected from..." link, so you can edit # the redirect. redirect_url = (None if request.GET.get('redirect') == 'no' else doc.get_redirect_url()) if redirect_url and redirect_url != doc.get_absolute_url(): url = urlparams(redirect_url, query_dict=request.GET) # TODO: Re-enable the link in this message after Django >1.5 upgrade # Redirected from <a href="%(url)s?redirect=no">%(url)s</a> messages.add_message( request, messages.WARNING, mark_safe(ugettext(u'Redirected from %(url)s') % { "url": request.build_absolute_uri(doc.get_absolute_url()) }), extra_tags='wiki_redirect') return HttpResponsePermanentRedirect(url) # Get the SEO summary seo_summary = doc.get_summary_text() # Get the additional title information, if necessary. seo_parent_title = _get_seo_parent_title(doc, slug_dict, document_locale) # Get the JSON data for this document doc_api_data = document_api_data(doc, ensure_contributors=True) document_data = doc_api_data['documentData'] # Bundle it all up and, finally, return. context = { 'document_data': document_data, # TODO: anything we're actually using in the template ought # to be bundled up into the json object above instead. 'seo_summary': seo_summary, 'seo_parent_title': seo_parent_title, } response = render(request, 'wiki/react_document.html', context) return _add_kuma_revision_header(doc, response)
def test_revisions_request_invalid_pages(root_doc, client): """$history?limit=nonsense uses the default pagination.""" url = reverse('wiki.document_revisions', args=(root_doc.slug, )) limit_url = urlparams(url, limit='nonsense') resp = client.get(limit_url) assert resp.status_code == 200
def test_compare_revisions_invalid_ids(root_doc, client, id1, id2): """Comparing badly-formed revision parameters return 404, not error.""" url = urlparams(reverse('wiki.compare_revisions', args=[root_doc.slug]), **{'from': id1, 'to': id2}) response = client.get(url, HTTP_HOST=settings.WIKI_HOST) assert response.status_code == 404
def edit(request, document_slug, document_locale): """ Create a new revision of a wiki document, or edit document metadata. """ doc = get_object_or_404(Document, locale=document_locale, slug=document_slug) # If this document has a parent, then the edit is handled by the # translate view. Pass it on. if doc.parent and doc.parent.id != doc.id: return translate( request, doc.parent.slug, doc.locale, bypass_process_document_path=True ) rev = doc.current_revision or doc.revisions.order_by("-created", "-id")[0] # Keep hold of the full post slug slug_dict = split_slug(document_slug) # Update the slug, removing the parent path, and # *only* using the last piece. # This is only for the edit form. rev.slug = slug_dict["specific"] section_id = request.GET.get("section", None) if section_id and not request.is_ajax(): return HttpResponse(ugettext("Sections may only be edited inline.")) disclose_description = bool(request.GET.get("opendescription")) doc_form = rev_form = None rev_form = RevisionForm( request=request, instance=rev, initial={"based_on": rev.id, "current_rev": rev.id, "comment": ""}, section_id=section_id, ) if doc.allows_editing_by(request.user): doc_form = DocumentForm(initial=document_form_initial(doc)) # Need to make check *here* to see if this could have a translation parent show_translation_parent_block = ( document_locale != settings.WIKI_DEFAULT_LANGUAGE ) and (not doc.parent_id) if request.method == "GET": if not (rev_form or doc_form): # You can't do anything on this page, so get lost. raise PermissionDenied else: # POST is_async_submit = request.is_ajax() is_raw = request.GET.get("raw", False) need_edit_links = request.GET.get("edit_links", False) parent_id = request.POST.get("parent_id", "") # Attempt to set a parent if show_translation_parent_block and parent_id: try: parent_doc = get_object_or_404(Document, id=parent_id) doc.parent = parent_doc except Document.DoesNotExist: pass # Comparing against localized names for the Save button bothers me, so # I embedded a hidden input: which_form = request.POST.get("form-type") if which_form == "doc": if doc.allows_editing_by(request.user): post_data = request.POST.copy() post_data.update({"locale": document_locale}) doc_form = DocumentForm(post_data, instance=doc) if doc_form.is_valid(): # if must be here for section edits if "slug" in post_data: post_data["slug"] = "/".join( [slug_dict["parent"], post_data["slug"]] ) # Get the possibly new slug for the imminent redirection: doc = doc_form.save(parent=None) return redirect(urlparams(doc.get_edit_url(), opendescription=1)) disclose_description = True else: raise PermissionDenied elif which_form == "rev": post_data = request.POST.copy() rev_form = RevisionForm( request=request, data=post_data, is_async_submit=is_async_submit, section_id=section_id, ) rev_form.instance.document = doc # for rev_form.clean() # Come up with the original revision to which these changes # would be applied. orig_rev_id = request.POST.get("current_rev", False) if orig_rev_id is False: orig_rev = None else: orig_rev = Revision.objects.get(pk=orig_rev_id) # Get the document's actual current revision. curr_rev = doc.current_revision if not rev_form.is_valid(): # If this was an Ajax POST, then return a JsonResponse if is_async_submit: # Was there a mid-air collision? if "current_rev" in rev_form._errors: # Make the error message safe so the '<' and '>' don't # get turned into '<' and '>', respectively rev_form.errors["current_rev"][0] = mark_safe( rev_form.errors["current_rev"][0] ) errors = [rev_form.errors[key][0] for key in rev_form.errors.keys()] data = { "error": True, "error_message": errors, "new_revision_id": curr_rev.id, } return JsonResponse(data=data) # Jump out to a function to escape indentation hell return _edit_document_collision( request, orig_rev, curr_rev, is_async_submit, is_raw, rev_form, doc_form, section_id, rev, doc, ) # Was this an Ajax submission that was marked as spam? if is_async_submit and "__all__" in rev_form._errors: # Return a JsonResponse data = { "error": True, "error_message": mark_safe(rev_form.errors["__all__"][0]), "new_revision_id": curr_rev.id, } return JsonResponse(data=data) if rev_form.is_valid(): rev_form.save(doc) if is_raw and orig_rev is not None and curr_rev.id != orig_rev.id: # If this is the raw view, and there was an original # revision, but the original revision differed from the # current revision at start of editing, we should tell # the client to refresh the page. response = HttpResponse("RESET") response["X-Frame-Options"] = "SAMEORIGIN" response.status_code = 205 return response # Is this an Ajax POST? if is_async_submit: # This is the most recent revision id new_rev_id = rev.document.revisions.order_by("-id").first().id data = {"error": False, "new_revision_id": new_rev_id} return JsonResponse(data) if rev_form.instance.is_approved: view = "wiki.document" else: view = "wiki.document_revisions" # Construct the redirect URL, adding any needed parameters url = reverse(view, args=[doc.slug], locale=doc.locale) params = {} if is_raw: params["raw"] = "true" if need_edit_links: # Only need to carry over ?edit_links with ?raw, # because they're on by default in the normal UI params["edit_links"] = "true" if section_id: # If a section was edited, and we're using the raw # content API, constrain to that section. params["section"] = section_id # Parameter for the document saved, so that we can delete the cached draft on load params["rev_saved"] = curr_rev.id if curr_rev else "" url = "%s?%s" % (url, urlencode(params)) if not is_raw and section_id: # If a section was edited, jump to the section anchor # if we're not getting raw content. url = "%s#%s" % (url, section_id) return redirect(url) parent_path = parent_slug = "" if slug_dict["parent"]: parent_slug = slug_dict["parent"] if doc.parent_topic_id: parent_doc = Document.objects.get(pk=doc.parent_topic_id) parent_path = parent_doc.get_absolute_url() parent_slug = parent_doc.slug context = { "revision_form": rev_form, "document_form": doc_form, "section_id": section_id, "disclose_description": disclose_description, "parent_slug": parent_slug, "parent_path": parent_path, "revision": rev, "document": doc, "attachment_form": AttachmentRevisionForm(), } return render(request, "wiki/edit.html", context)
def revisions(self, obj): """HTML link to user's revisions with count""" link = urlparams(reverse("dashboards.revisions"), user=obj.username) count = obj.created_revisions.count() return format_html('<a href="{}"><strong>{}</strong></a>', link, count)
def react_document(request, document_slug, document_locale): """ View a wiki document. """ fallback_reason = None slug_dict = split_slug(document_slug) # Is there a document at this slug, in this locale? doc, fallback_reason = _get_doc_and_fallback_reason( document_locale, document_slug) if doc is None: # We can throw a 404 immediately if the request type is HEAD. # TODO: take a shortcut if the document was found? if request.method == 'HEAD': raise Http404 # Check if we should fall back to default locale. fallback_doc, fallback_reason, redirect_url = _default_locale_fallback( request, document_slug, document_locale) if fallback_doc is not None: doc = fallback_doc if redirect_url is not None: return redirect(redirect_url) else: raise Http404 # We found a Document. Now we need to figure out how we're going # to display it. # If we're a redirect, and redirecting hasn't been disabled, redirect. # Obey explicit redirect pages: # Don't redirect on redirect=no (like Wikipedia), so we can link from a # redirected-to-page back to a "Redirected from..." link, so you can edit # the redirect. redirect_url = (None if request.GET.get('redirect') == 'no' else doc.get_redirect_url()) if redirect_url and redirect_url != doc.get_absolute_url(): url = urlparams(redirect_url, query_dict=request.GET) # TODO: Re-enable the link in this message after Django >1.5 upgrade # Redirected from <a href="%(url)s?redirect=no">%(url)s</a> messages.add_message( request, messages.WARNING, mark_safe( ugettext(u'Redirected from %(url)s') % {"url": request.build_absolute_uri(doc.get_absolute_url())}), extra_tags='wiki_redirect') return HttpResponsePermanentRedirect(url) # Get the SEO summary seo_summary = doc.get_summary_text() # Get the additional title information, if necessary. seo_parent_title = _get_seo_parent_title(doc, slug_dict, document_locale) # Record the English slug in Google Analytics, # to associate translations if doc.locale == 'en-US': en_slug = doc.slug elif doc.parent_id and doc.parent.locale == 'en-US': en_slug = doc.parent.slug else: en_slug = '' share_text = ugettext('I learned about %(title)s on MDN.') % { "title": doc.title } contributors = doc.contributors contributors_count = len(contributors) has_contributors = contributors_count > 0 other_translations = doc.get_other_translations( fields=['title', 'locale', 'slug', 'parent']) all_locales = (set([doc.locale]) | set(trans.locale for trans in other_translations)) # Bundle it all up and, finally, return. context = { 'document_api_data': base64.b64encode(json.dumps(document_api_data(doc))), # TODO: anything we're actually using in the template ought # to be bundled up into the json object above instead. 'document': doc, 'contributors': contributors, 'contributors_count': contributors_count, 'contributors_limit': 6, 'has_contributors': has_contributors, 'fallback_reason': fallback_reason, 'seo_summary': seo_summary, 'seo_parent_title': seo_parent_title, 'share_text': share_text, 'search_url': get_search_url_from_referer(request) or '', 'analytics_page_revision': doc.current_revision_id, 'analytics_en_slug': en_slug, 'other_translations': other_translations, 'all_locales': all_locales, } response = render(request, 'wiki/react_document.html', context) return _add_kuma_revision_header(doc, response)
def test_revisions_request_invalid_pages(root_doc, client): """$history?limit=nonsense uses the default pagination.""" url = reverse("wiki.document_revisions", args=(root_doc.slug, )) limit_url = urlparams(url, limit="nonsense") resp = client.get(limit_url, HTTP_HOST=settings.WIKI_HOST) assert resp.status_code == 200