Badword Filter für Kommentare

Veröffentlich am 11.03.2009, 12:56

Mich hat in den letzten Tagen eine heftige Spamwelle erwischt. Da ich die im django.contrib verfügbare Comments App verwende, gibt es neben dem honeypot Feld keinen Spamschutz.

Da mir Rechenaufgaben, Captchas und handische Moderation zu aufwändig sind, werde ich es mit einem Badword Filter versuchen.

Der Filter arbeitet sehr einfach. Über das comment_will_ne_posted Signal wird der Kommentartext auf Badwords überprüft und im Falle eines Treffers auf versteckt gesetzt. Dadurch wird der Kommentar nicht gelöscht und ich kann False-Positives wieder zum Leben erwecken.

models.py

from django.db import models
from django.utils.translation import ugettext as _

import re

class CommentBadword(models.Model):
    word = models.CharField(_('Bad word'), max_length=255, blank=False)
    is_regex = models.BooleanField(_('Is regex'), default=False)

    def __unicode__(self):
        return self.word

    def validate(self, text):
        if self.is_regex:
            if re.compile(self.word).search(text):
                return False
        else:
            if self.word in text:
                return False
        return True

    class Meta:
        verbose_name = _('Comment Badword')
        verbose_name_plural = _('Comment Badwords')

forms.py

from django import forms
from django.utils.translation import ugettext as _
from .models import CommentBadword

import re

class CommentBadwordForm(forms.ModelForm):
    def clean(self):
        if self.cleaned_data['is_regex'] and not self._errors.get('word', None):
            try:
                test = re.compile(self.cleaned_data['word'])
            except:
                self._errors['word'] = forms.util.ErrorList([_('Invalid regex pattern')])
        return self.cleaned_data

    class Meta:
        model = CommentBadword

admin.py

from django.contrib import admin
from .models CommentBadword
from .forms import CommentBadwordForm

class CommentBadwordAdmin(admin.ModelAdmin):
    list_display = ('word', 'is_regex')
    list_filter = ('is_regex',)
    search_fields = ('word',)
    form = CommentBadwordForm

admin.site.register(CommentBadword, CommentBadwordAdmin)

init.py oder auch woanders, hauptsache der Connect wird ausgeführt

from django.contrib.comments.models import Comment
from django.contrib.comments.signals import comment_will_be_posted

from .models import CommentBadword

def comment_badword_filter(sender, **kwargs):
    instance = kwargs['comment']
    for badword in CommentBadword.objects.all():
        if not badword.validate(instance.comment):
            instance.is_public = False
    return True

comment_will_be_posted.connect(comment_badword_filter, sender=Comment, dispatch_uid='comment_badword_filter')

Ich denke, dass sich der Code zu großen Teilen selbst erklärt. Zwei Anmerkungen möchte ich jedoch loswerden.

Das CommenBadword Model kann sowohl mit einzelnen gesperrten Wörtern als auch mit regulären Ausdrücken umgehen. Eine entsprechende Validierung im Django Admin wird durchgeführt.

Theoretisch kann man diesen Badword Filter auch für andere Texte verwenden (Foren, etc.). Zur Validierung muss lediglich die Methode validate des CommentBadword Models mit dem zu prüfenden Text aufgerufen werden.Beispiel:

mybadword.validate(mytext)

.. gibt True zurück, wenn der Text keine Badwords enthält und somit freigegeben werden kann.

Viel Spass damit!

Tags: comments, django, moderation

 

Kommentare

Kommentar von Arne Brodowski (12.03.2009, 15:57)

Dass das Honeypot-Feld nicht wirklich hilft, habe ich leider auch schon feststellen müssen. Ich hatte schon eine Stunde nach dem Relaunch meiner Seite mit contrib.comments den ersten Spam-Kommentar.

Mittlerweile habe ich Akismet integriert, und zwar genauso wie du beschreibst über das comment_will_be_posted Signal.

 

Kommentar von Marcel Leskowski (29.10.2009, 18:09)

Anscheinend hat diese Methode auch nicht geholfen, da oben wieder Spam-Kommentare aufgelistet sind.

Gruß
Marcel

 

Kommentar von steph (29.10.2009, 18:14)

ich bin einfach zu faul die Badwordliste zu pflegen ;)

 

Kommentar von georgesover (22.02.2010, 18:51)

We refit houses In Maryland,US.
Custom / External remodelings,
reasonable prices,license,
references,photos,free estimates,
also take houses to fix:
http://www.renewhouse4u.com.
Mobile:410-978-7981.
Thanks.

 

Kommentar von Astedoiteld (27.02.2010, 08:10)

http://blog.tellurideskiresort.com/members/paxil-side-effects.aspx

 

Kommentar von flofoloedgesy (28.02.2010, 11:49)

http://www.netknowledgenow.com/members/prevacid-side-effects.aspx

 

 

Kommentar schreiben