mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-02 23:48:47 +00:00
Update captcha
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
VERSION = (0, 4, 0)
|
VERSION = (0, 4, 3)
|
||||||
|
|
||||||
|
|
||||||
def get_version(svn=False):
|
def get_version(svn=False):
|
||||||
@@ -20,8 +20,8 @@ def pillow_required():
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
import Image
|
import Image
|
||||||
import ImageDraw
|
import ImageDraw # NOQA
|
||||||
import ImageFont
|
import ImageFont # NOQA
|
||||||
except ImportError:
|
except ImportError:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
|
||||||
|
|
||||||
CAPTCHA_FONT_PATH = getattr(settings, 'CAPTCHA_FONT_PATH', os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'fonts/Vera.ttf')))
|
CAPTCHA_FONT_PATH = getattr(settings, 'CAPTCHA_FONT_PATH', os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'fonts/Vera.ttf')))
|
||||||
CAPTCHA_FONT_SIZE = getattr(settings, 'CAPTCHA_FONT_SIZE', 22)
|
CAPTCHA_FONT_SIZE = getattr(settings, 'CAPTCHA_FONT_SIZE', 22)
|
||||||
@@ -19,9 +18,9 @@ CAPTCHA_IMAGE_BEFORE_FIELD = getattr(settings, 'CAPTCHA_IMAGE_BEFORE_FIELD', Tru
|
|||||||
CAPTCHA_DICTIONARY_MIN_LENGTH = getattr(settings, 'CAPTCHA_DICTIONARY_MIN_LENGTH', 0)
|
CAPTCHA_DICTIONARY_MIN_LENGTH = getattr(settings, 'CAPTCHA_DICTIONARY_MIN_LENGTH', 0)
|
||||||
CAPTCHA_DICTIONARY_MAX_LENGTH = getattr(settings, 'CAPTCHA_DICTIONARY_MAX_LENGTH', 99)
|
CAPTCHA_DICTIONARY_MAX_LENGTH = getattr(settings, 'CAPTCHA_DICTIONARY_MAX_LENGTH', 99)
|
||||||
if CAPTCHA_IMAGE_BEFORE_FIELD:
|
if CAPTCHA_IMAGE_BEFORE_FIELD:
|
||||||
CAPTCHA_OUTPUT_FORMAT = getattr(settings, 'CAPTCHA_OUTPUT_FORMAT', u'%(image)s %(hidden_field)s %(text_field)s')
|
CAPTCHA_OUTPUT_FORMAT = getattr(settings, 'CAPTCHA_OUTPUT_FORMAT', '%(image)s %(hidden_field)s %(text_field)s')
|
||||||
else:
|
else:
|
||||||
CAPTCHA_OUTPUT_FORMAT = getattr(settings, 'CAPTCHA_OUTPUT_FORMAT', u'%(hidden_field)s %(text_field)s %(image)s')
|
CAPTCHA_OUTPUT_FORMAT = getattr(settings, 'CAPTCHA_OUTPUT_FORMAT', '%(hidden_field)s %(text_field)s %(image)s')
|
||||||
|
|
||||||
CAPTCHA_TEST_MODE = getattr(settings, 'CAPTCHA_TEST_MODE', getattr(settings, 'CATPCHA_TEST_MODE', False))
|
CAPTCHA_TEST_MODE = getattr(settings, 'CAPTCHA_TEST_MODE', getattr(settings, 'CATPCHA_TEST_MODE', False))
|
||||||
|
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
from captcha.conf import settings
|
from captcha.conf import settings
|
||||||
from django.conf import settings as django_settings
|
|
||||||
from captcha.models import CaptchaStore, get_safe_now
|
from captcha.models import CaptchaStore, get_safe_now
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.core.urlresolvers import reverse, NoReverseMatch
|
from django.core.urlresolvers import reverse, NoReverseMatch
|
||||||
from django.forms import ValidationError
|
from django.forms import ValidationError
|
||||||
from django.forms.fields import CharField, MultiValueField
|
from django.forms.fields import CharField, MultiValueField
|
||||||
from django.forms.widgets import TextInput, MultiWidget, HiddenInput
|
from django.forms.widgets import TextInput, MultiWidget, HiddenInput
|
||||||
from django.utils.translation import ugettext, ugettext_lazy
|
from django.utils.translation import ugettext, ugettext_lazy
|
||||||
|
from six import u
|
||||||
|
|
||||||
|
|
||||||
class BaseCaptchaTextInput(MultiWidget):
|
class BaseCaptchaTextInput(MultiWidget):
|
||||||
@@ -38,14 +38,10 @@ class BaseCaptchaTextInput(MultiWidget):
|
|||||||
key = CaptchaStore.generate_key()
|
key = CaptchaStore.generate_key()
|
||||||
|
|
||||||
# these can be used by format_output and render
|
# these can be used by format_output and render
|
||||||
self._value = [key, u'']
|
self._value = [key, u('')]
|
||||||
self._key = key
|
self._key = key
|
||||||
self.id_ = self.build_attrs(attrs).get('id', None)
|
self.id_ = self.build_attrs(attrs).get('id', None)
|
||||||
|
|
||||||
def render(self, name, value, attrs=None):
|
|
||||||
#self.fetch_captcha_store(name, value, attrs)
|
|
||||||
return super(BaseCaptchaTextInput, self).render(name, self._value, attrs=attrs)
|
|
||||||
|
|
||||||
def id_for_label(self, id_):
|
def id_for_label(self, id_):
|
||||||
if id_:
|
if id_:
|
||||||
return id_ + '_1'
|
return id_ + '_1'
|
||||||
@@ -76,6 +72,7 @@ class CaptchaTextInput(BaseCaptchaTextInput):
|
|||||||
|
|
||||||
def format_output(self, rendered_widgets):
|
def format_output(self, rendered_widgets):
|
||||||
hidden_field, text_field = rendered_widgets
|
hidden_field, text_field = rendered_widgets
|
||||||
|
text_field = text_field.replace('<input', '<input autocomplete="off"')
|
||||||
return self._args['output_format'] % {
|
return self._args['output_format'] % {
|
||||||
'image': self.image_and_audio,
|
'image': self.image_and_audio,
|
||||||
'hidden_field': hidden_field,
|
'hidden_field': hidden_field,
|
||||||
@@ -88,8 +85,6 @@ class CaptchaTextInput(BaseCaptchaTextInput):
|
|||||||
self.image_and_audio = '<img src="%s" alt="captcha" class="captcha" />' % self.image_url()
|
self.image_and_audio = '<img src="%s" alt="captcha" class="captcha" />' % self.image_url()
|
||||||
if settings.CAPTCHA_FLITE_PATH:
|
if settings.CAPTCHA_FLITE_PATH:
|
||||||
self.image_and_audio = '<a href="%s" title="%s">%s</a>' % (self.audio_url(), ugettext('Play CAPTCHA as audio file'), self.image_and_audio)
|
self.image_and_audio = '<a href="%s" title="%s">%s</a>' % (self.audio_url(), ugettext('Play CAPTCHA as audio file'), self.image_and_audio)
|
||||||
|
|
||||||
|
|
||||||
return super(CaptchaTextInput, self).render(name, self._value, attrs=attrs)
|
return super(CaptchaTextInput, self).render(name, self._value, attrs=attrs)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
import random
|
import random
|
||||||
from captcha.conf import settings
|
from captcha.conf import settings
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
from six import u
|
||||||
|
|
||||||
|
|
||||||
def math_challenge():
|
def math_challenge():
|
||||||
@@ -15,14 +16,14 @@ def math_challenge():
|
|||||||
|
|
||||||
|
|
||||||
def random_char_challenge():
|
def random_char_challenge():
|
||||||
chars, ret = u'abcdefghijklmnopqrstuvwxyz', u''
|
chars, ret = u('abcdefghijklmnopqrstuvwxyz'), u('')
|
||||||
for i in range(settings.CAPTCHA_LENGTH):
|
for i in range(settings.CAPTCHA_LENGTH):
|
||||||
ret += random.choice(chars)
|
ret += random.choice(chars)
|
||||||
return ret.upper(), ret
|
return ret.upper(), ret
|
||||||
|
|
||||||
|
|
||||||
def unicode_challenge():
|
def unicode_challenge():
|
||||||
chars, ret = u'äàáëéèïíîöóòüúù', u''
|
chars, ret = u('äàáëéèïíîöóòüúù'), u('')
|
||||||
for i in range(settings.CAPTCHA_LENGTH):
|
for i in range(settings.CAPTCHA_LENGTH):
|
||||||
ret += random.choice(chars)
|
ret += random.choice(chars)
|
||||||
return ret.upper(), ret
|
return ret.upper(), ret
|
||||||
@@ -70,6 +71,10 @@ def noise_dots(draw, image):
|
|||||||
return draw
|
return draw
|
||||||
|
|
||||||
|
|
||||||
|
def noise_null(draw, image):
|
||||||
|
return draw
|
||||||
|
|
||||||
|
|
||||||
def post_smooth(image):
|
def post_smooth(image):
|
||||||
try:
|
try:
|
||||||
import ImageFilter
|
import ImageFilter
|
||||||
|
31
thirdpart/captcha/locale/bg/LC_MESSAGES/django.po
Normal file
31
thirdpart/captcha/locale/bg/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# django-simple-captcha Bulgarian translation
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the django-simple-captcha package.
|
||||||
|
# Venelin Stoykov <vkstoykov@gmail.com>, 2014.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: django-simple-captcha 0.4.1\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2014-02-10 14:43+0200\n"
|
||||||
|
"PO-Revision-Date: 2014-02-10 15:00+0200\n"
|
||||||
|
"Last-Translator: Venelin Stoykov <vkstoykov@gmail.com>\n"
|
||||||
|
"Language-Team: bg <vkstoykov@gmail.com>\n"
|
||||||
|
"Language: bg\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||||
|
|
||||||
|
#: fields.py:91
|
||||||
|
msgid "Play CAPTCHA as audio file"
|
||||||
|
msgstr "Чуй текста като аудио файл"
|
||||||
|
|
||||||
|
#: fields.py:106 fields.py:135 tests/tests.py:99 tests/tests.py:239
|
||||||
|
#: tests/tests.py:246
|
||||||
|
msgid "Invalid CAPTCHA"
|
||||||
|
msgstr "Сгрешен текст"
|
||||||
|
|
||||||
|
#: tests/tests.py:125
|
||||||
|
msgid "This field is required."
|
||||||
|
msgstr "Това поле е задължително"
|
@@ -11,7 +11,7 @@ msgstr ""
|
|||||||
"PO-Revision-Date: 2012-10-09 07:08+0200\n"
|
"PO-Revision-Date: 2012-10-09 07:08+0200\n"
|
||||||
"Last-Translator: Beda Kosata <bedrich.kosata@nic.cz>\n"
|
"Last-Translator: Beda Kosata <bedrich.kosata@nic.cz>\n"
|
||||||
"Language-Team: Czech <>\n"
|
"Language-Team: Czech <>\n"
|
||||||
"Language: \n"
|
"Language: cs\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
@@ -11,6 +11,7 @@ msgstr ""
|
|||||||
"PO-Revision-Date: 2013-07-16 12:10+0100\n"
|
"PO-Revision-Date: 2013-07-16 12:10+0100\n"
|
||||||
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
|
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
|
||||||
"Language-Team: DE <digi@treepy.com>\n"
|
"Language-Team: DE <digi@treepy.com>\n"
|
||||||
|
"Language: de\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
32
thirdpart/captcha/locale/es/LC_MESSAGES/django.po
Normal file
32
thirdpart/captcha/locale/es/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: django-simple-captcha\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2013-07-16 12:06+0200\n"
|
||||||
|
"PO-Revision-Date: 2014-05-20 21:22+0100\n"
|
||||||
|
"Last-Translator: https://github.com/dragosdobrota\n"
|
||||||
|
"Language-Team: es\n"
|
||||||
|
"Language: es\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Generator: Poedit 1.6.5\n"
|
||||||
|
|
||||||
|
#: fields.py:90
|
||||||
|
msgid "Play CAPTCHA as audio file"
|
||||||
|
msgstr "Reproducir CAPTCHA de audio"
|
||||||
|
|
||||||
|
#: fields.py:105 fields.py:134 tests/tests.py:99 tests/tests.py:239
|
||||||
|
#: tests/tests.py:246
|
||||||
|
msgid "Invalid CAPTCHA"
|
||||||
|
msgstr "CAPTCHA no válido"
|
||||||
|
|
||||||
|
#: tests/tests.py:125
|
||||||
|
msgid "This field is required."
|
||||||
|
msgstr "Este campo es obligatorio."
|
@@ -3,7 +3,6 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# Patrick Samson <maxcom@laposte.net>, 2010.
|
# Patrick Samson <maxcom@laposte.net>, 2010.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: django-simple-captcha 0.2.0\n"
|
"Project-Id-Version: django-simple-captcha 0.2.0\n"
|
||||||
@@ -11,8 +10,8 @@ msgstr ""
|
|||||||
"POT-Creation-Date: 2012-07-25 11:44+0300\n"
|
"POT-Creation-Date: 2012-07-25 11:44+0300\n"
|
||||||
"PO-Revision-Date: 2010-09-16 12:16+0200\n"
|
"PO-Revision-Date: 2010-09-16 12:16+0200\n"
|
||||||
"Last-Translator: Patrick Samson <maxcom@laposte.net>\n"
|
"Last-Translator: Patrick Samson <maxcom@laposte.net>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: fr <maxcom@laposte.net>\n"
|
||||||
"Language: \n"
|
"Language: fr\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# Arjuna Del Toso <stupidate@gmail.net>, 2012
|
# Arjuna Del Toso <stupidate@gmail.net>, 2012
|
||||||
#
|
#
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: django-simple-captcha 0.3.6\n"
|
"Project-Id-Version: django-simple-captcha 0.3.6\n"
|
||||||
@@ -12,6 +11,8 @@ msgstr ""
|
|||||||
"PO-Revision-Date: 2012-11-14 02:53+0000\n"
|
"PO-Revision-Date: 2012-11-14 02:53+0000\n"
|
||||||
"Last-Translator: Arjuna Del Toso <stupidate@gmail.com>\n"
|
"Last-Translator: Arjuna Del Toso <stupidate@gmail.com>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
|
"Language-Team: Arjuna Del Toso <stupidate@gmail.com>\n"
|
||||||
|
"Language: it\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n>1;\n"
|
"Plural-Forms: nplurals=2; plural=n>1;\n"
|
||||||
|
31
thirdpart/captcha/locale/ja/LC_MESSAGES/django.po
Normal file
31
thirdpart/captcha/locale/ja/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# Keisuke URAGO <bravo@resourcez.org>, 2014.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: django-simple-captcha\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2014-02-13 07:11+0900\n"
|
||||||
|
"PO-Revision-Date: 2014-02-13 07:11+0900\n"
|
||||||
|
"Last-Translator: Keisuke URAGO <bravo@resourcez.org>\n"
|
||||||
|
"Language-Team: Keisuke URAGO <bravo@resourcez.org>\n"
|
||||||
|
"Language: ja\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
|
|
||||||
|
#: fields.py:90
|
||||||
|
msgid "Play CAPTCHA as audio file"
|
||||||
|
msgstr "CAPTCHAをオーディオで読み上げる"
|
||||||
|
|
||||||
|
#: fields.py:105 fields.py:134 tests/tests.py:99 tests/tests.py:239
|
||||||
|
#: tests/tests.py:246
|
||||||
|
msgid "Invalid CAPTCHA"
|
||||||
|
msgstr "CAPTCHAの値が違っています"
|
||||||
|
|
||||||
|
#: tests/tests.py:125
|
||||||
|
msgid "This field is required."
|
||||||
|
msgstr "この項目は必須です"
|
@@ -3,15 +3,16 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# Leon de Rijke <leon@cmsworks.nl>, 2013.
|
# Leon de Rijke <leon@cmsworks.nl>, 2013.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: django-simple-captcha 0.3.6\n"
|
"Project-Id-Version: django-simple-captcha 0.3.6\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2013-02-15 13:26+0100\n"
|
"POT-Creation-Date: 2013-02-15 13:26+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: 2013-02-15 13:26+0100\n"
|
||||||
"Last-Translator: Leon de Rijke <leon@cmsworks.nl>\n"
|
"Last-Translator: Leon de Rijke <leon@cmsworks.nl>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
|
"Language-Team: Leon de Rijke <leon@cmsworks.nl>\n"
|
||||||
|
"Language: nl\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||||
|
@@ -3,16 +3,15 @@
|
|||||||
# This file is distributed under the same license as the django-simple-captcha package.
|
# This file is distributed under the same license as the django-simple-captcha package.
|
||||||
# Sławomir Zborowski <slawomir.zborowski@hotmail.com>, 2013.
|
# Sławomir Zborowski <slawomir.zborowski@hotmail.com>, 2013.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: django-simple-captcha 0.3.6\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2013-08-18 18:49+0200\n"
|
"POT-Creation-Date: 2013-08-18 18:49+0200\n"
|
||||||
"PO-Revision-Date: 2013-08-18 18:52+0200\n"
|
"PO-Revision-Date: 2013-08-18 18:52+0200\n"
|
||||||
"Last-Translator: Sławomir Zborowski <slawomir.zborowski@hotmail.com>\n"
|
"Last-Translator: Sławomir Zborowski <slawomir.zborowski@hotmail.com>\n"
|
||||||
"Language-Team: Polisch\n"
|
"Language-Team: Polisch\n"
|
||||||
"Language: \n"
|
"Language: pl\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# Alisson Patricio <eu@alisson.net>, 2013.
|
# Alisson Patricio <eu@alisson.net>, 2013.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: django-simple-captcha 0.3.7\n"
|
"Project-Id-Version: django-simple-captcha 0.3.7\n"
|
||||||
@@ -11,7 +10,8 @@ msgstr ""
|
|||||||
"POT-Creation-Date: 2013-05-18 10:58-0300\n"
|
"POT-Creation-Date: 2013-05-18 10:58-0300\n"
|
||||||
"PO-Revision-Date: 2013-05-18 13:12-0300\n"
|
"PO-Revision-Date: 2013-05-18 13:12-0300\n"
|
||||||
"Last-Translator: Alisson Patricio <eu@alisson.net>\n"
|
"Last-Translator: Alisson Patricio <eu@alisson.net>\n"
|
||||||
"Language: Portuguese (Brazilian)\n"
|
"Language-Team: Alisson Patricio <eu@alisson.net>\n"
|
||||||
|
"Language: pt_br\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
@@ -3,16 +3,15 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: django-simple-captcha 0.3.7\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2012-07-25 11:17+0300\n"
|
"POT-Creation-Date: 2012-07-25 11:17+0300\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: 2012-07-25 11:17+0300\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: ru <LL@li.org>\n"
|
||||||
"Language: \n"
|
"Language: ru\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
32
thirdpart/captcha/locale/sk/LC_MESSAGES/django.po
Normal file
32
thirdpart/captcha/locale/sk/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Slovak translation of django-simple-captcha.
|
||||||
|
# Copyright (C) 2013 THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# Pavol Otto <pavol.otto@nic.cz>, 2013.
|
||||||
|
#
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: django-simple-captcha 0.3.7\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2013-10-15 17:16+0200\n"
|
||||||
|
"PO-Revision-Date: 2013-10-15 17:16+0200\n"
|
||||||
|
"Last-Translator: Pavol Otto <pavol.otto@nic.cz>\n"
|
||||||
|
"Language-Team: SK\n"
|
||||||
|
"Language: sk\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||||
|
|
||||||
|
#: fields.py:90
|
||||||
|
msgid "Play CAPTCHA as audio file"
|
||||||
|
msgstr "Prehrať captchu ako audio súbor"
|
||||||
|
|
||||||
|
#: fields.py:105 fields.py:134 tests/tests.py:99 tests/tests.py:239
|
||||||
|
#: tests/tests.py:246
|
||||||
|
msgid "Invalid CAPTCHA"
|
||||||
|
msgstr "Neplatná CAPTCHA"
|
||||||
|
|
||||||
|
#: tests/tests.py:125
|
||||||
|
msgid "This field is required."
|
||||||
|
msgstr "Toto pole je povinné."
|
@@ -3,7 +3,6 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: django-simple-captcha 0.3.6\n"
|
"Project-Id-Version: django-simple-captcha 0.3.6\n"
|
||||||
@@ -11,7 +10,8 @@ msgstr ""
|
|||||||
"POT-Creation-Date: 2013-01-19 16:33-0200\n"
|
"POT-Creation-Date: 2013-01-19 16:33-0200\n"
|
||||||
"PO-Revision-Date: 2013-01-19 20:52+0200\n"
|
"PO-Revision-Date: 2013-01-19 20:52+0200\n"
|
||||||
"Last-Translator: Gokmen Gorgen <gokmen@alageek.com>\n"
|
"Last-Translator: Gokmen Gorgen <gokmen@alageek.com>\n"
|
||||||
"Language: \n"
|
"Language-Team: TR Gokmen Gorgen <gokmen@alageek.com>\n"
|
||||||
|
"Language: tr\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
32
thirdpart/captcha/locale/uk/LC_MESSAGES/django.po
Normal file
32
thirdpart/captcha/locale/uk/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: django-simple-captcha 0.3.6\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2014-02-21 22:05+0200\n"
|
||||||
|
"PO-Revision-Date: 2014-02-21 22:05+0200\n"
|
||||||
|
"Last-Translator: @FuriousCoder\n"
|
||||||
|
"Language-Team: uk @FuriousCoder\n"
|
||||||
|
"Language: uk\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||||
|
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
|
|
||||||
|
#: fields.py:91
|
||||||
|
msgid "Play CAPTCHA as audio file"
|
||||||
|
msgstr "Відтворити CAPTCHA як аудіо файл."
|
||||||
|
|
||||||
|
#: fields.py:106 fields.py:135 tests/tests.py:99 tests/tests.py:239
|
||||||
|
#: tests/tests.py:246
|
||||||
|
msgid "Invalid CAPTCHA"
|
||||||
|
msgstr "Неправильна відповідь."
|
||||||
|
|
||||||
|
#: tests/tests.py:125
|
||||||
|
msgid "This field is required."
|
||||||
|
msgstr "Це поле є обов'язковим."
|
@@ -3,15 +3,15 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# Ming Chen <c.ming@live.com>, 2013.
|
# Ming Chen <c.ming@live.com>, 2013.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: django-simple-captcha 0.3.6\n"
|
"Project-Id-Version: django-simple-captcha 0.3.6\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2013-03-01 05:04+0800\n"
|
"POT-Creation-Date: 2013-03-01 05:04+0800\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: 2013-03-01 05:04+0800\n"
|
||||||
"Last-Translator: Ming Chen <c.ming@live.com>\n"
|
"Last-Translator: Ming Chen <c.ming@live.com>\n"
|
||||||
"Language: \n"
|
"Language-Team: zh_cn Ming Chen <c.ming@live.com>\n"
|
||||||
|
"Language: zh_cn\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
@@ -11,15 +11,15 @@ class Command(BaseCommand):
|
|||||||
verbose = int(options.get('verbosity'))
|
verbose = int(options.get('verbosity'))
|
||||||
expired_keys = CaptchaStore.objects.filter(expiration__lte=get_safe_now()).count()
|
expired_keys = CaptchaStore.objects.filter(expiration__lte=get_safe_now()).count()
|
||||||
if verbose >= 1:
|
if verbose >= 1:
|
||||||
print "Currently %d expired hashkeys" % expired_keys
|
print("Currently %d expired hashkeys" % expired_keys)
|
||||||
try:
|
try:
|
||||||
CaptchaStore.remove_expired()
|
CaptchaStore.remove_expired()
|
||||||
except:
|
except:
|
||||||
if verbose >= 1:
|
if verbose >= 1:
|
||||||
print "Unable to delete expired hashkeys."
|
print("Unable to delete expired hashkeys.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if verbose >= 1:
|
if verbose >= 1:
|
||||||
if expired_keys > 0:
|
if expired_keys > 0:
|
||||||
print "%d expired hashkeys removed." % expired_keys
|
print("%d expired hashkeys removed." % expired_keys)
|
||||||
else:
|
else:
|
||||||
print "No keys to remove."
|
print("No keys to remove.")
|
||||||
|
@@ -1,39 +1,26 @@
|
|||||||
# encoding: utf-8
|
# -*- coding: utf-8 -*-
|
||||||
import datetime
|
from __future__ import unicode_literals
|
||||||
from south.db import db
|
|
||||||
from south.v2 import SchemaMigration
|
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
class Migration(SchemaMigration):
|
from django.db import models, migrations
|
||||||
|
|
||||||
def forwards(self, orm):
|
|
||||||
|
|
||||||
# Adding model 'CaptchaStore'
|
|
||||||
db.create_table('captcha_captchastore', (
|
|
||||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
|
||||||
('challenge', self.gf('django.db.models.fields.CharField')(max_length=32)),
|
|
||||||
('response', self.gf('django.db.models.fields.CharField')(max_length=32)),
|
|
||||||
('hashkey', self.gf('django.db.models.fields.CharField')(unique=True, max_length=40)),
|
|
||||||
('expiration', self.gf('django.db.models.fields.DateTimeField')()),
|
|
||||||
))
|
|
||||||
db.send_create_signal('captcha', ['CaptchaStore'])
|
|
||||||
|
|
||||||
|
|
||||||
def backwards(self, orm):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
# Deleting model 'CaptchaStore'
|
|
||||||
db.delete_table('captcha_captchastore')
|
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
models = {
|
operations = [
|
||||||
'captcha.captchastore': {
|
migrations.CreateModel(
|
||||||
'Meta': {'object_name': 'CaptchaStore'},
|
name='CaptchaStore',
|
||||||
'challenge': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
fields=[
|
||||||
'expiration': ('django.db.models.fields.DateTimeField', [], {}),
|
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||||
'hashkey': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40'}),
|
('challenge', models.CharField(max_length=32)),
|
||||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
('response', models.CharField(max_length=32)),
|
||||||
'response': ('django.db.models.fields.CharField', [], {'max_length': '32'})
|
('hashkey', models.CharField(unique=True, max_length=40)),
|
||||||
}
|
('expiration', models.DateTimeField()),
|
||||||
}
|
],
|
||||||
|
options={
|
||||||
complete_apps = ['captcha']
|
},
|
||||||
|
bases=(models.Model,),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
@@ -0,0 +1,21 @@
|
|||||||
|
"""
|
||||||
|
Django migrations for django-simple-captcha app
|
||||||
|
|
||||||
|
This package does not contain South migrations. South migrations can be found
|
||||||
|
in the ``south_migrations`` package.
|
||||||
|
"""
|
||||||
|
|
||||||
|
SOUTH_ERROR_MESSAGE = """\n
|
||||||
|
For South support, customize the SOUTH_MIGRATION_MODULES setting like so:
|
||||||
|
|
||||||
|
SOUTH_MIGRATION_MODULES = {
|
||||||
|
'captcha': 'captcha.south_migrations',
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Ensure the user is not using Django 1.6 or below with South
|
||||||
|
try:
|
||||||
|
from django.db import migrations # noqa
|
||||||
|
except ImportError:
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
raise ImproperlyConfigured(SOUTH_ERROR_MESSAGE)
|
@@ -40,10 +40,9 @@ class CaptchaStore(models.Model):
|
|||||||
expiration = models.DateTimeField(blank=False)
|
expiration = models.DateTimeField(blank=False)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
#import ipdb; ipdb.set_trace()
|
|
||||||
self.response = six.text_type(self.response).lower()
|
self.response = six.text_type(self.response).lower()
|
||||||
if not self.expiration:
|
if not self.expiration:
|
||||||
#self.expiration = datetime.datetime.now() + datetime.timedelta(minutes=int(captcha_settings.CAPTCHA_TIMEOUT))
|
|
||||||
self.expiration = get_safe_now() + datetime.timedelta(minutes=int(captcha_settings.CAPTCHA_TIMEOUT))
|
self.expiration = get_safe_now() + datetime.timedelta(minutes=int(captcha_settings.CAPTCHA_TIMEOUT))
|
||||||
if not self.hashkey:
|
if not self.hashkey:
|
||||||
key_ = unicodedata.normalize('NFKD', str(randrange(0, MAX_RANDOM_KEY)) + str(time.time()) + six.text_type(self.challenge)).encode('ascii', 'ignore') + unicodedata.normalize('NFKD', six.text_type(self.response)).encode('ascii', 'ignore')
|
key_ = unicodedata.normalize('NFKD', str(randrange(0, MAX_RANDOM_KEY)) + str(time.time()) + six.text_type(self.challenge)).encode('ascii', 'ignore') + unicodedata.normalize('NFKD', six.text_type(self.response)).encode('ascii', 'ignore')
|
||||||
|
39
thirdpart/captcha/south_migrations/0001_initial.py
Normal file
39
thirdpart/captcha/south_migrations/0001_initial.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# encoding: utf-8
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
|
||||||
|
# Adding model 'CaptchaStore'
|
||||||
|
db.create_table('captcha_captchastore', (
|
||||||
|
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||||
|
('challenge', self.gf('django.db.models.fields.CharField')(max_length=32)),
|
||||||
|
('response', self.gf('django.db.models.fields.CharField')(max_length=32)),
|
||||||
|
('hashkey', self.gf('django.db.models.fields.CharField')(unique=True, max_length=40)),
|
||||||
|
('expiration', self.gf('django.db.models.fields.DateTimeField')()),
|
||||||
|
))
|
||||||
|
db.send_create_signal('captcha', ['CaptchaStore'])
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
|
||||||
|
# Deleting model 'CaptchaStore'
|
||||||
|
db.delete_table('captcha_captchastore')
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'captcha.captchastore': {
|
||||||
|
'Meta': {'object_name': 'CaptchaStore'},
|
||||||
|
'challenge': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||||
|
'expiration': ('django.db.models.fields.DateTimeField', [], {}),
|
||||||
|
'hashkey': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'response': ('django.db.models.fields.CharField', [], {'max_length': '32'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['captcha']
|
0
thirdpart/captcha/south_migrations/__init__.py
Normal file
0
thirdpart/captcha/south_migrations/__init__.py
Normal file
@@ -1 +1 @@
|
|||||||
from .tests import CaptchaCase, trivial_challenge
|
from .tests import CaptchaCase, trivial_challenge # NOQA
|
||||||
|
@@ -12,6 +12,7 @@ import json
|
|||||||
import re
|
import re
|
||||||
import six
|
import six
|
||||||
import os
|
import os
|
||||||
|
from six import u
|
||||||
|
|
||||||
|
|
||||||
class CaptchaCase(TestCase):
|
class CaptchaCase(TestCase):
|
||||||
@@ -42,7 +43,6 @@ class CaptchaCase(TestCase):
|
|||||||
settings.CAPTCHA_WORDS_DICTIONARY = self.__current_settings_dictionary
|
settings.CAPTCHA_WORDS_DICTIONARY = self.__current_settings_dictionary
|
||||||
settings.CAPTCHA_PUNCTUATION = self.__current_settings_punctuation
|
settings.CAPTCHA_PUNCTUATION = self.__current_settings_punctuation
|
||||||
|
|
||||||
|
|
||||||
def __extract_hash_and_response(self, r):
|
def __extract_hash_and_response(self, r):
|
||||||
hash_ = re.findall(r'value="([0-9a-f]+)"', str(r.content))[0]
|
hash_ = re.findall(r'value="([0-9a-f]+)"', str(r.content))[0]
|
||||||
response = CaptchaStore.objects.get(hashkey=hash_).response
|
response = CaptchaStore.objects.get(hashkey=hash_).response
|
||||||
@@ -175,7 +175,7 @@ class CaptchaCase(TestCase):
|
|||||||
|
|
||||||
def testOutputFormat(self):
|
def testOutputFormat(self):
|
||||||
for urlname in ('captcha-test', 'captcha-test-model-form'):
|
for urlname in ('captcha-test', 'captcha-test-model-form'):
|
||||||
settings.CAPTCHA_OUTPUT_FORMAT = u'%(image)s<p>Hello, captcha world</p>%(hidden_field)s%(text_field)s'
|
settings.CAPTCHA_OUTPUT_FORMAT = u('%(image)s<p>Hello, captcha world</p>%(hidden_field)s%(text_field)s')
|
||||||
r = self.client.get(reverse(urlname))
|
r = self.client.get(reverse(urlname))
|
||||||
self.assertEqual(r.status_code, 200)
|
self.assertEqual(r.status_code, 200)
|
||||||
self.assertTrue('<p>Hello, captcha world</p>' in str(r.content))
|
self.assertTrue('<p>Hello, captcha world</p>' in str(r.content))
|
||||||
@@ -186,7 +186,7 @@ class CaptchaCase(TestCase):
|
|||||||
# we turn on DEBUG because CAPTCHA_OUTPUT_FORMAT is only checked debug
|
# we turn on DEBUG because CAPTCHA_OUTPUT_FORMAT is only checked debug
|
||||||
|
|
||||||
django_settings.DEBUG = True
|
django_settings.DEBUG = True
|
||||||
settings.CAPTCHA_OUTPUT_FORMAT = u'%(image)s'
|
settings.CAPTCHA_OUTPUT_FORMAT = u('%(image)s')
|
||||||
try:
|
try:
|
||||||
self.client.get(reverse(urlname))
|
self.client.get(reverse(urlname))
|
||||||
self.fail()
|
self.fail()
|
||||||
@@ -195,14 +195,14 @@ class CaptchaCase(TestCase):
|
|||||||
django_settings.DEBUG = __current_settings_debug
|
django_settings.DEBUG = __current_settings_debug
|
||||||
|
|
||||||
def testPerFormFormat(self):
|
def testPerFormFormat(self):
|
||||||
settings.CAPTCHA_OUTPUT_FORMAT = u'%(image)s testCustomFormatString %(hidden_field)s %(text_field)s'
|
settings.CAPTCHA_OUTPUT_FORMAT = u('%(image)s testCustomFormatString %(hidden_field)s %(text_field)s')
|
||||||
r = self.client.get(reverse('captcha-test'))
|
r = self.client.get(reverse('captcha-test'))
|
||||||
self.assertTrue('testCustomFormatString' in str(r.content))
|
self.assertTrue('testCustomFormatString' in str(r.content))
|
||||||
r = self.client.get(reverse('test_per_form_format'))
|
r = self.client.get(reverse('test_per_form_format'))
|
||||||
self.assertTrue('testPerFieldCustomFormatString' in str(r.content))
|
self.assertTrue('testPerFieldCustomFormatString' in str(r.content))
|
||||||
|
|
||||||
def testIssue31ProperLabel(self):
|
def testIssue31ProperLabel(self):
|
||||||
settings.CAPTCHA_OUTPUT_FORMAT = u'%(image)s %(hidden_field)s %(text_field)s'
|
settings.CAPTCHA_OUTPUT_FORMAT = u('%(image)s %(hidden_field)s %(text_field)s')
|
||||||
r = self.client.get(reverse('captcha-test'))
|
r = self.client.get(reverse('captcha-test'))
|
||||||
self.assertTrue('<label for="id_captcha_1"' in str(r.content))
|
self.assertTrue('<label for="id_captcha_1"' in str(r.content))
|
||||||
|
|
||||||
@@ -226,12 +226,12 @@ class CaptchaCase(TestCase):
|
|||||||
This test covers a default django field and widget behavior
|
This test covers a default django field and widget behavior
|
||||||
It not assert anything. If something is wrong it will raise a error!
|
It not assert anything. If something is wrong it will raise a error!
|
||||||
"""
|
"""
|
||||||
settings.CAPTCHA_OUTPUT_FORMAT = u'%(image)s %(hidden_field)s %(text_field)s'
|
settings.CAPTCHA_OUTPUT_FORMAT = u('%(image)s %(hidden_field)s %(text_field)s')
|
||||||
widget = CaptchaTextInput(attrs={'class': 'required'})
|
widget = CaptchaTextInput(attrs={'class': 'required'})
|
||||||
CaptchaField(widget=widget)
|
CaptchaField(widget=widget)
|
||||||
|
|
||||||
def testTestMode_Issue15(self):
|
def testTestMode_Issue15(self):
|
||||||
__current_test_mode_setting = settings.CAPTCHA_TEST_MODE
|
__current_test_mode_setting = settings.CAPTCHA_TEST_MODE
|
||||||
settings.CAPTCHA_TEST_MODE = False
|
settings.CAPTCHA_TEST_MODE = False
|
||||||
r = self.client.get(reverse('captcha-test'))
|
r = self.client.get(reverse('captcha-test'))
|
||||||
self.assertEqual(r.status_code, 200)
|
self.assertEqual(r.status_code, 200)
|
||||||
@@ -270,11 +270,30 @@ class CaptchaCase(TestCase):
|
|||||||
self.assertEqual(r.status_code, 200)
|
self.assertEqual(r.status_code, 200)
|
||||||
hash_, response = self.__extract_hash_and_response(r)
|
hash_, response = self.__extract_hash_and_response(r)
|
||||||
|
|
||||||
|
|
||||||
r = self.client.post(reverse('captcha-test-non-required'), dict(captcha_0=hash_, captcha_1=response, subject='xxx', sender='asasd@asdasd.com'))
|
r = self.client.post(reverse('captcha-test-non-required'), dict(captcha_0=hash_, captcha_1=response, subject='xxx', sender='asasd@asdasd.com'))
|
||||||
self.assertEqual(r.status_code, 200)
|
self.assertEqual(r.status_code, 200)
|
||||||
self.assertTrue(str(r.content).find('Form validated') > 0)
|
self.assertTrue(str(r.content).find('Form validated') > 0)
|
||||||
|
|
||||||
|
def test_autocomplete_off(self):
|
||||||
|
r = self.client.get(reverse('captcha-test'))
|
||||||
|
self.assertTrue('<input autocomplete="off" ' in six.text_type(r.content))
|
||||||
|
|
||||||
|
def test_autocomplete_not_on_hidden_input(self):
|
||||||
|
r = self.client.get(reverse('captcha-test'))
|
||||||
|
self.assertFalse('autocomplete="off" type="hidden" name="captcha_0"' in six.text_type(r.content))
|
||||||
|
self.assertFalse('autocomplete="off" id="id_captcha_0" name="captcha_0" type="hidden"' in six.text_type(r.content))
|
||||||
|
|
||||||
|
def test_transparent_background(self):
|
||||||
|
__current_test_mode_setting = settings.CAPTCHA_BACKGROUND_COLOR
|
||||||
|
settings.CAPTCHA_BACKGROUND_COLOR = "transparent"
|
||||||
|
for key in [store.hashkey for store in six.itervalues(self.stores)]:
|
||||||
|
response = self.client.get(reverse('captcha-image', kwargs=dict(key=key)))
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertTrue(response.has_header('content-type'))
|
||||||
|
self.assertEqual(response._headers.get('content-type'), ('Content-Type', 'image/png'))
|
||||||
|
|
||||||
|
settings.CAPTCHA_BACKGROUND_COLOR = __current_test_mode_setting
|
||||||
|
|
||||||
|
|
||||||
def trivial_challenge():
|
def trivial_challenge():
|
||||||
return 'trivial', 'trivial'
|
return 'trivial', 'trivial'
|
||||||
|
@@ -3,7 +3,8 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
from django.conf.urls.defaults import url, patterns, include
|
from django.conf.urls.defaults import url, patterns, include
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns(
|
||||||
|
'',
|
||||||
url(r'test/$', 'captcha.tests.views.test', name='captcha-test'),
|
url(r'test/$', 'captcha.tests.views.test', name='captcha-test'),
|
||||||
url(r'test-modelform/$', 'captcha.tests.views.test_model_form', name='captcha-test-model-form'),
|
url(r'test-modelform/$', 'captcha.tests.views.test_model_form', name='captcha-test-model-form'),
|
||||||
url(r'test2/$', 'captcha.tests.views.test_custom_error_message', name='captcha-test-custom-error-message'),
|
url(r'test2/$', 'captcha.tests.views.test_custom_error_message', name='captcha-test-custom-error-message'),
|
||||||
|
@@ -3,7 +3,7 @@ from captcha.fields import CaptchaField
|
|||||||
from django.template import RequestContext, loader
|
from django.template import RequestContext, loader
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from six import u
|
||||||
|
|
||||||
TEST_TEMPLATE = r'''
|
TEST_TEMPLATE = r'''
|
||||||
{% load url from future %}
|
{% load url from future %}
|
||||||
@@ -30,6 +30,7 @@ TEST_TEMPLATE = r'''
|
|||||||
</html>
|
</html>
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
def _test(request, form_class):
|
def _test(request, form_class):
|
||||||
passed = False
|
passed = False
|
||||||
if request.POST:
|
if request.POST:
|
||||||
@@ -80,8 +81,10 @@ def test_per_form_format(request):
|
|||||||
help_text='asdasd',
|
help_text='asdasd',
|
||||||
error_messages=dict(invalid='TEST CUSTOM ERROR MESSAGE'),
|
error_messages=dict(invalid='TEST CUSTOM ERROR MESSAGE'),
|
||||||
output_format=(
|
output_format=(
|
||||||
u'%(image)s testPerFieldCustomFormatString '
|
u(
|
||||||
u'%(hidden_field)s %(text_field)s'
|
'%(image)s testPerFieldCustomFormatString '
|
||||||
|
'%(hidden_field)s %(text_field)s'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return _test(request, CaptchaTestFormatForm)
|
return _test(request, CaptchaTestFormatForm)
|
||||||
|
@@ -3,7 +3,8 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
from django.conf.urls.defaults import patterns, url
|
from django.conf.urls.defaults import patterns, url
|
||||||
|
|
||||||
urlpatterns = patterns('captcha.views',
|
urlpatterns = patterns(
|
||||||
|
'captcha.views',
|
||||||
url(r'image/(?P<key>\w+)/$', 'captcha_image', name='captcha-image', kwargs={'scale': 1}),
|
url(r'image/(?P<key>\w+)/$', 'captcha_image', name='captcha-image', kwargs={'scale': 1}),
|
||||||
url(r'image/(?P<key>\w+)@2/$', 'captcha_image', name='captcha-image-2x', kwargs={'scale': 2}),
|
url(r'image/(?P<key>\w+)@2/$', 'captcha_image', name='captcha-image-2x', kwargs={'scale': 2}),
|
||||||
url(r'audio/(?P<key>\w+)/$', 'captcha_audio', name='captcha-audio'),
|
url(r'audio/(?P<key>\w+)/$', 'captcha_audio', name='captcha-audio'),
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
from captcha.conf import settings
|
from captcha.conf import settings
|
||||||
from captcha.helpers import captcha_image_url
|
from captcha.helpers import captcha_image_url
|
||||||
from captcha.models import CaptchaStore
|
from captcha.models import CaptchaStore
|
||||||
from django.http import HttpResponse, Http404
|
from django.http import HttpResponse, Http404
|
||||||
@@ -27,6 +27,15 @@ except ImportError:
|
|||||||
from django.utils import simplejson as json
|
from django.utils import simplejson as json
|
||||||
|
|
||||||
NON_DIGITS_RX = re.compile('[^\d]')
|
NON_DIGITS_RX = re.compile('[^\d]')
|
||||||
|
# Distance of the drawn text from the top of the captcha image
|
||||||
|
from_top = 4
|
||||||
|
|
||||||
|
|
||||||
|
def getsize(font, text):
|
||||||
|
if hasattr(font, 'getoffset'):
|
||||||
|
return [x + y for x, y in zip(font.getsize(text), font.getoffset(text))]
|
||||||
|
else:
|
||||||
|
return font.getsize(text)
|
||||||
|
|
||||||
|
|
||||||
def captcha_image(request, key, scale=1):
|
def captcha_image(request, key, scale=1):
|
||||||
@@ -38,9 +47,12 @@ def captcha_image(request, key, scale=1):
|
|||||||
else:
|
else:
|
||||||
font = ImageFont.load(settings.CAPTCHA_FONT_PATH)
|
font = ImageFont.load(settings.CAPTCHA_FONT_PATH)
|
||||||
|
|
||||||
size = font.getsize(text)
|
size = getsize(font, text)
|
||||||
size = (size[0] * 2, int(size[1] * 1.2))
|
size = (size[0] * 2, int(size[1] * 1.4))
|
||||||
image = Image.new('RGB', size, settings.CAPTCHA_BACKGROUND_COLOR)
|
if settings.CAPTCHA_BACKGROUND_COLOR == "transparent":
|
||||||
|
image = Image.new('RGBA', size)
|
||||||
|
else:
|
||||||
|
image = Image.new('RGB', size, settings.CAPTCHA_BACKGROUND_COLOR)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
PIL_VERSION = int(NON_DIGITS_RX.sub('', Image.VERSION))
|
PIL_VERSION = int(NON_DIGITS_RX.sub('', Image.VERSION))
|
||||||
@@ -56,7 +68,7 @@ def captcha_image(request, key, scale=1):
|
|||||||
charlist.append(char)
|
charlist.append(char)
|
||||||
for char in charlist:
|
for char in charlist:
|
||||||
fgimage = Image.new('RGB', size, settings.CAPTCHA_FOREGROUND_COLOR)
|
fgimage = Image.new('RGB', size, settings.CAPTCHA_FOREGROUND_COLOR)
|
||||||
charimage = Image.new('L', font.getsize(' %s ' % char), '#000000')
|
charimage = Image.new('L', getsize(font, ' %s ' % char), '#000000')
|
||||||
chardraw = ImageDraw.Draw(charimage)
|
chardraw = ImageDraw.Draw(charimage)
|
||||||
chardraw.text((0, 0), ' %s ' % char, font=font, fill='#ffffff')
|
chardraw.text((0, 0), ' %s ' % char, font=font, fill='#ffffff')
|
||||||
if settings.CAPTCHA_LETTER_ROTATION:
|
if settings.CAPTCHA_LETTER_ROTATION:
|
||||||
@@ -67,7 +79,7 @@ def captcha_image(request, key, scale=1):
|
|||||||
charimage = charimage.crop(charimage.getbbox())
|
charimage = charimage.crop(charimage.getbbox())
|
||||||
maskimage = Image.new('L', size)
|
maskimage = Image.new('L', size)
|
||||||
|
|
||||||
maskimage.paste(charimage, (xpos, 4, xpos + charimage.size[0], 4 + charimage.size[1]))
|
maskimage.paste(charimage, (xpos, from_top, xpos + charimage.size[0], from_top + charimage.size[1]))
|
||||||
size = maskimage.size
|
size = maskimage.size
|
||||||
image = Image.composite(fgimage, image, maskimage)
|
image = Image.composite(fgimage, image, maskimage)
|
||||||
xpos = xpos + 2 + charimage.size[0]
|
xpos = xpos + 2 + charimage.size[0]
|
||||||
|
Reference in New Issue
Block a user