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 _
7 from catalogue.models import Chunk, BookPublishRecord, Image, ImagePublishRecord
9 register = template.Library()
12 class WallItem(object):
21 def __init__(self, tag):
26 return self.user.email
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')
35 qs = qs.filter(Q(author=user) | Q(tree__user=user))
36 if max_len is not None:
39 next_day = day + timedelta(1)
40 qs = qs.filter(created_at__gte=day, created_at__lt=next_day)
42 tag = 'stage' if item.tags.count() else 'change'
45 if user and item.author != user:
46 w.header = _('Related 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
55 w.user_name = item.author_name
56 w.email = item.author_email
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')
64 qs = qs.filter(Q(author=user) | Q(tree__user=user))
65 if max_len is not None:
68 next_day = day + timedelta(1)
69 qs = qs.filter(created_at__gte=day, created_at__lt=next_day)
71 tag = 'stage' if item.tags.count() else 'change'
74 if user and item.author != user:
75 w.header = _('Related edit')
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
84 w.user_name = item.author_name
85 w.email = item.author_email
90 # TODO: marked for publishing
93 def published_wall(user=None, max_len=None, day=None):
94 qs = BookPublishRecord.objects.select_related('book')
96 # TODO: published my book
97 qs = qs.filter(Q(user=user))
98 if max_len is not None:
101 next_day = day + timedelta(1)
102 qs = qs.filter(timestamp__gte=day, timestamp__lt=next_day)
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()
110 w.email = item.user.email
114 def image_published_wall(user=None, max_len=None, day=None):
115 qs = ImagePublishRecord.objects.select_related('image')
117 # TODO: published my book
118 qs = qs.filter(Q(user=user))
119 if max_len is not None:
122 next_day = day + timedelta(1)
123 qs = qs.filter(timestamp__gte=day, timestamp__lt=next_day)
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()
131 w.email = item.user.email
135 def big_wall(walls, max_len=None):
137 Takes some WallItem iterators and zips them into one big wall.
138 Input iterators must already be sorted by timestamp.
143 subwalls.append([next(w), w])
144 except StopIteration:
149 while max_len and subwalls:
150 i, next_item = max(enumerate(subwalls), key=lambda x: x[1][0].timestamp)
154 next_item[0] = next(next_item[1])
155 except StopIteration:
159 @register.inclusion_tag("catalogue/wall.html", takes_context=True)
160 def wall(context, user=None, max_len=100):
162 "request": context['request'],
163 "STATIC_URL": context['STATIC_URL'],
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),
171 @register.inclusion_tag("catalogue/wall.html", takes_context=True)
172 def day_wall(context, day):
174 "request": context['request'],
175 "STATIC_URL": context['STATIC_URL'],
177 changes_wall(day=day),
178 published_wall(day=day),
179 image_changes_wall(day=day),
180 image_published_wall(day=day),