1 from __future__ import absolute_import
4 from django.db.models import Q, Count
5 from django import template
6 from django.utils.translation import ugettext_lazy as _
7 from django.contrib.auth.models import User
8 from catalogue.models import Chunk, Image, Project
10 register = template.Library()
13 class ChunksList(object):
14 def __init__(self, chunk_qs):
15 self.chunk_qs = chunk_qs.select_related('book')
16 self.book_qs = chunk_qs.values('book_id')
18 def __getitem__(self, key):
19 if isinstance(key, slice):
20 return self.get_slice(key)
21 elif isinstance(key, int):
22 return self.get_slice(slice(key, key+1))[0]
24 raise TypeError('Unsupported list index. Must be a slice or an int.')
27 return self.book_qs.count()
29 def get_slice(self, slice_):
30 book_ids = [x['book_id'] for x in self.book_qs[slice_]]
31 chunk_qs = self.chunk_qs.filter(book__in=book_ids)
35 for chunk in chunk_qs:
36 if chunk.book != book:
38 chunks_list.append(ChoiceChunks(book, [chunk]))
40 chunks_list[-1].chunks.append(chunk)
44 class ChoiceChunks(object):
46 Associates the given chunks iterable for a book.
51 def __init__(self, book, chunks):
56 def foreign_filter(qs, value, filter_field, model, model_field='slug', unset='-'):
58 return qs.filter(**{filter_field: None})
62 obj = model._default_manager.get(**{model_field: value})
63 except model.DoesNotExist:
66 return qs.filter(**{filter_field: obj})
69 def search_filter(qs, value, filter_fields):
72 q = Q(**{"%s__icontains" % filter_fields[0]: value})
73 for field in filter_fields[1:]:
74 q |= Q(**{"%s__icontains" % field: value})
79 ('publishable', _('publishable'), Q(book___new_publishable=True)),
80 ('changed', _('changed'), Q(_changed=True)),
81 ('published', _('published'), Q(book___published=True)),
82 ('unpublished', _('unpublished'), Q(book___published=False)),
83 ('empty', _('empty'), Q(head=None)),
85 _states_options = [s[:2] for s in _states]
86 _states_dict = dict([(s[0], s[2]) for s in _states])
89 def document_list_filter(request, **kwargs):
91 def arg_or_GET(field):
92 return kwargs.get(field, request.GET.get(field))
95 chunks = Chunk.objects.all()
97 chunks = Chunk.visible_objects.all()
99 chunks = chunks.order_by('book__title', 'book', 'number')
101 if not request.user.is_authenticated():
102 chunks = chunks.filter(book__public=True)
104 state = arg_or_GET('status')
105 if state in _states_dict:
106 chunks = chunks.filter(_states_dict[state])
108 chunks = foreign_filter(chunks, arg_or_GET('user'), 'user', User, 'username')
109 chunks = foreign_filter(chunks, arg_or_GET('stage'), 'stage', Chunk.tag_model, 'slug')
110 chunks = search_filter(chunks, arg_or_GET('title'), ['book__title', 'title'])
111 chunks = foreign_filter(chunks, arg_or_GET('project'), 'book__project', Project, 'pk')
115 @register.inclusion_tag('catalogue/book_list/book_list.html', takes_context=True)
116 def book_list(context, user=None):
117 request = context['request']
120 filters = {"user": user}
121 new_context = {"viewed_user": user}
125 "users": User.objects.annotate(
126 count=Count('chunk')).filter(count__gt=0).order_by(
127 '-count', 'last_name', 'first_name'),
128 "other_users": User.objects.annotate(
129 count=Count('chunk')).filter(count=0).order_by(
130 'last_name', 'first_name'),
136 "books": ChunksList(document_list_filter(request, **filters)),
137 "stages": Chunk.tag_model.objects.all(),
138 "states": _states_options,
139 "projects": Project.objects.all(),
147 ('publishable', _('publishable'), Q(_new_publishable=True)),
148 ('changed', _('changed'), Q(_changed=True)),
149 ('published', _('published'), Q(_published=True)),
150 ('unpublished', _('unpublished'), Q(_published=False)),
151 ('empty', _('empty'), Q(head=None)),
153 _image_states_options = [s[:2] for s in _image_states]
154 _image_states_dict = dict([(s[0], s[2]) for s in _image_states])
156 def image_list_filter(request, **kwargs):
158 def arg_or_GET(field):
159 return kwargs.get(field, request.GET.get(field))
161 images = Image.objects.all()
163 if not request.user.is_authenticated():
164 images = images.filter(public=True)
166 state = arg_or_GET('status')
167 if state in _image_states_dict:
168 images = images.filter(_image_states_dict[state])
170 images = foreign_filter(images, arg_or_GET('user'), 'user', User, 'username')
171 images = foreign_filter(images, arg_or_GET('stage'), 'stage', Image.tag_model, 'slug')
172 images = search_filter(images, arg_or_GET('title'), ['title', 'title'])
173 images = foreign_filter(images, arg_or_GET('project'), 'project', Project, 'pk')
177 @register.inclusion_tag('catalogue/image_table.html', takes_context=True)
178 def image_list(context, user=None):
179 request = context['request']
182 filters = {"user": user}
183 new_context = {"viewed_user": user}
187 "users": User.objects.annotate(
188 count=Count('image')).filter(count__gt=0).order_by(
189 '-count', 'last_name', 'first_name'),
190 "other_users": User.objects.annotate(
191 count=Count('image')).filter(count=0).order_by(
192 'last_name', 'first_name'),
198 "objects": image_list_filter(request, **filters),
199 "stages": Image.tag_model.objects.all(),
200 "states": _image_states_options,
201 "projects": Project.objects.all(),