337afa65d8f2c58558731b2355cc4da61cf5e7aa
[redakcja.git] / apps / wiki / templatetags / wiki.py
1 from __future__ import absolute_import
2
3 from django.core.urlresolvers import reverse
4 from django.contrib.comments.models import Comment
5 from django.template.defaultfilters import stringfilter
6 from django import template
7 from django.utils.translation import ugettext as _
8
9 from wiki.models import Book
10 from dvcs.models import Change
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("wiki/main_tabs.html", takes_context=True)
27 def main_tabs(context):
28     active = getattr(context['request'], 'wiki_active_tab', None)
29
30     tabs = []
31     user = context['user']
32     if user.is_authenticated():
33         tabs.append(Tab('my', _('Assigned to me'), reverse("wiki_user")))
34
35     tabs.append(Tab('unassigned', _('Unassigned'), reverse("wiki_unassigned")))
36     tabs.append(Tab('users', _('Users'), reverse("wiki_users")))
37     tabs.append(Tab('all', _('All'), reverse("wiki_document_list")))
38     tabs.append(Tab('create', _('Add'), reverse("wiki_create_missing")))
39     tabs.append(Tab('upload', _('Upload'), reverse("wiki_upload")))
40
41     if user.is_staff:
42         tabs.append(Tab('admin', _('Admin'), reverse("admin:index")))
43
44     return {"tabs": tabs, "active_tab": active}
45
46
47 class WallItem(object):
48     title = ''
49     summary = ''
50     url = ''
51     timestamp = ''
52     user = None
53     email = ''
54
55     def __init__(self, tag):
56         self.tag = tag
57
58     def get_email(self):
59         if self.user:
60             return self.user.email
61         else:
62             return self.email
63
64
65 def changes_wall(max_len):
66     qs = Change.objects.filter(revision__gt=-1).order_by('-created_at').select_related()
67     qs = qs[:max_len]
68     for item in qs:
69         tag = 'stage' if item.tags.count() else 'change'
70         chunk = item.tree.chunk
71         w  = WallItem(tag)
72         w.title = chunk.pretty_name()
73         w.summary = item.description
74         w.url = reverse('wiki_editor', 
75                 args=[chunk.book.slug, chunk.slug]) + '?diff=%d' % item.revision
76         w.timestamp = item.created_at
77         w.user = item.author
78         w.email = item.author_email
79         yield w
80
81
82 def published_wall(max_len):
83     qs = Book.objects.exclude(last_published=None).order_by('-last_published')
84     qs = qs[:max_len]
85     for item in qs:
86         w  = WallItem('publish')
87         w.title = item.title
88         w.summary = item.title
89         w.url = chunk.book.get_absolute_url()
90         w.timestamp = item.last_published
91         w.user = item.last_published_by
92         yield w
93
94
95 def comments_wall(max_len):
96     qs = Comment.objects.filter(is_public=True).select_related().order_by('-submit_date')
97     qs = qs[:max_len]
98     for item in qs:
99         w  = WallItem('comment')
100         w.title = item.content_object
101         w.summary = item.comment
102         w.url = item.content_object.get_absolute_url()
103         w.timestamp = item.submit_date
104         w.user = item.user
105         w.email = item.user_email
106         yield w
107
108
109 def big_wall(max_len, *args):
110     """
111         Takes some WallItem iterators and zips them into one big wall.
112         Input iterators must already be sorted by timestamp.
113     """
114     subwalls = []
115     for w in args:
116         try:
117             subwalls.append([next(w), w])
118         except StopIteration:
119             pass
120
121     while max_len and subwalls:
122         i, next_item = max(enumerate(subwalls), key=lambda x: x[1][0].timestamp)
123         yield next_item[0]
124         max_len -= 1
125         try:
126             next_item[0] = next(next_item[1])
127         except StopIteration:
128             del subwalls[i]
129
130
131 @register.inclusion_tag("wiki/wall.html", takes_context=True)
132 def wall(context, max_len=10):
133     return {
134         "request": context['request'],
135         "STATIC_URL": context['STATIC_URL'],
136         "wall": big_wall(max_len,
137             changes_wall(max_len),
138             published_wall(max_len),
139             comments_wall(max_len),
140         )}