Source

milton / middleware / redirection.py

Full commit
from django.conf import settings
from django.http import HttpResponsePermanentRedirect, HttpResponseRedirect, HttpResponseGone
from django.template import RequestContext, loader
from sitepoet.models import Redirect

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]
            
            # Also try without the trailing slash if someone tacked it on for us
            if settings.APPEND_SLASH:
                paths.append(path[:path.rfind('/')] + path[path.rfind('/')+1:])
            
            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:
                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 lost its battle with 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
            return response
        except:
            if settings.DEBUG:
                raise
        # If we're here, we didn't catch something -- just pass along the 404.
        return response