write lock mechanism

This commit is contained in:
James Turk 2010-03-30 17:26:43 -04:00
parent 8bcf29c8e5
commit 0026c12e64
2 changed files with 26 additions and 3 deletions

View File

@ -1,10 +1,13 @@
import datetime
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.cache import cache
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from markupfield.fields import MarkupField from markupfield.fields import MarkupField
DEFAULT_MARKUP_TYPE = getattr(settings, 'MARKUPWIKI_DEFAULT_MARKUP_TYPE', 'plain') DEFAULT_MARKUP_TYPE = getattr(settings, 'MARKUPWIKI_DEFAULT_MARKUP_TYPE', 'plain')
WRITE_LOCK_SECONDS = getattr(settings, 'MARKUPWIKI_WRITE_LOCK_SECONDS', 60)
PUBLIC, LOCKED, DELETED = range(3) PUBLIC, LOCKED, DELETED = range(3)
ARTICLE_STATUSES = ( ARTICLE_STATUSES = (
@ -39,6 +42,14 @@ class Article(models.Model):
else: else:
return user.is_authenticated() return user.is_authenticated()
def get_write_lock(self, user):
cache_key = 'markupwiki_articlelock_%s' % self.id
lock = cache.get(cache_key)
if lock:
return lock == user.id
cache.set(cache_key, user.id, WRITE_LOCK_SECONDS)
return True
class ArticleVersion(models.Model): class ArticleVersion(models.Model):
article = models.ForeignKey(Article, related_name='versions') article = models.ForeignKey(Article, related_name='versions')

View File

@ -3,6 +3,7 @@ from django.shortcuts import get_object_or_404, render_to_response, redirect
from django.http import HttpResponseForbidden from django.http import HttpResponseForbidden
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib import messages
from django.template import RequestContext from django.template import RequestContext
from django.utils.functional import wraps from django.utils.functional import wraps
from markupwiki.models import Article, PUBLIC, DELETED, LOCKED from markupwiki.models import Article, PUBLIC, DELETED, LOCKED
@ -75,13 +76,19 @@ def edit_article(request, title):
except Article.DoesNotExist: except Article.DoesNotExist:
article = None article = None
if article and article.is_locked() and not user.is_staff: # check for staff lock
return render_to_response('locked_article.html', {'article': article}, if article and not article.is_editable_by_user(request.user):
context_instance=RequestContext(request)) return HttpResponseForbidden('not authorized to edit')
if request.method == 'GET': if request.method == 'GET':
# either get an empty ArticleForm or one based on latest version # either get an empty ArticleForm or one based on latest version
if article: if article:
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)
version = article.versions.latest() version = article.versions.latest()
form = ArticleForm(data={'body':version.body, form = ArticleForm(data={'body':version.body,
'body_markup_type':version.body_markup_type}) 'body_markup_type':version.body_markup_type})
@ -96,6 +103,11 @@ def edit_article(request, title):
creator=request.user) creator=request.user)
num = 0 num = 0
else: else:
if not article.get_write_lock(request.user):
# set message and redirect
messages.error(request, 'You took too long to edit and someone else is now editing this page.')
return redirect(article)
# otherwise get latest num # otherwise get latest num
num = article.versions.latest().number + 1 num = article.versions.latest().number + 1