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