zinnia.moderator
Covered: 52 lines
Missed: 32 lines
Skipped 13 lines
Percent: 61 %
 1
"""Moderator of Zinnia comments
 2
   Based on Akismet for checking spams."""
 3
from django.conf import settings
 4
from django.template import Context
 5
from django.template import loader
 6
from django.core.mail import send_mail
 7
from django.utils.encoding import smart_str
 8
from django.contrib.sites.models import Site
 9
from django.utils.translation import ugettext_lazy as _
10
from django.contrib.comments.moderation import CommentModerator
12
from zinnia.settings import PROTOCOL
13
from zinnia.settings import MAIL_COMMENT
14
from zinnia.settings import MAIL_COMMENT_REPLY
15
from zinnia.settings import AKISMET_COMMENT
17
AKISMET_API_KEY = getattr(settings, 'AKISMET_SECRET_API_KEY', '')
20
class EntryCommentModerator(CommentModerator):
21
    """Moderate the comment of Entry"""
22
    email_notification = MAIL_COMMENT
23
    email_notification_reply = MAIL_COMMENT_REPLY
24
    enable_field = 'comment_enabled'
26
    def email(self, comment, content_object, request):
27
        if comment.is_public:
28
            super(EntryCommentModerator, self).email(comment, content_object,
29
                                                     request)
30
            self.email_reply(comment, content_object, request)
32
    def email_reply(self, comment, content_object, request):
33
        """Send email notification of a new comment to site staff when email
34
        notifications have been requested."""
35
        if not self.email_notification_reply:
36
            return
38
        if comment.flags.count():
39
            return
41
        exclude_list = [manager_tuple[1] for manager_tuple
42
                        in settings.MANAGERS] + [comment.userinfo['email']]
43
        recipient_list = set([comment.userinfo['email']
44
                              for comment in content_object.comments
45
                              if comment.userinfo['email']]) ^ \
46
                              set(exclude_list)
48
        if recipient_list:
49
            site = Site.objects.get_current()
50
            template = loader.get_template('comments/comment_reply_email.txt')
51
            context = Context({'comment': comment, 'site': site,
52
                               'protocol': PROTOCOL,
53
                               'content_object': content_object})
54
            subject = _('[%(site)s] New comment posted on "%(title)s"') % \
55
                      {'site': site.name,
56
                       'title': content_object.title}
57
            message = template.render(context)
58
            send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
59
                      recipient_list, fail_silently=not settings.DEBUG)
61
    def moderate(self, comment, content_object, request):
62
        """Need to pass Akismet test"""
63
        if not AKISMET_COMMENT or not AKISMET_API_KEY:
64
            return False
66
        try:
67
            from akismet import Akismet
68
            from akismet import APIKeyError
69
        except ImportError:
70
            return False
72
        akismet = Akismet(key=AKISMET_API_KEY,
73
                          blog_url='%s://%s/' % (
74
                              PROTOCOL, Site.objects.get_current().domain))
75
        if akismet.verify_key():
76
            akismet_data = {
77
                'user_ip': request.META.get('REMOTE_ADDR', ''),
78
                'user_agent': request.META.get('HTTP_USER_AGENT', ''),
79
                'referrer': request.META.get('HTTP_REFERER', 'unknown'),
80
                'permalink': content_object.get_absolute_url(),
81
                'comment_type': 'comment',
82
                'comment_author': smart_str(comment.userinfo.get('name', '')),
83
                'comment_author_email': smart_str(comment.userinfo.get(
84
                    'email', '')),
85
                'comment_author_url': smart_str(comment.userinfo.get(
86
                    'url', '')),
87
            }
88
            is_spam = akismet.comment_check(smart_str(comment.comment),
89
                                            data=akismet_data,
90
                                            build_data=True)
91
            if is_spam:
92
                comment.save()
93
                user = comment.content_object.authors.all()[0]
94
                comment.flags.create(user=user, flag='spam')
95
            return is_spam
96
        raise APIKeyError('Your Akismet API key is invalid.')