python-django-filebrowser-0+hg61/0000755000403700037200000000000011154175146016221 5ustar dwacredativpython-django-filebrowser-0+hg61/contact_form/0000755000403700037200000000000011154175146020677 5ustar dwacredativpython-django-filebrowser-0+hg61/contact_form/urls.py0000644000403700037200000000164611154175146022245 0ustar dwacredativ""" Example URLConf for a contact form. Because the ``contact_form`` view takes configurable arguments, it's recommended that you manually place it somewhere in your URL configuration with the arguments you want. If you just prefer the default, however, you can hang this URLConf somewhere in your URL hierarchy (for best results with the defaults, include it under ``/contact/``). """ from django.conf.urls.defaults import * from django.views.generic.simple import direct_to_template from contact_form.views import contact_form urlpatterns = patterns('', url(r'^$', contact_form, name='contact_form'), url(r'^sent/$', direct_to_template, { 'template': 'contact_form/contact_form_sent.html' }, name='contact_form_sent'), ) python-django-filebrowser-0+hg61/contact_form/__init__.py0000644000403700037200000000000011154175146022776 0ustar dwacredativpython-django-filebrowser-0+hg61/contact_form/forms.py0000644000403700037200000002446411154175146022411 0ustar dwacredativ""" 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 from django.template import 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'Your name') email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=200)), label=u'Your email address') body = forms.CharField(widget=forms.Textarea(attrs=attrs_dict), label=u'Your message') from_email = settings.DEFAULT_FROM_EMAIL recipient_list = [mail_tuple[1] for mail_tuple in settings.MANAGERS] subject_template_name = "contact_form/contact_form_subject.txt" template_name = 'contact_form/contact_form.txt' def message(self): """ Render 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): """ Render 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): """ Return the context used to render the templates for the email subject and body. By default, this context includes: * All of the validated values in the form, as variables of the same names as their fields. * The current ``Site`` object, as the variable ``site``. * Any additional variables added by context processors (this will be a ``RequestContext``). """ if not self.is_valid(): raise ValueError("Cannot generate Context from invalid contact form") return RequestContext(self.request, dict(self.cleaned_data, site=Site.objects.get_current())) def get_message_dict(self): """ Generate the various parts of the message and return them in a dictionary, suitable for passing directly as keyword arguments to ``django.core.mail.send_mail()``. By default, the following values are returned: * ``from_email`` * ``message`` * ``recipient_list`` * ``subject`` """ 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): """ Build and send 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): """ Perform Akismet validation of the message. """ 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'] python-django-filebrowser-0+hg61/contact_form/views.py0000644000403700037200000000632611154175146022415 0ustar dwacredativ""" View which can render and send email from a contact form. """ from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect from django.shortcuts import render_to_response from django.template import RequestContext from contact_form.forms import ContactForm def contact_form(request, form_class=ContactForm, template_name='contact_form/contact_form.html', success_url=None, extra_context=None, fail_silently=False): """ Render a contact form, validate its input and send an email from it. **Optional arguments:** ``extra_context`` A dictionary of variables to add to the template context. Any callable object in this dictionary will be called to produce the end result which appears in the context. ``fail_silently`` If ``True``, errors when sending the email will be silently supressed (i.e., with no logging or reporting of any such errors. Default value is ``False``. ``form_class`` The form to use. If not supplied, this will default to ``contact_form.forms.ContactForm``. If supplied, the form class must implement a method named ``save()`` which sends the email from the form; the form class must accept an ``HttpRequest`` as the keyword argument ``request`` to its constructor, and it must implement a method named ``save()`` which sends the email and which accepts the keyword argument ``fail_silently``. ``success_url`` The URL to redirect to after a successful submission. If not supplied, this will default to the URL pointed to by the named URL pattern ``contact_form_sent``. ``template_name`` The template to use for rendering the contact form. If not supplied, defaults to :template:`contact_form/contact_form.html`. **Context:** ``form`` The form instance. **Template:** The value of the ``template_name`` keyword argument, or :template:`contact_form/contact_form.html`. """ # # We set up success_url here, rather than as the default value for # the argument. Trying to do it as the argument's default would # mean evaluating the call to reverse() at the time this module is # first imported, which introduces a circular dependency: to # perform the reverse lookup we need access to contact_form/urls.py, # but contact_form/urls.py in turn imports from this module. # if success_url is None: success_url = reverse('contact_form_sent') if request.method == 'POST': form = form_class(data=request.POST, files=request.FILES, request=request) if form.is_valid(): form.save(fail_silently=fail_silently) return HttpResponseRedirect(success_url) else: form = form_class(request=request) if extra_context is None: extra_context = {} context = RequestContext(request) for key, value in extra_context.items(): context[key] = callable(value) and value() or value return render_to_response(template_name, { 'form': form }, context_instance=context) python-django-filebrowser-0+hg61/README.txt0000644000403700037200000000111211154175146017712 0ustar dwacredativ================================ Generic contact forms for Django ================================ This is an application which provides generic, extensible contact-form functionality for use in Django_ projects; for installation instructions, see the file ``INSTALL.txt`` in this directory, and for documentation see the files in the ``docs/`` directory. The latest versions of these documents can always be viewed on the Google Code project web site for this application, which is located at http://code.google.com/p/django-contact/form/. .. _Django: http://www.djangoproject.com/python-django-filebrowser-0+hg61/setup.py0000644000403700037200000000127011154175146017733 0ustar dwacredativfrom distutils.core import setup setup(name='django-contact-form', version='0.3', description='Generic contact-form application for Django', author='James Bennett', author_email='james@b-list.org', url='http://code.google.com/p/django-contact-form/', packages=['contact_form'], classifiers=['Development Status :: 4 - Beta', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Utilities'], ) python-django-filebrowser-0+hg61/LICENSE.txt0000644000403700037200000000275611154175146020056 0ustar dwacredativCopyright (c) 2007, James Bennett All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. python-django-filebrowser-0+hg61/MANIFEST.in0000644000403700037200000000014711154175146017761 0ustar dwacredativinclude INSTALL.txt include LICENSE.txt include README.txt include MANIFEST.in recursive-include docs *python-django-filebrowser-0+hg61/docs/0000755000403700037200000000000011154175146017151 5ustar dwacredativpython-django-filebrowser-0+hg61/docs/forms.txt0000644000403700037200000001415311154175146021044 0ustar dwacredativ===================== Included form classes ===================== Two form classes are included with this application; one, ``contact_form.forms.ContactForm`` implements the necessary base functionality of a contact form, and other contact-form classes should inherit from it to receive that functionality. The other, contact_form.forms.AkismetContactForm``, is a subclass of ``ContactForm`` provided both because it is useful and as a demonstration of subclassing ``ContactForm``. ``contact_form.forms.ContactForm`` ================================== 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 ``ContactForm`` class to determine which template to use for rendering the message. Default is ``contact_form/contact_form.txt``. * ``subject_template_name`` -- used by the base ``ContactForm`` class to determine which template to use for rendering the message's subject line. Regardless of the output of rendering this template, it will be condensed to a single line of text; multi-line subjects are not permitted. Default is ``contact_form/contact_form_subject.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, and the ``subject`` attribute which defaults to a similar method; because they pass ``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`` and/or ``subject_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`` and ``subject`` take advantage of this to use ``RequestContext`` when rendering their templates. 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"). ``contact_form.forms.AkismetContactForm`` ========================================= 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. python-django-filebrowser-0+hg61/docs/views.txt0000644000403700037200000000341411154175146021051 0ustar dwacredativ============== Included views ============== One view is included with this application: ``contact_form.views.contact_form``, which knows how to work with ``contact_form.forms.ContactForm`` and its subclasses, and takes several useful keyword arguments for specifying behavior. ``contact_form.views.contact_form`` ==================================== Render a contact form, validate its input and send an email from it. **Optional arguments:** ``extra_context`` A dictionary of variables to add to the template context. Any callable object in this dictionary will be called to produce the end result which appears in the context. ``fail_silently`` If ``True``, errors when sending the email will be silently supressed (i.e., with no logging or reporting of any such errors. Default value is ``False``. ``form_class`` The form to use. If not supplied, this will default to ``contact_form.forms.ContactForm``. If supplied, the form class must implement a method named ``save()`` which sends the email from the form; the form class must accept an ``HttpRequest`` as the keyword argument ``request`` to its constructor, and it must implement a method named ``save()`` which sends the email and which accepts the keyword argument ``fail_silently``. ``success_url`` The URL to redirect to after a successful submission. If not supplied, this will be the URL pointed to by the named URL pattern ``contact_form_sent``. ``template_name`` The template to use for rendering the contact form. If not supplied, defaults to :template:`contact_form/contact_form.html`. **Context:** ``form`` The form instance. **Template:** The value of the ``template_name`` keyword argument, or :template:`contact_form/contact_form.html`. python-django-filebrowser-0+hg61/docs/overview.txt0000644000403700037200000000746611154175146021575 0ustar dwacredativ================================ Generic contact forms for Django ================================ Providing some sort of contact or feedback form for soliciting information from site visitors is a common need in web development, and writing a contact form and associated handler view, while relatively straightforward to do with Django, can be a tedious and repetitive task. This application aims to remove or reduce that tedium and repetition by providing generic contact-form functionality. Requirements ============ This application makes heavy use of Django's newforms library, and was written *after* a backwards-incompatible change on Django trunk altered the way newforms stores valid data; as a result, this application requires a Subversion checkout of Django, revision 5237 or later. Because a recent trunk checkout of Django was already required, the default ``urls.py`` supplied with this application also takes advantage of named URL patterns, a feature which was not present in the Django 0.96 release. If you will be using the included ``AkismetContactForm`` class, which performs an Akismet spam check as part of its validation, you will need the `Python Akismet module`_ and a valid Akismet API key; you can obtain an Akismet API by following the instructions at `the Akismet web site`_. .. _Python Akismet module: http://www.voidspace.org.uk/python/modules.shtml#akismet .. _the Akismet web site: http://akismet.com/ High-level overview =================== This application contains a (newforms) form class called ``ContactForm``, which implements a useful baseline for contact forms -- collecting a name, email address and message, and emailing them to site staff -- and which is also designed so as to allow additional functionality to be added easily in subclasses. For specifics of how ``ContactForm`` works and what to look at when subclassing it, see the `forms documentation`_ included with this application. Also provided is a generic-style view called ``contact_form``, which is designed to work out-of-the-box with ``ContactForm`` and subclasses of ``ContactForm``, and has a number of configurable parameters to allow specification of the form class to use, whether to require a user to log in before using the form, etc. For full details on this view and the options it provides, see the `views_documentation`_ included with this application. A sample URLConf is included, and can be used "as-is" if the default ``ContactForm`` and default parameters of the ``contact_form`` view are all that's required, or studied as an example. .. _forms documentation: forms.html .. _views documentation: views.html Basic usage =========== To get up and running immediately using the default setup, do the following: * Add ``contact_form`` to your project's ``INSTALLED_APPS`` setting. You will *not* need to run ``manage.py syncdb``, since this application provides no models. * In your root URLConf, add the following URL pattern:: (r'^contact/', include('contact_form.urls'), * Create four templates: ``contact_form/contact_form_subject.txt`` and ``contact_form/contact_form.txt``, which will be used to render the email messages sent by the form; ``contact_form/contact_form.html``, which will be used to display the form to users; and ``contact_form/contact_form_sent.html``, which will be used after the form is successfully submitted. See the forms and views documentation, respectively, for details on the contexts available to the first three templates; the fourth is rendered from the ``direct_to_template`` generic view, and has no context. Once this is done, visiting the URL ``/contact/`` on your site will display the contact form, and submitting it will send an email to each address in the ``MANAGERS`` setting for your project. python-django-filebrowser-0+hg61/INSTALL.txt0000644000403700037200000000142011154175146020065 0ustar dwacredativ========================= Installation instructions ========================= There are two ways to install this application for use by your projects; the easiest in most cases is to do a Subversion checkout into a directory that's on your Python path:: svn co http://django-contact-form.googlecode.com/svn/trunk/contact_form/ The other method is to download a packaged version and use Python's ``distutils`` to install it onto your Python path:: wget http://django-contact-form.googlecode.com/files/contact_form-0.3.tar.gz tar zxvf contact_form-0.3.tar.gz cd contact-form-0.3 python setup.py install Depending on your system configuration, you may need to prefix the last command with ``sudo`` and supply your password to perform a system-wide installation.