2016-12-20 07:03:36 +00:00
|
|
|
from datetime import datetime, timedelta
|
2016-12-19 05:28:16 +00:00
|
|
|
from random import shuffle
|
|
|
|
|
2016-12-19 06:30:41 +00:00
|
|
|
from django.core.exceptions import ValidationError
|
2016-12-19 05:28:16 +00:00
|
|
|
from django.forms import ChoiceField
|
|
|
|
|
2019-03-08 22:12:28 +00:00
|
|
|
CAPTCHA_CHOICES = [('number', 'zorp borp'),
|
|
|
|
('hey', 'quop bop'),
|
|
|
|
('never', 'NO, I AM NOT A ROBOT'),
|
|
|
|
('eleven', 'crackle zop'),
|
|
|
|
('twelve', '*rusty screech*'),
|
|
|
|
('eighty', 'mother, give me legs')]
|
2016-12-19 05:28:16 +00:00
|
|
|
shuffle(CAPTCHA_CHOICES)
|
|
|
|
CAPTCHA_CHOICES.insert(0, ('one', 'beep boop'),)
|
2019-03-08 22:12:28 +00:00
|
|
|
NOT_A_ROBOT = 'never'
|
2016-12-19 05:28:16 +00:00
|
|
|
|
|
|
|
def validate_captcha(captcha):
|
|
|
|
if captcha != NOT_A_ROBOT:
|
|
|
|
raise ValidationError('Are you sure you are not a robot?')
|
|
|
|
|
2016-12-20 07:03:36 +00:00
|
|
|
|
2016-12-19 05:28:16 +00:00
|
|
|
class CaptchaField(ChoiceField):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__(choices=CAPTCHA_CHOICES,
|
|
|
|
label='are you a robot?',
|
|
|
|
help_text='pick the response that indicates whether or not you are a robot.',
|
|
|
|
validators=(validate_captcha,))
|
2016-12-20 07:03:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
# this should go in something like redis. I refuse, however, to involve redis
|
|
|
|
# in all of this until i have 2-3 more usecases.
|
|
|
|
def throttler(cache):
|
|
|
|
def throttle(key):
|
|
|
|
nonlocal cache
|
|
|
|
last_submission = cache.get(key)
|
|
|
|
now = datetime.now()
|
|
|
|
if last_submission is None\
|
|
|
|
or now - last_submission > timedelta(minutes=30):
|
|
|
|
cache[key] = now
|
|
|
|
else:
|
|
|
|
raise ValidationError('you have submitted pretty recently. try again in a bit.')
|
|
|
|
|
|
|
|
return throttle
|