view gpp/antispam/utils.py @ 260:3a4bbf9c2cce

Fixing #107. Apparently some signal handlers were getting connected twice (double import?) and thus saving a forum post would cause 2 email notifications to go out to the post topic's subscribers. Use the dispatch_uid parameter in the connect call to work around this issue.
author Brian Neal <bgneal@gmail.com>
date Wed, 22 Sep 2010 00:24:59 +0000
parents 8c1832b9d815
children 767cedc7d12a
line wrap: on
line source
"""Antispam utility functions other apps can use."""
import datetime
import logging
import textwrap

from django.core.cache import cache

from antispam import SPAM_PHRASE_KEY
from antispam.models import SpamPhrase
from core.functions import email_admins
from bio.models import STA_SUSPENDED


def contains_spam(s):
    """This function returns True if the supplied string s contains any spam
    phrases and False otherwise.
    """
    phrases = _get_spam_phrases()
    s = s.lower()
    for spam in phrases:
        if spam in s:
            return True

    return False


def spam_check(request, content):
    """This function checks the supplied content for spam if the user from the
    supplied request is a stranger (new to the site). If spam is found, the
    function makes a log entry, emails the admins, suspends the user's account
    and returns True. If spam is not found, False is returned.
    It is assumed that request.user is an authenticated user and thus has a
    user profile.
    """
    user = request.user
    if user.get_profile().is_stranger() and contains_spam(content):

        ip = request.META.get('REMOTE_ADDR', "unknown")

        msg = textwrap.dedent("""\
            SPAM FILTER TRIPPED by %s
            PATH: %s
            IP: %s
            Message:
            %s
            """ % (user.username, request.path, ip, content))

        logging.info(msg)
        email_admins("SPAM FILTER TRIPPED BY %s" % user.username, msg)
        suspend_user(user)
        return True

    return False


def suspend_user(user):
    """This function marks the user as suspended."""
    user.is_active = False
    user.save()
    profile = user.get_profile()
    profile.status = STA_SUSPENDED
    profile.status_date = datetime.datetime.now()
    profile.save()
    

def _get_spam_phrases():
    """This function returns the current list of spam phrase strings.
    The strings are cached to avoid hitting the database.
    """
    phrases = cache.get(SPAM_PHRASE_KEY)
    if phrases:
        return phrases

    phrases = SpamPhrase.objects.values_list('phrase', flat=True)
    cache.set(SPAM_PHRASE_KEY, phrases)
    return phrases