<commit_before>================
GLAMkit-stopspam
================

A tool for detecting and filtering spam in user input. It is part of the `GLAMkit project <http://glamkit.org/>`_. For more information, see the `documentation <http://docs.glamkit.org/stopspam/>`_.

View a full list of `GLAMkit components <http://docs.glamkit.org/components/>`_.

The approach
============

The stopspam app provides 3 forms of spam detection: Akismet, ReCAPTCHA, and a honeypot field. Each of those can be enabled in a given form by subclassing the form from the respective class. Note that since most of the below methods require access to the current request object, any forms that subclass the stopspam classes should be initalised in your views with the request as the first argument.

Akismet
-------

Akismet filtering, enabled by subclassing AkismetForm, sends off user input to the Akismet servers to determine whether it is likely to be spam. The request must be explicitly invoked using the akismet_check() method, allowing you to determine how to handle spam messages (e.g. if archiving such messages is desired).

Akismet filtering also requires an "akismet_fields" dictionary to be defined as a property of your form, mapping the fields in the form to Akismet fields as shown below. Note that only the "comment_content" item is strictly required.

::

	class YourForm(AkismetForm):
		akismet_fields = {
				'comment_author': 'name',
				'comment_author_email': 'email',
				'comment_author_url': 'url',
				'comment_content': 'comment',
				}
		name = forms.CharField(...)
		url = forms.URLField(...)
		email = forms.EmailField(...)
		comment = forms.TextField(...)

To use Akismet, an API key is also required (obtainable `on the Akismet website <http://akismet.com/>`_), which can either be provided as "AKISMET_API_KEY" in your Django settings file, or as an "akismet_api_key" property in your form.

ReCAPTCHA
---------

ReCAPTCHA validation, enabled by subclassing RecaptchaForm, displays a CAPTCHA image in your form, requiring users to input two distorted words that appear in the image. The words are checked as part of the form validation, so a validation error will be thrown if the user fails to type in the words correctly.

An optional "recaptcha_always_validate" property can also be defined in the form, and will disable ReCAPTCHA validation if set to True, while still displaying the widget, which can come in handy during testing.

To use ReCAPTCHA, a pair of public and private API keys is required (obtainable `here <http://recaptcha.net/whyrecaptcha.html>`_), which can be provided either as "RECAPTCHA_PUBLIC_KEY" and "RECAPTCHA_PRIVATE_KEY" in you Django settings file, or as "recaptcha_public_key" and "recaptcha_private_key" properties in your form.

ReCAPTCHA comes with different themes ('clean', 'red', 'white', 'blackglass', 'custom'). You can choose a theme using "RECAPTCHA_THEME" in your Django settings file or by providing a "recaptcha_theme" property in your form. The default theme is 'clean'. If you choose 'custom' you have to provide some html in your template.

::

	<div id="recaptcha_widget" style="display:none">

		<div id="recaptcha_image"></div>
		<span class="recaptcha_only_if_incorrect_sol error_msg">{% trans "Incorrect please try again" %}</span>
		
		<label>
			<span class="recaptcha_only_if_image">{% trans "Enter the words above:" %}</span>
			<span class="recaptcha_only_if_audio">{% trans "Enter the numbers you hear:" %}</span>
		</label>
		
		<input type="text" id="recaptcha_response_field" name="recaptcha_response_field" />
		
		<div><a href="javascript:Recaptcha.reload()">{% trans "Get another CAPTCHA" %}</a></div>
		<div class="recaptcha_only_if_image"><a href="javascript:Recaptcha.switch_type('audio')">{% trans "Get an audio CAPTCHA" %}</a></div>
		<div class="recaptcha_only_if_audio"><a href="javascript:Recaptcha.switch_type('image')">{% trans "Get an image CAPTCHA" %}</a></div>
		
		<div><a href="javascript:Recaptcha.showhelp()">{% trans "Help" %}</a>
	
	</div>
	
	{% autoescape off %}
	{{ form.recaptcha_response_field }}
	{% endautoescape %}
<commit_msg>Updated docs for ReCAPTCHA themes.<commit_after>================
GLAMkit-stopspam
================

