Ticket #11625: 11625.3.diff

File 11625.3.diff, 16.2 KB (added by Thejaswi Puthraya, 15 years ago)

git-patch against the latest checkout

  • django/contrib/comments/admin.py

    diff --git a/django/contrib/comments/admin.py b/django/contrib/comments/admin.py
    index c2f8e56..861db4a 100644
    a b from django.contrib import admin  
    22from django.contrib.comments.models import Comment
    33from django.utils.translation import ugettext_lazy as _
    44from django.contrib.comments import get_model
     5from django.contrib.comments.views.moderation import base_flag, base_approve, base_delete
    56
    67class CommentsAdmin(admin.ModelAdmin):
    78    fieldsets = (
    class CommentsAdmin(admin.ModelAdmin):  
    2223    ordering = ('-submit_date',)
    2324    raw_id_fields = ('user',)
    2425    search_fields = ('comment', 'user__username', 'user_name', 'user_email', 'user_url', 'ip_address')
     26    actions = ["flag_comments", "approve_comments", "remove_comments"]
     27
     28    def get_actions(self, request):
     29        actions = super(CommentsAdmin, self).get_actions(request)
     30        # Only superusers should be able to delete the comments from
     31        # the DB.
     32        if not request.user.is_superuser:
     33            actions.pop('delete_selected')
     34        if not request.user.has_perm('comments.can_moderate'):
     35            actions.pop('approve_comments')
     36            actions.pop('remove_comments')
     37        return actions
     38
     39    def flag_comments(self, request, queryset):
     40        for comment in queryset:
     41            base_flag(request, comment)
     42        self.message_user(request, "%s flagged." %self._get_message_bit(queryset.count()))
     43    flag_comments.short_description = "Flag selected comments"
     44
     45    def approve_comments(self, request, queryset):
     46        for comment in queryset:
     47            base_approve(request, comment)
     48        self.message_user(request, "%s approved." %self._get_message_bit(queryset.count()))
     49    approve_comments.short_description = "Approve selected comments"
     50
     51    def remove_comments(self, request, queryset):
     52        for comment in queryset:
     53            base_delete(request, comment)
     54        self.message_user(request, "%s removed." %self._get_message_bit(queryset.count()))
     55    remove_comments.short_description = "Remove selected comments"
     56
     57    def _get_message_bit(self, rows_updated):
     58        message_bit = ''
     59        if rows_updated == 1:
     60            message_bit += '1 comment was '
     61        else:
     62            message_bit += '%s comments were ' %rows_updated
     63        message_bit += 'successfully'
     64        return message_bit
    2565
    2666# Only register the default admin if the model is the built-in comment model
    2767# (this won't be true if there's a custom comment app).
  • deleted file django/contrib/comments/templates/comments/moderation_queue.html

    diff --git a/django/contrib/comments/templates/comments/moderation_queue.html b/django/contrib/comments/templates/comments/moderation_queue.html
    deleted file mode 100644
    index 73012b3..0000000
    + -  
    1 {% extends "admin/change_list.html" %}
    2 {% load adminmedia i18n %}
    3 
    4 {% block title %}{% trans "Comment moderation queue" %}{% endblock %}
    5 
    6 {% block extrahead %}
    7   {{ block.super }}
    8   <style type="text/css" media="screen">
    9     p#nocomments { font-size: 200%; text-align: center; border: 1px #ccc dashed; padding: 4em; }
    10     td.actions { width: 11em; }
    11     td.actions form { display: inline; }
    12     td.actions form input.submit { width: 5em; padding: 2px 4px; margin-right: 4px;}
    13     td.actions form input.approve { background: green; color: white; }
    14     td.actions form input.remove { background: red; color: white; }
    15   </style>
    16 {% endblock %}
    17 
    18 {% block branding %}
    19 <h1 id="site-name">{% trans "Comment moderation queue" %}</h1>
    20 {% endblock %}
    21 
    22 {% block breadcrumbs %}{% endblock %}
    23 
    24 {% block content %}
    25 {% if empty %}
    26 <p id="nocomments">{% trans "No comments to moderate" %}.</p>
    27 {% else %}
    28 <div id="content-main">
    29   <div class="module" id="changelist">
    30     <table cellspacing="0">
    31       <thead>
    32         <tr>
    33           <th>{% trans "Action" %}</th>
    34           <th>{% trans "Name" %}</th>
    35           <th>{% trans "Comment" %}</th>
    36           <th>{% trans "Email" %}</th>
    37           <th>{% trans "URL" %}</th>
    38           <th>{% trans "Authenticated?" %}</th>
    39           <th>{% trans "IP Address" %}</th>
    40           <th class="sorted desc">{% trans "Date posted" %}</th>
    41         </tr>
    42     </thead>
    43     <tbody>
    44       {% for comment in comments %}
    45         <tr class="{% cycle 'row1' 'row2' %}">
    46           <td class="actions">
    47             <form action="{% url comments-approve comment.pk %}" method="post">
    48               <input type="hidden" name="next" value="{% url comments-moderation-queue %}" />
    49               <input class="approve submit" type="submit" name="submit" value="{% trans "Approve" %}" />
    50             </form>
    51             <form action="{% url comments-delete comment.pk %}" method="post">
    52               <input type="hidden" name="next" value="{% url comments-moderation-queue %}" />
    53               <input class="remove submit" type="submit" name="submit" value="{% trans "Remove" %}" />
    54             </form>
    55           </td>
    56           <td>{{ comment.name }}</td>
    57           <td>{{ comment.comment|truncatewords:"50" }}</td>
    58           <td>{{ comment.email }}</td>
    59           <td>{{ comment.url }}</td>
    60           <td>
    61             <img
    62               src="{% admin_media_prefix %}img/admin/icon-{% if comment.user %}yes{% else %}no{% endif %}.gif"
    63               alt="{% if comment.user %}{% trans "yes" %}{% else %}{% trans "no" %}{% endif %}"
    64             />
    65           </td>
    66           <td>{{ comment.ip_address }}</td>
    67           <td>{{ comment.submit_date|date:"F j, P" }}</td>
    68         </tr>
    69       {% endfor %}
    70     </tbody>
    71     </table>
    72   </div>
    73 </div>
    74 {% endif %}
    75 {% endblock %}
  • django/contrib/comments/urls.py

    diff --git a/django/contrib/comments/urls.py b/django/contrib/comments/urls.py
    index 5caef9c..2bfefa3 100644
    a b urlpatterns = patterns('django.contrib.comments.views',  
    77    url(r'^flagged/$',       'moderation.flag_done',        name='comments-flag-done'),
    88    url(r'^delete/(\d+)/$',  'moderation.delete',           name='comments-delete'),
    99    url(r'^deleted/$',       'moderation.delete_done',      name='comments-delete-done'),
    10     url(r'^moderate/$',      'moderation.moderation_queue', name='comments-moderation-queue'),
    1110    url(r'^approve/(\d+)/$', 'moderation.approve',          name='comments-approve'),
    1211    url(r'^approved/$',      'moderation.approve_done',     name='comments-approve-done'),
    1312)
  • django/contrib/comments/views/moderation.py

    diff --git a/django/contrib/comments/views/moderation.py b/django/contrib/comments/views/moderation.py
    index 3334b09..965ee34 100644
    a b from django.http import Http404  
    88from django.contrib import comments
    99from django.contrib.comments import signals
    1010
     11def base_flag(request, comment):
     12    flag, created = comments.models.CommentFlag.objects.get_or_create(
     13        comment = comment,
     14        user    = request.user,
     15        flag    = comments.models.CommentFlag.SUGGEST_REMOVAL
     16        )
     17    signals.comment_was_flagged.send(
     18        sender  = comment.__class__,
     19        comment = comment,
     20        flag    = flag,
     21        created = created,
     22        request = request,
     23        )
     24
    1125#@login_required
    1226def flag(request, comment_id, next=None):
    1327    """
    def flag(request, comment_id, next=None):  
    2236
    2337    # Flag on POST
    2438    if request.method == 'POST':
    25         flag, created = comments.models.CommentFlag.objects.get_or_create(
    26             comment = comment,
    27             user    = request.user,
    28             flag    = comments.models.CommentFlag.SUGGEST_REMOVAL
    29         )
    30         signals.comment_was_flagged.send(
    31             sender  = comment.__class__,
    32             comment = comment,
    33             flag    = flag,
    34             created = created,
    35             request = request,
    36         )
     39        base_flag(request, comment)
    3740        return next_redirect(request.POST.copy(), next, flag_done, c=comment.pk)
    3841
    3942    # Render a form on GET
    def flag(request, comment_id, next=None):  
    4447        )
    4548flag = login_required(flag)
    4649
     50def base_delete(request, comment):
     51    flag, created = comments.models.CommentFlag.objects.get_or_create(
     52        comment = comment,
     53        user    = request.user,
     54        flag    = comments.models.CommentFlag.MODERATOR_DELETION
     55        )
     56    comment.is_removed = True
     57    comment.save()
     58    signals.comment_was_flagged.send(
     59        sender  = comment.__class__,
     60        comment = comment,
     61        flag    = flag,
     62        created = created,
     63        request = request,
     64        )
     65
    4766#@permission_required("comments.delete_comment")
    4867def delete(request, comment_id, next=None):
    4968    """
    def delete(request, comment_id, next=None):  
    6079    # Delete on POST
    6180    if request.method == 'POST':
    6281        # Flag the comment as deleted instead of actually deleting it.
    63         flag, created = comments.models.CommentFlag.objects.get_or_create(
    64             comment = comment,
    65             user    = request.user,
    66             flag    = comments.models.CommentFlag.MODERATOR_DELETION
    67         )
    68         comment.is_removed = True
    69         comment.save()
    70         signals.comment_was_flagged.send(
    71             sender  = comment.__class__,
    72             comment = comment,
    73             flag    = flag,
    74             created = created,
    75             request = request,
    76         )
     82        base_delete(request, comment)
    7783        return next_redirect(request.POST.copy(), next, delete_done, c=comment.pk)
    7884
    7985    # Render a form on GET
    def delete(request, comment_id, next=None):  
    8490        )
    8591delete = permission_required("comments.can_moderate")(delete)
    8692
     93def base_approve(request, comment):
     94    flag, created = comments.models.CommentFlag.objects.get_or_create(
     95        comment = comment,
     96        user    = request.user,
     97        flag    = comments.models.CommentFlag.MODERATOR_APPROVAL,
     98        )
     99
     100    comment.is_removed = False
     101    comment.is_public = True
     102    comment.save()
     103
     104    signals.comment_was_flagged.send(
     105        sender  = comment.__class__,
     106        comment = comment,
     107        flag    = flag,
     108        created = created,
     109        request = request,
     110        )
     111   
    87112#@permission_required("comments.can_moderate")
    88113def approve(request, comment_id, next=None):
    89114    """
    def approve(request, comment_id, next=None):  
    100125    # Delete on POST
    101126    if request.method == 'POST':
    102127        # Flag the comment as approved.
    103         flag, created = comments.models.CommentFlag.objects.get_or_create(
    104             comment = comment,
    105             user    = request.user,
    106             flag    = comments.models.CommentFlag.MODERATOR_APPROVAL,
    107         )
    108 
    109         comment.is_removed = False
    110         comment.is_public = True
    111         comment.save()
    112 
    113         signals.comment_was_flagged.send(
    114             sender  = comment.__class__,
    115             comment = comment,
    116             flag    = flag,
    117             created = created,
    118             request = request,
    119         )
     128        base_approve(request, comment)
    120129        return next_redirect(request.POST.copy(), next, approve_done, c=comment.pk)
    121130
    122131    # Render a form on GET
    def approve(request, comment_id, next=None):  
    128137
    129138approve = permission_required("comments.can_moderate")(approve)
    130139
    131 
    132 #@permission_required("comments.can_moderate")
    133 def moderation_queue(request):
    134     """
    135     Displays a list of unapproved comments to be approved.
    136 
    137     Templates: `comments/moderation_queue.html`
    138     Context:
    139         comments
    140             Comments to be approved (paginated).
    141         empty
    142             Is the comment list empty?
    143         is_paginated
    144             Is there more than one page?
    145         results_per_page
    146             Number of comments per page
    147         has_next
    148             Is there a next page?
    149         has_previous
    150             Is there a previous page?
    151         page
    152             The current page number
    153         next
    154             The next page number
    155         pages
    156             Number of pages
    157         hits
    158             Total number of comments
    159         page_range
    160             Range of page numbers
    161 
    162     """
    163     qs = comments.get_model().objects.filter(is_public=False, is_removed=False)
    164     paginator = Paginator(qs, 100)
    165 
    166     try:
    167         page = int(request.GET.get("page", 1))
    168     except ValueError:
    169         raise Http404
    170 
    171     try:
    172         comments_per_page = paginator.page(page)
    173     except InvalidPage:
    174         raise Http404
    175 
    176     return render_to_response("comments/moderation_queue.html", {
    177         'comments' : comments_per_page.object_list,
    178         'empty' : page == 1 and paginator.count == 0,
    179         'is_paginated': paginator.num_pages > 1,
    180         'results_per_page': 100,
    181         'has_next': comments_per_page.has_next(),
    182         'has_previous': comments_per_page.has_previous(),
    183         'page': page,
    184         'next': page + 1,
    185         'previous': page - 1,
    186         'pages': paginator.num_pages,
    187         'hits' : paginator.count,
    188         'page_range' : paginator.page_range
    189     }, context_instance=template.RequestContext(request))
    190 
    191 moderation_queue = permission_required("comments.can_moderate")(moderation_queue)
    192 
    193140flag_done = confirmation_view(
    194141    template = "comments/flagged.html",
    195142    doc = 'Displays a "comment was flagged" success page.'
  • tests/regressiontests/comment_tests/tests/moderation_view_tests.py

    diff --git a/tests/regressiontests/comment_tests/tests/moderation_view_tests.py b/tests/regressiontests/comment_tests/tests/moderation_view_tests.py
    index b9eadd7..047317b 100644
    a b class ApproveViewTests(CommentTestCase):  
    159159        response = self.client.get("/approved/", data={"c":pk})
    160160        self.assertTemplateUsed(response, "comments/approved.html")
    161161
     162def staff_status_for_user(username):
     163    u = User.objects.get(username=username)
     164    u.is_staff = True
     165    comment_perms = Permission.objects.filter(codename__contains="comment")
     166    for comment_perm in comment_perms:
     167        if comment_perm.codename in ["add_comment", "change_comment", "delete_comment"]:
     168            u.user_permissions.add(comment_perm)
     169    u.save()
    162170
    163 class ModerationQueueTests(CommentTestCase):
     171class AdminActionsTests(CommentTestCase):
     172    urls = "regressiontests.comment_tests.urls_admin"
    164173
    165     def testModerationQueuePermissions(self):
    166         """Only moderators can view the moderation queue"""
     174    def testActionsNonModerator(self):
     175        comments = self.createSomeComments()
     176        staff_status_for_user("normaluser")
    167177        self.client.login(username="normaluser", password="normaluser")
    168         response = self.client.get("/moderate/")
    169         self.assertEqual(response["Location"], "http://testserver/accounts/login/?next=/moderate/")
    170 
    171         makeModerator("normaluser")
    172         response = self.client.get("/moderate/")
    173         self.assertEqual(response.status_code, 200)
     178        response = self.client.get("/admin/comments/comment/")
     179        self.assertEquals("approve_comments" in response.content, False)
    174180
    175     def testModerationQueueContents(self):
    176         """Moderation queue should display non-public, non-removed comments."""
    177         c1, c2, c3, c4 = self.createSomeComments()
     181    def testActionsModerator(self):
     182        comments = self.createSomeComments()
     183        staff_status_for_user("normaluser")
    178184        makeModerator("normaluser")
    179185        self.client.login(username="normaluser", password="normaluser")
    180 
    181         c1.is_public = c2.is_public = False
    182         c1.save(); c2.save()
    183         response = self.client.get("/moderate/")
    184         self.assertEqual(list(response.context[0]["comments"]), [c1, c2])
    185 
    186         c2.is_removed = True
    187         c2.save()
    188         response = self.client.get("/moderate/")
    189         self.assertEqual(list(response.context[0]["comments"]), [c1])
     186        response = self.client.get("/admin/comments/comment/")
     187        self.assertEquals("approve_comments" in response.content, True)
  • new file tests/regressiontests/comment_tests/urls_admin.py

    diff --git a/tests/regressiontests/comment_tests/urls_admin.py b/tests/regressiontests/comment_tests/urls_admin.py
    new file mode 100644
    index 0000000..9e43d34
    - +  
     1from django.conf.urls.defaults import *
     2from django.contrib import admin
     3
     4admin.autodiscover()
     5
     6urlpatterns = patterns('',
     7    (r'^admin/', include(admin.site.urls)),
     8)
Back to Top