django-markupwiki/markupwiki/views.py

216 lines
8.0 KiB
Python
Raw Normal View History

2010-03-30 14:43:30 +00:00
from difflib import HtmlDiff
from django.shortcuts import get_object_or_404, render_to_response, redirect
from django.http import HttpResponseForbidden
from django.conf import settings
2010-03-30 14:43:30 +00:00
from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required, user_passes_test
2010-03-30 21:26:43 +00:00
from django.contrib import messages
from django.http import Http404
2010-03-30 14:43:30 +00:00
from django.template import RequestContext
from django.utils.functional import wraps
2012-01-05 16:43:00 +00:00
from markupwiki.models import Article, ArticleVersion, PUBLIC, DELETED, LOCKED
2010-04-02 17:50:49 +00:00
from markupwiki.forms import ArticleForm, StaffModerationForm, ArticleRenameForm
2010-03-30 14:43:30 +00:00
2010-09-28 14:39:45 +00:00
CREATE_MISSING_ARTICLE = getattr(settings,
'MARKUPWIKI_CREATE_MISSING_ARTICLES', True)
EDITOR_TEST_FUNC = getattr(settings, 'MARKUPWIKI_EDITOR_TEST_FUNC',
lambda u: u.is_authenticated())
MODERATOR_TEST_FUNC = getattr(settings, 'MARKUPWIKI_MODERATOR_TEST_FUNC',
lambda u: u.is_staff)
2010-03-30 14:43:30 +00:00
def title_check(view):
def new_view(request, title, *args, **kwargs):
newtitle = title.replace(' ', '_')
if newtitle != title:
2010-04-07 18:51:36 +00:00
return redirect(request.path.replace(title, newtitle),
permanent=True)
2010-03-30 14:43:30 +00:00
else:
return view(request, title, *args, **kwargs)
return wraps(view)(new_view)
@title_check
def view_article(request, title, n=None):
2010-03-30 15:15:15 +00:00
''' view an article (or a specific revision of an article)
if n is specified will show nth revision, otherwise latest will be shown
if the article does not exist the user will be redirected to the edit page
Context:
2010-04-02 17:50:49 +00:00
article - ``Article`` instance
version - ``ArticleVersion`` to display
mod_form - ``StaffModerationForm`` instance present if user is staff
rename_form - ``ArticleRenameForm`` instance present if user is staff
2010-03-30 15:15:15 +00:00
Template:
2010-03-30 15:15:15 +00:00
article.html - default template used
'''
2010-03-30 14:43:30 +00:00
try:
article = Article.objects.get(title=title)
except Article.DoesNotExist:
if CREATE_MISSING_ARTICLE:
return redirect('edit_article', title)
else:
raise Http404()
2010-03-30 14:43:30 +00:00
2010-04-02 17:50:49 +00:00
if article.redirect_to_id:
return redirect(article.redirect_to)
2010-03-30 14:43:30 +00:00
if n:
version = article.versions.get(number=n)
else:
version = article.versions.latest()
2010-03-30 16:12:10 +00:00
version.is_latest = True
# set editable flag on article
article.editable = article.is_editable_by_user(request.user)
2010-03-30 14:43:30 +00:00
context = {'article':article, 'version': version}
if request.user.is_staff:
2010-03-31 22:06:06 +00:00
context['mod_form'] = StaffModerationForm(instance=article)
2010-04-02 17:50:49 +00:00
context['rename_form'] = ArticleRenameForm()
2010-03-30 14:43:30 +00:00
2010-03-30 16:12:10 +00:00
return render_to_response('markupwiki/article.html', context,
2010-03-30 14:43:30 +00:00
context_instance=RequestContext(request))
@title_check
@user_passes_test(EDITOR_TEST_FUNC)
2010-03-30 14:43:30 +00:00
def edit_article(request, title):
2010-03-30 15:15:15 +00:00
''' edit (or create) an article
Context:
title - title of article being edited
article - article being edited (potentially None)
form - form to edit article
Templates:
edit_article.html - Default template for editing the article.
locked_article.html - Template shown if editing is locked.
'''
2010-03-30 14:43:30 +00:00
try:
article = Article.objects.get(title=title)
except Article.DoesNotExist:
article = None
2010-03-30 21:26:43 +00:00
# check for staff lock
if article and not article.is_editable_by_user(request.user):
return HttpResponseForbidden('not authorized to edit')
2010-03-30 14:43:30 +00:00
if request.method == 'GET':
2010-03-30 15:15:15 +00:00
# either get an empty ArticleForm or one based on latest version
2010-03-30 14:43:30 +00:00
if article:
2010-03-30 21:26:43 +00:00
if not article.get_write_lock(request.user):
# set message and redirect
messages.info(request, 'Someone else is currently editing this page, please wait and try again.')
return redirect(article)
2010-03-30 14:43:30 +00:00
version = article.versions.latest()
form = ArticleForm(data={'body':version.body,
'body_markup_type':version.body_markup_type})
else:
form = ArticleForm()
elif request.method == 'POST':
form = ArticleForm(request.POST)
2011-04-29 15:02:32 +00:00
user = None if request.user.is_anonymous() else request.user
2010-03-30 14:43:30 +00:00
if form.is_valid():
if not article:
2010-03-30 15:15:15 +00:00
# if article doesn't exist create it and start num at 0
2010-03-30 14:43:30 +00:00
article = Article.objects.create(title=title,
2011-04-29 15:02:32 +00:00
creator=user)
2010-03-30 14:43:30 +00:00
num = 0
else:
2010-03-30 21:26:43 +00:00
if not article.get_write_lock(request.user):
# set message and redirect
2010-03-31 14:33:40 +00:00
messages.error(request, 'Your session timed out and someone else is now editing this page.')
2010-03-30 21:26:43 +00:00
return redirect(article)
2010-03-30 15:15:15 +00:00
# otherwise get latest num
2010-03-30 14:43:30 +00:00
num = article.versions.latest().number + 1
2010-03-30 15:15:15 +00:00
# create a new version attached to article specified in name
2010-03-30 14:43:30 +00:00
version = form.save(False)
version.article = article
2011-04-29 15:02:32 +00:00
version.author = user
2010-03-30 14:43:30 +00:00
version.number = num
version.save()
2010-03-30 15:15:15 +00:00
2011-04-29 15:02:32 +00:00
article.get_write_lock(user or request, release=True)
2010-03-31 14:33:40 +00:00
2010-03-30 15:15:15 +00:00
# redirect to view article on save
2010-03-30 14:43:30 +00:00
return redirect(article)
2010-03-30 17:52:45 +00:00
return render_to_response('markupwiki/edit_article.html',
{'title':title, 'article':article, 'form': form},
context_instance=RequestContext(request))
2010-03-30 14:43:30 +00:00
@require_POST
@user_passes_test(MODERATOR_TEST_FUNC)
2010-03-30 14:43:30 +00:00
@title_check
def article_status(request, title):
''' POST-only view to update article status (staff-only)
2010-03-30 15:15:15 +00:00
'''
2010-03-30 14:43:30 +00:00
article = get_object_or_404(Article, title=title)
article.status = int(request.POST['status'])
article.save()
return redirect(article)
2010-03-30 14:43:30 +00:00
2010-03-31 16:02:07 +00:00
@require_POST
@user_passes_test(MODERATOR_TEST_FUNC)
2010-03-31 16:02:07 +00:00
@title_check
def revert(request, title):
''' POST-only view to revert article to a specific revision
'''
article = get_object_or_404(Article, title=title)
revision_id = int(request.POST['revision'])
2012-01-05 16:43:00 +00:00
revision = get_object_or_404(article.versions, number=revision_id)
2010-03-31 16:02:07 +00:00
ArticleVersion.objects.create(article=article, author=request.user,
number=article.versions.latest().number,
2010-04-02 17:50:49 +00:00
comment='reverted to r%s' % revision_id,
2010-03-31 16:02:07 +00:00
body=revision.body)
return redirect(article)
2010-04-02 17:50:49 +00:00
@require_POST
@user_passes_test(MODERATOR_TEST_FUNC)
2010-04-02 17:50:49 +00:00
@title_check
def rename(request, title):
''' POST-only view to rename article '''
article = get_object_or_404(Article, title=title)
new_title = request.POST['new_title']
2010-04-07 21:07:41 +00:00
article.title = new_title.replace(' ', '_')
2010-04-02 17:50:49 +00:00
article.save()
new_article = Article.objects.create(title=title, creator=request.user,
redirect_to=article)
2010-04-07 21:07:41 +00:00
return redirect(article)
2010-04-02 17:50:49 +00:00
2010-03-30 14:43:30 +00:00
@title_check
def article_history(request, title):
article = get_object_or_404(Article, title=title)
versions = article.versions.filter(removed=False)
2010-03-30 17:52:45 +00:00
return render_to_response('markupwiki/history.html',
{'article':article, 'versions':versions},
context_instance=RequestContext(request))
2010-03-30 14:43:30 +00:00
@title_check
def article_diff(request, title):
article = get_object_or_404(Article, title=title)
from_id = int(request.GET['from'])
to_id = int(request.GET['to'])
from_version = article.versions.get(number=from_id)
to_version = article.versions.get(number=to_id)
differ = HtmlDiff()
from_body = from_version.body.raw.split('\n')
to_body = to_version.body.raw.split('\n')
table = differ.make_table(from_body, to_body)
2010-04-02 18:07:51 +00:00
return render_to_response('markupwiki/article_diff.html',
2010-03-30 18:42:27 +00:00
{'article': article, 'table':table,
'from': from_id, 'to':to_id},
2010-03-30 17:52:45 +00:00
context_instance=RequestContext(request))