1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
import sys
from django.conf import settings as django_settings
from django.http import Http404, HttpResponseRedirect
def require_path_active_request_processor(page, request):
"""
Checks whether any ancestors are actually inaccessible (ie. not
inactive or expired) and raise a 404 if so.
"""
if not page.are_ancestors_active():
raise Http404()
def redirect_request_processor(page, request):
"""
Returns a ``HttpResponseRedirect`` instance if the current page says
a redirect should happen.
"""
target = page.get_redirect_to_target(request)
if target:
if request._feincms_extra_context.get('extra_path', '/') == '/':
return HttpResponseRedirect(target)
raise Http404()
def frontendediting_request_processor(page, request):
"""
Sets the frontend editing state in the session depending on the
``frontend_editing`` GET parameter and the user's permissions.
"""
if not 'frontend_editing' in request.GET:
return
if request.user.has_module_perms('page'):
try:
enable_fe = int(request.GET['frontend_editing']) > 0
except ValueError:
enable_fe = False
response = HttpResponseRedirect(request.path)
response.set_cookie('frontend_editing', enable_fe)
# Redirect to cleanup URLs
return response
def etag_request_processor(page, request):
"""
Short-circuits the request-response cycle if the ETag matches.
"""
# XXX is this a performance concern? Does it create a new class
# every time the processor is called or is this optimized to a static
# class??
class DummyResponse(dict):
"""
This is a dummy class with enough behaviour of HttpResponse so we
can use the condition decorator without too much pain.
"""
def has_header(page, what):
return False
def dummy_response_handler(*args, **kwargs):
return DummyResponse()
def etagger(request, page, *args, **kwargs):
etag = page.etag(request)
return etag
def lastmodifier(request, page, *args, **kwargs):
lm = page.last_modified()
return lm
# Unavailable in Django 1.0 -- the current implementation of ETag support
# requires Django 1.1 unfortunately.
from django.views.decorators.http import condition
# Now wrap the condition decorator around our dummy handler:
# the net effect is that we will be getting a DummyResponse from
# the handler if processing is to continue and a non-DummyResponse
# (should be a "304 not modified") if the etag matches.
rsp = condition(etag_func=etagger, last_modified_func=lastmodifier)(dummy_response_handler)(request, page)
# If dummy then don't do anything, if a real response, return and
# thus shortcut the request processing.
if not isinstance(rsp, DummyResponse):
return rsp
def etag_response_processor(page, request, response):
"""
Response processor to set an etag header on outgoing responses.
The Page.etag() method must return something valid as etag content
whenever you want an etag header generated.
"""
etag = page.etag(request)
if etag is not None:
response['ETag'] = '"' + etag + '"'
def debug_sql_queries_response_processor(verbose=False, file=sys.stderr):
"""
Attaches a handler which prints the query count (and optionally all individual queries
which have been executed) on the console. Does nothing if ``DEBUG = False``.
Example::
from feincms.module.page import models, processors
models.Page.register_response_procesors(
processors.debug_sql_queries_response_processor(verbose=True),
)
"""
if not django_settings.DEBUG:
return lambda page, request, response: None
def processor(page, request, response):
from django.db import connection
print_sql = lambda x: x
try:
import sqlparse
print_sql = lambda x: sqlparse.format(x, reindent=True, keyword_case='upper')
except:
pass
if verbose:
print >> file, "--------------------------------------------------------------"
time = 0.0
i = 0
for q in connection.queries:
i += 1
if verbose:
print >> file, "%d : [%s]\n%s\n" % ( i, q['time'], print_sql(q['sql']))
time += float(q['time'])
print >> file, "--------------------------------------------------------------"
print >> file, "Total: %d queries, %.3f ms" % (i, time)
print >> file, "--------------------------------------------------------------"
return processor
|