summaryrefslogtreecommitdiff
path: root/app/lib/contact_form/forms.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/lib/contact_form/forms.py')
-rw-r--r--app/lib/contact_form/forms.py240
1 files changed, 0 insertions, 240 deletions
diff --git a/app/lib/contact_form/forms.py b/app/lib/contact_form/forms.py
deleted file mode 100644
index dfa9ac8..0000000
--- a/app/lib/contact_form/forms.py
+++ /dev/null
@@ -1,240 +0,0 @@
-"""
-A base contact form for allowing users to send email messages through
-a web interface, and a subclass demonstrating useful functionality.
-
-"""
-
-
-from django import forms
-from django.conf import settings
-from django.core.mail import send_mail
-from django.template import loader, RequestContext
-from django.contrib.sites.models import Site
-
-
-# I put this on all required fields, because it's easier to pick up
-# on them with CSS or JavaScript if they have a class of "required"
-# in the HTML. Your mileage may vary.
-attrs_dict = { 'class': 'required' }
-
-
-class ContactForm(forms.Form):
- """
- Base contact form class from which all contact form classes should
- inherit.
-
- If you don't need any custom functionality, you can simply use
- this form to provide basic contact functionality; it will collect
- name, email address and message.
-
- The ``contact_form`` view included in this application knows how
- to work with this form and can handle many types of subclasses as
- well (see below for a discussion of the important points), so in
- many cases it will be all that you need. If you'd like to use this
- form or a subclass of it from one of your own views, just do the
- following:
-
- 1. When you instantiate the form, pass the current
- ``HttpRequest`` object to the constructor as the keyword
- argument ``request``; this is used internally by the base
- implementation, and also made available so that subclasses
- can add functionality which relies on inspecting the
- request.
-
- 2. To send the message, call the form's ``save`` method, which
- accepts the keyword argument ``fail_silently`` and defaults
- it to ``False``. This argument is passed directly to
- ``send_mail``, and allows you to suppress or raise
- exceptions as needed for debugging. The ``save`` method has
- no return value.
-
- Other than that, treat it like any other form; validity checks and
- validated data are handled normally, through the ``is_valid``
- method and the ``cleaned_data`` dictionary.
-
-
- Base implementation
- -------------------
-
- Under the hood, this form uses a somewhat abstracted interface in
- order to make it easier to subclass and add functionality. There
- are several important attributes subclasses may want to look at
- overriding, all of which will work (in the base implementation) as
- either plain attributes or as callable methods:
-
- * ``from_email`` -- used to get the address to use in the
- ``From:`` header of the message. The base implementation
- returns the value of the ``DEFAULT_FROM_EMAIL`` setting.
-
- * ``message`` -- used to get the message body as a string. The
- base implementation renders a template using the form's
- ``cleaned_data`` dictionary as context.
-
- * ``recipient_list`` -- used to generate the list of
- recipients for the message. The base implementation returns
- the email addresses specified in the ``MANAGERS`` setting.
-
- * ``subject`` -- used to generate the subject line for the
- message. The base implementation returns the string 'Message
- sent through the web site', with the name of the current
- ``Site`` prepended.
-
- * ``template_name`` -- used by the base ``message`` method to
- determine which template to use for rendering the
- message. Default is ``contact_form/contact_form.txt``.
-
- Internally, the base implementation ``_get_message_dict`` method
- collects ``from_email``, ``message``, ``recipient_list`` and
- ``subject`` into a dictionary, which the ``save`` method then
- passes directly to ``send_mail`` as keyword arguments.
-
- Particularly important is the ``message`` attribute, with its base
- implementation as a method which renders a template; because it
- passes ``cleaned_data`` as the template context, any additional
- fields added by a subclass will automatically be available in the
- template. This means that many useful subclasses can get by with
- just adding a few fields and possibly overriding
- ``template_name``.
-
- Much useful functionality can be achieved in subclasses without
- having to override much of the above; adding additional validation
- methods works the same as any other form, and typically only a few
- items -- ``recipient_list`` and ``subject_line``, for example,
- need to be overridden to achieve customized behavior.
-
-
- Other notes for subclassing
- ---------------------------
-
- Subclasses which want to inspect the current ``HttpRequest`` to
- add functionality can access it via the attribute ``request``; the
- base ``message`` takes advantage of this to use ``RequestContext``
- when rendering its template. See the ``AkismetContactForm``
- subclass in this file for an example of using the request to
- perform additional validation.
-
- Subclasses which override ``__init__`` need to accept ``*args``
- and ``**kwargs``, and pass them via ``super`` in order to ensure
- proper behavior.
-
- Subclasses should be careful if overriding ``_get_message_dict``,
- since that method **must** return a dictionary suitable for
- passing directly to ``send_mail`` (unless ``save`` is overridden
- as well).
-
- Overriding ``save`` is relatively safe, though remember that code
- which uses your form will expect ``save`` to accept the
- ``fail_silently`` keyword argument. In the base implementation,
- that argument defaults to ``False``, on the assumption that it's
- far better to notice errors than to silently not send mail from
- the contact form (see also the Zen of Python: "Errors should never
- pass silently, unless explicitly silenced").
-
- """
- def __init__(self, data=None, files=None, request=None, *args, **kwargs):
- if request is None:
- raise TypeError("Keyword argument 'request' must be supplied")
- super(ContactForm, self).__init__(data=data, files=files, *args, **kwargs)
- self.request = request
-
- name = forms.CharField(max_length=100,
- widget=forms.TextInput(attrs=attrs_dict),
- label=u'Name:')
- email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict,
- maxlength=200)),
- label=u'E-mail:')
- subject_line = forms.CharField(widget=forms.TextInput(attrs=dict(attrs_dict,
- maxlength=200)),
- label=u'Subject:')
- body = forms.CharField(widget=forms.Textarea(attrs=attrs_dict),
- label=u'Message:')
-
- def from_email(self):
- if self.cleaned_data['email']:
- addy = self.cleaned_data['email']
- else:
- addy = settings.DEFAULT_FROM_EMAIL
- return addy
-
- recipient_list = [mail_tuple[1] for mail_tuple in settings.CONTACT]
-
- subject_template_name = "contact_form/contact_form_subject.txt"
-
- template_name = 'contact_form/contact_form.txt'
-
- _context = None
-
- def message(self):
- """
- Renders the body of the message to a string.
-
- """
- if callable(self.template_name):
- template_name = self.template_name()
- else:
- template_name = self.template_name
- return loader.render_to_string(template_name,
- self.get_context())
-
- def subject(self):
- """
- Renders the subject of the message to a string.
-
- """
- subject = loader.render_to_string(self.subject_template_name,
- self.get_context())
- return ''.join(subject.splitlines())
-
-
-
-
-
- def get_context(self):
- if not self.is_valid():
- raise ValueError("Cannot generate Context from invalid contact form")
- if self._context is None:
- self._context = RequestContext(self.request,
- dict(self.cleaned_data,
- site=Site.objects.get_current()))
- return self._context
-
- def get_message_dict(self):
- if not self.is_valid():
- raise ValueError("Message cannot be sent from invalid contact form")
- message_dict = {}
- for message_part in ('from_email', 'message', 'recipient_list', 'subject'):
- attr = getattr(self, message_part)
- message_dict[message_part] = callable(attr) and attr() or attr
- return message_dict
-
- def save(self, fail_silently=False):
- """
- Builds and sends the email message.
-
- """
- send_mail(fail_silently=fail_silently, **self.get_message_dict())
-
-
-class AkismetContactForm(ContactForm):
- """
- Contact form which doesn't add any extra fields, but does add an
- Akismet spam check to the validation routine.
-
- Requires the setting ``AKISMET_API_KEY``, which should be a valid
- Akismet API key.
-
- """
- def clean_body(self):
- if 'body' in self.cleaned_data and getattr(settings, 'AKISMET_API_KEY', ''):
- from akismet import Akismet
- from django.utils.encoding import smart_str
- akismet_api = Akismet(key=settings.AKISMET_API_KEY,
- blog_url='http://%s/' % Site.objects.get_current().domain)
- if akismet_api.verify_key():
- akismet_data = { 'comment_type': 'comment',
- 'referer': self.request.META.get('HTTP_REFERER', ''),
- 'user_ip': self.request.META.get('REMOTE_ADDR', ''),
- 'user_agent': self.request.META.get('HTTP_USER_AGENT', '') }
- if akismet_api.comment_check(smart_str(self.cleaned_data['body']), data=akismet_data, build_data=True):
- raise forms.ValidationError(u"Akismet thinks this message is spam")
- return self.cleaned_data['body']