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