diff --git a/bin/activate b/bin/activate old mode 100644 new mode 100755 diff --git a/impuls/__pycache__/settings.cpython-311.pyc b/impuls/__pycache__/settings.cpython-311.pyc index 06384d09..900b3081 100644 Binary files a/impuls/__pycache__/settings.cpython-311.pyc and b/impuls/__pycache__/settings.cpython-311.pyc differ diff --git a/impuls/__pycache__/urls.cpython-311.pyc b/impuls/__pycache__/urls.cpython-311.pyc index d591439e..5ba46589 100644 Binary files a/impuls/__pycache__/urls.cpython-311.pyc and b/impuls/__pycache__/urls.cpython-311.pyc differ diff --git a/impuls/urls.py b/impuls/urls.py index 38f0d4fd..5f4b74d2 100644 --- a/impuls/urls.py +++ b/impuls/urls.py @@ -15,7 +15,7 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path +from django.urls import path, include from django.conf import settings from website.views import newspage, post, about, search, home, contact, datenschutz, impressum, anmeldung, tagungsplan, success, failure @@ -34,4 +34,5 @@ urlpatterns = [ path('tagungsplan/', tagungsplan, name = 'tagungsplan'), path('success/', success, name = 'success'), path('failure/', failure, name = 'failure'), + path('captcha/', include('captcha.urls')), ] diff --git a/lib/python3.11/site-packages/captcha/__init__.py b/lib/python3.11/site-packages/captcha/__init__.py new file mode 100644 index 00000000..0b612318 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/__init__.py @@ -0,0 +1,6 @@ +VERSION = (0, 5, 20) + + +def get_version(): + "Return the version as a human-format string." + return ".".join([str(i) for i in VERSION]) diff --git a/lib/python3.11/site-packages/captcha/__pycache__/__init__.cpython-311.pyc b/lib/python3.11/site-packages/captcha/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..e9f034af Binary files /dev/null and b/lib/python3.11/site-packages/captcha/__pycache__/__init__.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/__pycache__/fields.cpython-311.pyc b/lib/python3.11/site-packages/captcha/__pycache__/fields.cpython-311.pyc new file mode 100644 index 00000000..c495e0a9 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/__pycache__/fields.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/__pycache__/helpers.cpython-311.pyc b/lib/python3.11/site-packages/captcha/__pycache__/helpers.cpython-311.pyc new file mode 100644 index 00000000..73d2ae13 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/__pycache__/helpers.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/__pycache__/models.cpython-311.pyc b/lib/python3.11/site-packages/captcha/__pycache__/models.cpython-311.pyc new file mode 100644 index 00000000..ff1c02a7 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/__pycache__/models.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/__pycache__/urls.cpython-311.pyc b/lib/python3.11/site-packages/captcha/__pycache__/urls.cpython-311.pyc new file mode 100644 index 00000000..a65b700d Binary files /dev/null and b/lib/python3.11/site-packages/captcha/__pycache__/urls.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/__pycache__/views.cpython-311.pyc b/lib/python3.11/site-packages/captcha/__pycache__/views.cpython-311.pyc new file mode 100644 index 00000000..65193868 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/__pycache__/views.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/pip-23.2.1.dist-info/REQUESTED b/lib/python3.11/site-packages/captcha/conf/__init__.py similarity index 100% rename from lib/python3.11/site-packages/pip-23.2.1.dist-info/REQUESTED rename to lib/python3.11/site-packages/captcha/conf/__init__.py diff --git a/lib/python3.11/site-packages/captcha/conf/__pycache__/__init__.cpython-311.pyc b/lib/python3.11/site-packages/captcha/conf/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..a6021fc0 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/conf/__pycache__/__init__.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/conf/__pycache__/settings.cpython-311.pyc b/lib/python3.11/site-packages/captcha/conf/__pycache__/settings.cpython-311.pyc new file mode 100644 index 00000000..9c1a36bd Binary files /dev/null and b/lib/python3.11/site-packages/captcha/conf/__pycache__/settings.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/conf/settings.py b/lib/python3.11/site-packages/captcha/conf/settings.py new file mode 100644 index 00000000..f31cdd07 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/conf/settings.py @@ -0,0 +1,99 @@ +import os +import warnings + +from django.conf import settings + + +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_LETTER_ROTATION = getattr(settings, "CAPTCHA_LETTER_ROTATION", (-35, 35)) +CAPTCHA_BACKGROUND_COLOR = getattr(settings, "CAPTCHA_BACKGROUND_COLOR", "#ffffff") +CAPTCHA_FOREGROUND_COLOR = getattr(settings, "CAPTCHA_FOREGROUND_COLOR", "#001100") +CAPTCHA_CHALLENGE_FUNCT = getattr( + settings, "CAPTCHA_CHALLENGE_FUNCT", "captcha.helpers.random_char_challenge" +) +CAPTCHA_NOISE_FUNCTIONS = getattr( + settings, + "CAPTCHA_NOISE_FUNCTIONS", + ("captcha.helpers.noise_arcs", "captcha.helpers.noise_dots"), +) +CAPTCHA_FILTER_FUNCTIONS = getattr( + settings, "CAPTCHA_FILTER_FUNCTIONS", ("captcha.helpers.post_smooth",) +) +CAPTCHA_WORDS_DICTIONARY = getattr( + settings, "CAPTCHA_WORDS_DICTIONARY", "/usr/share/dict/words" +) +CAPTCHA_PUNCTUATION = getattr(settings, "CAPTCHA_PUNCTUATION", """_"',.;:-""") +CAPTCHA_FLITE_PATH = getattr(settings, "CAPTCHA_FLITE_PATH", None) +CAPTCHA_SOX_PATH = getattr(settings, "CAPTCHA_SOX_PATH", None) +CAPTCHA_TIMEOUT = getattr(settings, "CAPTCHA_TIMEOUT", 5) # Minutes +CAPTCHA_LENGTH = int(getattr(settings, "CAPTCHA_LENGTH", 4)) # Chars +# CAPTCHA_IMAGE_BEFORE_FIELD = getattr(settings, 'CAPTCHA_IMAGE_BEFORE_FIELD', True) +CAPTCHA_DICTIONARY_MIN_LENGTH = getattr(settings, "CAPTCHA_DICTIONARY_MIN_LENGTH", 0) +CAPTCHA_DICTIONARY_MAX_LENGTH = getattr(settings, "CAPTCHA_DICTIONARY_MAX_LENGTH", 99) +CAPTCHA_IMAGE_SIZE = getattr(settings, "CAPTCHA_IMAGE_SIZE", None) +CAPTCHA_IMAGE_TEMPLATE = getattr( + settings, "CAPTCHA_IMAGE_TEMPLATE", "captcha/image.html" +) +CAPTCHA_HIDDEN_FIELD_TEMPLATE = getattr( + settings, "CAPTCHA_HIDDEN_FIELD_TEMPLATE", "captcha/hidden_field.html" +) +CAPTCHA_TEXT_FIELD_TEMPLATE = getattr( + settings, "CAPTCHA_TEXT_FIELD_TEMPLATE", "captcha/text_field.html" +) + +if getattr(settings, "CAPTCHA_FIELD_TEMPLATE", None): + msg = "CAPTCHA_FIELD_TEMPLATE setting is deprecated in favor of widget's template_name." + warnings.warn(msg, DeprecationWarning) +CAPTCHA_FIELD_TEMPLATE = getattr(settings, "CAPTCHA_FIELD_TEMPLATE", None) +if getattr(settings, "CAPTCHA_OUTPUT_FORMAT", None): + msg = "CAPTCHA_OUTPUT_FORMAT setting is deprecated in favor of widget's template_name." + warnings.warn(msg, DeprecationWarning) +CAPTCHA_OUTPUT_FORMAT = getattr(settings, "CAPTCHA_OUTPUT_FORMAT", None) + +CAPTCHA_MATH_CHALLENGE_OPERATOR = getattr( + settings, "CAPTCHA_MATH_CHALLENGE_OPERATOR", "*" +) +CAPTCHA_GET_FROM_POOL = getattr(settings, "CAPTCHA_GET_FROM_POOL", False) +CAPTCHA_GET_FROM_POOL_TIMEOUT = getattr(settings, "CAPTCHA_GET_FROM_POOL_TIMEOUT", 5) + +CAPTCHA_TEST_MODE = getattr(settings, "CAPTCHA_TEST_MODE", False) + +CAPTCHA_2X_IMAGE = getattr(settings, "CAPTCHA_2X_IMAGE", True) + +# Failsafe +if CAPTCHA_DICTIONARY_MIN_LENGTH > CAPTCHA_DICTIONARY_MAX_LENGTH: + CAPTCHA_DICTIONARY_MIN_LENGTH, CAPTCHA_DICTIONARY_MAX_LENGTH = ( + CAPTCHA_DICTIONARY_MAX_LENGTH, + CAPTCHA_DICTIONARY_MIN_LENGTH, + ) + + +def _callable_from_string(string_or_callable): + if callable(string_or_callable): + return string_or_callable + else: + return getattr( + __import__(".".join(string_or_callable.split(".")[:-1]), {}, {}, [""]), + string_or_callable.split(".")[-1], + ) + + +def get_challenge(generator=None): + return _callable_from_string(generator or CAPTCHA_CHALLENGE_FUNCT) + + +def noise_functions(): + if CAPTCHA_NOISE_FUNCTIONS: + return map(_callable_from_string, CAPTCHA_NOISE_FUNCTIONS) + return [] + + +def filter_functions(): + if CAPTCHA_FILTER_FUNCTIONS: + return map(_callable_from_string, CAPTCHA_FILTER_FUNCTIONS) + return [] diff --git a/lib/python3.11/site-packages/captcha/fields.py b/lib/python3.11/site-packages/captcha/fields.py new file mode 100644 index 00000000..6aa4e59d --- /dev/null +++ b/lib/python3.11/site-packages/captcha/fields.py @@ -0,0 +1,276 @@ +import warnings + +import django +from django.core.exceptions import ImproperlyConfigured +from django.forms import ValidationError +from django.forms.fields import CharField, MultiValueField +from django.forms.widgets import HiddenInput, MultiWidget, TextInput +from django.template.loader import render_to_string +from django.urls import NoReverseMatch, reverse +from django.utils import timezone +from django.utils.safestring import mark_safe +from django.utils.translation import gettext_lazy + +from captcha.conf import settings +from captcha.models import CaptchaStore + + +class CaptchaHiddenInput(HiddenInput): + """Hidden input for the captcha key.""" + + # Use *args and **kwargs because signature changed in Django 1.11 + def build_attrs(self, *args, **kwargs): + """Disable autocomplete to prevent problems on page reload.""" + + attrs = super().build_attrs(*args, **kwargs) + attrs["autocomplete"] = "off" + return attrs + + +class CaptchaAnswerInput(TextInput): + """Text input for captcha answer.""" + + # Use *args and **kwargs because signature changed in Django 1.11 + def build_attrs(self, *args, **kwargs): + """Disable automatic corrections and completions.""" + attrs = super().build_attrs(*args, **kwargs) + attrs["autocapitalize"] = "off" + attrs["autocomplete"] = "off" + attrs["autocorrect"] = "off" + attrs["spellcheck"] = "false" + return attrs + + +class BaseCaptchaTextInput(MultiWidget): + """ + Base class for Captcha widgets + """ + + def __init__(self, attrs=None): + widgets = (CaptchaHiddenInput(attrs), CaptchaAnswerInput(attrs)) + super(BaseCaptchaTextInput, self).__init__(widgets, attrs) + + def decompress(self, value): + if value: + return value.split(",") + return [None, None] + + def fetch_captcha_store(self, name, value, attrs=None, generator=None): + """ + Fetches a new CaptchaStore + This has to be called inside render + """ + try: + reverse("captcha-image", args=("dummy",)) + except NoReverseMatch: + raise ImproperlyConfigured( + "Make sure you've included captcha.urls as explained in the INSTALLATION section on http://readthedocs.org/docs/django-simple-captcha/en/latest/usage.html#installation" + ) + + if settings.CAPTCHA_GET_FROM_POOL: + key = CaptchaStore.pick() + else: + key = CaptchaStore.generate_key(generator) + + # these can be used by format_output and render + self._value = [key, ""] + self._key = key + self.id_ = self.build_attrs(attrs).get("id", None) + + def id_for_label(self, id_): + if id_: + return id_ + "_1" + return id_ + + def image_url(self): + return reverse("captcha-image", kwargs={"key": self._key}) + + def audio_url(self): + return ( + reverse("captcha-audio", kwargs={"key": self._key}) + if settings.CAPTCHA_FLITE_PATH + else None + ) + + def refresh_url(self): + return reverse("captcha-refresh") + + +class CaptchaTextInput(BaseCaptchaTextInput): + + template_name = "captcha/widgets/captcha.html" + + def __init__( + self, + attrs=None, + field_template=None, + id_prefix=None, + generator=None, + output_format=None, + ): + self.id_prefix = id_prefix + self.generator = generator + if field_template is not None: + msg = "CaptchaTextInput's field_template argument is deprecated in favor of widget's template_name." + warnings.warn(msg, DeprecationWarning) + self.field_template = field_template or settings.CAPTCHA_FIELD_TEMPLATE + if output_format is not None: + msg = "CaptchaTextInput's output_format argument is deprecated in favor of widget's template_name." + warnings.warn(msg, DeprecationWarning) + self.output_format = output_format or settings.CAPTCHA_OUTPUT_FORMAT + # Fallback to custom rendering in Django < 1.11 + if ( + not hasattr(self, "_render") + and self.field_template is None + and self.output_format is None + ): + self.field_template = "captcha/field.html" + + if self.output_format: + for key in ("image", "hidden_field", "text_field"): + if "%%(%s)s" % key not in self.output_format: + raise ImproperlyConfigured( + "All of %s must be present in your CAPTCHA_OUTPUT_FORMAT setting. Could not find %s" + % ( + ", ".join( + [ + "%%(%s)s" % k + for k in ("image", "hidden_field", "text_field") + ] + ), + "%%(%s)s" % key, + ) + ) + + super(CaptchaTextInput, self).__init__(attrs) + + def build_attrs(self, *args, **kwargs): + ret = super(CaptchaTextInput, self).build_attrs(*args, **kwargs) + if self.id_prefix and "id" in ret: + ret["id"] = "%s_%s" % (self.id_prefix, ret["id"]) + return ret + + def id_for_label(self, id_): + ret = super(CaptchaTextInput, self).id_for_label(id_) + if self.id_prefix and "id" in ret: + ret = "%s_%s" % (self.id_prefix, ret) + return ret + + def get_context(self, name, value, attrs): + """Add captcha specific variables to context.""" + context = super(CaptchaTextInput, self).get_context(name, value, attrs) + context["image"] = self.image_url() + context["audio"] = self.audio_url() + return context + + def format_output(self, rendered_widgets): + # hidden_field, text_field = rendered_widgets + if self.output_format: + ret = self.output_format % { + "image": self.image_and_audio, + "hidden_field": self.hidden_field, + "text_field": self.text_field, + } + return ret + + elif self.field_template: + context = { + "image": mark_safe(self.image_and_audio), + "hidden_field": mark_safe(self.hidden_field), + "text_field": mark_safe(self.text_field), + } + return render_to_string(self.field_template, context) + + def _direct_render(self, name, attrs): + """Render the widget the old way - using field_template or output_format.""" + context = { + "image": self.image_url(), + "name": name, + "key": self._key, + "id": "%s_%s" % (self.id_prefix, attrs.get("id")) + if self.id_prefix + else attrs.get("id"), + "audio": self.audio_url(), + } + self.image_and_audio = render_to_string( + settings.CAPTCHA_IMAGE_TEMPLATE, context + ) + self.hidden_field = render_to_string( + settings.CAPTCHA_HIDDEN_FIELD_TEMPLATE, context + ) + self.text_field = render_to_string( + settings.CAPTCHA_TEXT_FIELD_TEMPLATE, context + ) + return self.format_output(None) + + def render(self, name, value, attrs=None, renderer=None): + self.fetch_captcha_store(name, value, attrs, self.generator) + + if self.field_template or self.output_format: + return self._direct_render(name, attrs) + + extra_kwargs = {} + if django.VERSION >= (1, 11): + # https://docs.djangoproject.com/en/1.11/ref/forms/widgets/#django.forms.Widget.render + extra_kwargs["renderer"] = renderer + + return super(CaptchaTextInput, self).render( + name, self._value, attrs=attrs, **extra_kwargs + ) + + +class CaptchaField(MultiValueField): + def __init__(self, *args, **kwargs): + fields = (CharField(show_hidden_initial=True), CharField()) + if "error_messages" not in kwargs or "invalid" not in kwargs.get( + "error_messages" + ): + if "error_messages" not in kwargs: + kwargs["error_messages"] = {} + kwargs["error_messages"].update( + {"invalid": gettext_lazy("Invalid CAPTCHA")} + ) + + kwargs["widget"] = kwargs.pop( + "widget", + CaptchaTextInput( + output_format=kwargs.pop("output_format", None), + id_prefix=kwargs.pop("id_prefix", None), + generator=kwargs.pop("generator", None), + ), + ) + + super(CaptchaField, self).__init__(fields, *args, **kwargs) + + def compress(self, data_list): + if data_list: + return ",".join(data_list) + return None + + def clean(self, value): + super(CaptchaField, self).clean(value) + response, value[1] = (value[1] or "").strip().lower(), "" + if not settings.CAPTCHA_GET_FROM_POOL: + CaptchaStore.remove_expired() + if settings.CAPTCHA_TEST_MODE and response.lower() == "passed": + # automatically pass the test + try: + # try to delete the captcha based on its hash + CaptchaStore.objects.get(hashkey=value[0]).delete() + except CaptchaStore.DoesNotExist: + # ignore errors + pass + elif not self.required and not response: + pass + else: + try: + CaptchaStore.objects.get( + response=response, hashkey=value[0], expiration__gt=timezone.now() + ).delete() + except CaptchaStore.DoesNotExist: + raise ValidationError( + getattr(self, "error_messages", {}).get( + "invalid", gettext_lazy("Invalid CAPTCHA") + ) + ) + return value diff --git a/lib/python3.11/site-packages/captcha/fonts/COPYRIGHT.TXT b/lib/python3.11/site-packages/captcha/fonts/COPYRIGHT.TXT new file mode 100644 index 00000000..bb7523a0 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/fonts/COPYRIGHT.TXT @@ -0,0 +1,123 @@ +Bitstream Vera Fonts Copyright + +The fonts have a generous copyright, allowing derivative works (as +long as "Bitstream" or "Vera" are not in the names), and full +redistribution (so long as they are not *sold* by themselves). They +can be be bundled, redistributed and sold with any software. + +The fonts are distributed under the following copyright: + +Copyright +========= + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream +Vera is a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute +the Font Software, including without limitation the rights to use, +copy, merge, publish, distribute, and/or sell copies of the Font +Software, and to permit persons to whom the Font Software is furnished +to do so, subject to the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Bitstream" or the word "Vera". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Bitstream Vera" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, +OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT +SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font +Software without prior written authorization from the Gnome Foundation +or Bitstream Inc., respectively. For further information, contact: +fonts at gnome dot org. + +Copyright FAQ +============= + + 1. I don't understand the resale restriction... What gives? + + Bitstream is giving away these fonts, but wishes to ensure its + competitors can't just drop the fonts as is into a font sale system + and sell them as is. It seems fair that if Bitstream can't make money + from the Bitstream Vera fonts, their competitors should not be able to + do so either. You can sell the fonts as part of any software package, + however. + + 2. I want to package these fonts separately for distribution and + sale as part of a larger software package or system. Can I do so? + + Yes. A RPM or Debian package is a "larger software package" to begin + with, and you aren't selling them independently by themselves. + See 1. above. + + 3. Are derivative works allowed? + Yes! + + 4. Can I change or add to the font(s)? + Yes, but you must change the name(s) of the font(s). + + 5. Under what terms are derivative works allowed? + + You must change the name(s) of the fonts. This is to ensure the + quality of the fonts, both to protect Bitstream and Gnome. We want to + ensure that if an application has opened a font specifically of these + names, it gets what it expects (though of course, using fontconfig, + substitutions could still could have occurred during font + opening). You must include the Bitstream copyright. Additional + copyrights can be added, as per copyright law. Happy Font Hacking! + + 6. If I have improvements for Bitstream Vera, is it possible they might get + adopted in future versions? + + Yes. The contract between the Gnome Foundation and Bitstream has + provisions for working with Bitstream to ensure quality additions to + the Bitstream Vera font family. Please contact us if you have such + additions. Note, that in general, we will want such additions for the + entire family, not just a single font, and that you'll have to keep + both Gnome and Jim Lyles, Vera's designer, happy! To make sense to add + glyphs to the font, they must be stylistically in keeping with Vera's + design. Vera cannot become a "ransom note" font. Jim Lyles will be + providing a document describing the design elements used in Vera, as a + guide and aid for people interested in contributing to Vera. + + 7. I want to sell a software package that uses these fonts: Can I do so? + + Sure. Bundle the fonts with your software and sell your software + with the fonts. That is the intent of the copyright. + + 8. If applications have built the names "Bitstream Vera" into them, + can I override this somehow to use fonts of my choosing? + + This depends on exact details of the software. Most open source + systems and software (e.g., Gnome, KDE, etc.) are now converting to + use fontconfig (see www.fontconfig.org) to handle font configuration, + selection and substitution; it has provisions for overriding font + names and substituting alternatives. An example is provided by the + supplied local.conf file, which chooses the family Bitstream Vera for + "sans", "serif" and "monospace". Other software (e.g., the XFree86 + core server) has other mechanisms for font substitution. diff --git a/lib/python3.11/site-packages/captcha/fonts/README.TXT b/lib/python3.11/site-packages/captcha/fonts/README.TXT new file mode 100644 index 00000000..1cf37bdb --- /dev/null +++ b/lib/python3.11/site-packages/captcha/fonts/README.TXT @@ -0,0 +1,11 @@ +Contained herin is the Bitstream Vera font family. + +The Copyright information is found in the COPYRIGHT.TXT file (along +with being incorporated into the fonts themselves). + +The releases notes are found in the file "RELEASENOTES.TXT". + +We hope you enjoy Vera! + + Bitstream, Inc. + The Gnome Project diff --git a/lib/python3.11/site-packages/captcha/fonts/Vera.ttf b/lib/python3.11/site-packages/captcha/fonts/Vera.ttf new file mode 100644 index 00000000..58cd6b5e Binary files /dev/null and b/lib/python3.11/site-packages/captcha/fonts/Vera.ttf differ diff --git a/lib/python3.11/site-packages/captcha/helpers.py b/lib/python3.11/site-packages/captcha/helpers.py new file mode 100644 index 00000000..c4338fa5 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/helpers.py @@ -0,0 +1,105 @@ +import random + +from django.urls import reverse + +from captcha.conf import settings + + +def math_challenge(): + operators = ("+", "*", "-") + operands = (random.randint(1, 10), random.randint(1, 10)) + operator = random.choice(operators) + if operands[0] < operands[1] and "-" == operator: + operands = (operands[1], operands[0]) + challenge = "%d%s%d" % (operands[0], operator, operands[1]) + return ( + "{}=".format(challenge.replace("*", settings.CAPTCHA_MATH_CHALLENGE_OPERATOR)), + str(eval(challenge)), + ) + + +def random_char_challenge(): + chars, ret = "abcdefghijklmnopqrstuvwxyz", "" + for i in range(settings.CAPTCHA_LENGTH): + ret += random.choice(chars) + return ret.upper(), ret + + +def unicode_challenge(): + chars, ret = "äàáëéèïíîöóòüúù", "" + for i in range(settings.CAPTCHA_LENGTH): + ret += random.choice(chars) + return ret.upper(), ret + + +def word_challenge(): + fd = open(settings.CAPTCHA_WORDS_DICTIONARY, "r") + lines = fd.readlines() + fd.close() + while True: + word = random.choice(lines).strip() + if ( + len(word) >= settings.CAPTCHA_DICTIONARY_MIN_LENGTH + and len(word) <= settings.CAPTCHA_DICTIONARY_MAX_LENGTH + ): + break + return word.upper(), word.lower() + + +def huge_words_and_punctuation_challenge(): + "Yay, undocumneted. Mostly used to test Issue 39 - http://code.google.com/p/django-simple-captcha/issues/detail?id=39" + fd = open(settings.CAPTCHA_WORDS_DICTIONARY, "rb") + lines = fd.readlines() + fd.close() + word = "" + while True: + word1 = random.choice(lines).strip() + word2 = random.choice(lines).strip() + punct = random.choice(settings.CAPTCHA_PUNCTUATION) + word = "%s%s%s" % (word1, punct, word2) + if ( + len(word) >= settings.CAPTCHA_DICTIONARY_MIN_LENGTH + and len(word) <= settings.CAPTCHA_DICTIONARY_MAX_LENGTH + ): + break + return word.upper(), word.lower() + + +def noise_arcs(draw, image): + size = image.size + draw.arc([-20, -20, size[0], 20], 0, 295, fill=settings.CAPTCHA_FOREGROUND_COLOR) + draw.line( + [-20, 20, size[0] + 20, size[1] - 20], fill=settings.CAPTCHA_FOREGROUND_COLOR + ) + draw.line([-20, 0, size[0] + 20, size[1]], fill=settings.CAPTCHA_FOREGROUND_COLOR) + return draw + + +def noise_dots(draw, image): + size = image.size + for p in range(int(size[0] * size[1] * 0.1)): + draw.point( + (random.randint(0, size[0]), random.randint(0, size[1])), + fill=settings.CAPTCHA_FOREGROUND_COLOR, + ) + return draw + + +def noise_null(draw, image): + return draw + + +def post_smooth(image): + from PIL import ImageFilter + + return image.filter(ImageFilter.SMOOTH) + + +def captcha_image_url(key): + """Return url to image. Need for ajax refresh and, etc""" + return reverse("captcha-image", args=[key]) + + +def captcha_audio_url(key): + """Return url to image. Need for ajax refresh and, etc""" + return reverse("captcha-audio", args=[key]) diff --git a/lib/python3.11/site-packages/captcha/jinja2/captcha/widgets/captcha.html b/lib/python3.11/site-packages/captcha/jinja2/captcha/widgets/captcha.html new file mode 100644 index 00000000..5531a1e8 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/jinja2/captcha/widgets/captcha.html @@ -0,0 +1,2 @@ +{% if audio %}{% endif %}captcha{% if audio %}{% endif %} +{% include "django/forms/widgets/multiwidget.html" %} diff --git a/lib/python3.11/site-packages/captcha/locale/bg/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/bg/LC_MESSAGES/django.mo new file mode 100644 index 00000000..79f3bffe Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/bg/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/bg/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/bg/LC_MESSAGES/django.po new file mode 100644 index 00000000..b384c573 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/bg/LC_MESSAGES/django.po @@ -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 , 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 \n" +"Language-Team: bg \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 "Това поле е задължително" diff --git a/lib/python3.11/site-packages/captcha/locale/cs/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/cs/LC_MESSAGES/django.mo new file mode 100644 index 00000000..2b086252 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/cs/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/cs/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/cs/LC_MESSAGES/django.po new file mode 100644 index 00000000..21ef0297 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/cs/LC_MESSAGES/django.po @@ -0,0 +1,30 @@ +# Czech translation of django-simple-captcha. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Beda Kosata , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: 0.3.5\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-10-09 07:05+0200\n" +"PO-Revision-Date: 2012-10-09 07:08+0200\n" +"Last-Translator: Beda Kosata \n" +"Language-Team: Czech <>\n" +"Language: cs\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:50 +msgid "Play CAPTCHA as audio file" +msgstr "Přehrát captchu jako audio soubor" + +#: fields.py:67 fields.py:99 tests/__init__.py:62 +msgid "Invalid CAPTCHA" +msgstr "Neplatná CAPTCHA" + +#: tests/__init__.py:88 +msgid "This field is required." +msgstr "Toto pole je povinné." diff --git a/lib/python3.11/site-packages/captcha/locale/de/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/de/LC_MESSAGES/django.mo new file mode 100644 index 00000000..3d7fbfbe Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/de/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/de/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/de/LC_MESSAGES/django.po new file mode 100644 index 00000000..0c446eba --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/de/LC_MESSAGES/django.po @@ -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 , 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: 2013-07-16 12:10+0100\n" +"Last-Translator: Patrick Lauber \n" +"Language-Team: DE \n" +"Language: de\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.5.7\n" + +#: fields.py:90 +msgid "Play CAPTCHA as audio file" +msgstr "CAPTCHA als Audiodatei abspielen." + +#: fields.py:105 fields.py:134 tests/tests.py:99 tests/tests.py:239 +#: tests/tests.py:246 +msgid "Invalid CAPTCHA" +msgstr "Ungültiges CAPTCHA" + +#: tests/tests.py:125 +msgid "This field is required." +msgstr "Dieses Feld wird benötigt." diff --git a/lib/python3.11/site-packages/captcha/locale/en/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/en/LC_MESSAGES/django.mo new file mode 100644 index 00000000..851e9562 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/en/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/en/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/en/LC_MESSAGES/django.po new file mode 100644 index 00000000..870d08e8 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,30 @@ +# django-simple-captcha French translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Patrick Samson , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.2.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-07-25 11:44+0300\n" +"PO-Revision-Date: 2010-09-16 12:16+0200\n" +"Last-Translator: Marco Bonetti \n" +"Language-Team: en \n" +"Language: en\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:49 +msgid "Play CAPTCHA as audio file" +msgstr "Play CAPTCHA as audio file" + +#: fields.py:66 fields.py:89 tests/__init__.py:62 +msgid "Invalid CAPTCHA" +msgstr "Invalid CAPTCHA" + +#: tests/__init__.py:88 +msgid "This field is required." +msgstr "This field is required." diff --git a/lib/python3.11/site-packages/captcha/locale/es/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/es/LC_MESSAGES/django.mo new file mode 100644 index 00000000..af8f4816 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/es/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/es/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/es/LC_MESSAGES/django.po new file mode 100644 index 00000000..bd44d3ee --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/es/LC_MESSAGES/django.po @@ -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 , 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." diff --git a/lib/python3.11/site-packages/captcha/locale/fa/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/fa/LC_MESSAGES/django.mo new file mode 100644 index 00000000..195c7ad1 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/fa/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/fa/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/fa/LC_MESSAGES/django.po new file mode 100644 index 00000000..ccd8a3f1 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/fa/LC_MESSAGES/django.po @@ -0,0 +1,31 @@ +# django-simple-captcha French translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Patrick Samson , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.2.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-07-25 11:44+0300\n" +"PO-Revision-Date: 2020-10-04 19:08+0330\n" +"Last-Translator: Mehdi Namaki \n" +"Language-Team: fa \n" +"Language: fa\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 2.3\n" + +#: fields.py:49 +msgid "Play CAPTCHA as audio file" +msgstr "پخش کد امنیتی به عنوان یک پرونده صوتی" + +#: fields.py:66 fields.py:89 tests/__init__.py:62 +msgid "Invalid CAPTCHA" +msgstr "کد امنیتی صحیح نیست" + +#: tests/__init__.py:88 +msgid "This field is required." +msgstr "این فیلد اجباری است." diff --git a/lib/python3.11/site-packages/captcha/locale/fr/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 00000000..1b539cf4 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/fr/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/fr/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 00000000..6bf14f12 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,30 @@ +# django-simple-captcha French translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Patrick Samson , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.2.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-07-25 11:44+0300\n" +"PO-Revision-Date: 2010-09-16 12:16+0200\n" +"Last-Translator: Patrick Samson \n" +"Language-Team: fr \n" +"Language: fr\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:49 +msgid "Play CAPTCHA as audio file" +msgstr "Écouter la version audio" + +#: fields.py:66 fields.py:89 tests/__init__.py:62 +msgid "Invalid CAPTCHA" +msgstr "CAPTCHA invalide" + +#: tests/__init__.py:88 +msgid "This field is required." +msgstr "Ce champ est obligatoire." diff --git a/lib/python3.11/site-packages/captcha/locale/it/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/it/LC_MESSAGES/django.mo new file mode 100644 index 00000000..ad235d1d Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/it/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/it/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/it/LC_MESSAGES/django.po new file mode 100644 index 00000000..03a5851f --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/it/LC_MESSAGES/django.po @@ -0,0 +1,30 @@ +# django-simple-captcha Italian translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Arjuna Del Toso , 2012 +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.3.6\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-11-14 02:53+0000\n" +"PO-Revision-Date: 2012-11-14 02:53+0000\n" +"Last-Translator: Arjuna Del Toso \n" +"MIME-Version: 1.0\n" +"Language-Team: Arjuna Del Toso \n" +"Language: it\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n>1;\n" + +#: .\fields.py:56 +msgid "Play CAPTCHA as audio file" +msgstr "Ascolta la parola di controllo" + +#: .\fields.py:71 .\fields.py:96 .\tests\__init__.py:70 +msgid "Invalid CAPTCHA" +msgstr "Parola di controllo sbagliata" + +#: .\tests\__init__.py:97 +msgid "This field is required." +msgstr "Questo campo è obbligatorio" diff --git a/lib/python3.11/site-packages/captcha/locale/ja/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/ja/LC_MESSAGES/django.mo new file mode 100644 index 00000000..12f291ee Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/ja/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/ja/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/ja/LC_MESSAGES/django.po new file mode 100644 index 00000000..f2aafbb5 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/ja/LC_MESSAGES/django.po @@ -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 , 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 \n" +"Language-Team: Keisuke URAGO \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 "この項目は必須です" diff --git a/lib/python3.11/site-packages/captcha/locale/nl/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/nl/LC_MESSAGES/django.mo new file mode 100644 index 00000000..7428e78b Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/nl/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/nl/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/nl/LC_MESSAGES/django.po new file mode 100644 index 00000000..bf69a6a9 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/nl/LC_MESSAGES/django.po @@ -0,0 +1,31 @@ +# django-simple-captcha Dutch translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Leon de Rijke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.3.6\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-02-15 13:26+0100\n" +"PO-Revision-Date: 2013-02-15 13:26+0100\n" +"Last-Translator: Leon de Rijke \n" +"MIME-Version: 1.0\n" +"Language-Team: Leon de Rijke \n" +"Language: nl\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: fields.py:50 +msgid "Play CAPTCHA as audio file" +msgstr "Speel CAPTCHA als audiobestand af" + +#: fields.py:67 fields.py:94 tests/__init__.py:64 tests/__init__.py:186 +#: tests/__init__.py:193 +msgid "Invalid CAPTCHA" +msgstr "CAPTCHA ongeldig, probeer het opnieuw" + +#: tests/__init__.py:90 +msgid "This field is required." +msgstr "Dit veld is verplicht." diff --git a/lib/python3.11/site-packages/captcha/locale/pl/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/pl/LC_MESSAGES/django.mo new file mode 100644 index 00000000..39c7ef90 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/pl/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/pl/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/pl/LC_MESSAGES/django.po new file mode 100644 index 00000000..8af4b949 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/pl/LC_MESSAGES/django.po @@ -0,0 +1,32 @@ +# Polish translation for django-simple-captcha. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the django-simple-captcha package. +# Sławomir Zborowski , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.3.6\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-08-18 18:49+0200\n" +"PO-Revision-Date: 2013-08-18 18:52+0200\n" +"Last-Translator: Sławomir Zborowski \n" +"Language-Team: Polisch\n" +"Language: pl\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%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2)\n" + +#: fields.py:90 +msgid "Play CAPTCHA as audio file" +msgstr "Odtwórz CAPTCHĘ jako plik dźwiękowy" + +#: fields.py:105 fields.py:134 tests/tests.py:99 tests/tests.py:239 +#: tests/tests.py:246 +msgid "Invalid CAPTCHA" +msgstr "Niepoprawnie wpisana CAPTCHA" + +#: tests/tests.py:125 +msgid "This field is required." +msgstr "To pole jest wymagane." diff --git a/lib/python3.11/site-packages/captcha/locale/pt_BR/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/pt_BR/LC_MESSAGES/django.mo new file mode 100644 index 00000000..8b5473b1 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/pt_BR/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/pt_BR/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/pt_BR/LC_MESSAGES/django.po new file mode 100644 index 00000000..47e84f12 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/pt_BR/LC_MESSAGES/django.po @@ -0,0 +1,31 @@ +# django-simple-captcha Portuguese (Brazilian) translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Alisson Patricio , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.3.7\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-05-18 10:58-0300\n" +"PO-Revision-Date: 2013-05-18 13:12-0300\n" +"Last-Translator: Alisson Patricio \n" +"Language-Team: Alisson Patricio \n" +"Language: pt_br\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:49 +msgid "Play CAPTCHA as audio file" +msgstr "Ouça o arquivo de áudio" + +#: fields.py:66 fields.py:93 tests/__init__.py:69 +#: tests/__init__.py:198 tests/__init__.py:205 +msgid "Invalid CAPTCHA" +msgstr "Resposta inválida" + +#: tests/__init__.py:95 +msgid "This field is required." +msgstr "Este campo é obrigatório." diff --git a/lib/python3.11/site-packages/captcha/locale/ru/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/ru/LC_MESSAGES/django.mo new file mode 100644 index 00000000..2e492576 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/ru/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/ru/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/ru/LC_MESSAGES/django.po new file mode 100644 index 00000000..5c6a9f38 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/ru/LC_MESSAGES/django.po @@ -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. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.3.7\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-07-25 11:17+0300\n" +"PO-Revision-Date: 2012-07-25 11:17+0300\n" +"Last-Translator: \n" +"Language-Team: ru \n" +"Language: ru\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:49 +msgid "Play CAPTCHA as audio file" +msgstr "Воспроизвести CAPTCHA в виде аудио файла" + +#: fields.py:66 fields.py:89 tests/__init__.py:62 +msgid "Invalid CAPTCHA" +msgstr "Неверный ответ" + +#: tests/__init__.py:88 +msgid "This field is required." +msgstr "Это поле обязательно для заполнения." diff --git a/lib/python3.11/site-packages/captcha/locale/sk/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/sk/LC_MESSAGES/django.mo new file mode 100644 index 00000000..70e54231 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/sk/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/sk/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/sk/LC_MESSAGES/django.po new file mode 100644 index 00000000..f3ce9b33 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/sk/LC_MESSAGES/django.po @@ -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 , 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 \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é." diff --git a/lib/python3.11/site-packages/captcha/locale/sv/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/sv/LC_MESSAGES/django.mo new file mode 100644 index 00000000..71c1558b Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/sv/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/sv/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/sv/LC_MESSAGES/django.po new file mode 100644 index 00000000..58f60d8e --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/sv/LC_MESSAGES/django.po @@ -0,0 +1,31 @@ +# django-simple-captcha Swedish translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Stefan Norman , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.2.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-07-25 11:44+0300\n" +"PO-Revision-Date: 2018-12-03 06:41+0100\n" +"Language-Team: en \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 2.2\n" +"Last-Translator: Stefan Norman \n" +"Language: sv\n" + +#: fields.py:49 +msgid "Play CAPTCHA as audio file" +msgstr "Spela CAPTCHA som ljudfil" + +#: fields.py:66 fields.py:89 tests/__init__.py:62 +msgid "Invalid CAPTCHA" +msgstr "Ogiltig CAPTCHA" + +#: tests/__init__.py:88 +msgid "This field is required." +msgstr "Detta fält är obligatoriskt." diff --git a/lib/python3.11/site-packages/captcha/locale/tr/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/tr/LC_MESSAGES/django.mo new file mode 100644 index 00000000..74c73e30 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/tr/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/tr/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/tr/LC_MESSAGES/django.po new file mode 100644 index 00000000..ed35e2bd --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/tr/LC_MESSAGES/django.po @@ -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. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.3.6\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-01-19 16:33-0200\n" +"PO-Revision-Date: 2013-01-19 20:52+0200\n" +"Last-Translator: Gokmen Gorgen \n" +"Language-Team: TR Gokmen Gorgen \n" +"Language: tr\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:50 +msgid "Play CAPTCHA as audio file" +msgstr "Değeri ses dosyası olarak çal" + +#: fields.py:67 fields.py:94 tests/__init__.py:64 tests/__init__.py:186 +#: tests/__init__.py:193 +msgid "Invalid CAPTCHA" +msgstr "Geçersiz değer" + +#: tests/__init__.py:90 +msgid "This field is required." +msgstr "Bu alan zorunludur." diff --git a/lib/python3.11/site-packages/captcha/locale/uk/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/uk/LC_MESSAGES/django.mo new file mode 100644 index 00000000..bc2839c4 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/uk/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/uk/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/uk/LC_MESSAGES/django.po new file mode 100644 index 00000000..50c505e9 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/uk/LC_MESSAGES/django.po @@ -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 , 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 "Це поле є обов'язковим." diff --git a/lib/python3.11/site-packages/captcha/locale/zh_CN/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/zh_CN/LC_MESSAGES/django.mo new file mode 100644 index 00000000..ee43e5fc Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/zh_CN/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/zh_CN/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/zh_CN/LC_MESSAGES/django.po new file mode 100644 index 00000000..257989dd --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/zh_CN/LC_MESSAGES/django.po @@ -0,0 +1,31 @@ +# django-simple-captcha Chinese Simplified translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Ming Chen , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.3.6\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-01 05:04+0800\n" +"PO-Revision-Date: 2013-03-01 05:04+0800\n" +"Last-Translator: Ming Chen \n" +"Language-Team: zh_cn Ming Chen \n" +"Language: zh_cn\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:49 +msgid "Play CAPTCHA as audio file" +msgstr "使用语音方式播放认证码" + +#: fields.py:66 fields.py:93 tests/__init__.py:69 tests/__init__.py:198 +#: tests/__init__.py:205 +msgid "Invalid CAPTCHA" +msgstr "认证码错误" + +#: tests/__init__.py:95 +msgid "This field is required." +msgstr "这个字段是必须的" diff --git a/lib/python3.11/site-packages/captcha/locale/zh_Hans/LC_MESSAGES/django.mo b/lib/python3.11/site-packages/captcha/locale/zh_Hans/LC_MESSAGES/django.mo new file mode 100644 index 00000000..ee43e5fc Binary files /dev/null and b/lib/python3.11/site-packages/captcha/locale/zh_Hans/LC_MESSAGES/django.mo differ diff --git a/lib/python3.11/site-packages/captcha/locale/zh_Hans/LC_MESSAGES/django.po b/lib/python3.11/site-packages/captcha/locale/zh_Hans/LC_MESSAGES/django.po new file mode 100644 index 00000000..257989dd --- /dev/null +++ b/lib/python3.11/site-packages/captcha/locale/zh_Hans/LC_MESSAGES/django.po @@ -0,0 +1,31 @@ +# django-simple-captcha Chinese Simplified translation. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Ming Chen , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: django-simple-captcha 0.3.6\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-03-01 05:04+0800\n" +"PO-Revision-Date: 2013-03-01 05:04+0800\n" +"Last-Translator: Ming Chen \n" +"Language-Team: zh_cn Ming Chen \n" +"Language: zh_cn\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:49 +msgid "Play CAPTCHA as audio file" +msgstr "使用语音方式播放认证码" + +#: fields.py:66 fields.py:93 tests/__init__.py:69 tests/__init__.py:198 +#: tests/__init__.py:205 +msgid "Invalid CAPTCHA" +msgstr "认证码错误" + +#: tests/__init__.py:95 +msgid "This field is required." +msgstr "这个字段是必须的" diff --git a/lib/python3.11/site-packages/captcha/management/__init__.py b/lib/python3.11/site-packages/captcha/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/python3.11/site-packages/captcha/management/__pycache__/__init__.cpython-311.pyc b/lib/python3.11/site-packages/captcha/management/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..54ffc967 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/management/__pycache__/__init__.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/management/commands/__init__.py b/lib/python3.11/site-packages/captcha/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/python3.11/site-packages/captcha/management/commands/__pycache__/__init__.cpython-311.pyc b/lib/python3.11/site-packages/captcha/management/commands/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..a45c3d1f Binary files /dev/null and b/lib/python3.11/site-packages/captcha/management/commands/__pycache__/__init__.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/management/commands/__pycache__/captcha_clean.cpython-311.pyc b/lib/python3.11/site-packages/captcha/management/commands/__pycache__/captcha_clean.cpython-311.pyc new file mode 100644 index 00000000..f69eed18 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/management/commands/__pycache__/captcha_clean.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/management/commands/__pycache__/captcha_create_pool.cpython-311.pyc b/lib/python3.11/site-packages/captcha/management/commands/__pycache__/captcha_create_pool.cpython-311.pyc new file mode 100644 index 00000000..e274c205 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/management/commands/__pycache__/captcha_create_pool.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/management/commands/captcha_clean.py b/lib/python3.11/site-packages/captcha/management/commands/captcha_clean.py new file mode 100644 index 00000000..78c86883 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/management/commands/captcha_clean.py @@ -0,0 +1,29 @@ +import sys + +from django.core.management.base import BaseCommand +from django.utils import timezone + + +class Command(BaseCommand): + help = "Clean up expired captcha hashkeys." + + def handle(self, **options): + from captcha.models import CaptchaStore + + verbose = int(options.get("verbosity")) + expired_keys = CaptchaStore.objects.filter( + expiration__lte=timezone.now() + ).count() + if verbose >= 1: + print("Currently %d expired hashkeys" % expired_keys) + try: + CaptchaStore.remove_expired() + except Exception: + if verbose >= 1: + print("Unable to delete expired hashkeys.") + sys.exit(1) + if verbose >= 1: + if expired_keys > 0: + print("%d expired hashkeys removed." % expired_keys) + else: + print("No keys to remove.") diff --git a/lib/python3.11/site-packages/captcha/management/commands/captcha_create_pool.py b/lib/python3.11/site-packages/captcha/management/commands/captcha_create_pool.py new file mode 100644 index 00000000..ef089059 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/management/commands/captcha_create_pool.py @@ -0,0 +1,34 @@ +from django.core.management.base import BaseCommand +from django.db import transaction + +from captcha.models import CaptchaStore + + +class Command(BaseCommand): + + help = "Create a pool of random captchas." + + def add_arguments(self, parser): + parser.add_argument( + "--pool-size", + type=int, + default=1000, + help="Number of new captchas to create, default=1000", + ) + parser.add_argument( + "--cleanup-expired", + action="store_true", + default=True, + help="Cleanup expired captchas after creating new ones", + ) + + @transaction.atomic() + def handle(self, **options): + verbose = int(options.get("verbosity")) + count = options.get("pool_size") + CaptchaStore.create_pool(count) + verbose and self.stdout.write("Created %d new captchas\n" % count) + options.get("cleanup_expired") and CaptchaStore.remove_expired() + options.get("cleanup_expired") and verbose and self.stdout.write( + "Expired captchas cleaned up\n" + ) diff --git a/lib/python3.11/site-packages/captcha/migrations/0001_initial.py b/lib/python3.11/site-packages/captcha/migrations/0001_initial.py new file mode 100644 index 00000000..e12b7ef2 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/migrations/0001_initial.py @@ -0,0 +1,31 @@ +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="CaptchaStore", + fields=[ + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("challenge", models.CharField(max_length=32)), + ("response", models.CharField(max_length=32)), + ("hashkey", models.CharField(unique=True, max_length=40)), + ("expiration", models.DateTimeField()), + ], + options={}, + bases=(models.Model,), + ) + ] diff --git a/lib/python3.11/site-packages/captcha/migrations/0002_alter_captchastore_id.py b/lib/python3.11/site-packages/captcha/migrations/0002_alter_captchastore_id.py new file mode 100644 index 00000000..472352d9 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/migrations/0002_alter_captchastore_id.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2022-03-06 11:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("captcha", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="captchastore", + name="id", + field=models.AutoField(primary_key=True, serialize=False), + ), + ] diff --git a/lib/python3.11/site-packages/captcha/migrations/__init__.py b/lib/python3.11/site-packages/captcha/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/python3.11/site-packages/captcha/migrations/__pycache__/0001_initial.cpython-311.pyc b/lib/python3.11/site-packages/captcha/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 00000000..f8e32f2e Binary files /dev/null and b/lib/python3.11/site-packages/captcha/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/migrations/__pycache__/0002_alter_captchastore_id.cpython-311.pyc b/lib/python3.11/site-packages/captcha/migrations/__pycache__/0002_alter_captchastore_id.cpython-311.pyc new file mode 100644 index 00000000..b8e31147 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/migrations/__pycache__/0002_alter_captchastore_id.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/migrations/__pycache__/__init__.cpython-311.pyc b/lib/python3.11/site-packages/captcha/migrations/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..6dee34aa Binary files /dev/null and b/lib/python3.11/site-packages/captcha/migrations/__pycache__/__init__.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/models.py b/lib/python3.11/site-packages/captcha/models.py new file mode 100644 index 00000000..57d005a1 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/models.py @@ -0,0 +1,88 @@ +import datetime +import hashlib +import logging +import random +import time + +from django.db import models +from django.utils import timezone +from django.utils.encoding import smart_str + +from captcha.conf import settings as captcha_settings + + +# Heavily based on session key generation in Django +# Use the system (hardware-based) random number generator if it exists. +if hasattr(random, "SystemRandom"): + randrange = random.SystemRandom().randrange +else: + randrange = random.randrange +MAX_RANDOM_KEY = 18446744073709551616 # 2 << 63 + +logger = logging.getLogger(__name__) + + +class CaptchaStore(models.Model): + id = models.AutoField(primary_key=True) + challenge = models.CharField(blank=False, max_length=32) + response = models.CharField(blank=False, max_length=32) + hashkey = models.CharField(blank=False, max_length=40, unique=True) + expiration = models.DateTimeField(blank=False) + + def save(self, *args, **kwargs): + self.response = self.response.lower() + if not self.expiration: + self.expiration = timezone.now() + datetime.timedelta( + minutes=int(captcha_settings.CAPTCHA_TIMEOUT) + ) + if not self.hashkey: + key_ = ( + smart_str(randrange(0, MAX_RANDOM_KEY)) + + smart_str(time.time()) + + smart_str(self.challenge, errors="ignore") + + smart_str(self.response, errors="ignore") + ).encode("utf8") + self.hashkey = hashlib.sha1(key_).hexdigest() + del key_ + super(CaptchaStore, self).save(*args, **kwargs) + + def __str__(self): + return self.challenge + + def remove_expired(cls): + cls.objects.filter(expiration__lte=timezone.now()).delete() + + remove_expired = classmethod(remove_expired) + + @classmethod + def generate_key(cls, generator=None): + challenge, response = captcha_settings.get_challenge(generator)() + store = cls.objects.create(challenge=challenge, response=response) + + return store.hashkey + + @classmethod + def pick(cls): + if not captcha_settings.CAPTCHA_GET_FROM_POOL: + return cls.generate_key() + + def fallback(): + logger.error("Couldn't get a captcha from pool, generating") + return cls.generate_key() + + # Pick up a random item from pool + minimum_expiration = timezone.now() + datetime.timedelta( + minutes=int(captcha_settings.CAPTCHA_GET_FROM_POOL_TIMEOUT) + ) + store = ( + cls.objects.filter(expiration__gt=minimum_expiration).order_by("?").first() + ) + + return (store and store.hashkey) or fallback() + + @classmethod + def create_pool(cls, count=1000): + assert count > 0 + while count > 0: + cls.generate_key() + count -= 1 diff --git a/lib/python3.11/site-packages/captcha/templates/captcha/field.html b/lib/python3.11/site-packages/captcha/templates/captcha/field.html new file mode 100644 index 00000000..8c5d5d61 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/templates/captcha/field.html @@ -0,0 +1 @@ +{{image}}{{hidden_field}}{{text_field}} diff --git a/lib/python3.11/site-packages/captcha/templates/captcha/hidden_field.html b/lib/python3.11/site-packages/captcha/templates/captcha/hidden_field.html new file mode 100644 index 00000000..36d7490a --- /dev/null +++ b/lib/python3.11/site-packages/captcha/templates/captcha/hidden_field.html @@ -0,0 +1 @@ + diff --git a/lib/python3.11/site-packages/captcha/templates/captcha/image.html b/lib/python3.11/site-packages/captcha/templates/captcha/image.html new file mode 100644 index 00000000..a73e956e --- /dev/null +++ b/lib/python3.11/site-packages/captcha/templates/captcha/image.html @@ -0,0 +1,4 @@ +{% load i18n %} +{% spaceless %} + {% if audio %}{% endif %}captcha{% if audio %}{% endif %} +{% endspaceless %} diff --git a/lib/python3.11/site-packages/captcha/templates/captcha/text_field.html b/lib/python3.11/site-packages/captcha/templates/captcha/text_field.html new file mode 100644 index 00000000..fee60f44 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/templates/captcha/text_field.html @@ -0,0 +1 @@ + diff --git a/lib/python3.11/site-packages/captcha/templates/captcha/widgets/captcha.html b/lib/python3.11/site-packages/captcha/templates/captcha/widgets/captcha.html new file mode 100644 index 00000000..49faaf25 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/templates/captcha/widgets/captcha.html @@ -0,0 +1,9 @@ +{% load i18n %} +{% spaceless %} + {% if audio %} + + {% endif %} + captcha + {% if audio %}{% endif %} +{% endspaceless %} +{% include "django/forms/widgets/multiwidget.html" %} diff --git a/lib/python3.11/site-packages/captcha/tests/__init__.py b/lib/python3.11/site-packages/captcha/tests/__init__.py new file mode 100644 index 00000000..8ce44e15 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/tests/__init__.py @@ -0,0 +1 @@ +from .tests import CaptchaCase, trivial_challenge # NOQA diff --git a/lib/python3.11/site-packages/captcha/tests/__pycache__/__init__.cpython-311.pyc b/lib/python3.11/site-packages/captcha/tests/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 00000000..42a88c3e Binary files /dev/null and b/lib/python3.11/site-packages/captcha/tests/__pycache__/__init__.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/tests/__pycache__/tests.cpython-311.pyc b/lib/python3.11/site-packages/captcha/tests/__pycache__/tests.cpython-311.pyc new file mode 100644 index 00000000..8c0c5123 Binary files /dev/null and b/lib/python3.11/site-packages/captcha/tests/__pycache__/tests.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/tests/__pycache__/urls.cpython-311.pyc b/lib/python3.11/site-packages/captcha/tests/__pycache__/urls.cpython-311.pyc new file mode 100644 index 00000000..8e983e6f Binary files /dev/null and b/lib/python3.11/site-packages/captcha/tests/__pycache__/urls.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/tests/__pycache__/views.cpython-311.pyc b/lib/python3.11/site-packages/captcha/tests/__pycache__/views.cpython-311.pyc new file mode 100644 index 00000000..2abcd66b Binary files /dev/null and b/lib/python3.11/site-packages/captcha/tests/__pycache__/views.cpython-311.pyc differ diff --git a/lib/python3.11/site-packages/captcha/tests/tests.py b/lib/python3.11/site-packages/captcha/tests/tests.py new file mode 100644 index 00000000..9d0f7158 --- /dev/null +++ b/lib/python3.11/site-packages/captcha/tests/tests.py @@ -0,0 +1,594 @@ +import datetime +import json +import os +import re +import warnings +from io import BytesIO + +from PIL import Image +from testfixtures import LogCapture + +import django +from django.core import management +from django.core.exceptions import ImproperlyConfigured +from django.test import TestCase, override_settings +from django.urls import reverse +from django.utils import timezone +from django.utils.translation import gettext_lazy + +from captcha.conf import settings +from captcha.fields import CaptchaField, CaptchaTextInput +from captcha.models import CaptchaStore + + +@override_settings(ROOT_URLCONF="captcha.tests.urls") +class CaptchaCase(TestCase): + def setUp(self): + + self.stores = {} + self.__current_settings_output_format = settings.CAPTCHA_OUTPUT_FORMAT + self.__current_settings_dictionary = settings.CAPTCHA_WORDS_DICTIONARY + self.__current_settings_punctuation = settings.CAPTCHA_PUNCTUATION + + tested_helpers = [ + "captcha.helpers.math_challenge", + "captcha.helpers.random_char_challenge", + "captcha.helpers.unicode_challenge", + ] + if os.path.exists("/usr/share/dict/words"): + settings.CAPTCHA_WORDS_DICTIONARY = "/usr/share/dict/words" + settings.CAPTCHA_PUNCTUATION = ";-,." + tested_helpers.append("captcha.helpers.word_challenge") + tested_helpers.append( + "captcha.helpers.huge_words_and_punctuation_challenge" + ) + for helper in tested_helpers: + challenge, response = settings._callable_from_string(helper)() + ( + self.stores[helper.rsplit(".", 1)[-1].replace("_challenge", "_store")], + _, + ) = CaptchaStore.objects.get_or_create( + challenge=challenge, response=response + ) + challenge, response = settings.get_challenge()() + self.stores["default_store"], _ = CaptchaStore.objects.get_or_create( + challenge=challenge, response=response + ) + self.default_store = self.stores["default_store"] + + def tearDown(self): + settings.CAPTCHA_OUTPUT_FORMAT = self.__current_settings_output_format + settings.CAPTCHA_WORDS_DICTIONARY = self.__current_settings_dictionary + settings.CAPTCHA_PUNCTUATION = self.__current_settings_punctuation + + def _assertFormError(self, response, form_name, *args, **kwargs): + if django.VERSION >= (4, 1): + self.assertFormError(response.context.get(form_name), *args, **kwargs) + else: + self.assertFormError(response, form_name, *args, **kwargs) + + def __extract_hash_and_response(self, r): + hash_ = re.findall(r'value="([0-9a-f]+)"', str(r.content))[0] + response = CaptchaStore.objects.get(hashkey=hash_).response + return hash_, response + + def test_image(self): + for key in [store.hashkey for store in self.stores.values()]: + 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["content-type"], "image/png") + + def test_audio(self): + if not settings.CAPTCHA_FLITE_PATH: + return + for key in ( + self.stores.get("math_store").hashkey, + self.stores.get("math_store").hashkey, + self.default_store.hashkey, + ): + response = self.client.get(reverse("captcha-audio", kwargs=dict(key=key))) + self.assertEqual(response.status_code, 200) + self.assertTrue(response.ranged_file.size > 1024) + self.assertTrue(response.has_header("content-type")) + self.assertEqual(response["content-type"], "audio/wav") + + def test_form_submit(self): + r = self.client.get(reverse("captcha-test")) + self.assertEqual(r.status_code, 200) + hash_, response = self.__extract_hash_and_response(r) + + r = self.client.post( + reverse("captcha-test"), + dict( + captcha_0=hash_, + captcha_1=response, + subject="xxx", + sender="asasd@asdasd.com", + ), + ) + self.assertEqual(r.status_code, 200) + self.assertTrue(str(r.content).find("Form validated") > 0) + + r = self.client.post( + reverse("captcha-test"), + dict( + captcha_0=hash_, + captcha_1=response, + subject="xxx", + sender="asasd@asdasd.com", + ), + ) + self.assertEqual(r.status_code, 200) + self.assertFalse(str(r.content).find("Form validated") > 0) + + def test_modelform(self): + r = self.client.get(reverse("captcha-test-model-form")) + self.assertEqual(r.status_code, 200) + hash_, response = self.__extract_hash_and_response(r) + + r = self.client.post( + reverse("captcha-test-model-form"), + dict( + captcha_0=hash_, + captcha_1=response, + subject="xxx", + sender="asasd@asdasd.com", + ), + ) + self.assertEqual(r.status_code, 200) + self.assertTrue(str(r.content).find("Form validated") > 0) + + r = self.client.post( + reverse("captcha-test-model-form"), + dict( + captcha_0=hash_, + captcha_1=response, + subject="xxx", + sender="asasd@asdasd.com", + ), + ) + self.assertEqual(r.status_code, 200) + self.assertFalse(str(r.content).find("Form validated") > 0) + + def test_wrong_submit(self): + for urlname in ("captcha-test", "captcha-test-model-form"): + r = self.client.get(reverse(urlname)) + self.assertEqual(r.status_code, 200) + r = self.client.post( + reverse(urlname), + dict( + captcha_0="abc", + captcha_1="wrong response", + subject="xxx", + sender="asasd@asdasd.com", + ), + ) + self._assertFormError(r, "form", "captcha", gettext_lazy("Invalid CAPTCHA")) + + def test_deleted_expired(self): + self.default_store.expiration = timezone.now() - datetime.timedelta(minutes=5) + self.default_store.save() + hash_ = self.default_store.hashkey + r = self.client.post( + reverse("captcha-test"), + dict( + captcha_0=hash_, + captcha_1=self.default_store.response, + subject="xxx", + sender="asasd@asdasd.com", + ), + ) + + self.assertEqual(r.status_code, 200) + self.assertFalse("Form validated" in str(r.content)) + + # expired -> deleted + try: + CaptchaStore.objects.get(hashkey=hash_) + self.fail() + except Exception: + pass + + def test_custom_error_message(self): + r = self.client.get(reverse("captcha-test-custom-error-message")) + self.assertEqual(r.status_code, 200) + # Wrong answer + r = self.client.post( + reverse("captcha-test-custom-error-message"), + dict(captcha_0="abc", captcha_1="wrong response"), + ) + self._assertFormError(r, "form", "captcha", "TEST CUSTOM ERROR MESSAGE") + # empty answer + r = self.client.post( + reverse("captcha-test-custom-error-message"), + dict(captcha_0="abc", captcha_1=""), + ) + self._assertFormError( + r, "form", "captcha", gettext_lazy("This field is required.") + ) + + def test_repeated_challenge(self): + CaptchaStore.objects.create(challenge="xxx", response="xxx") + try: + CaptchaStore.objects.create(challenge="xxx", response="xxx") + except Exception: + self.fail() + + def test_repeated_challenge_form_submit(self): + __current_challange_function = settings.CAPTCHA_CHALLENGE_FUNCT + for urlname in ("captcha-test", "captcha-test-model-form"): + settings.CAPTCHA_CHALLENGE_FUNCT = "captcha.tests.trivial_challenge" + + r1 = self.client.get(reverse(urlname)) + r2 = self.client.get(reverse(urlname)) + self.assertEqual(r1.status_code, 200) + self.assertEqual(r2.status_code, 200) + if re.findall(r'value="([0-9a-f]+)"', str(r1.content)): + hash_1 = re.findall(r'value="([0-9a-f]+)"', str(r1.content))[0] + else: + self.fail() + + if re.findall(r'value="([0-9a-f]+)"', str(r2.content)): + hash_2 = re.findall(r'value="([0-9a-f]+)"', str(r2.content))[0] + else: + self.fail() + try: + store_1 = CaptchaStore.objects.get(hashkey=hash_1) + store_2 = CaptchaStore.objects.get(hashkey=hash_2) + except Exception: + self.fail() + + self.assertTrue(store_1.pk != store_2.pk) + self.assertTrue(store_1.response == store_2.response) + self.assertTrue(hash_1 != hash_2) + + r1 = self.client.post( + reverse(urlname), + dict( + captcha_0=hash_1, + captcha_1=store_1.response, + subject="xxx", + sender="asasd@asdasd.com", + ), + ) + self.assertEqual(r1.status_code, 200) + self.assertTrue(str(r1.content).find("Form validated") > 0) + + try: + store_2 = CaptchaStore.objects.get(hashkey=hash_2) + except Exception: + self.fail() + + r2 = self.client.post( + reverse(urlname), + dict( + captcha_0=hash_2, + captcha_1=store_2.response, + subject="xxx", + sender="asasd@asdasd.com", + ), + ) + self.assertEqual(r2.status_code, 200) + self.assertTrue(str(r2.content).find("Form validated") > 0) + settings.CAPTCHA_CHALLENGE_FUNCT = __current_challange_function + + def test_output_format(self): + for urlname in ("captcha-test", "captcha-test-model-form"): + settings.CAPTCHA_OUTPUT_FORMAT = ( + "%(image)s

