diff options
author | Adolfo Fitoria <adolfo.fitoria@gmail.com> | 2011-09-09 17:09:28 -0300 |
---|---|---|
committer | Adolfo Fitoria <adolfo.fitoria@gmail.com> | 2011-09-09 17:09:28 -0300 |
commit | 468bd2543c715070abed0adf8f2f6f8008ad43ab (patch) | |
tree | e9e3c66ba4f00925e89ee8f1cb49c579e871653b | |
parent | b96bf535c16e42f407165ebecfb44302f763795f (diff) | |
download | askbot-468bd2543c715070abed0adf8f2f6f8008ad43ab.tar.gz askbot-468bd2543c715070abed0adf8f2f6f8008ad43ab.tar.bz2 askbot-468bd2543c715070abed0adf8f2f6f8008ad43ab.zip |
added akismet support
-rw-r--r-- | askbot/conf/external_keys.py | 19 | ||||
-rw-r--r-- | askbot/utils/decorators.py | 32 | ||||
-rw-r--r-- | askbot/utils/functions.py | 8 | ||||
-rw-r--r-- | askbot/views/writers.py | 20 |
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: |