]> git.openstreetmap.org Git - osqa.git/blob - forum/middleware/django_cookies.py
Resolves Jira OSQA-732, check twice for NoReverseMatch exceptions, try passing only...
[osqa.git] / forum / middleware / django_cookies.py
1 """
2 A two-part middleware which modifies request.COOKIES and adds a set and delete method.
3
4     `set` matches django.http.HttpResponse.set_cookie
5     `delete` matches django.http.HttpResponse.delete_cookie
6
7 MIDDLEWARE_CLASSES = (
8     'django_cookies.CookiePreHandlerMiddleware',
9     ...
10     'django_cookies.CookiePostHandlerMiddleware',
11 )
12
13 def my_view(request):
14     request.COOKIES.set([args])
15     ...
16     return response
17 """
18
19 from Cookie import SimpleCookie, Morsel
20 from django.utils.encoding import smart_unicode, smart_str
21 import copy
22
23 class CookiePreHandlerMiddleware(object):
24     """
25     This middleware modifies request.COOKIES and adds a set and delete method.
26
27     `set` matches django.http.HttpResponse.set_cookie
28     `delete` matches django.http.HttpResponse.delete_cookie
29
30     This should be the first middleware you load.
31     """
32     def process_request(self, request):
33         cookies = CookieHandler()
34         for k, v in request.COOKIES.iteritems():
35             cookies[k] = str(v)
36         request.COOKIES = cookies
37         request._orig_cookies = copy.deepcopy(request.COOKIES)
38
39 class CookiePostHandlerMiddleware(object):
40     """
41     This middleware modifies updates the response will all modified cookies.
42
43     This should be the last middleware you load.
44     """
45     def process_response(self, request, response):
46         if hasattr(request, '_orig_cookies') and request.COOKIES != request._orig_cookies:
47             for k,v in request.COOKIES.iteritems():
48                 if request._orig_cookies.get(k) != v:
49                     dict.__setitem__(response.cookies, k, v)
50         return response
51
52 class StringMorsel(Morsel):
53     def __str__(self):
54         return smart_str(self.value)
55
56     def __eq__(self, a):
57         if isinstance(a, str):
58             return smart_str(self) == a
59         elif isinstance(a, Morsel):
60             return a.output() == self.output()
61         return False
62
63     def __ne__(self, a):
64         if isinstance(a, str):
65             return smart_str(self) != a
66         elif isinstance(a, Morsel):
67             return a.output() != self.output()
68         return True
69
70     def __repr__(self):
71         return smart_unicode(self)
72
73     def decode(self, *args):
74         return self.__repr__()
75
76 class CookieHandler(SimpleCookie):
77     def __set(self, key, real_value, coded_value):
78         """Private method for setting a cookie's value"""
79         M = self.get(key, StringMorsel())
80         M.set(key, real_value, coded_value)
81         dict.__setitem__(self, key, M)
82
83     def __setitem__(self, key, value):
84         """Dictionary style assignment."""
85         rval, cval = self.value_encode(value)
86         self.__set(key, rval, cval)
87
88     def set(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=None):
89         self[key] = value
90         for var in ('max_age', 'path', 'domain', 'secure', 'expires'):
91             val = locals()[var]
92             if val is not None:
93                 self[key][var.replace('_', '-')] = val
94
95     def delete(self, key, path='/', domain=None):
96         self[key] = ''
97         if path is not None:
98             self[key]['path'] = path
99         if domain is not None:
100             self[key]['domain'] = domain
101         self[key]['expires'] = 0
102         self[key]['max-age'] = 0