A tool for detecting and filtering spam in user input. It is part of the `GLAMkit project <http://glamkit.org/>`_. For more information, see the `documentation <http://docs.glamkit.org/stopspam/>`_.

View a full list of `GLAMkit components <http://docs.glamkit.org/components/>`_.

The approach
============

The stopspam app provides 3 forms of spam detection: Akismet, ReCAPTCHA, and a honeypot field. Each of those can be enabled in a given form by subclassing the form from the respective class. Note that since most of the below methods require access to the current request object, any forms that subclass the stopspam classes should be initalised in your views with the request as the first argument.

Akismet
-------

Akismet filtering, enabled by subclassing AkismetForm, sends off user input to the Akismet servers to determine whether it is likely to be spam. The request must be explicitly invoked using the akismet_check() method, allowing you to determine how to handle spam messages (e.g. if archiving such messages is desired).

Akismet filtering also requires an "akismet_fields" dictionary to be defined as a property of your form, mapping the fields in the form to Akismet fields as shown below. Note that only the "comment_content" item is strictly required.

::

	class YourForm(AkismetForm):
		akismet_fields = {
				'comment_author': 'name',
				'comment_author_email': 'email',
				'comment_author_url': 'url',
				'comment_content': 'comment',
				}
		name = forms.CharField(...)
		url = forms.URLField(...)
		email = forms.EmailField(...)
		comment = forms.TextField(...)

To use Akismet, an API key is also required (obtainable `on the Akismet website <http://akismet.com/>`_), which can either be provided as "AKISMET_API_KEY" in your Django settings file, or as an "akismet_api_key" property in your form.

ReCAPTCHA
---------

ReCAPTCHA validation, enabled by subclassing RecaptchaForm, displays a CAPTCHA image in your form, requiring users to input two distorted words that appear in the image. The words are checked as part of the form validation, so a validation error will be thrown if the user fails to type in the words correctly.

An optional "recaptcha_always_validate" property can also be defined in the form, and will disable ReCAPTCHA validation if set to True, while still displaying the widget, which can come in handy during testing.

To use ReCAPTCHA, a pair of public and private API keys is required (obtainable `here <http://recaptcha.net/whyrecaptcha.html>`_), which can be provided either as "RECAPTCHA_PUBLIC_KEY" and "RECAPTCHA_PRIVATE_KEY" in you Django settings file, or as "recaptcha_public_key" and "recaptcha_private_key" properties in your form.

ReCAPTCHA comes with different themes ('clean', 'red', 'white', 'blackglass', 'custom'). You can choose a theme using "RECAPTCHA_THEME" in your Django settings file or by providing a "recaptcha_theme" property in your form. The default theme is 'clean'. If you choose 'custom' you have to provide some html in your template.

::

	<div id="recaptcha_widget" style="display:none">

		<div id="recaptcha_image"></div>
		<span class="recaptcha_only_if_incorrect_sol error_msg">{% trans "Incorrect please try again" %}</span>
		
		<label>
			<span class="recaptcha_only_if_image">{% trans "Enter the words above:" %}</span>
			<span class="recaptcha_only_if_audio">{% trans "Enter the numbers you hear:" %}</span>
		</label>
		
		<input type="text" id="recaptcha_response_field" name="recaptcha_response_field" />
		
		<div><a href="javascript:Recaptcha.reload()">{% trans "Get another CAPTCHA" %}</a></div>
		<div class="recaptcha_only_if_image">
			<a href="javascript:Recaptcha.switch_type('audio')">{% trans "Get an audio CAPTCHA" %}</a>
		</div>
		<div class="recaptcha_only_if_audio">
			<a href="javascript:Recaptcha.switch_type('image')">{% trans "Get an image CAPTCHA" %}</a>
		</div>
		
		<div><a href="javascript:Recaptcha.showhelp()">{% trans "Help" %}</a>
	
	</div>
	
	{% autoescape off %}
	{{ form.recaptcha_response_field }}
	{% endautoescape %}

{'fraction_non_alphanumeric': 0.11178102013746533, 'fraction_numerical': 0.0002411672494875196, 'mean_word_length': 4.80812324929972, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1391814', 'n_tokens_mistral': 2628, 'n_tokens_neox': 2403, 'n_words': 990}