Index: src/maintenancemode/admin.py =================================================================== --- src/maintenancemode/admin.py (revision 0) +++ src/maintenancemode/admin.py (revision 0) @@ -0,0 +1,26 @@ +from django import forms +from django.contrib import admin +from django.utils.translation import ugettext_lazy as _ +from maintenancemode.models import AllowedPath + +class AllowedPathForm(forms.ModelForm): + path = forms.RegexField( + label=_("Path"), max_length=100, regex=r'^[-\w/]+$', + help_text=_("Case-sensitive and recursive: /weblog/ match " + "/weblog/2009/05/01/..."), + error_message = _("This value must contain only letters, numbers," + " underscores, dashes or slashes.") + ) + + class Meta: + model = AllowedPath + +class AllowedPathAdmin(admin.ModelAdmin): + fieldsets = ( + (None, {'fields': ('path', 'apply_on')}), + ) + list_filter = ('apply_on',) + list_display = ('path', 'get_domain') + search_fields = ('path',) + +admin.site.register(AllowedPath, AllowedPathAdmin) Property changes on: src/maintenancemode/admin.py ___________________________________________________________________ Name: svn:keywords + Date Revision Author HeadURL Id Name: svn:eol-style + native Index: src/maintenancemode/middleware.py =================================================================== --- src/maintenancemode/middleware.py (revision 10) +++ src/maintenancemode/middleware.py (working copy) @@ -1,5 +1,7 @@ from django.conf import settings from django.core import urlresolvers +from maintenancemode.models import AllowedPath +from maintenancemode.conf.settings import MAINTENANCE_MODE, ALLOWED_PATHS from django.conf.urls import defaults defaults.handler503 = 'maintenancemode.views.defaults.temporary_unavailable' @@ -7,15 +9,30 @@ class MaintenanceModeMiddleware(object): def process_request(self, request): - # Check if maintenance mode is activated, if not set default to False - if getattr(settings, 'MAINTENANCE_MODE', False): - # Check if the user doing the request is logged in and a staff member - if hasattr(request, 'user') and request.user.is_staff: - # Let Django normally handle the request - return None + if not MAINTENANCE_MODE: + # let Django normally handle the request + return None - # Otherwise show the user the 503 page - resolver = urlresolvers.get_resolver(None) - - callback, param_dict = resolver._resolve_special('503') - return callback(request, **param_dict) \ No newline at end of file + # Allow acess if the user doing the request is logged in and a + # staff member. + if hasattr(request, 'user') and request.user.is_staff: + return None + + resolver = urlresolvers.get_resolver(None) + callback, param_dict = resolver._resolve_special('503') + + if not settings.DATABASE_ENGINE == 'dummy': + try: + # append allowed paths from database + query_set = AllowedPath.on_site.all() + ALLOWED_PATHS.extend(query_set.values_list('path', flat=True)) + except: + # show the user the 503 page if database error + return callback(request, **param_dict) + + # allow access if path starts with some path in ``allowed_paths`` + if True in map(request.path.startswith, ALLOWED_PATHS): + return None + + # otherwise, show the user the 503 page + return callback(request, **param_dict) Index: src/maintenancemode/conf/settings.py =================================================================== --- src/maintenancemode/conf/settings.py (revision 0) +++ src/maintenancemode/conf/settings.py (revision 0) @@ -0,0 +1,33 @@ +""" +maintenancemode application settings. + +If you not configure the settings below in your own project settings.py, +they assume default values:: + + MAINTENANCE_MODE + Boolean. Enable/disable maintenance mode. + Default: False + + MAINTENANCE_MODE_ALLOWED_PATHS + A list with paths can be acessed in maintenance mode. + Example: ['/admin', '/contact'] + Default: [] + + Note:: + The paths are case-sensitive, need starts with '/' and are + recusive: '/weblog' match '/weblog/2009/05/01', '/' match all + web site. + + Some observations: + + * If you uses a database, and the database is down, a maintenance + page is displayed; + + * If user is logged in and staff member, the maintenance page is + never displayed. +""" + +from django.conf import settings + +MAINTENANCE_MODE = getattr(settings, 'MAINTENANCE_MODE', False) +ALLOWED_PATHS = list(getattr(settings, 'MAINTENANCE_MODE_ALLOWED_PATHS', [])) Property changes on: src/maintenancemode/conf/settings.py ___________________________________________________________________ Name: svn:keywords + Date Revision Author HeadURL Id Name: svn:eol-style + native Index: src/maintenancemode/models.py =================================================================== --- src/maintenancemode/models.py (revision 0) +++ src/maintenancemode/models.py (revision 0) @@ -0,0 +1,43 @@ +from django.contrib.sites.managers import CurrentSiteManager +from django.contrib.sites.models import Site +from django.db import models +from django.db.models import Manager +from django.utils.translation import ugettext_lazy as _ + +class AllowedPath(models.Model): + path = models.CharField( + _('path'), + max_length=255, + db_index=True, + help_text=_('Allowed path in maintenance mode. ' + 'Example: /admin (needs start with /).'), + ) + apply_on = models.ManyToManyField( + Site, + default=str(Site.objects.get_current().id), + verbose_name=_('apply on') + ) + + objects = Manager() + on_site = CurrentSiteManager('apply_on') + + class Meta: + ordering = ('path',) + verbose_name = _('allowed path') + verbose_name_plural = _('allowed paths') + + def __unicode__(self): + return '%s' % self.path + + def get_domain(self): + return Site.objects.get_current().domain + get_domain.short_description = _('domain') + +# signals +from django.db.models import signals + +def allowed_path_pre_save(sender, instance, signal, *args, **kwargs): + if not instance.path.startswith('/'): + instance.path = '/' + instance.path + +signals.pre_save.connect(allowed_path_pre_save, sender=AllowedPath) Property changes on: src/maintenancemode/models.py ___________________________________________________________________ Name: svn:keywords + Date Revision Author HeadURL Id Name: svn:eol-style + native Index: src/maintenancemode/views/defaults.py =================================================================== --- src/maintenancemode/views/defaults.py (revision 10) +++ src/maintenancemode/views/defaults.py (working copy) @@ -1,6 +1,5 @@ from django.conf import settings from django.template import Context, RequestContext, loader - from maintenancemode import http def temporary_unavailable(request, template_name='503.html'): @@ -11,7 +10,7 @@ Templates: `503.html` Context: request_path - The path of the requested URL (e.g., '/app/pages/bad_page/') + The path of the requested URL (e.g., '/app/pages/bad_page/'). """ t = loader.get_template(template_name) # You need to create a 503.html template. - return http.HttpResponseTemporaryUnavailable(t.render(Context({}))) \ No newline at end of file + return http.HttpResponseTemporaryUnavailable(t.render(Context({})))