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