summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdolfo Fitoria <adolfo.fitoria@gmail.com>2011-09-09 17:09:28 -0300
committerAdolfo Fitoria <adolfo.fitoria@gmail.com>2011-09-09 17:09:28 -0300
commit468bd2543c715070abed0adf8f2f6f8008ad43ab (patch)
treee9e3c66ba4f00925e89ee8f1cb49c579e871653b
parentb96bf535c16e42f407165ebecfb44302f763795f (diff)
downloadaskbot-468bd2543c715070abed0adf8f2f6f8008ad43ab.tar.gz
askbot-468bd2543c715070abed0adf8f2f6f8008ad43ab.tar.bz2
askbot-468bd2543c715070abed0adf8f2f6f8008ad43ab.zip
added akismet support
-rw-r--r--askbot/conf/external_keys.py19
-rw-r--r--askbot/utils/decorators.py32
-rw-r--r--askbot/utils/functions.py8
-rw-r--r--askbot/views/writers.py20
4 files changed, 77 insertions, 2 deletions
diff --git a/askbot/conf/external_keys.py b/askbot/conf/external_keys.py
index 15ad2903..a2dc3094 100644
--- a/askbot/conf/external_keys.py
+++ b/askbot/conf/external_keys.py
@@ -73,6 +73,25 @@ settings.register(
)
)
+
+
+settings.register(
+ livesettings.BooleanValue(
+ EXTERNAL_KEYS,
+ 'USE_AKISMET',
+ description=_('Enable Akismet spam detection(keys below are required)'),
+ default=False
+ )
+)
+
+settings.register(
+ livesettings.StringValue(
+ EXTERNAL_KEYS,
+ 'AKISMET_API_KEY',
+ description=_('Akismet key for spam detection')
+ )
+)
+
settings.register(
livesettings.StringValue(
EXTERNAL_KEYS,
diff --git a/askbot/utils/decorators.py b/askbot/utils/decorators.py
index f2c86cd5..352c5497 100644
--- a/askbot/utils/decorators.py
+++ b/askbot/utils/decorators.py
@@ -8,13 +8,16 @@ import logging
from django.conf import settings
from django.core import exceptions as django_exceptions
from django.core import urlresolvers
+from django.core.urlresolvers import reverse
from django.http import HttpResponse, HttpResponseForbidden, Http404
from django.http import HttpResponseRedirect
from django.utils import simplejson
from django.utils.translation import ugettext as _
+from django.utils.encoding import smart_str
from askbot import exceptions as askbot_exceptions
from askbot.conf import settings as askbot_settings
from askbot.utils import url_utils
+from askbot import get_version
def auto_now_timestamp(func):
"""decorator that will automatically set
@@ -74,7 +77,6 @@ def post_only(view_func):
return view_func(request, *args, **kwargs)
return wrapper
-
def ajax_only(view_func):
@functools.wraps(view_func)
def wrapper(request,*args,**kwargs):
@@ -166,3 +168,31 @@ def profile(log_file):
return _inner
return _outer
+
+def check_spam(field):
+ '''Decorator to check if there is spam in the form'''
+
+ def decorator(view_func):
+ @functools.wraps(view_func)
+ def wrapper(request, *args, **kwargs):
+ if askbot_settings.USE_AKISMET and request.method=="POST":
+ comment = smart_str(request.POST[field])
+ data = {'user_ip': request.META["REMOTE_ADDR"],
+ 'user_agent': request.environ['HTTP_USER_AGENT'],
+ 'comment_author': smart_str(request.user.username),
+ }
+ if request.user.is_authenticated():
+ data.update({'comment_author_email': request.user.email})
+
+ from akismet import Akismet
+ api = Akismet(askbot_settings.AKISMET_API_KEY, smart_str(askbot_settings.APP_URL), "Askbot/%s" % get_version())
+
+ if api.comment_check(comment, data, build_data=False):
+ #if True:
+ request.user.message_set.create(message=_("Spam was detected on your post, sorry for that if you are not a spammer"))
+ return HttpResponseRedirect(reverse('index'))
+
+ return view_func(request, *args, **kwargs)
+ return wrapper
+
+ return decorator
diff --git a/askbot/utils/functions.py b/askbot/utils/functions.py
index a56ed897..3906bb9e 100644
--- a/askbot/utils/functions.py
+++ b/askbot/utils/functions.py
@@ -2,6 +2,7 @@ import re
import datetime
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
+from django.contrib.auth.models import User
def get_from_dict_or_object(source, key):
try:
@@ -126,3 +127,10 @@ def setup_paginator(context):
"pages_outside_trailing_range": pages_outside_trailing_range,
"extend_url" : extend_url
}
+
+def get_admin():
+ '''Returns an admin users, usefull for raising flags'''
+ try:
+ return User.objects.filter(is_superuser=True)[0]
+ except:
+ raise Exception('there is no admin users')
diff --git a/askbot/views/writers.py b/askbot/views/writers.py
index a2540a90..a4ec0bc1 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -189,6 +189,7 @@ def import_data(request):
#@login_required #actually you can post anonymously, but then must register
@csrf.csrf_protect
@decorators.check_authorization_to_post(_('Please log in to ask questions'))
+@decorators.check_spam('text')
def ask(request):#view used to ask a new question
"""a view to ask a new question
gives space for q title, body, tags and checkbox for to post as wiki
@@ -240,6 +241,18 @@ def ask(request):#view used to ask a new question
)
question.save()
return HttpResponseRedirect(url_utils.get_login_url())
+ else:
+ form = forms.AskForm(request.POST)
+ if 'title' in request.GET:
+ #normally this title is inherited from search query
+ #but it is possible to ask with a parameter title in the url query
+ form.initial['title'] = request.GET['title']
+ else:
+ #attempt to extract title from previous search query
+ search_state = request.session.get('search_state',None)
+ if search_state:
+ query = search_state.query
+ form.initial['title'] = query
else:
#this branch is for the initial load of ask form
form = forms.AskForm()
@@ -319,6 +332,7 @@ def retag_question(request, id):
@login_required
@csrf.csrf_protect
+@decorators.check_spam('text')
def edit_question(request, id):
"""edit question view
"""
@@ -406,6 +420,7 @@ def edit_question(request, id):
@login_required
@csrf.csrf_protect
+@decorators.check_spam('text')
def edit_answer(request, id):
answer = get_object_or_404(models.Answer, id=id)
try:
@@ -464,6 +479,7 @@ def edit_answer(request, id):
#todo: rename this function to post_new_answer
@decorators.check_authorization_to_post(_('Please log in to answer questions'))
+@decorators.check_spam('text')
def answer(request, id):#process a new answer
"""view that posts new answer
@@ -548,6 +564,7 @@ def __generate_comments_json(obj, user):#non-view generates json data for the po
data = simplejson.dumps(json_comments)
return HttpResponse(data, mimetype="application/json")
+@decorators.check_spam('comment')
def post_comments(request):#generic ajax handler to load comments to an object
# only support get post comments by ajax now
user = request.user
@@ -587,6 +604,7 @@ def post_comments(request):#generic ajax handler to load comments to an object
raise Http404
@decorators.ajax_only
+@decorators.check_spam('text')
def edit_comment(request):
if request.user.is_authenticated():
comment_id = int(request.POST['comment_id'])
@@ -609,7 +627,7 @@ def edit_comment(request):
'user_id': comment.user.id,
'is_deletable': is_deletable,
'is_editable': is_editable,
- 'score': comment.score,
+ 'score': comment.score,
'voted': comment.is_upvoted_by(request.user),
}
else: