dvcs history fixes
[redakcja.git] / apps / catalogue / templatetags / wall.py
1 from __future__ import absolute_import
2
3 from django.db.models import Q
4 from django.core.urlresolvers import reverse
5 from django.contrib.comments.models import Comment
6 from django import template
7 from django.utils.translation import ugettext as _
8
9 from catalogue.models import Chunk, BookPublishRecord
10
11 register = template.Library()
12
13
14 class WallItem(object):
15     title = ''
16     summary = ''
17     url = ''
18     timestamp = ''
19     user = None
20     email = ''
21
22     def __init__(self, tag):
23         self.tag = tag
24
25     def get_email(self):
26         if self.user:
27             return self.user.email
28         else:
29             return self.email
30
31
32 def changes_wall(user, max_len):
33     qs = Chunk.change_model.objects.order_by('-created_at')
34     qs = qs.select_related('author', 'tree', 'tree__book__title')
35     if user:
36         qs = qs.filter(Q(author=user) | Q(tree__user=user))
37     qs = qs[:max_len]
38     for item in qs:
39         tag = 'stage' if item.tags.count() else 'change'
40         chunk = item.tree
41         w  = WallItem(tag)
42         if user and item.author != user:
43             w.header = _('Related edit')
44         else:
45             w.header = _('Edit')
46         w.title = chunk.pretty_name()
47         w.summary = item.description
48         w.url = reverse('wiki_editor', 
49                 args=[chunk.book.slug, chunk.slug]) + '?diff=%d' % item.revision
50         w.timestamp = item.created_at
51         w.user = item.author
52         w.email = item.author_email
53         yield w
54
55
56 # TODO: marked for publishing
57
58
59 def published_wall(user, max_len):
60     qs = BookPublishRecord.objects.select_related('book__title')
61     if user:
62         # TODO: published my book
63         qs = qs.filter(Q(user=user))
64     qs = qs[:max_len]
65     for item in qs:
66         w = WallItem('publish')
67         w.header = _('Publication')
68         w.title = item.book.title
69         w.timestamp = item.timestamp
70         w.url = item.book.get_absolute_url()
71         w.user = item.user
72         w.email = item.user.email
73         yield w
74
75
76 def comments_wall(user, max_len):
77     qs = Comment.objects.filter(is_public=True).select_related().order_by('-submit_date')
78     if user:
79         # TODO: comments concerning my books
80         qs = qs.filter(Q(user=user))
81     qs = qs[:max_len]
82     for item in qs:
83         w  = WallItem('comment')
84         w.header = _('Comment')
85         w.title = item.content_object
86         w.summary = item.comment
87         w.url = item.content_object.get_absolute_url()
88         w.timestamp = item.submit_date
89         w.user = item.user
90         w.email = item.user_email
91         yield w
92
93
94 def big_wall(max_len, *args):
95     """
96         Takes some WallItem iterators and zips them into one big wall.
97         Input iterators must already be sorted by timestamp.
98     """
99     subwalls = []
100     for w in args:
101         try:
102             subwalls.append([next(w), w])
103         except StopIteration:
104             pass
105
106     while max_len and subwalls:
107         i, next_item = max(enumerate(subwalls), key=lambda x: x[1][0].timestamp)
108         yield next_item[0]
109         max_len -= 1
110         try:
111             next_item[0] = next(next_item[1])
112         except StopIteration:
113             del subwalls[i]
114
115
116 @register.inclusion_tag("catalogue/wall.html", takes_context=True)
117 def wall(context, user=None, max_len=100):
118     return {
119         "request": context['request'],
120         "STATIC_URL": context['STATIC_URL'],
121         "wall": big_wall(max_len,
122             changes_wall(user, max_len),
123             published_wall(user, max_len),
124             comments_wall(user, max_len),
125         )}