Source

milton / middleware / __init__.py

from logging import getLogger

from django.conf import settings
from django.http import HttpResponsePermanentRedirect, HttpResponseRedirect, HttpResponseGone, Http404
from django.template import RequestContext, loader

from milton.models import Redirect, Page
from milton.views import story_archive, view_page


logger = getLogger(__name__)

class RedirectionMiddleware(object):
    def process_response(self, request, response):
        # If the response found something, return it.
        if response.status_code != 404:
            return response
        try:
            # Look for an exact redirect
            path = request.path
            paths = [path]
            
            logger.debug("Redirect: Looking for %s" % (path,))

            r = Redirect.objects.get(site__id__exact=settings.SITE_ID, original__in=paths)
            
            # If the destination is not visible, let the 404 shine.
            if hasattr(r.target_object, 'visible') and r.target_object.visible == False:
                logger.debug("Redirect: Object exists, but is unpublished.")
                return response
            
            # If there's a redirect, process it
            destination = r.destination()
            
            # If we're about to tell someone to go where we already are, stop and think...
            if destination == request.path_info:
                return response
            
            if destination == None:
                # No destination means it's been removed, so make it a dead end.
                context = RequestContext(request, {
                    'title':'410 Gone',
                    'content':'the resource you seek / has been taken by time / seek answers within'
                })
                template = loader.get_template("error.html")
                return HttpResponseGone(template.render(context))
            
            if r.permanent == True:
                # 301 Moved
                return HttpResponsePermanentRedirect(destination)
            else:
                # 302 Found
                return HttpResponseRedirect(destination)
        
        except Redirect.DoesNotExist, e:
            # Otherwise, return the original response
            logger.debug("Redirect: No redirect found for for %s" % (path,))
            return response
        except:
            if settings.DEBUG:
                raise
        # If we're here, we didn't catch something -- just pass along the 404.
        logger.debug("Redirect: No alternate plan for %s; passing along the NotFound." % (path,))
        return response


class PageMiddleware(object):
    def process_request(self, request):
        path = request.path_info
        page = None
        
        # Look for a Page that matches; pass on failure.
        try:
            logger.debug("PageMiddleware: Looking for a page for %s" % (path,))
            page = Page.published.get(url=path)
        except Page.DoesNotExist, e:
            return None
        
        logger.debug("PageMiddleware: Found for a page for %s" % (path,))
        return view_page(request, path)