summaryrefslogtreecommitdiffstats
path: root/mycomments/signals.py
blob: 99d2267678dad992fd70b4e97470554863885428 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from django.core import urlresolvers
from django.contrib.sites.models import Site
from django.template.loader import render_to_string

from blog.models import Post
from mycomments.models import MyComment, BannedIP, BannedUserName
from mycomments.utils import akismet_check

def send_comment_by_mail(sender, **kwargs):
    import socket, errno
    comment = kwargs['comment']
    if comment.content_type.model_class() != Post:
        return
    # if the comment has a logged-in user, we don't need an email
    if comment.user:
        return
    post = comment.content_object

    commenturl = 'https://%s%s' % ( Site.objects.get_current().domain,
            comment.get_absolute_url() )
    adminsite = 'https://%s%s' % ( Site.objects.get_current().domain,
            urlresolvers.reverse('admin:mycomments_mycomment_changelist') )
    usercount = MyComment.objects.filter(user_name=comment.user_name).count()
    ipcount = MyComment.objects.filter(ip_address=comment.ip_address).count()
    content = {
        'post': post,
        'comment': comment,
        'commenturl': commenturl,
        'adminsite': adminsite,
        'usercount': usercount,
        'ipcount': ipcount,
    }
    # write out a subject and body
    subject = render_to_string('mycomments/email_subject.txt', content)
    subject = subject.replace('\n', '').replace('\r', '').strip()
    body = render_to_string('mycomments/email_body.txt', content)
    # send the email
    try:
        post.author.email_user(subject, body)
    except socket.error, e:
        # TODO really should have a logger or something here
        if not e.errno == errno.ECONNREFUSED:
            raise e

def check_spam_comment(sender, **kwargs):
    comment = kwargs['comment']
    request = kwargs['request']
    # we shouldn't have comments on anything except Post objects...
    if comment.content_type.model_class() != Post:
        return False
    content_obj = comment.content_object
    if not getattr(content_obj, 'comments_enabled', True):
        return False
    # if the comment has a logged-in user, we don't to check it
    if comment.user:
        return True
    ip_addr = rewrite_ip_address(comment.ip_address)
    ip_exists = BannedIP.objects.filter(ip_address=ip_addr).exists()
    ip_net_exists = BannedIP.objects.extra(where=['%s << ip_address'],
            params=[ip_addr]).exists()
    un_exists = BannedUserName.objects.filter(
            user_name=comment.user_name).exists()
    if ip_exists or ip_net_exists or un_exists:
        # If we found the IP or name in the ban table, this comment is bogus.
        # Returning 'False' will throw a 403 and comment is discarded.
        return False

    # run our Akismet comment checking for things that passed initial check
    spam = akismet_check(request, comment)
    if spam:
        # mark the comment as non-public/bogus
        comment.is_public = False

def rewrite_ip_address(addr):
    """
    Coerce an IPv6 address to IPv4 if possible.
    Examples:
      ::ffff:1.2.3.4 --> 1.2.3.4
      ::1 --> 127.0.0.1
    """
    if addr.startswith('::ffff:'):
        addr = addr[7:]
    if addr == '::1':
        addr = '127.0.0.1'
    return addr

def set_comment_ip_address(sender, **kwargs):
    """
    Run comment.ip_adddress field through the IPv6 rewriter.
    """
    comment = kwargs['instance']
    comment.ip_address = rewrite_ip_address(comment.ip_address)

# vim: set ts=4 sw=4 et: