diff --git a/boards/forms.py b/boards/forms.py
--- a/boards/forms.py
+++ b/boards/forms.py
@@ -4,7 +4,7 @@ from django import forms
from django.forms.util import ErrorList
from boards.models import TITLE_MAX_LENGTH
from neboard import settings
-
+from boards import utils
class PlainErrorList(ErrorList):
def __unicode__(self):
@@ -67,9 +67,6 @@ class PostForm(forms.Form):
self._errors['image'] = self.error_class([error_message])
-class PostCaptchaForm(PostForm):
- captcha = CaptchaField()
-
class ThreadForm(PostForm):
regex_tags = re.compile(ur'^[\w\s\d]+$', re.UNICODE)
@@ -91,9 +88,47 @@ class ThreadForm(PostForm):
return cleaned_data
+class PostCaptchaForm(PostForm):
+ captcha = CaptchaField()
+
+ def __init__(self, *args, **kwargs):
+ self.request = kwargs['request']
+ del kwargs['request']
+
+ super(PostCaptchaForm, self).__init__(*args, **kwargs)
+
+ def clean(self):
+ cleaned_data = super(PostCaptchaForm, self).clean()
+
+ success = self.is_valid()
+ utils.update_captcha_access(self.request, success)
+
+ if success:
+ return cleaned_data
+ else:
+ raise forms.ValidationError("captcha validation failed")
+
+
class ThreadCaptchaForm(ThreadForm):
captcha = CaptchaField()
+ def __init__(self, *args, **kwargs):
+ self.request = kwargs['request']
+ del kwargs['request']
+
+ super(ThreadCaptchaForm, self).__init__(*args, **kwargs)
+
+ def clean(self):
+ cleaned_data = super(ThreadCaptchaForm, self).clean()
+
+ success = self.is_valid()
+ utils.update_captcha_access(self.request, success)
+
+ if success:
+ return cleaned_data
+ else:
+ raise forms.ValidationError("captcha validation failed")
+
class SettingsForm(forms.Form):
- theme = forms.ChoiceField(choices=settings.THEMES, widget=forms.RadioSelect)
\ No newline at end of file
+ theme = forms.ChoiceField(choices=settings.THEMES, widget=forms.RadioSelect)
diff --git a/boards/models.py b/boards/models.py
--- a/boards/models.py
+++ b/boards/models.py
@@ -8,6 +8,7 @@ from django.db import models
from django.http import Http404
from django.utils import timezone
from markupfield.fields import MarkupField
+from threading import Thread
from neboard import settings
import thumbs
diff --git a/boards/templates/boards/posting_general.html b/boards/templates/boards/posting_general.html
--- a/boards/templates/boards/posting_general.html
+++ b/boards/templates/boards/posting_general.html
@@ -130,6 +130,7 @@
diff --git a/boards/templates/boards/thread.html b/boards/templates/boards/thread.html
--- a/boards/templates/boards/thread.html
+++ b/boards/templates/boards/thread.html
@@ -84,6 +84,7 @@
diff --git a/boards/utils.py b/boards/utils.py
--- a/boards/utils.py
+++ b/boards/utils.py
@@ -1,14 +1,64 @@
"""
This module contains helper functions and helper classes.
"""
+
from neboard import settings
+import time
-def check_if_human(request):
+KEY_CAPTCHA_FAILS = 'key_captcha_fails'
+KEY_CAPTCHA_DELAY_TIME = 'key_captcha_delay_time'
+KEY_CAPTCHA_LAST_ACTIVITY = 'key_captcha_last_activity'
+
+
+def need_include_captcha(request):
"""
Check if request is made by a user.
It contains rules which check for bots.
"""
- # FIXME: need to insert checking logic
- return not settings.ENABLE_CAPTCHA
+ if not settings.ENABLE_CAPTCHA:
+ return False
+
+ enable_captcha = False
+
+ #newcomer
+ if KEY_CAPTCHA_LAST_ACTIVITY not in request.session:
+ return settings.ENABLE_CAPTCHA
+
+ last_activity = request.session[KEY_CAPTCHA_LAST_ACTIVITY]
+ current_delay = int(time.time()) - last_activity
+
+ delay_time = (request.session[KEY_CAPTCHA_DELAY_TIME]
+ if KEY_CAPTCHA_DELAY_TIME in request.session
+ else settings.CAPTCHA_DEFAULT_SAFE_TIME)
+
+ if current_delay < delay_time:
+ enable_captcha = True
+
+ print 'ENABLING' + str(enable_captcha)
+
+ return enable_captcha
+
+
+def update_captcha_access(request, passed):
+ """
+ Update captcha fields.
+ It will reduce delay time if user passed captcha verification and
+ it will increase it otherwise.
+ """
+ session = request.session
+
+ delay_time = (request.session[KEY_CAPTCHA_DELAY_TIME]
+ if KEY_CAPTCHA_DELAY_TIME in request.session
+ else settings.CAPTCHA_DEFAULT_SAFE_TIME)
+
+ print "DELAY TIME = " + str(delay_time)
+
+ if passed:
+ delay_time -= 2 if delay_time >= 7 else 5
+ else:
+ delay_time += 10
+
+ session[KEY_CAPTCHA_LAST_ACTIVITY] = int(time.time())
+ session[KEY_CAPTCHA_DELAY_TIME] = delay_time
diff --git a/boards/views.py b/boards/views.py
--- a/boards/views.py
+++ b/boards/views.py
@@ -16,18 +16,21 @@ import neboard
def index(request, page=0):
context = RequestContext(request)
- threadFormClass = (ThreadForm
- if utils.check_if_human(request)
- else ThreadCaptchaForm)
+ if utils.need_include_captcha(request):
+ threadFormClass = ThreadCaptchaForm
+ kwargs = {'request': request}
+ else:
+ threadFormClass = ThreadForm
+ kwargs = {}
if request.method == 'POST':
form = threadFormClass(request.POST, request.FILES,
- error_class=PlainErrorList)
+ error_class=PlainErrorList, **kwargs)
if form.is_valid():
return _new_post(request, form)
else:
- form = threadFormClass(error_class=PlainErrorList)
+ form = threadFormClass(error_class=PlainErrorList, **kwargs)
threads = Post.objects.get_threads(page=int(page))
@@ -119,16 +122,20 @@ def tag(request, tag_name, page=0):
def thread(request, post_id):
"""Get all thread posts"""
- postFormClass = (PostForm if utils.check_if_human(request) else
- PostCaptchaForm)
+ if utils.need_include_captcha(request):
+ postFormClass = PostCaptchaForm
+ kwargs = {'request': request}
+ else:
+ postFormClass = PostForm
+ kwargs = {}
if request.method == 'POST':
form = postFormClass(request.POST, request.FILES,
- error_class=PlainErrorList)
+ error_class=PlainErrorList, **kwargs)
if form.is_valid():
return _new_post(request, form, post_id)
else:
- form = postFormClass(error_class=PlainErrorList)
+ form = postFormClass(error_class=PlainErrorList, **kwargs)
posts = Post.objects.get_thread(post_id)
diff --git a/neboard/settings.py b/neboard/settings.py
--- a/neboard/settings.py
+++ b/neboard/settings.py
@@ -187,9 +187,12 @@ SITE_NAME = 'Neboard'
THEMES = [
('md', 'Mystic Dark'),
('sw', 'Snow White') ]
+
DEFAULT_THEME = 'md'
POPULAR_TAGS = 10
LAST_REPLIES_COUNT = 3
-ENABLE_CAPTCHA = False
\ No newline at end of file
+ENABLE_CAPTCHA = True
+# if user tries to post before CAPTCHA_DEFAULT_SAFE_TIME. Captcha will be shown
+CAPTCHA_DEFAULT_SAFE_TIME = 30 # seconds
\ No newline at end of file