PageRenderTime 158ms CodeModel.GetById 29ms RepoModel.GetById 2ms app.codeStats 0ms

/sphene/community/middleware.py

https://github.com/tsaylor/BARcamp-Chicago-Website
Python | 335 lines | 300 code | 20 blank | 15 comment | 23 complexity | 073e92c778c8b725182a4eb6df1872a7 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. from django.conf import settings
  2. from django.conf.urls.defaults import *
  3. from django.core import urlresolvers
  4. from django.http import Http404
  5. from django.shortcuts import get_object_or_404
  6. from django.contrib.sites.models import SiteManager, Site
  7. from sphene.community.models import Group
  8. from sphene.community.sphsettings import get_sph_setting
  9. import re
  10. import logging
  11. logger = logging.getLogger('sphene.community.middleware')
  12. def my_get_current(self):
  13. group = get_current_group()
  14. from django.conf import settings
  15. if not group:
  16. return self.get(pk=settings.SITE_ID)
  17. else:
  18. return Site( pk=settings.SITE_ID, domain = group.baseurl, name = group.name )
  19. SiteManager.get_current = my_get_current
  20. # If all are used the following order has to remain:
  21. # 1.) ThreadLocals (required)
  22. # 2.) MultiHostMiddleware (optional, but very much recommended!)
  23. # 3.) GroupMiddleware (required)
  24. # all other orders will lead to problems ..
  25. #
  26. # Short descriptions:
  27. # every module within SCT requires a Group object - this can either come from the
  28. # MultiHostMiddleware - ie. from the domain/host name (vhosts) or from an URL parameter.
  29. # we need to somehow distuingish between those two within the reverse URL lookups.
  30. #
  31. class MultiHostMiddleware:
  32. def process_request(self, request):
  33. try:
  34. sphdata = get_current_sphdata()
  35. host = request.META['HTTP_HOST']
  36. if host[-3:] == ':80':
  37. host = host[:-3] # ignore default port number, if present
  38. urlconf = None
  39. urlconf_params = None
  40. if host in settings.SPH_HOST_MIDDLEWARE_URLCONF_MAP:
  41. urlconf = settings.SPH_HOST_MIDDLEWARE_URLCONF_MAP[host]
  42. else:
  43. # TODO cache results ? - cache regular expressions .. ?
  44. for key, value in settings.SPH_HOST_MIDDLEWARE_URLCONF_MAP.iteritems():
  45. regex = re.compile(key)
  46. match = regex.match(host)
  47. if not match:
  48. continue
  49. # We got a match.
  50. urlconf = value
  51. urlconf_params = 'params' in urlconf and urlconf['params'].copy() or dict()
  52. namedgroups = match.groupdict()
  53. for key, value in namedgroups.iteritems():
  54. urlconf_params[key] = value
  55. break
  56. if not urlconf:
  57. logging.info("Unable to find urlconf for %s / map: %s !!!" % (host, str(settings.SPH_HOST_MIDDLEWARE_URLCONF_MAP)))
  58. return
  59. while 'alias' in urlconf:
  60. urlconf = settings.SPH_HOST_MIDDLEWARE_URLCONF_MAP[urlconf['alias']]
  61. myparams = urlconf_params or urlconf['params']
  62. # if there is a parameter called 'groupName', load the given group,
  63. # and set it into the thread locals.
  64. if myparams and 'groupName' in myparams:
  65. try:
  66. set_current_group( Group.objects.get( name__exact = myparams['groupName'] ) )
  67. sphdata['group_fromhost'] = True
  68. except Group.DoesNotExist:
  69. pass
  70. set_current_urlconf_params( urlconf_params or urlconf['params'] )
  71. request.urlconf = urlconf['urlconf']
  72. except KeyError:
  73. pass # use default urlconf
  74. class GroupMiddleware(object):
  75. def process_view(self, request, view_func, view_args, view_kwargs):
  76. request.attributes = { }
  77. if 'urlPrefix' in view_kwargs:
  78. urlPrefix = view_kwargs['urlPrefix']
  79. if urlPrefix != '':
  80. urlPrefix = '/' + urlPrefix
  81. request.attributes['urlPrefix'] = urlPrefix
  82. del view_kwargs['urlPrefix']
  83. group = None
  84. groupName = None
  85. if get_current_urlconf_params() and 'groupName' in get_current_urlconf_params():
  86. groupName = get_current_urlconf_params()['groupName']
  87. # Check if we already loaded the current group in another
  88. # middleware.
  89. group = get_current_group()
  90. if group is None or group.name != groupName:
  91. group = get_object_or_404(Group, name = groupName)
  92. if 'groupName' in view_kwargs:
  93. if view_kwargs.get( 'noGroup', False ):
  94. del view_kwargs['groupName']
  95. del view_kwargs['noGroup']
  96. else:
  97. groupName = view_kwargs['groupName']
  98. if groupName == None: groupName = get_current_urlconf_params()['groupName']
  99. sphdata = get_current_sphdata()
  100. if group == None:
  101. group = get_object_or_404(Group, name = groupName )
  102. sphdata['group_fromhost'] = not get_sph_setting('community_groups_in_url')
  103. del view_kwargs['groupName']
  104. view_kwargs['group'] = group
  105. request.attributes['group'] = group
  106. #settings.TEMPLATE_DIRS = ( "/tmp/hehe", ) + settings.TEMPLATE_DIRS
  107. set_current_group( group )
  108. return None
  109. # copied from http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser
  110. # threadlocals middleware
  111. try:
  112. from threading import local
  113. except ImportError:
  114. from django.utils._threading_local import local
  115. #print "Executing module body."
  116. _thread_locals = local()
  117. def get_current_request():
  118. return getattr(_thread_locals, 'request', None)
  119. def get_current_urlconf():
  120. return getattr(get_current_request(), 'urlconf', None)
  121. def get_current_session():
  122. req = get_current_request()
  123. if req == None: return None
  124. return req.session
  125. def get_current_user():
  126. user = getattr(_thread_locals, 'user', None)
  127. if user != None: return user
  128. req = get_current_request()
  129. if req == None: return None
  130. return req.user
  131. def get_current_group():
  132. return Group.objects.get(id=2)
  133. try:
  134. return _thread_locals.group
  135. except AttributeError, e:
  136. logger.error('Unable to retrieve group. Is GroupMiddleware enabled?')
  137. raise e
  138. def get_current_urlconf_params():
  139. return getattr(_thread_locals, 'urlconf_params', None)
  140. def set_current_urlconf_params(urlconf_params):
  141. _thread_locals.urlconf_params = urlconf_params
  142. def set_current_group(group):
  143. _thread_locals.group = group
  144. def get_current_sphdata():
  145. return getattr(_thread_locals, 'sphdata', None)
  146. class ThreadLocals(object):
  147. """Middleware that gets various objects from the
  148. request object and saves them in thread local storage."""
  149. def process_request(self, request):
  150. _thread_locals.request = request
  151. _thread_locals.user = getattr(request, 'user', None)
  152. _thread_locals.sphdata = { }
  153. try:
  154. delattr(_thread_locals, 'urlconf_params')
  155. except AttributeError:
  156. pass
  157. _thread_locals.group = None
  158. ## copied from http://code.djangoproject.com/wiki/PageStatsMiddleware
  159. import re
  160. from operator import add
  161. from time import time
  162. from django.db import connection
  163. import logging
  164. logger = logging.getLogger('sphene.community.middleware')
  165. class StatsMiddleware(object):
  166. def process_view(self, request, view_func, view_args, view_kwargs):
  167. # turn on debugging in db backend to capture time
  168. from django.conf import settings
  169. debug = settings.DEBUG
  170. settings.DEBUG = True
  171. # get number of db queries before we do anything
  172. n = len(connection.queries)
  173. # time the view
  174. start = time()
  175. response = None
  176. try:
  177. response = view_func(request, *view_args, **view_kwargs)
  178. finally:
  179. if request.path.startswith('/static'):
  180. return response
  181. totTime = time() - start
  182. # compute the db time for the queries just run
  183. queries = len(connection.queries) - n
  184. if queries:
  185. dbTime = reduce(add, [float(q['time'])
  186. for q in connection.queries[n:]])
  187. else:
  188. dbTime = 0.0
  189. # and backout python time
  190. pyTime = totTime - dbTime
  191. # restore debugging setting
  192. settings.DEBUG = debug
  193. stats = {
  194. 'totTime': totTime,
  195. 'pyTime': pyTime,
  196. 'dbTime': dbTime,
  197. 'queries': queries,
  198. }
  199. # replace the comment if found
  200. if response and response.content:
  201. s = response.content
  202. regexp = re.compile(r'(?P<cmt><!--\s*STATS:(?P<fmt>.*?)-->)')
  203. match = regexp.search(s)
  204. if match:
  205. s = s[:match.start('cmt')] + \
  206. match.group('fmt') % stats + \
  207. s[match.end('cmt'):]
  208. out = match.group('fmt') % stats
  209. #for query in connection.queries:
  210. # logger.debug( ' %5s : %s' % (query['time'], query['sql'], ) )
  211. response.content = s
  212. querystr = ''
  213. for query in connection.queries:
  214. sql = query['sql']
  215. if sql is None: sql = " ?WTF?None?WTF? "
  216. querystr += "\t" + query['time'] + "\t" + sql + "\n"
  217. logger.debug( 'All Queries: %s' % (querystr,) )
  218. logger.info( 'Request %s: %s' % (request.get_full_path(), stats,) )
  219. return response
  220. from django.core.handlers.modpython import ModPythonRequest
  221. class ModPythonSetLoggedinUser(object):
  222. def process_request(self, request):
  223. if not isinstance(request, ModPythonRequest):
  224. return None
  225. if not hasattr(request, '_req'):
  226. return None
  227. if not hasattr(request, 'user') or not request.user.is_authenticated():
  228. return None
  229. # request.user.username is a unicode string
  230. # but _req.user requires an ascii string (afaik)
  231. request._req.user = str(request.user.username)
  232. return None
  233. class PsycoMiddleware(object):
  234. def process_request(self, request):
  235. import psyco
  236. psyco.profile()
  237. return None
  238. from sphene.community import PermissionDenied
  239. from django.template.context import RequestContext
  240. from django.shortcuts import render_to_response
  241. from django.template import loader
  242. from django.http import HttpResponseForbidden
  243. class PermissionDeniedMiddleware(object):
  244. def process_exception(self, request, exception):
  245. if isinstance(exception, PermissionDenied):
  246. return HttpResponseForbidden(loader.render_to_string( 'sphene/community/permissiondenied.html',
  247. { 'exception': exception,
  248. },
  249. context_instance = RequestContext(request) ) )
  250. return None
  251. class LastModified(object):
  252. """ Middleware that sets the Last-Modified and associated headers,
  253. if requested by the view. (By setting the sph_lastmodified attribute
  254. of the response object.
  255. based on a contribution of Andrew Plotkin:
  256. http://eblong.com/zarf/boodler/sitework/
  257. """
  258. def process_response(self, request, response):
  259. stamp = getattr(response, 'sph_lastmodified', None)
  260. if not stamp: return response
  261. import rfc822
  262. import calendar
  263. if stamp is True:
  264. val = rfc822.formatdate()
  265. else:
  266. val = rfc822.formatdate(calendar.timegm(stamp.timetuple()))
  267. response['Last-Modified'] = val
  268. response['Cache-Control'] = 'private, must-revalidate, max-age=0'
  269. return response