Rearrange source to src dir.
[redakcja.git] / src / catalogue / templatetags / wall.py
1 from __future__ import absolute_import
2
3 from datetime import timedelta
4 from django.db.models import Q
5 from django.core.urlresolvers import reverse
6 from django.contrib.comments.models import Comment
7 from django import template
8 from django.utils.translation import ugettext as _
9
10 from catalogue.models import Chunk, BookPublishRecord, Image, ImagePublishRecord
11
12 register = template.Library()
13
14
15 class WallItem(object):
16     title = ''
17     summary = ''
18     url = ''
19     timestamp = ''
20     user = None
21     user_name = ''
22     email = ''
23
24     def __init__(self, tag):
25         self.tag = tag
26
27     def get_email(self):
28         if self.user:
29             return self.user.email
30         else:
31             return self.email
32
33
34 def changes_wall(user=None, max_len=None, day=None):
35     qs = Chunk.change_model.objects.order_by('-created_at')
36     qs = qs.select_related('author', 'tree', 'tree__book__title')
37     if user is not None:
38         qs = qs.filter(Q(author=user) | Q(tree__user=user))
39     if max_len is not None:
40         qs = qs[:max_len]
41     if day is not None:
42         next_day = day + timedelta(1)
43         qs = qs.filter(created_at__gte=day, created_at__lt=next_day)
44     for item in qs:
45         tag = 'stage' if item.tags.count() else 'change'
46         chunk = item.tree
47         w = WallItem(tag)
48         if user and item.author != user:
49             w.header = _('Related edit')
50         else:
51             w.header = _('Edit')
52         w.title = chunk.pretty_name()
53         w.summary = item.description
54         w.url = reverse('wiki_editor', 
55                 args=[chunk.book.slug, chunk.slug]) + '?diff=%d' % item.revision
56         w.timestamp = item.created_at
57         w.user = item.author
58         w.user_name = item.author_name
59         w.email = item.author_email
60         yield w
61
62
63 def image_changes_wall(user=None, max_len=None, day=None):
64     qs = Image.change_model.objects.order_by('-created_at')
65     qs = qs.select_related('author', 'tree', 'tree__title')
66     if user is not None:
67         qs = qs.filter(Q(author=user) | Q(tree__user=user))
68     if max_len is not None:
69         qs = qs[:max_len]
70     if day is not None:
71         next_day = day + timedelta(1)
72         qs = qs.filter(created_at__gte=day, created_at__lt=next_day)
73     for item in qs:
74         tag = 'stage' if item.tags.count() else 'change'
75         image = item.tree
76         w  = WallItem(tag)
77         if user and item.author != user:
78             w.header = _('Related edit')
79         else:
80             w.header = _('Edit')
81         w.title = image.title
82         w.summary = item.description
83         w.url = reverse('wiki_img_editor', 
84                 args=[image.slug]) + '?diff=%d' % item.revision
85         w.timestamp = item.created_at
86         w.user = item.author
87         w.user_name = item.author_name
88         w.email = item.author_email
89         yield w
90
91
92
93 # TODO: marked for publishing
94
95
96 def published_wall(user=None, max_len=None, day=None):
97     qs = BookPublishRecord.objects.select_related('book__title')
98     if user:
99         # TODO: published my book
100         qs = qs.filter(Q(user=user))
101     if max_len is not None:
102         qs = qs[:max_len]
103     if day is not None:
104         next_day = day + timedelta(1)
105         qs = qs.filter(timestamp__gte=day, timestamp__lt=next_day)
106     for item in qs:
107         w = WallItem('publish')
108         w.header = _('Publication')
109         w.title = item.book.title
110         w.timestamp = item.timestamp
111         w.url = item.book.get_absolute_url()
112         w.user = item.user
113         w.email = item.user.email
114         yield w
115
116
117 def image_published_wall(user=None, max_len=None, day=None):
118     qs = ImagePublishRecord.objects.select_related('image__title')
119     if user:
120         # TODO: published my book
121         qs = qs.filter(Q(user=user))
122     if max_len is not None:
123         qs = qs[:max_len]
124     if day is not None:
125         next_day = day + timedelta(1)
126         qs = qs.filter(timestamp__gte=day, timestamp__lt=next_day)
127     for item in qs:
128         w = WallItem('publish')
129         w.header = _('Publication')
130         w.title = item.image.title
131         w.timestamp = item.timestamp
132         w.url = item.image.get_absolute_url()
133         w.user = item.user
134         w.email = item.user.email
135         yield w
136
137
138 def comments_wall(user=None, max_len=None, day=None):
139     qs = Comment.objects.filter(is_public=True).select_related().order_by('-submit_date')
140     if user:
141         # TODO: comments concerning my books
142         qs = qs.filter(Q(user=user))
143     if max_len is not None:
144         qs = qs[:max_len]
145     if day is not None:
146         next_day = day + timedelta(1)
147         qs = qs.filter(submit_date__gte=day, submit_date__lt=next_day)
148     for item in qs:
149         w  = WallItem('comment')
150         w.header = _('Comment')
151         w.title = item.content_object
152         w.summary = item.comment
153         w.url = item.content_object.get_absolute_url()
154         w.timestamp = item.submit_date
155         w.user = item.user
156         ui = item.userinfo
157         w.email = item.email
158         w.user_name = item.name
159         yield w
160
161
162 def big_wall(walls, max_len=None):
163     """
164         Takes some WallItem iterators and zips them into one big wall.
165         Input iterators must already be sorted by timestamp.
166     """
167     subwalls = []
168     for w in walls:
169         try:
170             subwalls.append([next(w), w])
171         except StopIteration:
172             pass
173
174     if max_len is None:
175         max_len = -1
176     while max_len and subwalls:
177         i, next_item = max(enumerate(subwalls), key=lambda x: x[1][0].timestamp)
178         yield next_item[0]
179         max_len -= 1
180         try:
181             next_item[0] = next(next_item[1])
182         except StopIteration:
183             del subwalls[i]
184
185
186 @register.inclusion_tag("catalogue/wall.html", takes_context=True)
187 def wall(context, user=None, max_len=100):
188     return {
189         "request": context['request'],
190         "STATIC_URL": context['STATIC_URL'],
191         "wall": big_wall([
192             changes_wall(user, max_len),
193             published_wall(user, max_len),
194             image_changes_wall(user, max_len),
195             image_published_wall(user, max_len),
196             comments_wall(user, max_len),
197         ], max_len)}
198
199 @register.inclusion_tag("catalogue/wall.html", takes_context=True)
200 def day_wall(context, day):
201     return {
202         "request": context['request'],
203         "STATIC_URL": context['STATIC_URL'],
204         "wall": big_wall([
205             changes_wall(day=day),
206             published_wall(day=day),
207             image_changes_wall(day=day),
208             image_published_wall(day=day),
209             comments_wall(day=day),
210         ])}