Moved philo files into a philo subdirectory and added a setup.py file. Philo can...
[philo.git] / philo / middleware.py
1 from django.conf import settings
2 from django.contrib.sites.models import Site
3 from django.http import Http404
4 from philo.models import Node, View
5
6
7 class LazyNode(object):
8         def __get__(self, request, obj_type=None):
9                 if not hasattr(request, '_cached_node_path'):
10                         return None
11                 
12                 if not hasattr(request, '_found_node'):
13                         try:
14                                 current_site = Site.objects.get_current()
15                         except Site.DoesNotExist:
16                                 current_site = None
17                         
18                         path = request._cached_node_path
19                         trailing_slash = False
20                         if path[-1] == '/':
21                                 trailing_slash = True
22                         
23                         try:
24                                 node, subpath = Node.objects.get_with_path(path, root=getattr(current_site, 'root_node', None), absolute_result=False)
25                         except Node.DoesNotExist:
26                                 node = None
27                         else:
28                                 if subpath is None:
29                                         subpath = ""
30                                 subpath = "/" + subpath
31                                 
32                                 if not node.handles_subpath(subpath):
33                                         node = None
34                                 else:
35                                         if trailing_slash and subpath[-1] != "/":
36                                                 subpath += "/"
37                                         
38                                         node.subpath = subpath
39                         
40                         request._found_node = node
41                 
42                 return request._found_node
43
44
45 class RequestNodeMiddleware(object):
46         """Middleware to process the request's path and attach the closest ancestor node."""
47         def process_request(self, request):
48                 request.__class__.node = LazyNode()
49         
50         def process_view(self, request, view_func, view_args, view_kwargs):
51                 try:
52                         request._cached_node_path = view_kwargs['path']
53                 except KeyError:
54                         pass
55         
56         def process_exception(self, request, exception):
57                 if settings.DEBUG or not hasattr(request, 'node') or not request.node:
58                         return
59                 
60                 if isinstance(exception, Http404):
61                         error_view = request.node.attributes.get('Http404', None)
62                 else:
63                         error_view = request.node.attributes.get('Http500', None)
64                 
65                 if error_view is None or not isinstance(error_view, View):
66                         # Should this be duck-typing? Perhaps even no testing?
67                         return
68                 
69                 extra_context = {'exception': exception}
70                 return error_view.render_to_response(request, extra_context)