X-Git-Url: https://git.mdrn.pl/redakcja.git/blobdiff_plain/d5011c4876bdae561f396c64cac6503ad51d5fa5..6a259b96cff47e1fd64cbfd6f3d1e1d8e8b6486c:/apps/catalogue/templatetags/book_list.py diff --git a/apps/catalogue/templatetags/book_list.py b/apps/catalogue/templatetags/book_list.py new file mode 100755 index 00000000..15654be2 --- /dev/null +++ b/apps/catalogue/templatetags/book_list.py @@ -0,0 +1,134 @@ +from __future__ import absolute_import + +from re import split +from django.db.models import Q, Count +from django import template +from django.utils.translation import ugettext_lazy as _ +from django.contrib.auth.models import User +from catalogue.models import Chunk + +register = template.Library() + + +class ChunksList(object): + def __init__(self, chunk_qs): + #self.chunk_qs = chunk_qs#.annotate( + #book_length=Count('book__chunk')).select_related( + #'book')#, 'stage__name', + #'user') + self.chunk_qs = chunk_qs.select_related('book__hidden') + + self.book_qs = chunk_qs.values('book_id') + + def __getitem__(self, key): + if isinstance(key, slice): + return self.get_slice(key) + elif isinstance(key, int): + return self.get_slice(slice(key, key+1))[0] + else: + raise TypeError('Unsupported list index. Must be a slice or an int.') + + def __len__(self): + return self.book_qs.count() + + def get_slice(self, slice_): + book_ids = [x['book_id'] for x in self.book_qs[slice_]] + chunk_qs = self.chunk_qs.filter(book__in=book_ids) + + chunks_list = [] + book = None + for chunk in chunk_qs: + if chunk.book != book: + book = chunk.book + chunks_list.append(ChoiceChunks(book, [chunk])) + else: + chunks_list[-1].chunks.append(chunk) + return chunks_list + + +class ChoiceChunks(object): + """ + Associates the given chunks iterable for a book. + """ + + chunks = None + + def __init__(self, book, chunks): + self.book = book + self.chunks = chunks + + +def foreign_filter(qs, value, filter_field, model, model_field='slug', unset='-'): + if value == unset: + return qs.filter(**{filter_field: None}) + if not value: + return qs + try: + obj = model._default_manager.get(**{model_field: value}) + except model.DoesNotExist: + return qs.none() + else: + return qs.filter(**{filter_field: obj}) + + +def search_filter(qs, value, filter_field): + if not value: + return qs + return qs.filter(**{"%s__icontains" % filter_field: value}) + + +_states = [ + ('publishable', _('publishable'), Q(book___new_publishable=True)), + ('changed', _('changed'), Q(_changed=True)), + ('published', _('published'), Q(book___published=True)), + ('unpublished', _('unpublished'), Q(book___published=False)), + ('empty', _('empty'), Q(head=None)), + ] +_states_options = [s[:2] for s in _states] +_states_dict = dict([(s[0], s[2]) for s in _states]) + + +def document_list_filter(request, **kwargs): + + def arg_or_GET(field): + return kwargs.get(field, request.GET.get(field)) + + if arg_or_GET('all'): + chunks = Chunk.objects.all() + else: + chunks = Chunk.visible_objects.all() + + chunks = chunks.order_by('book__title', 'book', 'number') + + state = arg_or_GET('status') + if state in _states_dict: + chunks = chunks.filter(_states_dict[state]) + + chunks = foreign_filter(chunks, arg_or_GET('user'), 'user', User, 'username') + chunks = foreign_filter(chunks, arg_or_GET('stage'), 'stage', Chunk.tag_model, 'slug') + chunks = search_filter(chunks, arg_or_GET('title'), 'book__title') + return chunks + + +@register.inclusion_tag('catalogue/book_list/book_list.html', takes_context=True) +def book_list(context, user=None): + request = context['request'] + + if user: + filters = {"user": user} + new_context = {"viewed_user": user} + else: + filters = {} + new_context = {"users": User.objects.annotate( + count=Count('chunk')).filter(count__gt=0).order_by( + '-count', 'last_name', 'first_name')} + + new_context.update({ + "request": request, + "books": ChunksList(document_list_filter(request, **filters)), + "stages": Chunk.tag_model.objects.all(), + "states": _states_options, + }) + + return new_context +