import logging from django import forms from django.conf import settings from sphene.community import sphutils from akismet import Akismet def check_spam(request, body, author_email = None, author_name = None, author_url = None): """ checks the given body for spam. you might pass in additional information like the user's email address. otherwise best guesses are used. returns True if comment is recognized as spam, False otherwise. """ Akismet.baseurl = settings.AKISMET_BASEURL api = Akismet(settings.AKISMET_API_KEY) if request.user.is_authenticated(): if author_email is None: author_email = request.user.email if author_name is None: author_name = request.user.username data = { 'user_ip': request.META.get('REMOTE_ADDR', '127.0.0.1'), 'user_agent': request.META.get('HTTP_USER_AGENT', ''), 'referrer': request.META.get('HTTP_REFERER', ''), 'comment_type': 'comment', 'comment_author': author_name, 'comment_author_email': author_email, 'comment_author_url': author_url, } try: r = api.comment_check(body, data) logger.debug('checked comment for spam - result: %r (from %s <%s>)' % (r, author_name, author_email)) if r: logger.info("We detected spam!! body: {%s} - data: {%s}" % (body, repr(data))) return r except: logger.exception('Error while checking for spam.') return False class SpamCheckedForm(forms.Form): """ checks the field called 'comment' if it is spam. and if it is recognized as spam, will show a captcha which has to be solved. """ def __init__(self, *args, **kwargs): super(SpamCheckedForm, self).__init__(*args, **kwargs) if self.data.get('captcha_0', False): self._add_captcha_field() def _add_captcha_field(self): self.fields['captcha'] = sphutils.CaptchaField( \ label=u'Captcha', widget=sphutils.CaptchaWidget, help_text = mark_safe(u'Bitte gib das Ergebnis der Rechnung ein.'), ) def clean(self): if not 'captcha' in self.fields: # We only need to to checking if there was no captcha field # in the form already. d = self.cleaned_data body = self.cleaned_data['comment'] if check_spam(get_current_request(), body, author_email = d.get('email', None), author_name = d.get('name', None), author_url = d.get('url', None)): # We got spam :( self.cleaned_data['requires_captcha'] = 1 self._add_captcha_field() self._errors['captcha'] = self.error_class([u'Deine Nachricht wurde als Spam erkannt. Bitte löse das Captcha.']) return self.cleaned_data