]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/templatetags/node_tags.py
Migrate to Django 1.6
[osqa.git] / forum / templatetags / node_tags.py
index be54232f8e44e35a1921ca1fb8e099bef60196c5..ff63ec84350ed3c5929dab371ca0352db0987350 100644 (file)
-from datetime import datetime, timedelta\r
-import re\r
-\r
-from forum.models import Question, Action\r
-from django.template import Template, Context\r
-from django.utils.translation import ungettext, ugettext as _\r
-from django.utils.html import strip_tags\r
-from django.utils.encoding import smart_unicode\r
-from django.utils.safestring import mark_safe\r
-from django.conf import settings as django_settings\r
-from django.core.urlresolvers import reverse\r
-from django import template\r
-from forum.actions import *\r
-from forum import settings\r
-\r
-register = template.Library()\r
-\r
-@register.inclusion_tag('node/vote_buttons.html')\r
-def vote_buttons(post, user):\r
-    context = dict(post=post, user_vote='none')\r
-\r
-    if user.is_authenticated():\r
-        context['user_vote'] = {1: 'up', -1: 'down', None: 'none'}[VoteAction.get_for(user, post)]\r
-\r
-    return context\r
-\r
-@register.inclusion_tag('node/accept_button.html')\r
-def accept_button(answer, user):\r
-    if not settings.DISABLE_ACCEPTING_FEATURE:\r
-        return {\r
-            'can_accept': user.is_authenticated() and user.can_accept_answer(answer),\r
-            'answer': answer,\r
-            'user': user\r
-        }\r
-    else:\r
-        return ''\r
-\r
-@register.inclusion_tag('node/wiki_symbol.html')\r
-def wiki_symbol(user, post):\r
-    context = {\r
-        'is_wiki': post.nis.wiki,\r
-        'post_type': post.friendly_name\r
-    }\r
-\r
-    if post.nis.wiki:\r
-        if user.can_edit_post(post):\r
-            context['can_edit'] = True\r
-            context['edit_url'] = reverse('edit_' + post.node_type, kwargs={'id': post.id})\r
-        context['by'] = post.nstate.wiki.by.username\r
-        context['at'] = post.nstate.wiki.at\r
-\r
-    return context\r
-\r
-@register.inclusion_tag('node/favorite_mark.html')\r
-def favorite_mark(question, user):\r
-    try:\r
-        FavoriteAction.objects.get(canceled=False, node=question, user=user)\r
-        favorited = True\r
-    except:\r
-        favorited = False\r
-\r
-    return {'favorited': favorited, 'favorite_count': question.favorite_count, 'question': question}\r
-\r
-@register.simple_tag\r
-def post_classes(post):\r
-    classes = []\r
-\r
-    if post.nis.deleted:\r
-        classes.append('deleted')\r
-\r
-    if post.node_type == "answer":\r
-        if (not settings.DISABLE_ACCEPTING_FEATURE) and post.nis.accepted:\r
-            classes.append('accepted-answer')\r
-\r
-        if post.author == post.question.author:\r
-            classes.append('answered-by-owner')\r
-\r
-    return " ".join(classes)\r
-\r
-def post_control(text, url, command=False, withprompt=False, confirm=False, title="", copy=False, extra_classes=[]):\r
-    classes = (command and "ajax-command" or " ") + (withprompt and " withprompt" or " ") + (confirm and " confirm" or " ") + \\r
-        (copy and " copy" or " ")\r
-\r
-    for extra_class in extra_classes:\r
-        classes += " %s" % extra_class\r
-\r
-    return {'text': text, 'url': url, 'classes': classes, 'title': title}\r
-\r
-\r
-moderation_enabled = False\r
-for m in django_settings.MODULE_LIST:\r
-    if m.__name__.endswith('moderation'):\r
-        moderation_enabled = True\r
-\r
-@register.inclusion_tag('node/post_controls.html' if not moderation_enabled else "modules/moderation/node/post_controls.html")\r
-def post_controls(post, user):\r
-    controls = []\r
-    menu = []\r
-    post_type = post.node_type\r
-\r
-    # We show the link tool if the post is an Answer. It is visible to Guests too.\r
-    if post_type == "answer":\r
-        # Answer permanent link tool\r
-        controls.append(post_control(_('permanent link'), reverse('answer_permanent_link', kwargs={'id' : post.id,}),\r
-                                     title=_("answer permanent link"), command=True, withprompt=True, copy=True))\r
-\r
-        # Users should be able to award points for an answer. Users cannot award their own answers\r
-        if user != post.author and user.is_authenticated() and user.reputation > 1:\r
-            controls.append(post_control(_("award points"), reverse('award_points', kwargs={'user_id' : post.author.id,\r
-                                         'answer_id' : post.id}), title=_("award points to %s") % smart_unicode(post.author.username),\r
-                                         command=True, withprompt=True))\r
-\r
-    # The other controls are visible only to authenticated users.\r
-    if user.is_authenticated():\r
-        try:\r
-            edit_url = reverse('edit_' + post_type, kwargs={'id': post.id})\r
-            if user.can_edit_post(post):\r
-                controls.append(post_control(_('edit'), edit_url))\r
-            elif post_type == 'question' and user.can_retag_questions():\r
-                controls.append(post_control(_('retag'), edit_url))\r
-        except:\r
-            pass\r
-\r
-        if post_type == 'question':\r
-            if post.nis.closed and user.can_reopen_question(post):\r
-                controls.append(post_control(_('reopen'), reverse('reopen', kwargs={'id': post.id}), command=True))\r
-            elif not post.nis.closed and user.can_close_question(post):\r
-                controls.append(post_control(_('close'), reverse('close', kwargs={'id': post.id}), command=True, withprompt=True))\r
-\r
-        if user.can_flag_offensive(post):\r
-            label = _('report')\r
-            \r
-            if user.can_view_offensive_flags(post):\r
-                label =  "%s (%d)" % (label, post.flag_count)\r
-\r
-\r
-            report_control = post_control(label, reverse('flag_post', kwargs={'id': post.id}),\r
-                    command=True, withprompt=True,\r
-                    title=_("report as offensive (i.e containing spam, advertising, malicious text, etc.)"))\r
-\r
-            # Depending on the setting choose where to attach the control\r
-            if settings.REPORT_OFFENSIVE_CONTROL_POSITION.value == "more":\r
-                menu.append(report_control)\r
-            else:\r
-                controls.append(report_control)\r
-\r
-        if user.can_delete_post(post):\r
-            if post.nis.deleted:\r
-                controls.append(post_control(_('undelete'), reverse('delete_post', kwargs={'id': post.id}),\r
-                        command=True, confirm=True))\r
-            else:\r
-                controls.append(post_control(_('delete'), reverse('delete_post', kwargs={'id': post.id}),\r
-                        command=True, confirm=True))\r
-\r
-        if user.can_delete_post(post):\r
-            menu.append(post_control(_('see revisions'),\r
-                        reverse('revisions',\r
-                        kwargs={'id': post.id}),\r
-                        command=False, confirm=False))\r
-\r
-        if settings.WIKI_ON:\r
-            if (not post.nis.wiki) and user.can_wikify(post):\r
-                menu.append(post_control(_('mark as community wiki'), reverse('wikify', kwargs={'id': post.id}),\r
-                            command=True, confirm=True))\r
-\r
-            elif post.nis.wiki and user.can_cancel_wiki(post):\r
-                menu.append(post_control(_('cancel community wiki'), reverse('wikify', kwargs={'id': post.id}),\r
-                            command=True, confirm=True))\r
-\r
-        if post.node_type == "answer" and user.can_convert_to_comment(post):\r
-            menu.append(post_control(_('convert to comment'), reverse('convert_to_comment', kwargs={'id': post.id}),\r
-                        command=True, withprompt=True))\r
-        \r
-        if post.node_type == "answer" and user.can_convert_to_question(post):\r
-            menu.append(post_control(_('convert to question'), reverse('convert_to_question', kwargs={'id': post.id}),\r
-                        command=False, confirm=True))\r
-\r
-        if user.is_superuser or user.is_staff:\r
-            plain_text = strip_tags(post.html)\r
-\r
-            char_count = len(plain_text)\r
-            fullStr = plain_text + " "\r
-            left_trimmedStr = re.sub(re.compile(r"^[^\w]+", re.IGNORECASE), "", fullStr)\r
-            cleanedStr = re.sub(re.compile(r"[^\w]+", re.IGNORECASE), " ", left_trimmedStr)\r
-            splitString = cleanedStr.split(" ")\r
-            word_count = len(splitString) - 1\r
-\r
-            metrics = mark_safe("<b>%s %s / %s %s</b>" % (char_count, ungettext('character', 'characters', char_count),\r
-                                        word_count, ungettext('word', 'words', word_count)))\r
-\r
-            menu.append(post_control(metrics, "#", command=False, withprompt=False))\r
-\r
-    return {'controls': controls, 'menu': menu, 'post': post, 'user': user}\r
-\r
-def _comments(post, user):\r
-    all_comments = post.comments.filter_state(deleted=False)\\r
-                                .order_by('-added_at' if settings.SHOW_LATEST_COMMENTS_FIRST else 'added_at')\r
-\r
-    if len(all_comments) <= 5:\r
-        top_scorers = all_comments\r
-    else:\r
-        top_scorers = sorted(all_comments, lambda c1, c2: cmp(c2.score, c1.score))[0:5]\r
-\r
-    comments = []\r
-    showing = 0\r
-    for c in all_comments:\r
-        context = {\r
-            'can_delete': user.can_delete_comment(c),\r
-            'can_like': user.can_like_comment(c),\r
-            'can_edit': user.can_edit_comment(c),\r
-            'can_convert': user.can_convert_comment_to_answer(c)\r
-        }\r
-\r
-        if c in top_scorers or c.is_reply_to(user):\r
-            context['top_scorer'] = True\r
-            showing += 1\r
-        \r
-        if context['can_like']:\r
-            context['likes'] = VoteAction.get_for(user, c) == 1\r
-\r
-        context['user'] = c.user\r
-        context['comment'] = c.comment\r
-        context.update(dict(c.__dict__))\r
-        comments.append(context)\r
-\r
-    # Generate canned comments\r
-    canned_comments = []\r
-    for comment in settings.CANNED_COMMENTS:\r
-        t = Template(smart_unicode(comment))\r
-        c = Context({\r
-            'post' : post,\r
-            'settings' : settings,\r
-        })\r
-        canned_comments.append(t.render(c))\r
-\r
-    total = len(all_comments)\r
-    return {\r
-        'comments': comments,\r
-        'canned_comments': canned_comments,\r
-        'post': post,\r
-        'can_comment': user.can_comment(post),\r
-        'max_length': settings.FORM_MAX_COMMENT_BODY,\r
-        'min_length': settings.FORM_MIN_COMMENT_BODY,\r
-        'show_gravatar': settings.FORM_GRAVATAR_IN_COMMENTS,\r
-        'showing': showing,\r
-        'total': total,\r
-        'more_comments_count' : int(total - showing),\r
-        'show_latest_comments_first' : settings.SHOW_LATEST_COMMENTS_FIRST,\r
-        'user': user,\r
-    }\r
-\r
-@register.inclusion_tag('node/comments.html')\r
-def comments(post, user):\r
-    return _comments(post, user)\r
-\r
-@register.inclusion_tag("node/contributors_info.html", takes_context=True)\r
-def contributors_info(context, node, verb=None):\r
-    return {\r
-        'node_verb': verb and verb or ((node.node_type == "question") and _("asked") or (\r
-                    (node.node_type == "answer") and _("answered") or _("posted"))),\r
-        'node': node,\r
-        'context' : context\r
-    }\r
-\r
-@register.inclusion_tag("node/reviser_info.html")\r
-def reviser_info(revision):\r
-    return {'revision': revision}\r
+from datetime import datetime, timedelta
+import re
+
+from forum.models import Question, Action
+from django.template import Template, Context
+from django.utils.translation import ungettext, ugettext as _
+from django.utils.html import strip_tags
+from django.utils.encoding import smart_unicode
+from django.utils.safestring import mark_safe
+from django.conf import settings as django_settings
+from django.core.urlresolvers import reverse
+from django import template
+from forum.actions import *
+from forum import settings
+
+register = template.Library()
+
+@register.inclusion_tag('node/vote_buttons.html')
+def vote_buttons(post, user):
+    context = dict(post=post, user_vote='none')
+
+    if user.is_authenticated():
+        context['user_vote'] = {1: 'up', -1: 'down', None: 'none'}[VoteAction.get_for(user, post)]
+
+    return context
+
+@register.inclusion_tag('node/accept_button.html')
+def accept_button(answer, user):
+    if not settings.DISABLE_ACCEPTING_FEATURE:
+        return {
+            'can_accept': user.is_authenticated() and user.can_accept_answer(answer),
+            'answer': answer,
+            'user': user
+        }
+    else:
+        return ''
+
+@register.inclusion_tag('node/wiki_symbol.html')
+def wiki_symbol(user, post):
+    context = {
+        'is_wiki': post.nis.wiki,
+        'post_type': post.friendly_name
+    }
+
+    if post.nis.wiki:
+        if user.can_edit_post(post):
+            context['can_edit'] = True
+            context['edit_url'] = reverse('edit_' + post.node_type, kwargs={'id': post.id})
+        context['by'] = post.nstate.wiki.by.username
+        context['at'] = post.nstate.wiki.at
+
+    return context
+
+@register.inclusion_tag('node/favorite_mark.html')
+def favorite_mark(question, user):
+    try:
+        FavoriteAction.objects.get(canceled=False, node=question, user=user)
+        favorited = True
+    except:
+        favorited = False
+
+    return {'favorited': favorited, 'favorite_count': question.favorite_count, 'question': question}
+
+@register.simple_tag
+def post_classes(post):
+    classes = []
+
+    if post.nis.deleted:
+        classes.append('deleted')
+
+    if post.node_type == "answer":
+        if (not settings.DISABLE_ACCEPTING_FEATURE) and post.nis.accepted:
+            classes.append('accepted-answer')
+
+        if post.author == post.question.author:
+            classes.append('answered-by-owner')
+
+    return " ".join(classes)
+
+def post_control(text, url, command=False, withprompt=False, confirm=False, title="", copy=False, extra_classes=[]):
+    classes = (command and "ajax-command" or " ") + (withprompt and " withprompt" or " ") + (confirm and " confirm" or " ") + \
+        (copy and " copy" or " ")
+
+    for extra_class in extra_classes:
+        classes += " %s" % extra_class
+
+    return {'text': text, 'url': url, 'classes': classes, 'title': title}
+
+
+moderation_enabled = False
+for m in django_settings.MODULE_LIST:
+    if m.__name__.endswith('moderation'):
+        moderation_enabled = True
+
+@register.inclusion_tag('node/post_controls.html' if not moderation_enabled else "modules/moderation/node/post_controls.html")
+def post_controls(post, user):
+    controls = []
+    menu = []
+    post_type = post.node_type
+
+    # We show the link tool if the post is an Answer. It is visible to Guests too.
+    if post_type == "answer":
+        # Answer permanent link tool
+        controls.append(post_control(_('permanent link'), reverse('answer_permanent_link', kwargs={'id' : post.id,}),
+                                     title=_("answer permanent link"), command=True, withprompt=True, copy=True))
+
+        # Users should be able to award points for an answer. Users cannot award their own answers
+        if user != post.author and user.is_authenticated() and user.reputation > 1:
+            controls.append(post_control(_("award points"), reverse('award_points', kwargs={'user_id' : post.author.id,
+                                         'answer_id' : post.id}), title=_("award points to %s") % smart_unicode(post.author.username),
+                                         command=True, withprompt=True))
+
+    # The other controls are visible only to authenticated users.
+    if user.is_authenticated():
+        try:
+            edit_url = reverse('edit_' + post_type, kwargs={'id': post.id})
+            if user.can_edit_post(post):
+                controls.append(post_control(_('edit'), edit_url))
+            elif post_type == 'question' and user.can_retag_questions():
+                controls.append(post_control(_('retag'), edit_url))
+        except:
+            pass
+
+        if post_type == 'question':
+            if post.nis.closed and user.can_reopen_question(post):
+                controls.append(post_control(_('reopen'), reverse('reopen', kwargs={'id': post.id}), command=True))
+            elif not post.nis.closed and user.can_close_question(post):
+                controls.append(post_control(_('close'), reverse('close', kwargs={'id': post.id}), command=True, withprompt=True))
+
+        if user.can_flag_offensive(post):
+            label = _('report')
+            
+            if user.can_view_offensive_flags(post):
+                label =  "%s (%d)" % (label, post.flag_count)
+
+
+            report_control = post_control(label, reverse('flag_post', kwargs={'id': post.id}),
+                    command=True, withprompt=True,
+                    title=_("report as offensive (i.e containing spam, advertising, malicious text, etc.)"))
+
+            # Depending on the setting choose where to attach the control
+            if settings.REPORT_OFFENSIVE_CONTROL_POSITION.value == "more":
+                menu.append(report_control)
+            else:
+                controls.append(report_control)
+
+        if user.can_delete_post(post):
+            if post.nis.deleted:
+                controls.append(post_control(_('undelete'), reverse('delete_post', kwargs={'id': post.id}),
+                        command=True, confirm=True))
+            else:
+                controls.append(post_control(_('delete'), reverse('delete_post', kwargs={'id': post.id}),
+                        command=True, confirm=True))
+
+        if user.can_delete_post(post):
+            menu.append(post_control(_('see revisions'),
+                        reverse('revisions',
+                        kwargs={'id': post.id}),
+                        command=False, confirm=False))
+
+        if settings.WIKI_ON:
+            if (not post.nis.wiki) and user.can_wikify(post):
+                menu.append(post_control(_('mark as community wiki'), reverse('wikify', kwargs={'id': post.id}),
+                            command=True, confirm=True))
+
+            elif post.nis.wiki and user.can_cancel_wiki(post):
+                menu.append(post_control(_('cancel community wiki'), reverse('wikify', kwargs={'id': post.id}),
+                            command=True, confirm=True))
+
+        if post.node_type == "answer" and user.can_convert_to_comment(post):
+            menu.append(post_control(_('convert to comment'), reverse('convert_to_comment', kwargs={'id': post.id}),
+                        command=True, withprompt=True))
+        
+        if post.node_type == "answer" and user.can_convert_to_question(post):
+            menu.append(post_control(_('convert to question'), reverse('convert_to_question', kwargs={'id': post.id}),
+                        command=False, confirm=True))
+
+        if user.is_superuser or user.is_staff:
+            plain_text = strip_tags(post.html)
+
+            char_count = len(plain_text)
+            fullStr = plain_text + " "
+            left_trimmedStr = re.sub(re.compile(r"^[^\w]+", re.IGNORECASE), "", fullStr)
+            cleanedStr = re.sub(re.compile(r"[^\w]+", re.IGNORECASE), " ", left_trimmedStr)
+            splitString = cleanedStr.split(" ")
+            word_count = len(splitString) - 1
+
+            metrics = mark_safe("<b>%s %s / %s %s</b>" % (char_count, ungettext('character', 'characters', char_count),
+                                        word_count, ungettext('word', 'words', word_count)))
+
+            menu.append(post_control(metrics, "#", command=False, withprompt=False))
+
+    return {'controls': controls, 'menu': menu, 'post': post, 'user': user}
+
+def _comments(post, user):
+    all_comments = post.comments.filter_state(deleted=False)\
+                                .order_by('-added_at' if settings.SHOW_LATEST_COMMENTS_FIRST else 'added_at')
+
+    if len(all_comments) <= 5:
+        top_scorers = all_comments
+    else:
+        top_scorers = sorted(all_comments, lambda c1, c2: cmp(c2.score, c1.score))[0:5]
+
+    comments = []
+    showing = 0
+    for c in all_comments:
+        context = {
+            'can_delete': user.can_delete_comment(c),
+            'can_like': user.can_like_comment(c),
+            'can_edit': user.can_edit_comment(c),
+            'can_convert': user.can_convert_comment_to_answer(c)
+        }
+
+        if c in top_scorers or c.is_reply_to(user):
+            context['top_scorer'] = True
+            showing += 1
+        
+        if context['can_like']:
+            context['likes'] = VoteAction.get_for(user, c) == 1
+
+        context['user'] = c.user
+        context['comment'] = c.comment
+        context.update(dict(c.__dict__))
+        comments.append(context)
+
+    # Generate canned comments
+    canned_comments = []
+    for comment in settings.CANNED_COMMENTS:
+        t = Template(smart_unicode(comment))
+        c = Context({
+            'post' : post,
+            'settings' : settings,
+        })
+        canned_comments.append(t.render(c))
+
+    total = len(all_comments)
+    return {
+        'comments': comments,
+        'canned_comments': canned_comments,
+        'post': post,
+        'can_comment': user.can_comment(post),
+        'max_length': settings.FORM_MAX_COMMENT_BODY,
+        'min_length': settings.FORM_MIN_COMMENT_BODY,
+        'show_gravatar': settings.FORM_GRAVATAR_IN_COMMENTS,
+        'showing': showing,
+        'total': total,
+        'more_comments_count' : int(total - showing),
+        'show_latest_comments_first' : settings.SHOW_LATEST_COMMENTS_FIRST,
+        'user': user,
+    }
+
+@register.inclusion_tag('node/comments.html')
+def comments(post, user):
+    return _comments(post, user)
+
+@register.inclusion_tag("node/contributors_info.html", takes_context=True)
+def contributors_info(context, node, verb=None):
+    return {
+        'node_verb': verb and verb or ((node.node_type == "question") and _("asked") or (
+                    (node.node_type == "answer") and _("answered") or _("posted"))),
+        'node': node,
+        'context' : context
+    }
+
+@register.inclusion_tag("node/reviser_info.html")
+def reviser_info(revision):
+    return {'revision': revision}