]> git.openstreetmap.org Git - osqa.git/blob - forum/templatetags/node_tags.py
Adding ability to convert comments to answers.
[osqa.git] / forum / templatetags / node_tags.py
1 from datetime import datetime, timedelta\r
2 import re\r
3 \r
4 from forum.models import Question, Action\r
5 from django.utils.translation import ungettext, ugettext as _\r
6 from django.utils.html import strip_tags\r
7 from django.utils.safestring import mark_safe\r
8 from django.core.urlresolvers import reverse\r
9 from django import template\r
10 from forum.actions import *\r
11 from forum import settings\r
12 \r
13 register = template.Library()\r
14 \r
15 @register.inclusion_tag('node/vote_buttons.html')\r
16 def vote_buttons(post, user):\r
17     context = dict(post=post, user_vote='none')\r
18 \r
19     if user.is_authenticated():\r
20         context['user_vote'] = {1: 'up', -1: 'down', None: 'none'}[VoteAction.get_for(user, post)]\r
21 \r
22     return context\r
23 \r
24 @register.inclusion_tag('node/accept_button.html')\r
25 def accept_button(answer, user):\r
26     if not settings.DISABLE_ACCEPTING_FEATURE:\r
27         return {\r
28             'can_accept': user.is_authenticated() and user.can_accept_answer(answer),\r
29             'answer': answer,\r
30             'user': user\r
31         }\r
32     else:\r
33         return ''\r
34 \r
35 @register.inclusion_tag('node/wiki_symbol.html')\r
36 def wiki_symbol(user, post):\r
37     context = {\r
38         'is_wiki': post.nis.wiki,\r
39         'post_type': post.friendly_name\r
40     }\r
41 \r
42     if post.nis.wiki:\r
43         if user.can_edit_post(post):\r
44             context['can_edit'] = True\r
45             context['edit_url'] = reverse('edit_' + post.node_type, kwargs={'id': post.id})\r
46         context['by'] = post.nstate.wiki.by.username\r
47         context['at'] = post.nstate.wiki.at\r
48 \r
49     return context\r
50 \r
51 @register.inclusion_tag('node/favorite_mark.html')\r
52 def favorite_mark(question, user):\r
53     try:\r
54         FavoriteAction.objects.get(canceled=False, node=question, user=user)\r
55         favorited = True\r
56     except:\r
57         favorited = False\r
58 \r
59     return {'favorited': favorited, 'favorite_count': question.favorite_count, 'question': question}\r
60 \r
61 @register.simple_tag\r
62 def post_classes(post):\r
63     classes = []\r
64 \r
65     if post.nis.deleted:\r
66         classes.append('deleted')\r
67 \r
68     if post.node_type == "answer":\r
69         if (not settings.DISABLE_ACCEPTING_FEATURE) and post.nis.accepted:\r
70             classes.append('accepted-answer')\r
71 \r
72         if post.author == post.question.author:\r
73             classes.append('answered-by-owner')\r
74 \r
75     return " ".join(classes)\r
76 \r
77 def post_control(text, url, command=False, withprompt=False, confirm=False, title=""):\r
78     classes = (command and "ajax-command" or " ") + (withprompt and " withprompt" or " ") + (confirm and " confirm" or " ")\r
79     return {'text': text, 'url': url, 'classes': classes, 'title': title}\r
80 \r
81 @register.inclusion_tag('node/post_controls.html')\r
82 def post_controls(post, user):\r
83     controls = []\r
84     menu = []\r
85 \r
86     if user.is_authenticated():\r
87         post_type = post.node_type\r
88 \r
89         if post_type == "answer":\r
90             controls.append(post_control(_('permanent link'), post.get_absolute_url(), title=_("answer permanent link")))\r
91 \r
92         edit_url = reverse('edit_' + post_type, kwargs={'id': post.id})\r
93         if user.can_edit_post(post):\r
94             controls.append(post_control(_('edit'), edit_url))\r
95         elif post_type == 'question' and user.can_retag_questions():\r
96             controls.append(post_control(_('retag'), edit_url))\r
97 \r
98         if post_type == 'question':\r
99             if post.nis.closed and user.can_reopen_question(post):\r
100                 controls.append(post_control(_('reopen'), reverse('reopen', kwargs={'id': post.id}), command=True))\r
101             elif not post.nis.closed and user.can_close_question(post):\r
102                 controls.append(post_control(_('close'), reverse('close', kwargs={'id': post.id}), command=True, withprompt=True))\r
103 \r
104         if user.can_flag_offensive(post):\r
105             label = _('report')\r
106             \r
107             if user.can_view_offensive_flags(post):\r
108                 label =  "%s (%d)" % (label, post.flag_count)\r
109 \r
110             controls.append(post_control(label, reverse('flag_post', kwargs={'id': post.id}),\r
111                     command=True, withprompt=True, title=_("report as offensive (i.e containing spam, advertising, malicious text, etc.)")))\r
112 \r
113         if user.can_delete_post(post):\r
114             if post.nis.deleted:\r
115                 controls.append(post_control(_('undelete'), reverse('delete_post', kwargs={'id': post.id}),\r
116                         command=True, confirm=True))\r
117             else:\r
118                 controls.append(post_control(_('delete'), reverse('delete_post', kwargs={'id': post.id}),\r
119                         command=True, confirm=True))\r
120 \r
121         if user.can_delete_post(post):\r
122             menu.append(post_control(_('see revisions'),\r
123                         reverse('revisions',\r
124                         kwargs={'id': post.id}),\r
125                         command=False, confirm=False))\r
126 \r
127         if settings.WIKI_ON:\r
128             if (not post.nis.wiki) and user.can_wikify(post):\r
129                 menu.append(post_control(_('mark as community wiki'), reverse('wikify', kwargs={'id': post.id}),\r
130                             command=True, confirm=True))\r
131 \r
132             elif post.nis.wiki and user.can_cancel_wiki(post):\r
133                 menu.append(post_control(_('cancel community wiki'), reverse('wikify', kwargs={'id': post.id}),\r
134                             command=True, confirm=True))\r
135 \r
136         if post.node_type == "answer" and user.can_convert_to_comment(post):\r
137             menu.append(post_control(_('convert to comment'), reverse('convert_to_comment', kwargs={'id': post.id}),\r
138                         command=True, withprompt=True))\r
139         \r
140         if post.node_type == "answer" and user.can_convert_to_question(post):\r
141             menu.append(post_control(_('convert to question'), reverse('convert_to_question', kwargs={'id': post.id}),\r
142                         command=True, withprompt=True))\r
143 \r
144         if user.is_superuser or user.is_staff:\r
145             plain_text = strip_tags(post.html)\r
146 \r
147             char_count = len(plain_text)\r
148             fullStr = plain_text + " "\r
149             left_trimmedStr = re.sub(re.compile(r"^[^\w]+", re.IGNORECASE), "", fullStr)\r
150             cleanedStr = re.sub(re.compile(r"[^\w]+", re.IGNORECASE), " ", left_trimmedStr)\r
151             splitString = cleanedStr.split(" ")\r
152             word_count = len(splitString) - 1\r
153 \r
154             metrics = mark_safe("<b>%s %s / %s %s</b>" % (char_count, ungettext('character', 'characters', char_count),\r
155                                         word_count, ungettext('word', 'words', word_count)))\r
156 \r
157             menu.append(post_control(metrics, "#", command=False, withprompt=False))\r
158 \r
159     return {'controls': controls, 'menu': menu, 'post': post, 'user': user}\r
160 \r
161 @register.inclusion_tag('node/comments.html')\r
162 def comments(post, user):\r
163     all_comments = post.comments.filter_state(deleted=False).order_by('added_at')\r
164 \r
165     if len(all_comments) <= 5:\r
166         top_scorers = all_comments\r
167     else:\r
168         top_scorers = sorted(all_comments, lambda c1, c2: cmp(c2.score, c1.score))[0:5]\r
169 \r
170     comments = []\r
171     showing = 0\r
172     for c in all_comments:\r
173         context = {\r
174             'can_delete': user.can_delete_comment(c),\r
175             'can_like': user.can_like_comment(c),\r
176             'can_edit': user.can_edit_comment(c),\r
177             'can_convert': user.can_convert_comment_to_answer(c)\r
178         }\r
179 \r
180         if c in top_scorers or c.is_reply_to(user):\r
181             context['top_scorer'] = True\r
182             showing += 1\r
183         \r
184         if context['can_like']:\r
185             context['likes'] = VoteAction.get_for(user, c) == 1\r
186 \r
187         context['user'] = c.user\r
188         context['comment'] = c.comment\r
189         context.update(dict(c.__dict__))\r
190         comments.append(context)\r
191 \r
192     return {\r
193         'comments': comments,\r
194         'post': post,\r
195         'can_comment': user.can_comment(post),\r
196         'max_length': settings.FORM_MAX_COMMENT_BODY,\r
197         'min_length': settings.FORM_MIN_COMMENT_BODY,\r
198         'show_gravatar': settings.FORM_GRAVATAR_IN_COMMENTS,\r
199         'showing': showing,\r
200         'total': len(all_comments),\r
201         'user': user,\r
202     }\r
203 \r
204 \r
205 @register.inclusion_tag("node/contributors_info.html")\r
206 def contributors_info(node):\r
207     return {\r
208         'node_verb': (node.node_type == "question") and _("asked") or (\r
209                     (node.node_type == "answer") and _("answered") or _("posted")),\r
210         'node': node,\r
211     }\r
212 \r
213 @register.inclusion_tag("node/reviser_info.html")\r
214 def reviser_info(revision):\r
215     return {'revision': revision}\r