from django.shortcuts import render from django.utils.decorators import method_decorator from django.views.generic import FormView from django.views.generic.detail import SingleObjectMixin from judge.utils.diggpaginator import DiggPaginator from django.utils.html import mark_safe def class_view_decorator(function_decorator): """Convert a function based decorator into a class based decorator usable on class based Views. Can't subclass the `View` as it breaks inheritance (super in particular), so we monkey-patch instead. """ def simple_decorator(View): View.dispatch = method_decorator(function_decorator)(View.dispatch) return View return simple_decorator def generic_message(request, title, message, status=None): return render(request, 'generic-message.html', { 'message': message, 'title': title, }, status=status) def paginate_query_context(request): query = request.GET.copy() query.setlist('page', []) query = query.urlencode() if query: return {'page_prefix': '%s?%s&page=' % (request.path, query), 'first_page_href': '%s?%s' % (request.path, query)} else: return {'page_prefix': '%s?page=' % request.path, 'first_page_href': request.path} class TitleMixin(object): title = '(untitled)' content_title = None def get_context_data(self, **kwargs): context = super(TitleMixin, self).get_context_data(**kwargs) context['title'] = self.get_title() content_title = self.get_content_title() if content_title is not None: context['content_title'] = content_title return context def get_content_title(self): return self.content_title def get_title(self): return self.title class DiggPaginatorMixin(object): def get_paginator(self, queryset, per_page, orphans=0, allow_empty_first_page=True, **kwargs): return DiggPaginator(queryset, per_page, body=6, padding=2, orphans=orphans, allow_empty_first_page=allow_empty_first_page, **kwargs) class QueryStringSortMixin(object): all_sorts = None default_sort = None default_desc = () def get_default_sort_order(self, request): return self.default_sort def get(self, request, *args, **kwargs): order = request.GET.get('order', '') if not ((not order.startswith('-') or order.count('-') == 1) and (order.lstrip('-') in self.all_sorts)): order = self.get_default_sort_order(request) self.order = order return super(QueryStringSortMixin, self).get(request, *args, **kwargs) def get_sort_context(self): query = self.request.GET.copy() query.setlist('order', []) query = query.urlencode() sort_prefix = '%s?%s&order=' % (self.request.path, query) if query else '%s?order=' % self.request.path current = self.order.lstrip('-') links = {key: sort_prefix + ('-' if key in self.default_desc else '') + key for key in self.all_sorts} links[current] = sort_prefix + ('' if self.order.startswith('-') else '-') + current order = {key: '' for key in self.all_sorts} order[current] = ' \u25BE' if self.order.startswith('-') else u' \u25B4' return {'sort_links': links, 'sort_order': order} def get_sort_paginate_context(self): return paginate_query_context(self.request) def short_circuit_middleware(view): view.short_circuit_middleware = True return view class SingleObjectFormView(SingleObjectMixin, FormView): def post(self, request, *args, **kwargs): self.object = self.get_object() return super().post(request, *args, **kwargs) def get(self, request, *args, **kwargs): self.object = self.get_object() return super().get(request, *args, **kwargs)