1 from django import http
 
   2 from django.utils import simplejson as json
 
   3 from django.utils.functional import Promise
 
   4 from datetime import datetime
 
   5 from functools import wraps
 
   8 class ExtendedEncoder(json.JSONEncoder):
 
  10     def default(self, obj):
 
  11         if isinstance(obj, Promise):
 
  14         if isinstance(obj, datetime):
 
  15             return datetime.ctime(obj) + " " + (datetime.tzname(obj) or 'GMT')
 
  17         return json.JSONEncoder.default(self, obj)
 
  20 # shortcut for JSON reponses
 
  21 class JSONResponse(http.HttpResponse):
 
  23     def __init__(self, data={}, **kwargs):
 
  25         kwargs.pop('mimetype', None)
 
  27         data = json.dumps(data, cls=ExtendedEncoder)
 
  28         super(JSONResponse, self).__init__(data, mimetype="application/json", **kwargs)
 
  32 class JSONFormInvalid(JSONResponse):
 
  33     def __init__(self, form):
 
  34         super(JSONFormInvalid, self).__init__(form.errors, status=400)
 
  37 class JSONServerError(JSONResponse):
 
  38     def __init__(self, *args, **kwargs):
 
  39         kwargs['status'] = 500
 
  40         super(JSONServerError, self).__init__(*args, **kwargs)
 
  43 def ajax_login_required(view):
 
  45     def authenticated_view(request, *args, **kwargs):
 
  46         if not request.user.is_authenticated():
 
  47             return http.HttpResponse("Login required.", status=401, mimetype="text/plain")
 
  48         return view(request, *args, **kwargs)
 
  49     return authenticated_view
 
  52 def ajax_require_permission(permission):
 
  55         def authorized_view(request, *args, **kwargs):
 
  56             if not request.user.has_perm(permission):
 
  57                 return http.HttpResponse("Access Forbidden.", status=403, mimetype="text/plain")
 
  58             return view(request, *args, **kwargs)
 
  59         return authorized_view
 
  64 def recursive_groupby(iterable):
 
  66 #    >>> recursive_groupby([1,2,3,4,5])
 
  69     >>> recursive_groupby([[1]])
 
  72     >>> recursive_groupby([('a', 1),('a', 2), 3, ('b', 4), 5])
 
  73     ['a', [1, 2], 3, 'b', [4], 5]
 
  75     >>> recursive_groupby([('a', 'x', 1),('a', 'x', 2), ('a', 'x', 3)])
 
  76     ['a', ['x', [1, 2, 3]]]
 
  80     def _generator(iterator):
 
  85             if not isinstance(item, collections.Sequence):
 
  86                 if grouper is not None:
 
  89                         yield recursive_groupby(group)
 
  95                 if grouper is not None:
 
  98                         yield recursive_groupby(group)
 
 111             if grouper != item[0]:
 
 112                 if grouper is not None:
 
 115                         yield recursive_groupby(group)
 
 122             group.append(item[1:])
 
 124         if grouper is not None:
 
 127                 yield recursive_groupby(group)
 
 131     return list(_generator(iterable))
 
 136         View decorator, which puts tab info on a request.
 
 140         def wrapped(request, *args, **kwargs):
 
 141             request.wiki_active_tab = tab
 
 142             return f(request, *args, **kwargs)
 
 147 class BookChunks(object):
 
 149         Yields the chunks of a book.
 
 152     def __init__(self, book):
 
 157         return self.book.chunk_set.all()
 
 160 class ChoiceChunks(BookChunks):
 
 162         Associates the given chunks iterable for a book.
 
 167     def __init__(self, book, chunks):