Hello, captcha world

%(hidden_field)s%(text_field)s" + ) + r = self.client.get(reverse(urlname)) + self.assertEqual(r.status_code, 200) + self.assertTrue("

Hello, captcha world

" in str(r.content)) + + def test_invalid_output_format(self): + for urlname in ("captcha-test", "captcha-test-model-form"): + settings.CAPTCHA_OUTPUT_FORMAT = "%(image)s" + try: + with warnings.catch_warnings(record=True) as w: + self.client.get(reverse(urlname)) + assert len(w) == 1 + self.assertTrue("CAPTCHA_OUTPUT_FORMAT" in str(w[-1].message)) + self.fail() + + except ImproperlyConfigured as e: + self.assertTrue("CAPTCHA_OUTPUT_FORMAT" in str(e)) + + def test_per_form_format(self): + settings.CAPTCHA_OUTPUT_FORMAT = ( + "%(image)s testCustomFormatString %(hidden_field)s %(text_field)s" + ) + r = self.client.get(reverse("captcha-test")) + self.assertTrue("testCustomFormatString" in str(r.content)) + r = self.client.get(reverse("test_per_form_format")) + self.assertTrue("testPerFieldCustomFormatString" in str(r.content)) + + def test_custom_generator(self): + r = self.client.get(reverse("test_custom_generator")) + hash_, response = self.__extract_hash_and_response(r) + self.assertEqual(response, "111111") + + def test_issue31_proper_abel(self): + settings.CAPTCHA_OUTPUT_FORMAT = "%(image)s %(hidden_field)s %(text_field)s" + r = self.client.get(reverse("captcha-test")) + self.assertTrue('