Commit 5fade4566c673bb94bb2c7d026d380300fe98cc9

Authored by Łukasz Banasiak
Committed by Claude Paroz
1 parent 52cb6fe3

Reformatted code to be PEP 8 compliant

... ... @@ -10,6 +10,7 @@ except ImportError:
10 10
11 11 DEFAULT_COMMENTS_APP = 'django_comments'
12 12
  13 +
13 14 def get_comment_app():
14 15 """
15 16 Get the comment app (i.e. "django_comments") as defined in the settings
... ... @@ -17,18 +18,21 @@ def get_comment_app():
17 18 # Make sure the app's in INSTALLED_APPS
18 19 comments_app = get_comment_app_name()
19 20 if comments_app not in settings.INSTALLED_APPS:
20   - raise ImproperlyConfigured("The COMMENTS_APP (%r) "\
21   - "must be in INSTALLED_APPS" % settings.COMMENTS_APP)
  21 + raise ImproperlyConfigured(
  22 + "The COMMENTS_APP (%r) must be in INSTALLED_APPS" % settings.COMMENTS_APP
  23 + )
22 24
23 25 # Try to import the package
24 26 try:
25 27 package = import_module(comments_app)
26 28 except ImportError as e:
27   - raise ImproperlyConfigured("The COMMENTS_APP setting refers to "\
28   - "a non-existing package. (%s)" % e)
  29 + raise ImproperlyConfigured(
  30 + "The COMMENTS_APP setting refers to a non-existing package. (%s)" % e
  31 + )
29 32
30 33 return package
31 34
  35 +
32 36 def get_comment_app_name():
33 37 """
34 38 Returns the name of the comment app (either the setting value, if it
... ... @@ -36,6 +40,7 @@ def get_comment_app_name():
36 40 """
37 41 return getattr(settings, 'COMMENTS_APP', DEFAULT_COMMENTS_APP)
38 42
  43 +
39 44 def get_model():
40 45 from django_comments.models import Comment
41 46 """
... ... @@ -46,6 +51,7 @@ def get_model():
46 51 else:
47 52 return Comment
48 53
  54 +
49 55 def get_form():
50 56 from django_comments.forms import CommentForm
51 57 """
... ... @@ -56,6 +62,7 @@ def get_form():
56 62 else:
57 63 return CommentForm
58 64
  65 +
59 66 def get_form_target():
60 67 """
61 68 Returns the target URL for the comment form submission view.
... ... @@ -65,6 +72,7 @@ def get_form_target():
65 72 else:
66 73 return urlresolvers.reverse("django_comments.views.comments.post_comment")
67 74
  75 +
68 76 def get_flag_url(comment):
69 77 """
70 78 Get the URL for the "flag this comment" view.
... ... @@ -75,6 +83,7 @@ def get_flag_url(comment):
75 83 return urlresolvers.reverse("django_comments.views.moderation.flag",
76 84 args=(comment.id,))
77 85
  86 +
78 87 def get_delete_url(comment):
79 88 """
80 89 Get the URL for the "delete this comment" view.
... ... @@ -85,6 +94,7 @@ def get_delete_url(comment):
85 94 return urlresolvers.reverse("django_comments.views.moderation.delete",
86 95 args=(comment.id,))
87 96
  97 +
88 98 def get_approve_url(comment):
89 99 """
90 100 Get the URL for the "approve this comment from moderation" view.
... ...
... ... @@ -14,22 +14,26 @@ class UsernameSearch(object):
14 14 a mechanism for issuing the equivalent of a .filter(user__username=...)
15 15 search in CommentAdmin.
16 16 """
  17 +
17 18 def __str__(self):
18 19 return 'user__%s' % get_user_model().USERNAME_FIELD
19 20
20 21
21 22 class CommentsAdmin(admin.ModelAdmin):
22 23 fieldsets = (
23   - (None,
24   - {'fields': ('content_type', 'object_pk', 'site')}
  24 + (
  25 + None,
  26 + {'fields': ('content_type', 'object_pk', 'site')}
25 27 ),
26   - (_('Content'),
27   - {'fields': ('user', 'user_name', 'user_email', 'user_url', 'comment')}
  28 + (
  29 + _('Content'),
  30 + {'fields': ('user', 'user_name', 'user_email', 'user_url', 'comment')}
28 31 ),
29   - (_('Metadata'),
30   - {'fields': ('submit_date', 'ip_address', 'is_public', 'is_removed')}
  32 + (
  33 + _('Metadata'),
  34 + {'fields': ('submit_date', 'ip_address', 'is_public', 'is_removed')}
31 35 ),
32   - )
  36 + )
33 37
34 38 list_display = ('name', 'content_type', 'object_pk', 'ip_address', 'submit_date', 'is_public', 'is_removed')
35 39 list_filter = ('submit_date', 'site', 'is_public', 'is_removed')
... ... @@ -54,16 +58,19 @@ class CommentsAdmin(admin.ModelAdmin):
54 58 def flag_comments(self, request, queryset):
55 59 self._bulk_flag(request, queryset, perform_flag,
56 60 lambda n: ungettext('flagged', 'flagged', n))
  61 +
57 62 flag_comments.short_description = _("Flag selected comments")
58 63
59 64 def approve_comments(self, request, queryset):
60 65 self._bulk_flag(request, queryset, perform_approve,
61 66 lambda n: ungettext('approved', 'approved', n))
  67 +
62 68 approve_comments.short_description = _("Approve selected comments")
63 69
64 70 def remove_comments(self, request, queryset):
65 71 self._bulk_flag(request, queryset, perform_delete,
66 72 lambda n: ungettext('removed', 'removed', n))
  73 +
67 74 remove_comments.short_description = _("Remove selected comments")
68 75
69 76 def _bulk_flag(self, request, queryset, action, done_message):
... ...
... ... @@ -4,6 +4,7 @@ from django.utils.translation import ugettext as _
4 4
5 5 import django_comments
6 6
  7 +
7 8 class LatestCommentFeed(Feed):
8 9 """Feed of latest comments on the current site."""
9 10
... ... @@ -22,9 +23,9 @@ class LatestCommentFeed(Feed):
22 23
23 24 def items(self):
24 25 qs = django_comments.get_model().objects.filter(
25   - site__pk = self.site.pk,
26   - is_public = True,
27   - is_removed = False,
  26 + site__pk=self.site.pk,
  27 + is_public=True,
  28 + is_removed=False,
28 29 )
29 30 return qs.order_by('-submit_date')[:40]
30 31
... ...
1 1 import time
  2 +
2 3 from django import forms
3 4
4 5 try:
... ... @@ -13,18 +14,18 @@ from django.utils.encoding import force_text
13 14 from django.utils.text import get_text_list
14 15 from django.utils import timezone
15 16 from django.utils.translation import ungettext, ugettext, ugettext_lazy as _
16   -
17 17 from django_comments.models import Comment
18 18
19   -COMMENT_MAX_LENGTH = getattr(settings,'COMMENT_MAX_LENGTH', 3000)
  19 +COMMENT_MAX_LENGTH = getattr(settings, 'COMMENT_MAX_LENGTH', 3000)
  20 +
20 21
21 22 class CommentSecurityForm(forms.Form):
22 23 """
23 24 Handles the security aspects (anti-spoofing) for comment forms.
24 25 """
25   - content_type = forms.CharField(widget=forms.HiddenInput)
26   - object_pk = forms.CharField(widget=forms.HiddenInput)
27   - timestamp = forms.IntegerField(widget=forms.HiddenInput)
  26 + content_type = forms.CharField(widget=forms.HiddenInput)
  27 + object_pk = forms.CharField(widget=forms.HiddenInput)
  28 + timestamp = forms.IntegerField(widget=forms.HiddenInput)
28 29 security_hash = forms.CharField(min_length=40, max_length=40, widget=forms.HiddenInput)
29 30
30 31 def __init__(self, target_object, data=None, initial=None):
... ... @@ -45,9 +46,9 @@ class CommentSecurityForm(forms.Form):
45 46 def clean_security_hash(self):
46 47 """Check the security hash."""
47 48 security_hash_dict = {
48   - 'content_type' : self.data.get("content_type", ""),
49   - 'object_pk' : self.data.get("object_pk", ""),
50   - 'timestamp' : self.data.get("timestamp", ""),
  49 + 'content_type': self.data.get("content_type", ""),
  50 + 'object_pk': self.data.get("object_pk", ""),
  51 + 'timestamp': self.data.get("timestamp", ""),
51 52 }
52 53 expected_hash = self.generate_security_hash(**security_hash_dict)
53 54 actual_hash = self.cleaned_data["security_hash"]
... ... @@ -65,11 +66,11 @@ class CommentSecurityForm(forms.Form):
65 66 def generate_security_data(self):
66 67 """Generate a dict of security data for "initial" data."""
67 68 timestamp = int(time.time())
68   - security_dict = {
69   - 'content_type' : str(self.target_object._meta),
70   - 'object_pk' : str(self.target_object._get_pk_val()),
71   - 'timestamp' : str(timestamp),
72   - 'security_hash' : self.initial_security_hash(timestamp),
  69 + security_dict = {
  70 + 'content_type': str(self.target_object._meta),
  71 + 'object_pk': str(self.target_object._get_pk_val()),
  72 + 'timestamp': str(timestamp),
  73 + 'security_hash': self.initial_security_hash(timestamp),
73 74 }
74 75 return security_dict
75 76
... ... @@ -80,10 +81,10 @@ class CommentSecurityForm(forms.Form):
80 81 """
81 82
82 83 initial_security_dict = {
83   - 'content_type' : str(self.target_object._meta),
84   - 'object_pk' : str(self.target_object._get_pk_val()),
85   - 'timestamp' : str(timestamp),
86   - }
  84 + 'content_type': str(self.target_object._meta),
  85 + 'object_pk': str(self.target_object._get_pk_val()),
  86 + 'timestamp': str(timestamp),
  87 + }
87 88 return self.generate_security_hash(**initial_security_dict)
88 89
89 90 def generate_security_hash(self, content_type, object_pk, timestamp):
... ... @@ -95,15 +96,16 @@ class CommentSecurityForm(forms.Form):
95 96 value = "-".join(info)
96 97 return salted_hmac(key_salt, value).hexdigest()
97 98
  99 +
98 100 class CommentDetailsForm(CommentSecurityForm):
99 101 """
100 102 Handles the specific details of the comment (name, comment, etc.).
101 103 """
102   - name = forms.CharField(label=_("Name"), max_length=50)
103   - email = forms.EmailField(label=_("Email address"))
104   - url = forms.URLField(label=_("URL"), required=False)
105   - comment = forms.CharField(label=_('Comment'), widget=forms.Textarea,
106   - max_length=COMMENT_MAX_LENGTH)
  104 + name = forms.CharField(label=_("Name"), max_length=50)
  105 + email = forms.EmailField(label=_("Email address"))
  106 + url = forms.URLField(label=_("URL"), required=False)
  107 + comment = forms.CharField(label=_('Comment'), widget=forms.Textarea,
  108 + max_length=COMMENT_MAX_LENGTH)
107 109
108 110 def get_comment_object(self):
109 111 """
... ... @@ -138,16 +140,16 @@ class CommentDetailsForm(CommentSecurityForm):
138 140 method to add extra fields onto a custom comment model.
139 141 """
140 142 return dict(
141   - content_type = ContentType.objects.get_for_model(self.target_object),
142   - object_pk = force_text(self.target_object._get_pk_val()),
143   - user_name = self.cleaned_data["name"],
144   - user_email = self.cleaned_data["email"],
145   - user_url = self.cleaned_data["url"],
146   - comment = self.cleaned_data["comment"],
147   - submit_date = timezone.now(),
148   - site_id = settings.SITE_ID,
149   - is_public = True,
150   - is_removed = False,
  143 + content_type=ContentType.objects.get_for_model(self.target_object),
  144 + object_pk=force_text(self.target_object._get_pk_val()),
  145 + user_name=self.cleaned_data["name"],
  146 + user_email=self.cleaned_data["email"],
  147 + user_url=self.cleaned_data["url"],
  148 + comment=self.cleaned_data["comment"],
  149 + submit_date=timezone.now(),
  150 + site_id=settings.SITE_ID,
  151 + is_public=True,
  152 + is_removed=False,
151 153 )
152 154
153 155 def check_for_duplicate_comment(self, new):
... ... @@ -158,11 +160,11 @@ class CommentDetailsForm(CommentSecurityForm):
158 160 possible_duplicates = self.get_comment_model()._default_manager.using(
159 161 self.target_object._state.db
160 162 ).filter(
161   - content_type = new.content_type,
162   - object_pk = new.object_pk,
163   - user_name = new.user_name,
164   - user_email = new.user_email,
165   - user_url = new.user_url,
  163 + content_type=new.content_type,
  164 + object_pk=new.object_pk,
  165 + user_name=new.user_name,
  166 + user_email=new.user_email,
  167 + user_url=new.user_url,
166 168 )
167 169 for old in possible_duplicates:
168 170 if old.submit_date.date() == new.submit_date.date() and old.comment == new.comment:
... ... @@ -184,14 +186,15 @@ class CommentDetailsForm(CommentSecurityForm):
184 186 "Watch your mouth! The word %s is not allowed here.",
185 187 "Watch your mouth! The words %s are not allowed here.",
186 188 len(bad_words)) % get_text_list(
187   - ['"%s%s%s"' % (i[0], '-'*(len(i)-2), i[-1])
188   - for i in bad_words], ugettext('and')))
  189 + ['"%s%s%s"' % (i[0], '-' * (len(i) - 2), i[-1])
  190 + for i in bad_words], ugettext('and')))
189 191 return comment
190 192
  193 +
191 194 class CommentForm(CommentDetailsForm):
192   - honeypot = forms.CharField(required=False,
193   - label=_('If you enter anything in this field '\
194   - 'your comment will be treated as spam'))
  195 + honeypot = forms.CharField(required=False,
  196 + label=_('If you enter anything in this field '
  197 + 'your comment will be treated as spam'))
195 198
196 199 def clean_honeypot(self):
197 200 """Check that nothing's been entered into the honeypot."""
... ...
... ... @@ -2,8 +2,8 @@ from django.db import models
2 2 from django.contrib.contenttypes.models import ContentType
3 3 from django.utils.encoding import force_text
4 4
5   -class CommentManager(models.Manager):
6 5
  6 +class CommentManager(models.Manager):
7 7 def in_moderation(self):
8 8 """
9 9 QuerySet for all comments currently in the moderation queue.
... ...
... ... @@ -24,12 +24,20 @@ class Migration(migrations.Migration):
24 24 ('user_url', models.URLField(verbose_name="user's URL", blank=True)),
25 25 ('comment', models.TextField(max_length=3000, verbose_name='comment')),
26 26 ('submit_date', models.DateTimeField(default=None, verbose_name='date/time submitted')),
27   - ('ip_address', models.GenericIPAddressField(unpack_ipv4=True, null=True, verbose_name='IP address', blank=True)),
28   - ('is_public', models.BooleanField(default=True, help_text='Uncheck this box to make the comment effectively disappear from the site.', verbose_name='is public')),
29   - ('is_removed', models.BooleanField(default=False, help_text='Check this box if the comment is inappropriate. A "This comment has been removed" message will be displayed instead.', verbose_name='is removed')),
30   - ('content_type', models.ForeignKey(related_name='content_type_set_for_comment', verbose_name='content type', to='contenttypes.ContentType')),
  27 + ('ip_address', models.GenericIPAddressField(
  28 + unpack_ipv4=True, null=True, verbose_name='IP address', blank=True)),
  29 + ('is_public', models.BooleanField(default=True,
  30 + help_text='Uncheck this box to make the comment effectively disappear from the site.',
  31 + verbose_name='is public')),
  32 + ('is_removed', models.BooleanField(default=False,
  33 + help_text='Check this box if the comment is inappropriate. A "This comment has been removed"'
  34 + 'message will be displayed instead.',
  35 + verbose_name='is removed')),
  36 + ('content_type', models.ForeignKey(related_name='content_type_set_for_comment',
  37 + verbose_name='content type', to='contenttypes.ContentType')),
31 38 ('site', models.ForeignKey(to='sites.Site')),
32   - ('user', models.ForeignKey(related_name='comment_comments', verbose_name='user', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
  39 + ('user', models.ForeignKey(related_name='comment_comments', verbose_name='user',
  40 + blank=True, to=settings.AUTH_USER_MODEL, null=True)),
33 41 ],
34 42 options={
35 43 'ordering': ('submit_date',),
... ... @@ -46,8 +54,10 @@ class Migration(migrations.Migration):
46 54 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
47 55 ('flag', models.CharField(max_length=30, verbose_name='flag', db_index=True)),
48 56 ('flag_date', models.DateTimeField(default=None, verbose_name='date')),
49   - ('comment', models.ForeignKey(related_name='flags', verbose_name='comment', to='django_comments.Comment')),
50   - ('user', models.ForeignKey(related_name='comment_flags', verbose_name='user', to=settings.AUTH_USER_MODEL)),
  57 + ('comment', models.ForeignKey(related_name='flags', verbose_name='comment',
  58 + to='django_comments.Comment')),
  59 + ('user', models.ForeignKey(related_name='comment_flags', verbose_name='user',
  60 + to=settings.AUTH_USER_MODEL)),
51 61 ],
52 62 options={
53 63 'db_table': 'django_comment_flags',
... ...
... ... @@ -26,8 +26,8 @@ class BaseCommentAbstractModel(models.Model):
26 26
27 27 # Content-object field
28 28 content_type = models.ForeignKey(ContentType,
29   - verbose_name=_('content type'),
30   - related_name="content_type_set_for_%(class)s")
  29 + verbose_name=_('content type'),
  30 + related_name="content_type_set_for_%(class)s")
31 31 object_pk = models.TextField(_('object ID'))
32 32 content_object = GenericForeignKey(ct_field="content_type", fk_field="object_pk")
33 33
... ... @@ -57,7 +57,7 @@ class Comment(BaseCommentAbstractModel):
57 57 # user; otherwise at least user_name should have been set and the comment
58 58 # was posted by a non-authenticated user.
59 59 user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'),
60   - blank=True, null=True, related_name="%(class)s_comments")
  60 + blank=True, null=True, related_name="%(class)s_comments")
61 61 user_name = models.CharField(_("user's name"), max_length=50, blank=True)
62 62 user_email = models.EmailField(_("user's email address"), blank=True)
63 63 user_url = models.URLField(_("user's URL"), blank=True)
... ... @@ -68,12 +68,12 @@ class Comment(BaseCommentAbstractModel):
68 68 submit_date = models.DateTimeField(_('date/time submitted'), default=None)
69 69 ip_address = models.GenericIPAddressField(_('IP address'), unpack_ipv4=True, blank=True, null=True)
70 70 is_public = models.BooleanField(_('is public'), default=True,
71   - help_text=_('Uncheck this box to make the comment effectively ' \
72   - 'disappear from the site.'))
  71 + help_text=_('Uncheck this box to make the comment effectively '
  72 + 'disappear from the site.'))
73 73 is_removed = models.BooleanField(_('is removed'), default=False,
74   - help_text=_('Check this box if the comment is inappropriate. ' \
75   - 'A "This comment has been removed" message will ' \
76   - 'be displayed instead.'))
  74 + help_text=_('Check this box if the comment is inappropriate. '
  75 + 'A "This comment has been removed" message will '
  76 + 'be displayed instead.'))
77 77
78 78 # Manager
79 79 objects = CommentManager()
... ... @@ -120,6 +120,7 @@ class Comment(BaseCommentAbstractModel):
120 120 userinfo["name"] = u.get_username()
121 121 self._userinfo = userinfo
122 122 return self._userinfo
  123 +
123 124 userinfo = property(_get_userinfo, doc=_get_userinfo.__doc__)
124 125
125 126 def _get_name(self):
... ... @@ -127,9 +128,10 @@ class Comment(BaseCommentAbstractModel):
127 128
128 129 def _set_name(self, val):
129 130 if self.user_id:
130   - raise AttributeError(_("This comment was posted by an authenticated "\
  131 + raise AttributeError(_("This comment was posted by an authenticated "
131 132 "user and thus the name is read-only."))
132 133 self.user_name = val
  134 +
133 135 name = property(_get_name, _set_name, doc="The name of the user who posted this comment")
134 136
135 137 def _get_email(self):
... ... @@ -137,9 +139,10 @@ class Comment(BaseCommentAbstractModel):
137 139
138 140 def _set_email(self, val):
139 141 if self.user_id:
140   - raise AttributeError(_("This comment was posted by an authenticated "\
  142 + raise AttributeError(_("This comment was posted by an authenticated "
141 143 "user and thus the email is read-only."))
142 144 self.user_email = val
  145 +
143 146 email = property(_get_email, _set_email, doc="The email of the user who posted this comment")
144 147
145 148 def _get_url(self):
... ... @@ -147,6 +150,7 @@ class Comment(BaseCommentAbstractModel):
147 150
148 151 def _set_url(self, val):
149 152 self.user_url = val
  153 +
150 154 url = property(_get_url, _set_url, doc="The URL given by the user who posted this comment")
151 155
152 156 def get_absolute_url(self, anchor_pattern="#c%(id)s"):
... ... @@ -197,8 +201,9 @@ class CommentFlag(models.Model):
197 201 verbose_name_plural = _('comment flags')
198 202
199 203 def __str__(self):
200   - return "%s flag of comment ID %s by %s" % \
201   - (self.flag, self.comment_id, self.user.get_username())
  204 + return "%s flag of comment ID %s by %s" % (
  205 + self.flag, self.comment_id, self.user.get_username()
  206 + )
202 207
203 208 def save(self, *args, **kwargs):
204 209 if self.flag_date is None:
... ...
... ... @@ -66,6 +66,7 @@ from django.utils import timezone
66 66 import django_comments
67 67 from django_comments import signals
68 68
  69 +
69 70 class AlreadyModerated(Exception):
70 71 """
71 72 Raised when a model which is already registered for moderation is
... ... @@ -74,6 +75,7 @@ class AlreadyModerated(Exception):
74 75 """
75 76 pass
76 77
  78 +
77 79 class NotModerated(Exception):
78 80 """
79 81 Raised when a model which is not registered for moderation is
... ... @@ -82,6 +84,7 @@ class NotModerated(Exception):
82 84 """
83 85 pass
84 86
  87 +
85 88 class CommentModerator(object):
86 89 """
87 90 Encapsulates comment-moderation options for a given model.
... ... @@ -209,7 +212,8 @@ class CommentModerator(object):
209 212 return False
210 213 if self.auto_close_field and self.close_after is not None:
211 214 close_after_date = getattr(content_object, self.auto_close_field)
212   - if close_after_date is not None and self._get_delta(timezone.now(), close_after_date).days >= self.close_after:
  215 + if close_after_date is not None and self._get_delta(timezone.now(),
  216 + close_after_date).days >= self.close_after:
213 217 return False
214 218 return True
215 219
... ... @@ -225,7 +229,8 @@ class CommentModerator(object):
225 229 """
226 230 if self.auto_moderate_field and self.moderate_after is not None:
227 231 moderate_after_date = getattr(content_object, self.auto_moderate_field)
228   - if moderate_after_date is not None and self._get_delta(timezone.now(), moderate_after_date).days >= self.moderate_after:
  232 + if moderate_after_date is not None and self._get_delta(timezone.now(),
  233 + moderate_after_date).days >= self.moderate_after:
229 234 return True
230 235 return False
231 236
... ... @@ -239,13 +244,14 @@ class CommentModerator(object):
239 244 return
240 245 recipient_list = [manager_tuple[1] for manager_tuple in settings.MANAGERS]
241 246 t = loader.get_template('comments/comment_notification_email.txt')
242   - c = Context({ 'comment': comment,
243   - 'content_object': content_object })
  247 + c = Context({'comment': comment,
  248 + 'content_object': content_object})
244 249 subject = '[%s] New comment posted on "%s"' % (get_current_site(request).name,
245   - content_object)
  250 + content_object)
246 251 message = t.render(c)
247 252 send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list, fail_silently=True)
248 253
  254 +
249 255 class Moderator(object):
250 256 """
251 257 Handles moderation of a set of models.
... ... @@ -277,6 +283,7 @@ class Moderator(object):
277 283 around, will send any notification emails the comment generated.
278 284
279 285 """
  286 +
280 287 def __init__(self):
281 288 self._registry = {}
282 289 self.connect()
... ...
1 1 <!DOCTYPE html>
2 2 <html lang="en">
3 3 <head>
4   - <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  4 + <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
5 5 <title>Comment post not allowed (400)</title>
6   - <meta name="robots" content="NONE,NOARCHIVE" />
  6 + <meta name="robots" content="NONE,NOARCHIVE"/>
7 7 <style type="text/css">
8   - <![CDATA[
9   - html * { padding:0; margin:0; }
10   - body * { padding:10px 20px; }
11   - body * * { padding:0; }
12   - body { font:small sans-serif; background:#eee; }
13   - body>div { border-bottom:1px solid #ddd; }
14   - h1 { font-weight:normal; margin-bottom:.4em; }
15   - h1 span { font-size:60%; color:#666; font-weight:normal; }
16   - table { border:none; border-collapse: collapse; width:100%; }
17   - td, th { vertical-align:top; padding:2px 3px; }
18   - th { width:12em; text-align:right; color:#666; padding-right:.5em; }
19   - #info { background:#f6f6f6; }
20   - #info ol { margin: 0.5em 4em; }
21   - #info ol li { font-family: monospace; }
22   - #summary { background: #ffc; }
23   - #explanation { background:#eee; border-bottom: 0px none; }
24   - ]]>
  8 + <
  9 + !
  10 + [CDATA[
  11 + html * {
  12 + padding: 0;
  13 + margin: 0;
  14 + }
  15 +
  16 + body * {
  17 + padding: 10px 20px;
  18 + }
  19 +
  20 + body * * {
  21 + padding: 0;
  22 + }
  23 +
  24 + body {
  25 + font: small sans-serif;
  26 + background: #eee;
  27 + }
  28 +
  29 + body > div {
  30 + border-bottom: 1px solid #ddd;
  31 + }
  32 +
  33 + h1 {
  34 + font-weight: normal;
  35 + margin-bottom: .4em;
  36 + }
  37 +
  38 + h1 span {
  39 + font-size: 60%;
  40 + color: #666;
  41 + font-weight: normal;
  42 + }
  43 +
  44 + table {
  45 + border: none;
  46 + border-collapse: collapse;
  47 + width: 100%;
  48 + }
  49 +
  50 + td, th {
  51 + vertical-align: top;
  52 + padding: 2px 3px;
  53 + }
  54 +
  55 + th {
  56 + width: 12em;
  57 + text-align: right;
  58 + color: #666;
  59 + padding-right: .5em;
  60 + }
  61 +
  62 + #info {
  63 + background: #f6f6f6;
  64 + }
  65 +
  66 + #info ol {
  67 + margin: 0.5em 4em;
  68 + }
  69 +
  70 + #info ol li {
  71 + font-family: monospace;
  72 + }
  73 +
  74 + #summary {
  75 + background: #ffc;
  76 + }
  77 +
  78 + #explanation {
  79 + background: #eee;
  80 + border-bottom: 0px none;
  81 + }
  82 +
  83 + ]
  84 + ]
  85 + >
25 86 </style>
26 87 </head>
27 88 <body>
28   - <div id="summary">
29   - <h1>Comment post not allowed <span>(400)</span></h1>
30   - <table class="meta">
31   - <tr>
32   - <th>Why:</th>
33   - <td>{{ why }}</td>
34   - </tr>
35   - </table>
36   - </div>
37   - <div id="info">
38   - <p>
  89 +<div id="summary">
  90 + <h1>Comment post not allowed <span>(400)</span></h1>
  91 + <table class="meta">
  92 + <tr>
  93 + <th>Why:</th>
  94 + <td>{{ why }}</td>
  95 + </tr>
  96 + </table>
  97 +</div>
  98 +<div id="info">
  99 + <p>
39 100 The comment you tried to post to this view wasn't saved because something
40 101 tampered with the security information in the comment form. The message
41 102 above should explain the problem, or you can check the <a
42   - href="http://docs.djangoproject.com/en/dev/ref/contrib/comments/">comment
  103 + href="http://docs.djangoproject.com/en/dev/ref/contrib/comments/">comment
43 104 documentation</a> for more help.
44   - </p>
45   - </div>
46   -
47   - <div id="explanation">
48   - <p>
49   - You're seeing this error because you have <code>DEBUG = True</code> in
50   - your Django settings file. Change that to <code>False</code>, and Django
51   - will display a standard 400 error page.
52   - </p>
53   - </div>
  105 + </p>
  106 +</div>
  107 +
  108 +<div id="explanation">
  109 + <p>
  110 + You're seeing this error because you have <code>DEBUG = True</code> in
  111 + your Django settings file. Change that to <code>False</code>, and Django
  112 + will display a standard 400 error page.
  113 + </p>
  114 +</div>
54 115 </body>
55 116 </html>
... ...
... ... @@ -7,9 +7,10 @@
7 7 <h1>{% trans "Really make this comment public?" %}</h1>
8 8 <blockquote>{{ comment|linebreaks }}</blockquote>
9 9 <form action="." method="post">{% csrf_token %}
10   - {% if next %}<div><input type="hidden" name="next" value="{{ next }}" id="next" /></div>{% endif %}
  10 + {% if next %}
  11 + <div><input type="hidden" name="next" value="{{ next }}" id="next"/></div>{% endif %}
11 12 <p class="submit">
12   - <input type="submit" name="submit" value="{% trans "Approve" %}" /> or <a href="{{ comment.get_absolute_url }}">cancel</a>
  13 + <input type="submit" name="submit" value="{% trans "Approve" %}"/> or <a href="{{ comment.get_absolute_url }}">cancel</a>
13 14 </p>
14 15 </form>
15 16 {% endblock %}
... ...
1 1 <!DOCTYPE html>
2 2 <html>
3 3 <head>
4   - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  4 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5 5 <title>{% block title %}{% endblock %}</title>
6 6 </head>
7 7 <body>
8   - {% block content %}{% endblock %}
  8 +{% block content %}{% endblock %}
9 9 </body>
10 10 </html>
... ...
... ... @@ -4,12 +4,13 @@
4 4 {% block title %}{% trans "Remove a comment" %}{% endblock %}
5 5
6 6 {% block content %}
7   -<h1>{% trans "Really remove this comment?" %}</h1>
  7 + <h1>{% trans "Really remove this comment?" %}</h1>
8 8 <blockquote>{{ comment|linebreaks }}</blockquote>
9 9 <form action="." method="post">{% csrf_token %}
10   - {% if next %}<div><input type="hidden" name="next" value="{{ next }}" id="next" /></div>{% endif %}
  10 + {% if next %}
  11 + <div><input type="hidden" name="next" value="{{ next }}" id="next"/></div>{% endif %}
11 12 <p class="submit">
12   - <input type="submit" name="submit" value="{% trans "Remove" %}" /> or <a href="{{ comment.get_absolute_url }}">cancel</a>
  13 + <input type="submit" name="submit" value="{% trans "Remove" %}"/> or <a href="{{ comment.get_absolute_url }}">cancel</a>
13 14 </p>
14 15 </form>
15 16 {% endblock %}
... ...
... ... @@ -4,12 +4,14 @@
4 4 {% block title %}{% trans "Flag this comment" %}{% endblock %}
5 5
6 6 {% block content %}
7   -<h1>{% trans "Really flag this comment?" %}</h1>
  7 + <h1>{% trans "Really flag this comment?" %}</h1>
8 8 <blockquote>{{ comment|linebreaks }}</blockquote>
9 9 <form action="." method="post">{% csrf_token %}
10   - {% if next %}<div><input type="hidden" name="next" value="{{ next }}" id="next" /></div>{% endif %}
  10 + {% if next %}
  11 + <div><input type="hidden" name="next" value="{{ next }}" id="next"/></div>{% endif %}
11 12 <p class="submit">
12   - <input type="submit" name="submit" value="{% trans "Flag" %}" /> or <a href="{{ comment.get_absolute_url }}">cancel</a>
  13 + <input type="submit" name="submit" value="{% trans "Flag" %}"/> or <a
  14 + href="{{ comment.get_absolute_url }}">cancel</a>
13 15 </p>
14 16 </form>
15 17 {% endblock %}
... ...
1 1 {% load comments i18n %}
2 2 <form action="{% comment_form_target %}" method="post">{% csrf_token %}
3   - {% if next %}<div><input type="hidden" name="next" value="{{ next }}" /></div>{% endif %}
  3 + {% if next %}
  4 + <div><input type="hidden" name="next" value="{{ next }}"/></div>{% endif %}
4 5 {% for field in form %}
5 6 {% if field.is_hidden %}
6 7 <div>{{ field }}</div>
7 8 {% else %}
8 9 {% if field.errors %}{{ field.errors }}{% endif %}
9 10 <p
10   - {% if field.errors %} class="error"{% endif %}
11   - {% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}>
  11 + {% if field.errors %} class="error"{% endif %}
  12 + {% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}>
12 13 {{ field.label_tag }} {{ field }}
13 14 </p>
14 15 {% endif %}
15 16 {% endfor %}
16 17 <p class="submit">
17   - <input type="submit" name="post" class="submit-post" value="{% trans "Post" %}" />
18   - <input type="submit" name="preview" class="submit-preview" value="{% trans "Preview" %}" />
  18 + <input type="submit" name="post" class="submit-post" value="{% trans "Post" %}"/>
  19 + <input type="submit" name="preview" class="submit-preview" value="{% trans "Preview" %}"/>
19 20 </p>
20 21 </form>
... ...
1 1 <dl id="comments">
2 2 {% for comment in comment_list %}
3 3 <dt id="c{{ comment.id }}">
4   - {{ comment.submit_date }} - {{ comment.name }}
  4 + {{ comment.submit_date }} - {{ comment.name }}
5 5 </dt>
6 6 <dd>
7   - <p>{{ comment.comment }}</p>
  7 + <p>{{ comment.comment }}</p>
8 8 </dd>
9 9 {% endfor %}
10 10 </dl>
... ...
... ... @@ -6,14 +6,17 @@
6 6 {% block content %}
7 7 {% load comments %}
8 8 <form action="{% comment_form_target %}" method="post">{% csrf_token %}
9   - {% if next %}<div><input type="hidden" name="next" value="{{ next }}" /></div>{% endif %}
  9 + {% if next %}
  10 + <div><input type="hidden" name="next" value="{{ next }}"/></div>{% endif %}
10 11 {% if form.errors %}
11   - <h1>{% blocktrans count counter=form.errors|length %}Please correct the error below{% plural %}Please correct the errors below{% endblocktrans %}</h1>
  12 + <h1>{% blocktrans count counter=form.errors|length %}Please correct the error below{% plural %}Please correct the
  13 + errors below{% endblocktrans %}</h1>
12 14 {% else %}
13   - <h1>{% trans "Preview your comment" %}</h1>
  15 + <h1>{% trans "Preview your comment" %}</h1>
14 16 <blockquote>{{ comment|linebreaks }}</blockquote>
15 17 <p>
16   - {% trans "and" %} <input type="submit" name="submit" class="submit-post" value="{% trans "Post your comment" %}" id="submit" /> {% trans "or make changes" %}:
  18 + {% trans "and" %} <input type="submit" name="submit" class="submit-post" value="{% trans "Post your comment" %}"
  19 + id="submit"/> {% trans "or make changes" %}:
17 20 </p>
18 21 {% endif %}
19 22 {% for field in form %}
... ... @@ -22,15 +25,15 @@
22 25 {% else %}
23 26 {% if field.errors %}{{ field.errors }}{% endif %}
24 27 <p
25   - {% if field.errors %} class="error"{% endif %}
26   - {% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}>
  28 + {% if field.errors %} class="error"{% endif %}
  29 + {% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}>
27 30 {{ field.label_tag }} {{ field }}
28 31 </p>
29 32 {% endif %}
30 33 {% endfor %}
31 34 <p class="submit">
32   - <input type="submit" name="submit" class="submit-post" value="{% trans "Post" %}" />
33   - <input type="submit" name="preview" class="submit-preview" value="{% trans "Preview" %}" />
  35 + <input type="submit" name="submit" class="submit-post" value="{% trans "Post" %}"/>
  36 + <input type="submit" name="preview" class="submit-preview" value="{% trans "Preview" %}"/>
34 37 </p>
35 38 </form>
36 39 {% endblock %}
... ...
... ... @@ -28,8 +28,8 @@ class BaseCommentNode(template.Node):
28 28 if tokens[3] != 'as':
29 29 raise template.TemplateSyntaxError("Third argument in %r must be 'as'" % tokens[0])
30 30 return cls(
31   - object_expr = parser.compile_filter(tokens[2]),
32   - as_varname = tokens[4],
  31 + object_expr=parser.compile_filter(tokens[2]),
  32 + as_varname=tokens[4],
33 33 )
34 34
35 35 # {% get_whatever for app.model pk as varname %}
... ... @@ -37,9 +37,9 @@ class BaseCommentNode(template.Node):
37 37 if tokens[4] != 'as':
38 38 raise template.TemplateSyntaxError("Fourth argument in %r must be 'as'" % tokens[0])
39 39 return cls(
40   - ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]),
41   - object_pk_expr = parser.compile_filter(tokens[3]),
42   - as_varname = tokens[5]
  40 + ctype=BaseCommentNode.lookup_content_type(tokens[2], tokens[0]),
  41 + object_pk_expr=parser.compile_filter(tokens[3]),
  42 + as_varname=tokens[5]
43 43 )
44 44
45 45 else:
... ... @@ -57,7 +57,8 @@ class BaseCommentNode(template.Node):
57 57
58 58 def __init__(self, ctype=None, object_pk_expr=None, object_expr=None, as_varname=None, comment=None):
59 59 if ctype is None and object_expr is None:
60   - raise template.TemplateSyntaxError("Comment nodes must be given either a literal object or a ctype and object pk.")
  60 + raise template.TemplateSyntaxError(
  61 + "Comment nodes must be given either a literal object or a ctype and object pk.")
61 62 self.comment_model = django_comments.get_model()
62 63 self.as_varname = as_varname
63 64 self.ctype = ctype
... ... @@ -76,9 +77,9 @@ class BaseCommentNode(template.Node):
76 77 return self.comment_model.objects.none()
77 78
78 79 qs = self.comment_model.objects.filter(
79   - content_type = ctype,
80   - object_pk = smart_text(object_pk),
81   - site__pk = settings.SITE_ID,
  80 + content_type=ctype,
  81 + object_pk=smart_text(object_pk),
  82 + site__pk=settings.SITE_ID,
82 83 )
83 84
84 85 # The is_public and is_removed fields are implementation details of the
... ... @@ -107,16 +108,21 @@ class BaseCommentNode(template.Node):
107 108 """Subclasses should override this."""
108 109 raise NotImplementedError
109 110
  111 +
110 112 class CommentListNode(BaseCommentNode):
111 113 """Insert a list of comments into the context."""
  114 +
112 115 def get_context_value_from_queryset(self, context, qs):
113 116 return list(qs)
114 117
  118 +
115 119 class CommentCountNode(BaseCommentNode):
116 120 """Insert a count of comments into the context."""
  121 +
117 122 def get_context_value_from_queryset(self, context, qs):
118 123 return qs.count()
119 124
  125 +
120 126 class CommentFormNode(BaseCommentNode):
121 127 """Insert a form for the comment model into the context."""
122 128
... ... @@ -135,13 +141,14 @@ class CommentFormNode(BaseCommentNode):
135 141 return None
136 142 else:
137 143 object_pk = self.object_pk_expr.resolve(context,
138   - ignore_failures=True)
  144 + ignore_failures=True)
139 145 return self.ctype.get_object_for_this_type(pk=object_pk)
140 146
141 147 def render(self, context):
142 148 context[self.as_varname] = self.get_form(context)
143 149 return ''
144 150
  151 +
145 152 class RenderCommentFormNode(CommentFormNode):
146 153 """Render the comment form directly"""
147 154
... ... @@ -159,8 +166,8 @@ class RenderCommentFormNode(CommentFormNode):
159 166 # {% render_comment_form for app.models pk %}
160 167 elif len(tokens) == 4:
161 168 return cls(
162   - ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]),
163   - object_pk_expr = parser.compile_filter(tokens[3])
  169 + ctype=BaseCommentNode.lookup_content_type(tokens[2], tokens[0]),
  170 + object_pk_expr=parser.compile_filter(tokens[3])
164 171 )
165 172
166 173 def render(self, context):
... ... @@ -172,12 +179,13 @@ class RenderCommentFormNode(CommentFormNode):
172 179 "comments/form.html"
173 180 ]
174 181 context.push()
175   - formstr = render_to_string(template_search_list, {"form" : self.get_form(context)}, context)
  182 + formstr = render_to_string(template_search_list, {"form": self.get_form(context)}, context)
176 183 context.pop()
177 184 return formstr
178 185 else:
179 186 return ''
180 187
  188 +
181 189 class RenderCommentListNode(CommentListNode):
182 190 """Render the comment list directly"""
183 191
... ... @@ -195,8 +203,8 @@ class RenderCommentListNode(CommentListNode):
195 203 # {% render_comment_list for app.models pk %}
196 204 elif len(tokens) == 4:
197 205 return cls(
198   - ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]),
199   - object_pk_expr = parser.compile_filter(tokens[3])
  206 + ctype=BaseCommentNode.lookup_content_type(tokens[2], tokens[0]),
  207 + object_pk_expr=parser.compile_filter(tokens[3])
200 208 )
201 209
202 210 def render(self, context):
... ... @@ -210,13 +218,14 @@ class RenderCommentListNode(CommentListNode):
210 218 qs = self.get_queryset(context)
211 219 context.push()
212 220 liststr = render_to_string(template_search_list, {
213   - "comment_list" : self.get_context_value_from_queryset(context, qs)
  221 + "comment_list": self.get_context_value_from_queryset(context, qs)
214 222 }, context)
215 223 context.pop()
216 224 return liststr
217 225 else:
218 226 return ''
219 227
  228 +
220 229 # We could just register each classmethod directly, but then we'd lose out on
221 230 # the automagic docstrings-into-admin-docs tricks. So each node gets a cute
222 231 # wrapper function that just exists to hold the docstring.
... ... @@ -242,6 +251,7 @@ def get_comment_count(parser, token):
242 251 """
243 252 return CommentCountNode.handle_token(parser, token)
244 253
  254 +
245 255 @register.tag
246 256 def get_comment_list(parser, token):
247 257 """
... ... @@ -264,6 +274,7 @@ def get_comment_list(parser, token):
264 274 """
265 275 return CommentListNode.handle_token(parser, token)
266 276
  277 +
267 278 @register.tag
268 279 def render_comment_list(parser, token):
269 280 """
... ... @@ -282,6 +293,7 @@ def render_comment_list(parser, token):
282 293 """
283 294 return RenderCommentListNode.handle_token(parser, token)
284 295
  296 +
285 297 @register.tag
286 298 def get_comment_form(parser, token):
287 299 """
... ... @@ -294,6 +306,7 @@ def get_comment_form(parser, token):
294 306 """
295 307 return CommentFormNode.handle_token(parser, token)
296 308
  309 +
297 310 @register.tag
298 311 def render_comment_form(parser, token):
299 312 """
... ... @@ -307,6 +320,7 @@ def render_comment_form(parser, token):
307 320 """
308 321 return RenderCommentFormNode.handle_token(parser, token)
309 322
  323 +
310 324 @register.simple_tag
311 325 def comment_form_target():
312 326 """
... ... @@ -318,6 +332,7 @@ def comment_form_target():
318 332 """
319 333 return django_comments.get_form_target()
320 334
  335 +
321 336 @register.simple_tag
322 337 def get_comment_permalink(comment, anchor_pattern=None):
323 338 """
... ... @@ -331,4 +346,3 @@ def get_comment_permalink(comment, anchor_pattern=None):
331 346 if anchor_pattern:
332 347 return comment.get_absolute_url(anchor_pattern)
333 348 return comment.get_absolute_url()
334   -
... ...
1 1 from django.conf.urls import patterns, url
2 2
3 3 urlpatterns = patterns('django_comments.views',
4   - url(r'^post/$', 'comments.post_comment', name='comments-post-comment'),
5   - url(r'^posted/$', 'comments.comment_done', name='comments-comment-done'),
6   - url(r'^flag/(\d+)/$', 'moderation.flag', name='comments-flag'),
7   - url(r'^flagged/$', 'moderation.flag_done', name='comments-flag-done'),
8   - url(r'^delete/(\d+)/$', 'moderation.delete', name='comments-delete'),
9   - url(r'^deleted/$', 'moderation.delete_done', name='comments-delete-done'),
10   - url(r'^approve/(\d+)/$', 'moderation.approve', name='comments-approve'),
11   - url(r'^approved/$', 'moderation.approve_done', name='comments-approve-done'),
  4 + url(r'^post/$', 'comments.post_comment', name='comments-post-comment'),
  5 + url(r'^posted/$', 'comments.comment_done', name='comments-comment-done'),
  6 + url(r'^flag/(\d+)/$', 'moderation.flag', name='comments-flag'),
  7 + url(r'^flagged/$', 'moderation.flag_done', name='comments-flag-done'),
  8 + url(r'^delete/(\d+)/$', 'moderation.delete', name='comments-delete'),
  9 + url(r'^deleted/$', 'moderation.delete_done', name='comments-delete-done'),
  10 + url(r'^approve/(\d+)/$', 'moderation.approve', name='comments-approve'),
  11 + url(r'^approved/$', 'moderation.approve_done', name='comments-approve-done'),
12 12 )
13 13
14 14 urlpatterns += patterns('',
15   - url(r'^cr/(\d+)/(.+)/$', 'django.contrib.contenttypes.views.shortcut', name='comments-url-redirect'),
  15 + url(r'^cr/(\d+)/(.+)/$', 'django.contrib.contenttypes.views.shortcut',
  16 + name='comments-url-redirect'),
16 17 )
... ...
... ... @@ -15,12 +15,14 @@ import django_comments
15 15 from django_comments import signals
16 16 from django_comments.views.utils import next_redirect, confirmation_view
17 17
  18 +
18 19 class CommentPostBadRequest(http.HttpResponseBadRequest):
19 20 """
20 21 Response returned when a comment post is invalid. If ``DEBUG`` is on a
21 22 nice-ish error message will be displayed (for debugging purposes), but in
22 23 production mode a simple opaque 400 page will be displayed.
23 24 """
  25 +
24 26 def __init__(self, why):
25 27 super(CommentPostBadRequest, self).__init__()
26 28 if settings.DEBUG:
... ... @@ -57,16 +59,15 @@ def post_comment(request, next=None, using=None):
57 59 "Invalid content_type value: %r" % escape(ctype))
58 60 except AttributeError:
59 61 return CommentPostBadRequest(
60   - "The given content-type %r does not resolve to a valid model." % \
61   - escape(ctype))
  62 + "The given content-type %r does not resolve to a valid model." % escape(ctype))
62 63 except ObjectDoesNotExist:
63 64 return CommentPostBadRequest(
64   - "No object matching content-type %r and object PK %r exists." % \
65   - (escape(ctype), escape(object_pk)))
  65 + "No object matching content-type %r and object PK %r exists." % (
  66 + escape(ctype), escape(object_pk)))
66 67 except (ValueError, ValidationError) as e:
67 68 return CommentPostBadRequest(
68   - "Attempting go get content-type %r and object PK %r exists raised %s" % \
69   - (escape(ctype), escape(object_pk), e.__class__.__name__))
  69 + "Attempting go get content-type %r and object PK %r exists raised %s" % (
  70 + escape(ctype), escape(object_pk), e.__class__.__name__))
70 71
71 72 # Do we want to preview the comment?
72 73 preview = "preview" in data
... ... @@ -77,8 +78,7 @@ def post_comment(request, next=None, using=None):
77 78 # Check security information
78 79 if form.security_errors():
79 80 return CommentPostBadRequest(
80   - "The comment form failed security verification: %s" % \
81   - escape(str(form.security_errors())))
  81 + "The comment form failed security verification: %s" % escape(str(form.security_errors())))
82 82
83 83 # If there are errors or if we requested a preview show the comment
84 84 if form.errors or preview:
... ... @@ -116,7 +116,7 @@ def post_comment(request, next=None, using=None):
116 116 )
117 117
118 118 for (receiver, response) in responses:
119   - if response == False:
  119 + if response is False:
120 120 return CommentPostBadRequest(
121 121 "comment_will_be_posted receiver %r killed the comment" % receiver.__name__)
122 122
... ... @@ -129,7 +129,8 @@ def post_comment(request, next=None, using=None):
129 129 )
130 130
131 131 return next_redirect(request, fallback=next or 'comments-comment-done',
132   - c=comment._get_pk_val())
  132 + c=comment._get_pk_val())
  133 +
133 134
134 135 comment_done = confirmation_view(
135 136 template="comments/posted.html",
... ...
... ... @@ -10,6 +10,7 @@ import django_comments
10 10 from django_comments import signals
11 11 from django_comments.views.utils import next_redirect, confirmation_view
12 12
  13 +
13 14 @csrf_protect
14 15 @login_required
15 16 def flag(request, comment_id, next=None):
... ... @@ -27,15 +28,17 @@ def flag(request, comment_id, next=None):
27 28 if request.method == 'POST':
28 29 perform_flag(request, comment)
29 30 return next_redirect(request, fallback=next or 'comments-flag-done',
30   - c=comment.pk)
  31 + c=comment.pk)
31 32
32 33 # Render a form on GET
33 34 else:
34   - return render_to_response('comments/flag.html',
  35 + return render_to_response(
  36 + 'comments/flag.html',
35 37 {'comment': comment, "next": next},
36 38 template.RequestContext(request)
37 39 )
38 40
  41 +
39 42 @csrf_protect
40 43 @permission_required("django_comments.can_moderate")
41 44 def delete(request, comment_id, next=None):
... ... @@ -55,15 +58,17 @@ def delete(request, comment_id, next=None):
55 58 # Flag the comment as deleted instead of actually deleting it.
56 59 perform_delete(request, comment)
57 60 return next_redirect(request, fallback=next or 'comments-delete-done',
58   - c=comment.pk)
  61 + c=comment.pk)
59 62
60 63 # Render a form on GET
61 64 else:
62   - return render_to_response('comments/delete.html',
  65 + return render_to_response(
  66 + 'comments/delete.html',
63 67 {'comment': comment, "next": next},
64 68 template.RequestContext(request)
65 69 )
66 70
  71 +
67 72 @csrf_protect
68 73 @permission_required("django_comments.can_moderate")
69 74 def approve(request, comment_id, next=None):
... ... @@ -83,15 +88,17 @@ def approve(request, comment_id, next=None):
83 88 # Flag the comment as approved.
84 89 perform_approve(request, comment)
85 90 return next_redirect(request, fallback=next or 'comments-approve-done',
86   - c=comment.pk)
  91 + c=comment.pk)
87 92
88 93 # Render a form on GET
89 94 else:
90   - return render_to_response('comments/approve.html',
  95 + return render_to_response(
  96 + 'comments/approve.html',
91 97 {'comment': comment, "next": next},
92 98 template.RequestContext(request)
93 99 )
94 100
  101 +
95 102 # The following functions actually perform the various flag/aprove/delete
96 103 # actions. They've been broken out into separate functions to that they
97 104 # may be called from admin actions.
... ... @@ -101,40 +108,41 @@ def perform_flag(request, comment):
101 108 Actually perform the flagging of a comment from a request.
102 109 """
103 110 flag, created = django_comments.models.CommentFlag.objects.get_or_create(
104   - comment = comment,
105   - user = request.user,
106   - flag = django_comments.models.CommentFlag.SUGGEST_REMOVAL
  111 + comment=comment,
  112 + user=request.user,
  113 + flag=django_comments.models.CommentFlag.SUGGEST_REMOVAL
107 114 )
108 115 signals.comment_was_flagged.send(
109   - sender = comment.__class__,
110   - comment = comment,
111   - flag = flag,
112   - created = created,
113   - request = request,
  116 + sender=comment.__class__,
  117 + comment=comment,
  118 + flag=flag,
  119 + created=created,
  120 + request=request,
114 121 )
115 122
  123 +
116 124 def perform_delete(request, comment):
117 125 flag, created = django_comments.models.CommentFlag.objects.get_or_create(
118   - comment = comment,
119   - user = request.user,
120   - flag = django_comments.models.CommentFlag.MODERATOR_DELETION
  126 + comment=comment,
  127 + user=request.user,
  128 + flag=django_comments.models.CommentFlag.MODERATOR_DELETION
121 129 )
122 130 comment.is_removed = True
123 131 comment.save()
124 132 signals.comment_was_flagged.send(
125   - sender = comment.__class__,
126   - comment = comment,
127   - flag = flag,
128   - created = created,
129   - request = request,
  133 + sender=comment.__class__,
  134 + comment=comment,
  135 + flag=flag,
  136 + created=created,
  137 + request=request,
130 138 )
131 139
132 140
133 141 def perform_approve(request, comment):
134 142 flag, created = django_comments.models.CommentFlag.objects.get_or_create(
135   - comment = comment,
136   - user = request.user,
137   - flag = django_comments.models.CommentFlag.MODERATOR_APPROVAL,
  143 + comment=comment,
  144 + user=request.user,
  145 + flag=django_comments.models.CommentFlag.MODERATOR_APPROVAL,
138 146 )
139 147
140 148 comment.is_removed = False
... ... @@ -142,24 +150,24 @@ def perform_approve(request, comment):
142 150 comment.save()
143 151
144 152 signals.comment_was_flagged.send(
145   - sender = comment.__class__,
146   - comment = comment,
147   - flag = flag,
148   - created = created,
149   - request = request,
  153 + sender=comment.__class__,
  154 + comment=comment,
  155 + flag=flag,
  156 + created=created,
  157 + request=request,
150 158 )
151 159
152 160 # Confirmation views.
153 161
154 162 flag_done = confirmation_view(
155   - template = "comments/flagged.html",
156   - doc = 'Displays a "comment was flagged" success page.'
  163 + template="comments/flagged.html",
  164 + doc='Displays a "comment was flagged" success page.'
157 165 )
158 166 delete_done = confirmation_view(
159   - template = "comments/deleted.html",
160   - doc = 'Displays a "comment was deleted" success page.'
  167 + template="comments/deleted.html",
  168 + doc='Displays a "comment was deleted" success page.'
161 169 )
162 170 approve_done = confirmation_view(
163   - template = "comments/approved.html",
164   - doc = 'Displays a "comment was approved" success page.'
  171 + template="comments/approved.html",
  172 + doc='Displays a "comment was approved" success page.'
165 173 )
... ...
... ... @@ -3,9 +3,10 @@ A few bits of helper functions for comment views.
3 3 """
4 4
5 5 import textwrap
  6 +
6 7 try:
7 8 from urllib.parse import urlencode
8   -except ImportError: # Python 2
  9 +except ImportError: # Python 2
9 10 from urllib import urlencode
10 11
11 12 from django.http import HttpResponseRedirect
... ... @@ -16,6 +17,7 @@ from django.utils.http import is_safe_url
16 17
17 18 import django_comments
18 19
  20 +
19 21 def next_redirect(request, fallback, **get_kwargs):
20 22 """
21 23 Handle the "where should I go next?" part of comment views.
... ... @@ -42,11 +44,13 @@ def next_redirect(request, fallback, **get_kwargs):
42 44 next += joiner + urlencode(get_kwargs) + anchor
43 45 return HttpResponseRedirect(next)
44 46
  47 +
45 48 def confirmation_view(template, doc="Display a confirmation view."):
46 49 """
47 50 Confirmation view generator for the "comment was
48 51 posted/flagged/deleted/approved" views.
49 52 """
  53 +
50 54 def confirmed(request):
51 55 comment = None
52 56 if 'c' in request.GET:
... ... @@ -54,7 +58,8 @@ def confirmation_view(template, doc="Display a confirmation view."):
54 58 comment = django_comments.get_model().objects.get(pk=request.GET['c'])
55 59 except (ObjectDoesNotExist, ValueError):
56 60 pass
57   - return render_to_response(template,
  61 + return render_to_response(
  62 + template,
58 63 {'comment': comment},
59 64 context_instance=RequestContext(request)
60 65 )
... ...
... ... @@ -11,7 +11,8 @@
11 11 # All configuration values have a default; values that are commented out
12 12 # serve to show the default.
13 13
14   -import sys, os
  14 +import os
  15 +import sys
15 16
16 17 # If extensions (or modules to document with autodoc) are in another directory,
17 18 # add these directories to sys.path here. If the directory is relative to the
... ...
  1 +[flake8]
  2 +exclude = docs/*
  3 +ignore = E128
  4 +max-line-length = 119
  5 +
  6 +[wheel]
  7 +universal = 1
... ...
... ... @@ -2,29 +2,35 @@ from django.core import urlresolvers
2 2 from .models import CustomComment
3 3 from .forms import CustomCommentForm
4 4
  5 +
5 6 def get_model():
6 7 return CustomComment
7 8
  9 +
8 10 def get_form():
9 11 return CustomCommentForm
10 12
  13 +
11 14 def get_form_target():
12 15 return urlresolvers.reverse(
13 16 "custom_comments.views.custom_submit_comment"
14 17 )
15 18
  19 +
16 20 def get_flag_url(c):
17 21 return urlresolvers.reverse(
18 22 "custom_comments.views.custom_flag_comment",
19 23 args=(c.id,)
20 24 )
21 25
  26 +
22 27 def get_delete_url(c):
23 28 return urlresolvers.reverse(
24 29 "custom_comments.views.custom_delete_comment",
25 30 args=(c.id,)
26 31 )
27 32
  33 +
28 34 def get_approve_url(c):
29 35 return urlresolvers.reverse(
30 36 "custom_comments.views.custom_approve_comment",
... ...
... ... @@ -4,11 +4,14 @@ from django.http import HttpResponse
4 4 def custom_submit_comment(request):
5 5 return HttpResponse("Hello from the custom submit comment view.")
6 6
  7 +
7 8 def custom_flag_comment(request, comment_id):
8 9 return HttpResponse("Hello from the custom flag view.")
9 10
  11 +
10 12 def custom_delete_comment(request, comment_id):
11 13 return HttpResponse("Hello from the custom delete view.")
12 14
  15 +
13 16 def custom_approve_comment(request, comment_id):
14 17 return HttpResponse("Hello from the custom approve view.")
... ...
... ... @@ -14,8 +14,8 @@ sys.path[0:0] = [here, parent]
14 14
15 15 from django.conf import settings
16 16 settings.configure(
17   - DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3'}},
18   - INSTALLED_APPS = [
  17 + DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3'}},
  18 + INSTALLED_APPS=[
19 19 "django.contrib.auth",
20 20 "django.contrib.contenttypes",
21 21 "django.contrib.sessions",
... ... @@ -30,13 +30,14 @@ settings.configure(
30 30 'django.contrib.auth.middleware.AuthenticationMiddleware',
31 31 'django.contrib.messages.middleware.MessageMiddleware',
32 32 ),
33   - ROOT_URLCONF = 'testapp.urls',
34   - SECRET_KEY = "it's a secret to everyone",
35   - SITE_ID = 1,
  33 + ROOT_URLCONF='testapp.urls',
  34 + SECRET_KEY="it's a secret to everyone",
  35 + SITE_ID=1,
36 36 )
37 37
38 38 from django.test.runner import DiscoverRunner
39 39
  40 +
40 41 def main():
41 42 if django.VERSION >= (1, 7):
42 43 django.setup()
... ...
... ... @@ -17,6 +17,7 @@ class Author(models.Model):
17 17 def __str__(self):
18 18 return '%s %s' % (self.first_name, self.last_name)
19 19
  20 +
20 21 @python_2_unicode_compatible
21 22 class Article(models.Model):
22 23 author = models.ForeignKey(Author)
... ... @@ -25,6 +26,7 @@ class Article(models.Model):
25 26 def __str__(self):
26 27 return self.headline
27 28
  29 +
28 30 @python_2_unicode_compatible
29 31 class Entry(models.Model):
30 32 title = models.CharField(max_length=250)
... ... @@ -35,5 +37,6 @@ class Entry(models.Model):
35 37 def __str__(self):
36 38 return self.title
37 39
  40 +
38 41 class Book(models.Model):
39 42 dewey_decimal = models.DecimalField(primary_key=True, decimal_places=2, max_digits=5)
... ...
... ... @@ -14,70 +14,73 @@ from ..models import Article, Author
14 14 # Shortcut
15 15 CT = ContentType.objects.get_for_model
16 16
17   -# Helper base class for comment tests that need data.
  17 +
18 18 @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.UnsaltedMD5PasswordHasher',))
19 19 class CommentTestCase(TestCase):
  20 + """
  21 + Helper base class for comment tests that need data.
  22 + """
20 23 fixtures = ["comment_tests"]
21 24 urls = 'testapp.urls_default'
22 25
23 26 def createSomeComments(self):
24 27 # Two anonymous comments on two different objects
25 28 c1 = Comment.objects.create(
26   - content_type = CT(Article),
27   - object_pk = "1",
28   - user_name = "Joe Somebody",
29   - user_email = "jsomebody@example.com",
30   - user_url = "http://example.com/~joe/",
31   - comment = "First!",
32   - site = Site.objects.get_current(),
  29 + content_type=CT(Article),
  30 + object_pk="1",
  31 + user_name="Joe Somebody",
  32 + user_email="jsomebody@example.com",
  33 + user_url="http://example.com/~joe/",
  34 + comment="First!",
  35 + site=Site.objects.get_current(),
33 36 )
34 37 c2 = Comment.objects.create(
35   - content_type = CT(Author),
36   - object_pk = "1",
37   - user_name = "Joe Somebody",
38   - user_email = "jsomebody@example.com",
39   - user_url = "http://example.com/~joe/",
40   - comment = "First here, too!",
41   - site = Site.objects.get_current(),
  38 + content_type=CT(Author),
  39 + object_pk="1",
  40 + user_name="Joe Somebody",
  41 + user_email="jsomebody@example.com",
  42 + user_url="http://example.com/~joe/",
  43 + comment="First here, too!",
  44 + site=Site.objects.get_current(),
42 45 )
43 46
44 47 # Two authenticated comments: one on the same Article, and
45 48 # one on a different Author
46 49 user = User.objects.create(
47   - username = "frank_nobody",
48   - first_name = "Frank",
49   - last_name = "Nobody",
50   - email = "fnobody@example.com",
51   - password = "",
52   - is_staff = False,
53   - is_active = True,
54   - is_superuser = False,
  50 + username="frank_nobody",
  51 + first_name="Frank",
  52 + last_name="Nobody",
  53 + email="fnobody@example.com",
  54 + password="",
  55 + is_staff=False,
  56 + is_active=True,
  57 + is_superuser=False,
55 58 )
56 59 c3 = Comment.objects.create(
57   - content_type = CT(Article),
58   - object_pk = "1",
59   - user = user,
60   - user_url = "http://example.com/~frank/",
61   - comment = "Damn, I wanted to be first.",
62   - site = Site.objects.get_current(),
  60 + content_type=CT(Article),
  61 + object_pk="1",
  62 + user=user,
  63 + user_url="http://example.com/~frank/",
  64 + comment="Damn, I wanted to be first.",
  65 + site=Site.objects.get_current(),
63 66 )
64 67 c4 = Comment.objects.create(
65   - content_type = CT(Author),
66   - object_pk = "2",
67   - user = user,
68   - user_url = "http://example.com/~frank/",
69   - comment = "You get here first, too?",
70   - site = Site.objects.get_current(),
  68 + content_type=CT(Author),
  69 + object_pk="2",
  70 + user=user,
  71 + user_url="http://example.com/~frank/",
  72 + comment="You get here first, too?",
  73 + site=Site.objects.get_current(),
71 74 )
72 75
73 76 return c1, c2, c3, c4
74 77
75 78 def getData(self):
76 79 return {
77   - 'name' : 'Jim Bob',
78   - 'email' : 'jim.bob@example.com',
79   - 'url' : '',
80   - 'comment' : 'This is my comment',
  80 + 'name': 'Jim Bob',
  81 + 'email': 'jim.bob@example.com',
  82 + 'url': '',
  83 + 'comment': 'This is my comment',
81 84 }
82 85
83 86 def getValidData(self, obj):
... ...
... ... @@ -32,7 +32,7 @@ class CommentAppAPITests(CommentTestCase):
32 32 )
33 33 def testGetMissingCommentApp(self):
34 34 with six.assertRaisesRegex(self, ImproperlyConfigured, 'missing_app'):
35   - _ = django_comments.get_comment_app()
  35 + django_comments.get_comment_app()
36 36
37 37 def testGetForm(self):
38 38 self.assertEqual(django_comments.get_form(), CommentForm)
... ...
... ... @@ -14,25 +14,31 @@ from ..models import Entry
14 14 class EntryModerator1(CommentModerator):
15 15 email_notification = True
16 16
  17 +
17 18 class EntryModerator2(CommentModerator):
18 19 enable_field = 'enable_comments'
19 20
  21 +
20 22 class EntryModerator3(CommentModerator):
21 23 auto_close_field = 'pub_date'
22 24 close_after = 7
23 25
  26 +
24 27 class EntryModerator4(CommentModerator):
25 28 auto_moderate_field = 'pub_date'
26 29 moderate_after = 7
27 30
  31 +
28 32 class EntryModerator5(CommentModerator):
29 33 auto_moderate_field = 'pub_date'
30 34 moderate_after = 0
31 35
  36 +
32 37 class EntryModerator6(CommentModerator):
33 38 auto_close_field = 'pub_date'
34 39 close_after = 0
35 40
  41 +
36 42 class CommentUtilsModeratorTests(CommentTestCase):
37 43 fixtures = ["comment_utils.xml"]
38 44
... ...
... ... @@ -14,6 +14,7 @@ from ..models import Article, Book
14 14
15 15 post_redirect_re = re.compile(r'^http://testserver/posted/\?c=(?P<pk>\d+$)')
16 16
  17 +
17 18 class CommentViewTests(CommentTestCase):
18 19
19 20 def testPostCommentHTTPMethods(self):
... ... @@ -214,7 +215,8 @@ class CommentViewTests(CommentTestCase):
214 215 Test that the comment_will_be_posted signal can prevent the comment from
215 216 actually getting saved
216 217 """
217   - def receive(sender, **kwargs): return False
  218 + def receive(sender, **kwargs):
  219 + return False
218 220 signals.comment_will_be_posted.connect(receive, dispatch_uid="comment-test")
219 221 a = Article.objects.get(pk=1)
220 222 data = self.getValidData(a)
... ... @@ -229,7 +231,7 @@ class CommentViewTests(CommentTestCase):
229 231 it gets posted
230 232 """
231 233 def receive(sender, **kwargs):
232   - # a bad but effective spam filter :)...
  234 + # a bad but effective spam filter :)...
233 235 kwargs['comment'].is_public = False
234 236
235 237 signals.comment_will_be_posted.connect(receive)
... ... @@ -244,21 +246,21 @@ class CommentViewTests(CommentTestCase):
244 246 response = self.client.post("/post/", data)
245 247 location = response["Location"]
246 248 match = post_redirect_re.match(location)
247   - self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
  249 + self.assertisNotNone(match, "Unexpected redirect location: %s" % location)
248 250
249 251 data["next"] = "/somewhere/else/"
250 252 data["comment"] = "This is another comment"
251 253 response = self.client.post("/post/", data)
252 254 location = response["Location"]
253 255 match = re.search(r"^http://testserver/somewhere/else/\?c=\d+$", location)
254   - self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
  256 + self.assertIsNotNone(match, "Unexpected redirect location: %s" % location)
255 257
256 258 data["next"] = "http://badserver/somewhere/else/"
257 259 data["comment"] = "This is another comment with an unsafe next url"
258 260 response = self.client.post("/post/", data)
259 261 location = response["Location"]
260 262 match = post_redirect_re.match(location)
261   - self.assertTrue(match != None, "Unsafe redirection to: %s" % location)
  263 + self.assertIsNotNone(match, "Unsafe redirection to: %s" % location)
262 264
263 265 def testCommentDoneView(self):
264 266 a = Article.objects.get(pk=1)
... ... @@ -266,7 +268,7 @@ class CommentViewTests(CommentTestCase):
266 268 response = self.client.post("/post/", data)
267 269 location = response["Location"]
268 270 match = post_redirect_re.match(location)
269   - self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
  271 + self.assertIsNotNone(match, "Unexpected redirect location: %s" % location)
270 272 pk = int(match.group('pk'))
271 273 response = self.client.get(location)
272 274 self.assertTemplateUsed(response, "comments/posted.html")
... ... @@ -283,7 +285,7 @@ class CommentViewTests(CommentTestCase):
283 285 response = self.client.post("/post/", data)
284 286 location = response["Location"]
285 287 match = re.search(r"^http://testserver/somewhere/else/\?foo=bar&c=\d+$", location)
286   - self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
  288 + self.assertIsNotNone(match, "Unexpected redirect location: %s" % location)
287 289
288 290 def testCommentPostRedirectWithInvalidIntegerPK(self):
289 291 """
... ... @@ -312,7 +314,7 @@ class CommentViewTests(CommentTestCase):
312 314 response = self.client.post("/post/", data)
313 315 location = response["Location"]
314 316 match = re.search(r"^http://testserver/somewhere/else/\?foo=bar&c=\d+#baz$", location)
315   - self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
  317 + self.assertIsNotNone(match, "Unexpected redirect location: %s" % location)
316 318
317 319 # Without a query string
318 320 a = Article.objects.get(pk=1)
... ... @@ -322,4 +324,4 @@ class CommentViewTests(CommentTestCase):
322 324 response = self.client.post("/post/", data)
323 325 location = response["Location"]
324 326 match = re.search(r"^http://testserver/somewhere/else/\?c=\d+#baz$", location)
325   - self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
  327 + self.assertIsNotNone(match, "Unexpected redirect location: %s" % location)
... ...
... ... @@ -17,17 +17,17 @@ class CommentFeedTests(CommentTestCase):
17 17 feed_url = '/rss/comments/'
18 18
19 19 def setUp(self):
20   - site_2 = Site.objects.create(id=settings.SITE_ID+1,
  20 + site_2 = Site.objects.create(id=settings.SITE_ID + 1,
21 21 domain="example2.com", name="example2.com")
22 22 # A comment for another site
23   - c5 = Comment.objects.create(
24   - content_type = ContentType.objects.get_for_model(Article),
25   - object_pk = "1",
26   - user_name = "Joe Somebody",
27   - user_email = "jsomebody@example.com",
28   - user_url = "http://example.com/~joe/",
29   - comment = "A comment for the second site.",
30   - site = site_2,
  23 + Comment.objects.create(
  24 + content_type=ContentType.objects.get_for_model(Article),
  25 + object_pk="1",
  26 + user_name="Joe Somebody",
  27 + user_email="jsomebody@example.com",
  28 + user_url="http://example.com/~joe/",
  29 + comment="A comment for the second site.",
  30 + site=site_2,
31 31 )
32 32
33 33 def test_feed(self):
... ...
... ... @@ -20,6 +20,7 @@ class CommentModelTests(CommentTestCase):
20 20 self.assertEqual(c1.user, None)
21 21 self.assertEqual(c3.user, c4.user)
22 22
  23 +
23 24 class CommentManagerTests(CommentTestCase):
24 25
25 26 def testInModeration(self):
... ...
... ... @@ -96,12 +96,14 @@ class FlagViewTests(CommentTestCase):
96 96
97 97 signals.comment_was_flagged.disconnect(receive)
98 98
  99 +
99 100 def makeModerator(username):
100 101 u = User.objects.get(username=username)
101 102 ct = ContentType.objects.get_for_model(Comment)
102 103 p = Permission.objects.get(content_type=ct, codename="can_moderate")
103 104 u.user_permissions.add(p)
104 105
  106 +
105 107 class DeleteViewTests(CommentTestCase):
106 108
107 109 def testDeletePermissions(self):
... ... @@ -175,6 +177,7 @@ class DeleteViewTests(CommentTestCase):
175 177 response = self.client.get("/deleted/", data={"c": pk})
176 178 self.assertTemplateUsed(response, "comments/deleted.html")
177 179
  180 +
178 181 class ApproveViewTests(CommentTestCase):
179 182
180 183 def testApprovePermissions(self):
... ... @@ -192,7 +195,8 @@ class ApproveViewTests(CommentTestCase):
192 195 def testApprovePost(self):
193 196 """POSTing the approve view should mark the comment as removed"""
194 197 c1, c2, c3, c4 = self.createSomeComments()
195   - c1.is_public = False; c1.save()
  198 + c1.is_public = False
  199 + c1.save()
196 200
197 201 makeModerator("normaluser")
198 202 self.client.login(username="normaluser", password="normaluser")
... ... @@ -208,7 +212,8 @@ class ApproveViewTests(CommentTestCase):
208 212 url.
209 213 """
210 214 c1, c2, c3, c4 = self.createSomeComments()
211   - c1.is_public = False; c1.save()
  215 + c1.is_public = False
  216 + c1.save()
212 217
213 218 makeModerator("normaluser")
214 219 self.client.login(username="normaluser", password="normaluser")
... ... @@ -223,7 +228,8 @@ class ApproveViewTests(CommentTestCase):
223 228 provided url when redirecting.
224 229 """
225 230 c1, c2, c3, c4 = self.createSomeComments()
226   - c1.is_public = False; c1.save()
  231 + c1.is_public = False
  232 + c1.save()
227 233
228 234 makeModerator("normaluser")
229 235 self.client.login(username="normaluser", password="normaluser")
... ... @@ -249,9 +255,10 @@ class ApproveViewTests(CommentTestCase):
249 255 def testApprovedView(self):
250 256 comments = self.createSomeComments()
251 257 pk = comments[0].pk
252   - response = self.client.get("/approved/", data={"c":pk})
  258 + response = self.client.get("/approved/", data={"c": pk})
253 259 self.assertTemplateUsed(response, "comments/approved.html")
254 260
  261 +
255 262 class AdminActionsTests(CommentTestCase):
256 263 urls = "testapp.urls_admin"
257 264
... ... @@ -262,21 +269,21 @@ class AdminActionsTests(CommentTestCase):
262 269 u = User.objects.get(username="normaluser")
263 270 u.is_staff = True
264 271 perms = Permission.objects.filter(
265   - content_type__app_label = 'django_comments',
266   - codename__endswith = 'comment'
  272 + content_type__app_label='django_comments',
  273 + codename__endswith='comment'
267 274 )
268 275 for perm in perms:
269 276 u.user_permissions.add(perm)
270 277 u.save()
271 278
272 279 def testActionsNonModerator(self):
273   - comments = self.createSomeComments()
  280 + self.createSomeComments()
274 281 self.client.login(username="normaluser", password="normaluser")
275 282 response = self.client.get("/admin/django_comments/comment/")
276 283 self.assertNotContains(response, "approve_comments")
277 284
278 285 def testActionsModerator(self):
279   - comments = self.createSomeComments()
  286 + self.createSomeComments()
280 287 makeModerator("normaluser")
281 288 self.client.login(username="normaluser", password="normaluser")
282 289 response = self.client.get("/admin/django_comments/comment/")
... ... @@ -284,7 +291,7 @@ class AdminActionsTests(CommentTestCase):
284 291
285 292 def testActionsDisabledDelete(self):
286 293 "Tests a CommentAdmin where 'delete_selected' has been disabled."
287   - comments = self.createSomeComments()
  294 + self.createSomeComments()
288 295 self.client.login(username="normaluser", password="normaluser")
289 296 response = self.client.get('/admin2/django_comments/comment/')
290 297 self.assertEqual(response.status_code, 200)
... ... @@ -308,12 +315,18 @@ class AdminActionsTests(CommentTestCase):
308 315 makeModerator("normaluser")
309 316 self.client.login(username="normaluser", password="normaluser")
310 317 with translation.override('en'):
311   - #Test approving
312   - self.performActionAndCheckMessage('approve_comments', one_comment, '1 comment was successfully approved.')
313   - self.performActionAndCheckMessage('approve_comments', many_comments, '3 comments were successfully approved.')
314   - #Test flagging
315   - self.performActionAndCheckMessage('flag_comments', one_comment, '1 comment was successfully flagged.')
316   - self.performActionAndCheckMessage('flag_comments', many_comments, '3 comments were successfully flagged.')
317   - #Test removing
318   - self.performActionAndCheckMessage('remove_comments', one_comment, '1 comment was successfully removed.')
319   - self.performActionAndCheckMessage('remove_comments', many_comments, '3 comments were successfully removed.')
  318 + # Test approving
  319 + self.performActionAndCheckMessage('approve_comments', one_comment,
  320 + '1 comment was successfully approved.')
  321 + self.performActionAndCheckMessage('approve_comments', many_comments,
  322 + '3 comments were successfully approved.')
  323 + # Test flagging
  324 + self.performActionAndCheckMessage('flag_comments', one_comment,
  325 + '1 comment was successfully flagged.')
  326 + self.performActionAndCheckMessage('flag_comments', many_comments,
  327 + '3 comments were successfully flagged.')
  328 + # Test removing
  329 + self.performActionAndCheckMessage('remove_comments', one_comment,
  330 + '1 comment was successfully removed.')
  331 + self.performActionAndCheckMessage('remove_comments', many_comments,
  332 + '3 comments were successfully removed.')
... ...
... ... @@ -12,6 +12,7 @@ from . import CommentTestCase
12 12
13 13 register = Library()
14 14
  15 +
15 16 @register.filter
16 17 def noop(variable, param=None):
17 18 return variable
... ... @@ -87,7 +88,7 @@ class CommentTemplateTagTests(CommentTestCase):
87 88
88 89 def verifyGetCommentList(self, tag=None):
89 90 c1, c2, c3, c4 = Comment.objects.all()[:4]
90   - t = "{% load comments %}" + (tag or "{% get_comment_list for testapp.author a.id as cl %}")
  91 + t = "{% load comments %}" + (tag or "{% get_comment_list for testapp.author a.id as cl %}")
91 92 ctx, out = self.render(t, a=Author.objects.get(pk=1))
92 93 self.assertEqual(out, "")
93 94 self.assertEqual(list(ctx["cl"]), [c2])
... ...
... ... @@ -8,7 +8,7 @@ from custom_comments import views
8 8
9 9
10 10 feeds = {
11   - 'comments': LatestCommentFeed,
  11 + 'comments': LatestCommentFeed,
12 12 }
13 13
14 14 urlpatterns = patterns('',
... ...
Please register or login to post a comment