Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit
- Loading branch information
Stijn Debrouwere
authored and
Stijn Debrouwere
committed
Jun 1, 2010
0 parents
commit 616d0ad
Showing
40 changed files
with
1,963 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
*.pyc | ||
docs/_build | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Copyright 2010 Stijn Debrouwere. All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without modification, are | ||
permitted provided that the following conditions are met: | ||
|
||
1. Redistributions of source code must retain the above copyright notice, this list of | ||
conditions and the following disclaimer. | ||
|
||
2. Redistributions in binary form must reproduce the above copyright notice, this list | ||
of conditions and the following disclaimer in the documentation and/or other materials | ||
provided with the distribution. | ||
|
||
THIS SOFTWARE IS PROVIDED BY STIJN DEBROUWERE ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STIJN DEBROUWERE OR | ||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
||
The views and conclusions contained in the software and documentation are those of the | ||
authors and should not be interpreted as representing official policies, either expressed | ||
or implied, of Stijn Debrouwere. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
## What the heck is this? | ||
|
||
Django has seen great adoption in the content management sphere, especially among the newspaper crowd. One of the trickier things to get right, is to make sure that nobody steps on each others toes while editing and modifying existing content. Newspaper editors might not always be aware of what other editors are up to, and this goes double for distributed teams. When different people work on the same content, the one who saves last will win the day, while the other edits are overwritten. | ||
|
||
`django-locking` provides a system that makes concurrent editing impossible, and informs users of what other users are working on and for how long that content will remain locked. Users can still read locked content, but cannot modify or save it. | ||
|
||
## Documentation | ||
|
||
`django-locking` is well-documented. Check out the docs! | ||
|
||
## License | ||
|
||
django-locking comes with the simplified BSD license, see the included LICENSE file for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import sys | ||
import logging | ||
from django.conf import settings | ||
|
||
LOCK_TIMEOUT = getattr(settings, 'LOCK_TIMEOUT', 1800) | ||
LOCKING_LOG_LEVEL = getattr(settings, 'LOCKING_LOG_LEVEL', logging.INFO) | ||
|
||
logging.basicConfig(stream=sys.stderr, level=LOCKING_LOG_LEVEL) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# encoding: utf-8 | ||
|
||
from datetime import datetime | ||
|
||
from django.contrib import admin | ||
from django.conf import settings | ||
from django.core.urlresolvers import reverse | ||
from django.utils.translation import ugettext as _ | ||
from django import forms | ||
|
||
from locking import LOCK_TIMEOUT, views | ||
|
||
class LockableAdmin(admin.ModelAdmin): | ||
@property | ||
def media(self): | ||
# because reverse() doesn't yet work when this module is first loaded | ||
# (the urlconf still has to load at that point) the media definition | ||
# has to be dynamic, and we can't simply add a Media class to the | ||
# ModelAdmin as you usually would. | ||
# | ||
# Doing so would result in an ImproperlyConfigured exception, stating | ||
# "The included urlconf doesn't have any patterns in it." | ||
# | ||
# See http://docs.djangoproject.com/en/dev/topics/forms/media/#media-as-a-dynamic-property | ||
# for more information about dynamic media definitions. | ||
|
||
css = { | ||
'all': ('locking/css/locking.css',) | ||
} | ||
js = ( | ||
'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js', | ||
'locking/js/jquery.url.packed.js', | ||
#reverse('django.views.i18n.javascript_catalog'), | ||
reverse('locking_variables'), | ||
'locking/js/admin.locking.js', | ||
) | ||
|
||
return forms.Media(css=css, js=js) | ||
|
||
# niet vergeten js en dit hier te documenteren, | ||
# gezien overrides in subklassen zonder supers het anders kapot zouden kunnen maken | ||
def changelist_view(self, request, extra_context=None): | ||
# we need the request objects in a few places where it's usually not present, | ||
# so we're tacking it on to the LockableAdmin class | ||
self.request = request | ||
return super(LockableAdmin, self).changelist_view(request, extra_context) | ||
|
||
def lock(self, obj): | ||
print obj.is_locked | ||
if obj.is_locked: | ||
seconds_remaining = obj.lock_seconds_remaining | ||
minutes_remaining = seconds_remaining/60 | ||
locked_until = _("Still locked for %s minutes by %s") % (minutes_remaining, obj.locked_by) | ||
|
||
if self.request.user == obj.locked_by: | ||
return '<img src="%slocking/img/page_edit.png" title="%s" />' % (settings.MEDIA_URL, locked_until) | ||
else: | ||
return '<img src="%slocking/img/lock.png" title="%s" />' % (settings.MEDIA_URL, locked_until) | ||
else: | ||
return '' | ||
lock.allow_tags = True | ||
|
||
list_display = ('lock', ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# encoding: utf-8 | ||
|
||
from django.http import HttpResponse | ||
from django.contrib.contenttypes.models import ContentType | ||
|
||
from locking.models import LockableModel | ||
from locking import logging | ||
|
||
def user_may_change_model(fn): | ||
def view(request, app, model, *vargs, **kwargs): | ||
may_change = '%s.change_%s' % (app, model) | ||
if not request.user.has_perm(may_change): | ||
return HttpResponse(status=401) | ||
else: | ||
return fn(request, app, model, *vargs, **kwargs) | ||
|
||
return view | ||
|
||
def is_lockable(fn): | ||
def view(request, app, model, *vargs, **kwargs): | ||
try: | ||
cls = ContentType.objects.get(app_label=app, model=model).model_class() | ||
if issubclass(cls, LockableModel): | ||
lockable = True | ||
except ContentType.DoesNotExist: | ||
lockable = False | ||
|
||
if lockable: | ||
return fn(request, app, model, *vargs, **kwargs) | ||
else: | ||
return HttpResponse(status=404) | ||
return view | ||
|
||
def log(view): | ||
def decorated_view(*vargs, **kwargs): | ||
response = view(*vargs, **kwargs) | ||
logging.debug("Sending a request: \n\t%s" % (response.content)) | ||
return response | ||
|
||
return decorated_view |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
# Makefile for Sphinx documentation | ||
# | ||
|
||
# You can set these variables from the command line. | ||
SPHINXOPTS = | ||
SPHINXBUILD = sphinx-build | ||
PAPER = | ||
BUILDDIR = _build | ||
|
||
# Internal variables. | ||
PAPEROPT_a4 = -D latex_paper_size=a4 | ||
PAPEROPT_letter = -D latex_paper_size=letter | ||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . | ||
|
||
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest | ||
|
||
help: | ||
@echo "Please use \`make <target>' where <target> is one of" | ||
@echo " html to make standalone HTML files" | ||
@echo " dirhtml to make HTML files named index.html in directories" | ||
@echo " pickle to make pickle files" | ||
@echo " json to make JSON files" | ||
@echo " htmlhelp to make HTML files and a HTML help project" | ||
@echo " qthelp to make HTML files and a qthelp project" | ||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" | ||
@echo " changes to make an overview of all changed/added/deprecated items" | ||
@echo " linkcheck to check all external links for integrity" | ||
@echo " doctest to run all doctests embedded in the documentation (if enabled)" | ||
|
||
clean: | ||
-rm -rf $(BUILDDIR)/* | ||
|
||
html: | ||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html | ||
@echo | ||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html." | ||
|
||
dirhtml: | ||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml | ||
@echo | ||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." | ||
|
||
pickle: | ||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle | ||
@echo | ||
@echo "Build finished; now you can process the pickle files." | ||
|
||
json: | ||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json | ||
@echo | ||
@echo "Build finished; now you can process the JSON files." | ||
|
||
htmlhelp: | ||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp | ||
@echo | ||
@echo "Build finished; now you can run HTML Help Workshop with the" \ | ||
".hhp project file in $(BUILDDIR)/htmlhelp." | ||
|
||
qthelp: | ||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp | ||
@echo | ||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \ | ||
".qhcp project file in $(BUILDDIR)/qthelp, like this:" | ||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-locking.qhcp" | ||
@echo "To view the help file:" | ||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-locking.qhc" | ||
|
||
latex: | ||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex | ||
@echo | ||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." | ||
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ | ||
"run these through (pdf)latex." | ||
|
||
changes: | ||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes | ||
@echo | ||
@echo "The overview file is in $(BUILDDIR)/changes." | ||
|
||
linkcheck: | ||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck | ||
@echo | ||
@echo "Link check complete; look for any errors in the above output " \ | ||
"or in $(BUILDDIR)/linkcheck/output.txt." | ||
|
||
doctest: | ||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest | ||
@echo "Testing of doctests in the sources finished, look at the " \ | ||
"results in $(BUILDDIR)/doctest/output.txt." |
Oops, something went wrong.