bgneal@214: """Antispam utility functions other apps can use."""
bgneal@215: import datetime
bgneal@215: import logging
bgneal@215: import textwrap
bgneal@215: 
bgneal@214: from django.core.cache import cache
bgneal@214: 
bgneal@214: from antispam import SPAM_PHRASE_KEY
bgneal@214: from antispam.models import SpamPhrase
bgneal@215: from core.functions import email_admins
bgneal@215: from bio.models import STA_SUSPENDED
bgneal@214: 
bgneal@214: 
bgneal@214: def contains_spam(s):
bgneal@214:     """This function returns True if the supplied string s contains any spam
bgneal@214:     phrases and False otherwise.
bgneal@214:     """
bgneal@214:     phrases = _get_spam_phrases()
bgneal@215:     s = s.lower()
bgneal@214:     for spam in phrases:
bgneal@214:         if spam in s:
bgneal@214:             return True
bgneal@214: 
bgneal@214:     return False
bgneal@214: 
bgneal@214: 
bgneal@215: def spam_check(request, content):
bgneal@215:     """This function checks the supplied content for spam if the user from the
bgneal@215:     supplied request is a stranger (new to the site). If spam is found, the
bgneal@215:     function makes a log entry, emails the admins, suspends the user's account
bgneal@215:     and returns True. If spam is not found, False is returned.
bgneal@215:     It is assumed that request.user is an authenticated user and thus has a
bgneal@215:     user profile.
bgneal@215:     """
bgneal@215:     user = request.user
bgneal@215:     if user.get_profile().is_stranger() and contains_spam(content):
bgneal@215: 
bgneal@215:         ip = request.META.get('REMOTE_ADDR', "unknown")
bgneal@215: 
bgneal@215:         msg = textwrap.dedent("""\
bgneal@215:             SPAM FILTER TRIPPED by %s
bgneal@215:             PATH: %s
bgneal@215:             IP: %s
bgneal@215:             Message:
bgneal@215:             %s
bgneal@215:             """ % (user.username, request.path, ip, content))
bgneal@215: 
bgneal@215:         logging.info(msg)
bgneal@215:         email_admins("SPAM FILTER TRIPPED BY %s" % user.username, msg)
bgneal@215:         suspend_user(user)
bgneal@215:         return True
bgneal@215: 
bgneal@215:     return False
bgneal@215: 
bgneal@215: 
bgneal@215: def suspend_user(user):
bgneal@215:     """This function marks the user as suspended."""
bgneal@215:     user.is_active = False
bgneal@215:     user.save()
bgneal@215:     profile = user.get_profile()
bgneal@215:     profile.status = STA_SUSPENDED
bgneal@215:     profile.status_date = datetime.datetime.now()
bgneal@215:     profile.save()
bgneal@316: 
bgneal@215: 
bgneal@214: def _get_spam_phrases():
bgneal@214:     """This function returns the current list of spam phrase strings.
bgneal@214:     The strings are cached to avoid hitting the database.
bgneal@214:     """
bgneal@214:     phrases = cache.get(SPAM_PHRASE_KEY)
bgneal@214:     if phrases:
bgneal@214:         return phrases
bgneal@214: 
bgneal@214:     phrases = SpamPhrase.objects.values_list('phrase', flat=True)
bgneal@214:     cache.set(SPAM_PHRASE_KEY, phrases)
bgneal@214:     return phrases