Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 1990615ae1ec1e18931dc17ba91597c49eec1de9 David Cramer committed Feb 17, 2010
Showing with 182 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +24 −0 README.rst
  3. +40 −0 djcookies/__init__.py
  4. +98 −0 djcookies/middleware.py
  5. +18 −0 setup.py
@@ -0,0 +1,2 @@
+*.pyc
+/build
@@ -0,0 +1,24 @@
+A two-part middleware which modifies request.COOKIES and adds a set and delete method.
+
+* ``set`` matches ``django.http.HttpResponse.set_cookie``
+* ``delete`` matches ``django.http.HttpResponse.delete_cookie``
+
+Installation
+------------
+
+Just modify your ``MIDDLEWARE_CLASSES`` setting, order is important here!
+
+:
+ MIDDLEWARE_CLASSES = (
+ 'djcookies.CookiePreHandlerMiddleware',
+ ...
+ 'djcookies.CookiePostHandlerMiddleware',
+ )
+
+Usage
+-----
+
+ def my_view(request):
+ request.COOKIES.set([args])
+ ...
+ return response
@@ -0,0 +1,40 @@
+"""
+django-cookies
+~~~~~~
+
+`django-cookies <http://www.github.com/dcramer/django-cookies>` is a package
+that aims to replace the built-in request.COOKIES to add methods to set
+and delete cookies without having a response ready.
+
+:copyright: 2010 by David Cramer
+"""
+
+__all__ = ('__version__', '__build__', '__docformat__', 'get_revision')
+__version__ = (0, 0, 1)
+__docformat__ = 'restructuredtext en'
+
+import os
+
+def _get_git_revision(path):
+ revision_file = os.path.join(path, 'refs', 'heads', 'master')
+ if not os.path.exists(revision_file):
+ return None
+ fh = open(revision_file, 'r')
+ try:
+ return fh.read()
+ finally:
+ fh.close()
+
+def get_revision():
+ """
+ :returns: Revision number of this branch/checkout, if available. None if
+ no revision number can be determined.
+ """
+ package_dir = os.path.dirname(__file__)
+ checkout_dir = os.path.normpath(os.path.join(package_dir, '..'))
+ path = os.path.join(checkout_dir, '.git')
+ if os.path.exists(path):
+ return _get_git_revision(path)
+ return None
+
+__build__ = get_revision()
@@ -0,0 +1,98 @@
+"""
+A two-part middleware which modifies request.COOKIES and adds a set and delete method.
+
+ `set` matches django.http.HttpResponse.set_cookie
+ `delete` matches django.http.HttpResponse.delete_cookie
+
+MIDDLEWARE_CLASSES = (
+ 'djcookies.CookiePreHandlerMiddleware',
+ ...
+ 'djcookies.CookiePostHandlerMiddleware',
+)
+
+def my_view(request):
+ request.COOKIES.set([args])
+ ...
+ return response
+"""
+
+from Cookie import SimpleCookie, Morsel
+import copy
+
+class CookiePreHandlerMiddleware(object):
+ """
+ This middleware modifies request.COOKIES and adds a set and delete method.
+
+ `set` matches django.http.HttpResponse.set_cookie
+ `delete` matches django.http.HttpResponse.delete_cookie
+
+ This should be the first middleware you load.
+ """
+ def process_request(self, request):
+ cookies = CookieHandler()
+ for k, v in request.COOKIES.iteritems():
+ cookies[k] = str(v)
+ request.COOKIES = cookies
+ request._orig_cookies = copy.deepcopy(request.COOKIES)
+
+class CookiePostHandlerMiddleware(object):
+ """
+ This middleware modifies updates the response will all modified cookies.
+
+ This should be the last middleware you load.
+ """
+ def process_response(self, request, response):
+ if hasattr(request, '_orig_cookies') and request.COOKIES != request._orig_cookies:
+ for k,v in request.COOKIES.iteritems():
+ if request._orig_cookies.get(k) != v:
+ dict.__setitem__(response.cookies, k, v)
+ return response
+
+class StringMorsel(Morsel):
+ def __str__(self):
+ return self.value
+
+ def __eq__(self, a):
+ if isinstance(a, str):
+ return str(self) == a
+ elif isinstance(a, Morsel):
+ return a.output() == self.output()
+ return False
+
+ def __ne__(self, a):
+ if isinstance(a, str):
+ return str(self) != a
+ elif isinstance(a, Morsel):
+ return a.output() != self.output()
+ return True
+
+ def __repr__(self):
+ return str(self)
+
+class CookieHandler(SimpleCookie):
+ def __set(self, key, real_value, coded_value):
+ """Private method for setting a cookie's value"""
+ M = self.get(key, StringMorsel())
+ M.set(key, real_value, coded_value)
+ dict.__setitem__(self, key, M)
+
+ def __setitem__(self, key, value):
+ """Dictionary style assignment."""
+ rval, cval = self.value_encode(value)
+ self.__set(key, rval, cval)
+
+ def set(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=None):
+ self[key] = value
+ for var in ('max_age', 'path', 'domain', 'secure', 'expires'):
+ val = locals()[var]
+ if val is not None:
+ self[key][var.replace('_', '-')] = val
+
+ def delete(self, key, path='/', domain=None):
+ self[key] = ''
+ if path is not None:
+ self[key]['path'] = path
+ if domain is not None:
+ self[key]['domain'] = domain
+ self[key]['expires'] = 0
+ self[key]['max-age'] = 0
@@ -0,0 +1,18 @@
+import os
+from setuptools import setup, find_packages
+
+setup(name='django-cookies',
+ version=".".join(map(str, __import__("djcookies").__version__)),
+ description='Drop-in replacement for Django\'s request.COOKIES',
+ author='David Cramer',
+ author_email='dcramer@gmail.com',
+ url='http://github.com/dcramer/django-cookies',
+ packages=find_packages(),
+ classifiers=[
+ "Framework :: Django",
+ "Intended Audience :: Developers",
+ "Intended Audience :: System Administrators",
+ "Operating System :: OS Independent",
+ "Topic :: Software Development"
+ ],
+)

0 comments on commit 1990615

Please sign in to comment.