django-contact-form-master/contact_form/tests/templates/contact_form/contact_form_subject.txt000664 001750 001750 00000000024 12634621623 033014 0ustar00asbasb000000 000000 Contact form messagedjango-contact-form-master/LICENSE000664 001750 001750 00000002763 12634621623 016603 0ustar00asbasb000000 000000 Copyright (c) 2007-2015, 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. django-contact-form-master/docs/install.rst000664 001750 001750 00000011774 12634621623 020730 0ustar00asbasb000000 000000 .. _install: Installation guide ================== Before installing ``django-contact-form``, you'll need to have a copy of `Django `_ already installed. For information on obtaining and installing Django, consult the `Django download page `_, which offers convenient packaged downloads and installation instructions. The |version| release of ``django-contact-form`` supports Django 1.8 and 1.9, on any of Python 2.7, 3.3, 3.4, or 3.5. Older versions of Django and/or Python may work, but are not tested or officially supported. Normal installation ------------------- The preferred method of installing ``django-contact-form`` is via ``pip``, the standard Python package-installation tool. If you don't have ``pip``, instructions are available for `how to obtain and install it `_. Once you have ``pip``, simply type:: pip install django-contact-form Manual installation ------------------- It's also possible to install ``django-contact-form`` manually. To do so, obtain the latest packaged version from `the listing on the Python Package Index `_. Unpack the ``.tar.gz`` file, and run:: python setup.py install Once you've installed ``django-contact-form``, you can verify successful installation by opening a Python interpreter and typing ``import contact_form``. If the installation was successful, you'll simply get a fresh Python prompt. If you instead see an ``ImportError``, check the configuration of your install tools and your Python import path to ensure ``django-contact-form`` installed into a location Python can import from. Installing from a source checkout --------------------------------- The development repository for ``django-contact-form`` is at . Presuming you have `git `_ installed, you can obtain a copy of the repository by typing:: git clone https://github.com/ubernostrum/django-contact-form.git From there, you can use normal git commands to check out the specific revision you want, and install it using ``python setup.py install``. Basic configuration and use --------------------------- Once installed, only a small amount of setup is required to use ``django-contact-form``. First, you'll need to make sure you've specified the appropriate settings for `Django to send email `_. Most commonly, this will be ``EMAIL_HOST``, ``EMAIL_PORT``, ``EMAIL_HOST_USER`` and ``EMAIL_HOST_PASSWORD``. You'll also want to make sure ``django-contact-form`` sends mail from the correct address, and sends to the correct address(es). Two standard Django settings control this: * By default, the ``From:`` header of all emails sent by ``django-contact-form`` will be whatever email address is specified in ``DEFAULT_FROM_EMAIL``. * By default, the recipient list for emails sent by ``django-contact-form`` will be the email addresses specified in ``MANAGERS``. If you'd prefer something else, this behavior is configurable; see :ref:`the form documentation ` for details on how to customize the email addresses used. Templates ~~~~~~~~~ The following templates are required by the default setup of ``django-contact-form``, so you'll need to create them: * ``contact_form/contact_form.html`` is the template which actually renders the contact form. Important context variables are: ``form`` The contact form instance. * ``contact_form/contact_form_sent.html`` is the template rendered after a message is successfully sent through the contact form. It has no specific context variables, beyond whatever's supplied by the context processors in use on your site. Additionally, the generated email makes use of two templates: ``contact_form/contact_form_subject.txt`` will be rendered to obtain the subject line, and ``contact_form/contact_form.txt`` will be rendered to obtain the body of the email. These templates use ``RequestContext``, so any context processors will be applied, and have the following additional context: ``site`` The current site. Either a ``Site`` instance if ``django.contrib.sites`` is installed, or a ``RequestSite`` instance if not. ``body`` The body of the message the user entered into the contact form. ``email`` The email address the user supplied to the contact form. ``name`` The name the user supplied to the contact form. URL configuration ~~~~~~~~~~~~~~~~~ Once you've got settings and templates set up, all that's left is to configure your URLs to point to the ``django-contact-form`` views. A URLconf -- ``contact_form.urls`` -- is provided with ``django-contact-form``, which will wire up these views with default behavior; to make use of it, simply include it at whatever point in your URL hierarchy you'd like your contact form to live. For example, to place it at ``/contact/``: .. code-block:: python url(r'^contact/', include('contact_form.urls')), django-contact-form-master/000700 001750 001750 00000000000 12637311163 015550 5ustar00asbasb000000 000000 django-contact-form-master/contact_form/tests/templates/contact_form/contact_form.txt000664 001750 001750 00000000012 12634621623 031272 0ustar00asbasb000000 000000 {{ body }}django-contact-form-master/contact_form/urls.py000664 001750 001750 00000001104 12634621623 021577 0ustar00asbasb000000 000000 """ Example URLConf for a contact form. If all you want is the basic ContactForm with default behavior, just include this URLConf somewhere in your URL hierarchy (for example, at ``/contact/``)> """ from django.conf.urls import url from django.views.generic import TemplateView from contact_form.views import ContactFormView urlpatterns = [ url(r'^$', ContactFormView.as_view(), name='contact_form'), url(r'^sent/$', TemplateView.as_view( template_name='contact_form/contact_form_sent.html'), name='contact_form_sent'), ] django-contact-form-master/contact_form/tests/test_urls.py000664 001750 001750 00000001124 12634621623 024002 0ustar00asbasb000000 000000 """ URLConf for testing django-contact-form. """ from django.conf.urls import url from django.views.generic import TemplateView from ..views import ContactFormView urlpatterns = [ url(r'^$', ContactFormView.as_view(), name='contact_form'), url(r'^sent/$', TemplateView.as_view( template_name='contact_form/contact_form_sent.html' ), name='contact_form_sent'), url(r'^test_recipient_list/$', ContactFormView.as_view( recipient_list=['recipient_list@example.com']), name='test_recipient_list'), ] django-contact-form-master/docs/Makefile000664 001750 001750 00000012760 12634621623 020164 0ustar00asbasb000000 000000 # Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-contact-form.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-contact-form.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/django-contact-form" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-contact-form" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." django-contact-form-master/setup.py000664 001750 001750 00000002675 12634621623 017312 0ustar00asbasb000000 000000 import os from setuptools import setup setup(name='django-contact-form', version='1.2', zip_safe=False, # eggs are the devil. description='Generic contact-form application for Django', long_description=open(os.path.join(os.path.dirname(__file__), 'README.rst')).read(), author='James Bennett', author_email='james@b-list.org', url='https://github.com/ubernostrum/django-contact-form/', packages=['contact_form', 'contact_form.tests'], test_suite='contact_form.runtests.run_tests', classifiers=['Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', 'Framework :: Django', 'Framework :: Django :: 1.8', 'Framework :: Django :: 1.9', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Topic :: Utilities'], ) django-contact-form-master/contact_form/tests/templates/contact_form/contact_form_sent.html000664 001750 001750 00000000025 12634621623 032454 0ustar00asbasb000000 000000

Message sent!

django-contact-form-master/contact_form/tests/test_forms.py000664 001750 001750 00000010446 12634621623 024152 0ustar00asbasb000000 000000 from django.conf import settings from django.core import mail from django.test import RequestFactory, TestCase from ..forms import ContactForm class ContactFormTests(TestCase): valid_data = {'name': 'Test', 'email': 'test@example.com', 'body': 'Test message'} def request(self): return RequestFactory().request() def test_request_required(self): """ Can't instantiate without an HttpRequest. """ self.assertRaises(TypeError, ContactForm) def test_valid_data_required(self): """ Can't try to build the message dict unless data is valid. """ data = {'name': 'Test', 'body': 'Test message'} form = ContactForm(request=self.request(), data=data) self.assertRaises(ValueError, form.get_message_dict) self.assertRaises(ValueError, form.get_context) def test_send(self): """ Valid form can and does in fact send email. """ form = ContactForm(request=self.request(), data=self.valid_data) self.assertTrue(form.is_valid()) form.save() self.assertEqual(1, len(mail.outbox)) message = mail.outbox[0] self.assertTrue(self.valid_data['body'] in message.body) self.assertEqual(settings.DEFAULT_FROM_EMAIL, message.from_email) self.assertEqual(form.recipient_list, message.recipients()) def test_no_sites(self): """ Sites integration works with or without installed contrib.sites. """ with self.modify_settings( INSTALLED_APPS={ 'remove': ['django.contrib.sites'], }): form = ContactForm(request=self.request(), data=self.valid_data) self.assertTrue(form.is_valid()) form.save() self.assertEqual(1, len(mail.outbox)) def test_recipient_list(self): """ Passing recipient_list when instantiating ContactForm properly overrides the list of recipients. """ recipient_list = ['recipient_list@example.com'] form = ContactForm(request=self.request(), data=self.valid_data, recipient_list=recipient_list) self.assertTrue(form.is_valid()) form.save() self.assertEqual(1, len(mail.outbox)) message = mail.outbox[0] self.assertEqual(recipient_list, message.recipients()) def test_callable_template_name(self): """ When a template_name() method is defined, it is used and preferred over a 'template_name' attribute. """ class CallableTemplateName(ContactForm): def template_name(self): return 'contact_form/test_callable_template_name.html' form = CallableTemplateName(request=self.request(), data=self.valid_data) self.assertTrue(form.is_valid()) form.save() self.assertEqual(1, len(mail.outbox)) message = mail.outbox[0] self.assertTrue('Callable template_name used.' in message.body) def test_callable_message_parts(self): """ Message parts implemented as methods are called and preferred over attributes. """ overridden_data = { 'from_email': 'override@example.com', 'message': 'Overridden message.', 'recipient_list': ['override_recpt@example.com'], 'subject': 'Overridden subject', } class CallableMessageParts(ContactForm): def from_email(self): return overridden_data['from_email'] def message(self): return overridden_data['message'] def recipient_list(self): return overridden_data['recipient_list'] def subject(self): return overridden_data['subject'] form = CallableMessageParts(request=self.request(), data=self.valid_data) self.assertTrue(form.is_valid()) self.assertEqual(overridden_data, form.get_message_dict()) django-contact-form-master/contact_form/forms.py000664 001750 001750 00000010026 12634621623 021743 0ustar00asbasb000000 000000 """ A base contact form for allowing users to send email messages through a web interface. """ from django import forms from django.conf import settings from django.contrib.sites.models import Site from django.contrib.sites.requests import RequestSite from django.utils.translation import ugettext_lazy as _ from django.core.mail import send_mail from django.template import RequestContext, loader class ContactForm(forms.Form): """ The base contact form class from which all contact form classes should inherit. """ name = forms.CharField(max_length=100, label=_(u'Your name')) email = forms.EmailField(max_length=200, label=_(u'Your email address')) body = forms.CharField(widget=forms.Textarea, 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 __init__(self, data=None, files=None, request=None, recipient_list=None, *args, **kwargs): if request is None: raise TypeError("Keyword argument 'request' must be supplied") self.request = request if recipient_list is not None: self.recipient_list = recipient_list super(ContactForm, self).__init__(data=data, files=files, *args, **kwargs) 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" ) if Site._meta.installed: site = Site.objects.get_current() else: site = RequestSite(self.request) return RequestContext(self.request, dict(self.cleaned_data, site=site)) 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] = attr() if callable(attr) else 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()) django-contact-form-master/docs/conf.py000664 001750 001750 00000001233 12634621623 020014 0ustar00asbasb000000 000000 import os on_rtd = os.environ.get('READTHEDOCS', None) == 'True' extensions = [] templates_path = ['_templates'] source_suffix = '.rst' master_doc = 'index' project = u'django-contact-form' copyright = u'2007-2015, James Bennett' version = '1.2' release = '1.2' exclude_trees = ['_build'] pygments_style = 'sphinx' html_static_path = ['_static'] htmlhelp_basename = 'django-contact-formdoc' latex_documents = [ ('index', 'django-contact-form.tex', u'django-contact-form Documentation', u'James Bennett', 'manual'), ] if not on_rtd: import sphinx_rtd_theme html_theme = 'sphinx_rtd_theme' html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] django-contact-form-master/MANIFEST.in000664 001750 001750 00000000117 12634621623 017323 0ustar00asbasb000000 000000 include LICENSE include MANIFEST.in include README.rst recursive-include docs *django-contact-form-master/contact_form/tests/templates/contact_form/000700 001750 001750 00000000000 12637311163 026044 5ustar00asbasb000000 000000 contact_form/tests/templates/contact_form/test_callable_template_name.html000664 001750 001750 00000000035 12634621623 034360 0ustar00asbasb000000 000000 django-contact-form-masterCallable template_name used. django-contact-form-master/docs/faq.rst000664 001750 001750 00000005552 12634621623 020026 0ustar00asbasb000000 000000 .. _faq: Frequently asked questions ========================== The following notes answer some common questions, and may be useful to you when installing, configuring or using ``django-contact-form``. What versions of Django are supported? -------------------------------------- As of ``django-contact-form`` |version|, Django 1.8 and 1.9 are supported. What versions of Python are supported? -------------------------------------- As of |version|, ``django-contact-form`` supports Python 2.7, 3.3, 3.4, and 3.5. Why aren't there any default templates I can use? ------------------------------------------------- Usable default templates, for an application designed to be widely reused, are essentially impossible to produce; variations in site design, block structure, etc. cannot be reliably accounted for. As such, ``django-contact-form`` provides bare-bones (i.e., containing no HTML structure whatsoever) templates in its source distribution to enable running tests, and otherwise simply provides good documentation of all required templates and the context made available to them. What happened to the spam-filtering form in previous versions? -------------------------------------------------------------- Older versions of ``django-contact-form`` shipped a subclass of :class:`~contact_form.forms.ContactForm` which used `the Akismet web service `_ to identify and reject spam submissions. Unfortunately, the Akismet Python library -- required in order to use such a class -- does not currently support all versions of Python on which ``django-contact-form`` is supported, meaning it cannot be included in ``django-contact-form`` by default. The author of ``django-contact-form`` is working on producing a version of the Akismet library compatible with Python 3, but it was not yet ready as of the release of ``django-contact-form`` |version|. Why am I getting a bunch of ``BadHeaderError`` exceptions? ---------------------------------------------------------- Most likely, you have an error in your :class:`~contact_form.forms.ContactForm` subclass. Specifically, one or more of :attr:`~contact_form.forms.ContactForm.from_email`, :attr:`~contact_form.forms.ContactForm.recipient_list` or :meth:`~contact_form.forms.ContactForm.subject` are returning values which contain newlines. As a security precaution against email header injection attacks (which allow spammers and other malicious users to manipulate email and potentially cause automated systems to send mail to unintended recipients), `Django's email-sending framework does not permit newlines in message headers `_. ``BadHeaderError`` is the exception Django raises when a newline is detected in a header. Note that this only applies to the headers of an email message; the message body can (and usually does) contain newlines. django-contact-form-master/docs/make.bat000664 001750 001750 00000012002 12634621623 020116 0ustar00asbasb000000 000000 @ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-contact-form.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-contact-form.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) :end django-contact-form-master/contact_form/tests/templates/contact_form/contact_form.html000664 001750 001750 00000000013 12634621623 031420 0ustar00asbasb000000 000000 {{ body }} django-contact-form-master/contact_form/runtests.py000664 001750 001750 00000004021 12634621623 022502 0ustar00asbasb000000 000000 """ A standalone test runner script, configuring the minimum settings required for django-contact-form' tests to execute. Re-use at your own risk: many Django applications will require full settings and/or templates in order to execute their tests, while django-contact-form does not. """ import os import sys # Make sure django-contact-form is (at least temporarily) on the # import path. CONTACT_FORM_DIR = os.path.abspath(os.path.dirname(__file__)) sys.path.insert(0, CONTACT_FORM_DIR) # Minimum settings required for django-contact-form to work. SETTINGS_DICT = { 'BASE_DIR': CONTACT_FORM_DIR, 'INSTALLED_APPS': ( 'contact_form', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sites', ), 'ROOT_URLCONF': 'contact_form.tests.urls', 'DATABASES': { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(CONTACT_FORM_DIR, 'db.sqlite3'), }, }, 'MIDDLEWARE_CLASSES': ( 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', ), 'TEMPLATE_DIRS': ( os.path.join(CONTACT_FORM_DIR, 'tests/templates'), ), 'SITE_ID': 1, 'DEFAULT_FROM_EMAIL': 'contact@example.com', 'MANAGERS': [('Manager', 'noreply@example.com')], } def run_tests(): # Making Django run this way is a two-step process. First, call # settings.configure() to give Django settings to work with: from django.conf import settings settings.configure(**SETTINGS_DICT) # Then, call django.setup() to initialize the application cache # and other bits: import django if hasattr(django, 'setup'): django.setup() # Now we instantiate a test runner... from django.test.utils import get_runner TestRunner = get_runner(settings) # And then we run tests and return the results. test_runner = TestRunner(verbosity=1, interactive=True) failures = test_runner.run_tests(['contact_form.tests']) sys.exit(bool(failures)) django-contact-form-master/contact_form/tests/templates/000700 001750 001750 00000000000 12637311163 023366 5ustar00asbasb000000 000000 django-contact-form-master/contact_form/000700 001750 001750 00000000000 12637311163 020226 5ustar00asbasb000000 000000 django-contact-form-master/README.rst000664 001750 001750 00000000663 12634621623 017262 0ustar00asbasb000000 000000 .. -*-restructuredtext-*- .. image:: https://travis-ci.org/ubernostrum/django-contact-form.svg?branch=master :target: https://travis-ci.org/ubernostrum/django-contact-form This application provids simple, extensible contact-form functionality for `Django `_ sites. Full documentation for all functionality is included and is also `available online `_.django-contact-form-master/.gitignore000664 001750 001750 00000000063 12634621623 017555 0ustar00asbasb000000 000000 *.pyc __pycache__ *.egg-info docs/_build/ .coveragedjango-contact-form-master/contact_form/tests/000700 001750 001750 00000000000 12637311163 021370 5ustar00asbasb000000 000000 django-contact-form-master/contact_form/tests/test_views.py000664 001750 001750 00000005461 12634621623 024162 0ustar00asbasb000000 000000 from django.conf import settings from django.core import mail from django.core.urlresolvers import reverse from django.test import RequestFactory, TestCase from django.test.utils import override_settings from ..forms import ContactForm @override_settings(ROOT_URLCONF='contact_form.tests.test_urls') class ContactFormViewTests(TestCase): def test_get(self): """ HTTP GET on the form view just shows the form. """ contact_url = reverse('contact_form') response = self.client.get(contact_url) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'contact_form/contact_form.html') def test_send(self): """ Valid data through the view results in a successful send. """ contact_url = reverse('contact_form') data = {'name': 'Test', 'email': 'test@example.com', 'body': 'Test message'} response = self.client.post(contact_url, data=data) self.assertRedirects(response, reverse('contact_form_sent')) self.assertEqual(1, len(mail.outbox)) message = mail.outbox[0] self.assertTrue(data['body'] in message.body) self.assertEqual(settings.DEFAULT_FROM_EMAIL, message.from_email) form = ContactForm(request=RequestFactory().request) self.assertEqual(form.recipient_list, message.recipients()) def test_invalid(self): """ Invalid data doesn't work. """ contact_url = reverse('contact_form') data = {'name': 'Test', 'body': 'Test message'} response = self.client.post(contact_url, data=data) self.assertEqual(200, response.status_code) self.assertFormError(response, 'form', 'email', 'This field is required.') self.assertEqual(0, len(mail.outbox)) def test_recipient_list(self): """ Passing recipient_list when instantiating ContactFormView properly overrides the list of recipients. """ contact_url = reverse('test_recipient_list') data = {'name': 'Test', 'email': 'test@example.com', 'body': 'Test message'} response = self.client.post(contact_url, data=data) self.assertRedirects(response, reverse('contact_form_sent')) self.assertEqual(1, len(mail.outbox)) message = mail.outbox[0] self.assertEqual(['recipient_list@example.com'], message.recipients()) django-contact-form-master/.travis.yml000664 001750 001750 00000000565 12634621623 017705 0ustar00asbasb000000 000000 language: python sudo: false python: - "3.5" - "3.4" - "3.3" - "2.7" env: - DJANGO_VERSION=1.8.7 - DJANGO_VERSION=1.9 install: - pip install coverage>=4.0 - pip install flake8 - pip install -q Django==$DJANGO_VERSION matrix: exclude: - python: "3.3" env: DJANGO_VERSION=1.9 script: - coverage run setup.py test - flake8 contact_form - coverage report -m django-contact-form-master/docs/views.rst000664 001750 001750 00000005214 12634621623 020407 0ustar00asbasb000000 000000 .. _views: .. module:: contact_form.views Built-in views ============== .. class:: ContactFormView The base view class from which most custom contact-form views should inherit. If you don't need any custom functionality, and are content with the default :class:`~contact_form.forms.ContactForm` class, you can also just use it as-is (and the provided URLConf, ``contact_form.urls``, does exactly this). This is a subclass of `Django's FormView `_, so refer to the Django documentation for a list of attributes/methods which can be overridden to customize behavior. One non-standard attribute is defined here: .. attribute:: recipient_list The list of email addresses to send mail to. If not specified, defaults to the :attr:`~contact_form.forms.ContactForm.recipient_list` of the form. Additionally, the following standard (from ``FormView``) methods and attributes are commonly useful to override: .. attribute:: form_class The form class to use. By default, will be :class:`~contact_form.forms.ContactForm`. This can also be overridden as a method named ``form_class()``; this permits, for example, per-request customization (by inspecting attributes of ``self.request``). .. attribute:: template_name The template to use when rendering the form. By default, will be ``contact_form/contact_form.html``. .. method:: get_success_url() The URL to redirect to after successful form submission. By default, this is the named URL ``contact_form.sent``. In the default URLconf provided with ``django-contact-form``, that URL is mapped to ``TemplateView`` rendering the template ``contact_form/contact_form_sent.html``. .. method:: get_form_kwargs() Returns additional keyword arguments (as a dictionary) to pass to the form class on initialization. By default, this will return a dictionary containing the current ``HttpRequest`` (as the key ``request``) and, if :attr:`~ContactFormView.recipient_list` was defined, its value (as the key ``recipient_list``). .. warning:: If you override ``get_form_kwargs()``, you **must** ensure that, at the very least, the keyword argument ``request`` is still provided, or ``ContactForm`` initialization will raise ``TypeError``. The simplest approach is to use ``super()`` to call the base implementation in ``ContactFormView``, and modify the dictionary it returns. /000700 001750 001750 00000000000 12637311163 010502 5ustar00asbasb000000 000000 django-contact-form-master/contact_form/__init__.py000664 001750 001750 00000000000 12634621623 022343 0ustar00asbasb000000 000000 django-contact-form-master/contact_form/views.py000664 001750 001750 00000004540 12634621623 021756 0ustar00asbasb000000 000000 """ View which can render and send email from a contact form. """ from django.core.urlresolvers import reverse from django.views.generic.edit import FormView from .forms import ContactForm class ContactFormView(FormView): form_class = ContactForm recipient_list = None template_name = 'contact_form/contact_form.html' def form_valid(self, form): form.save() return super(ContactFormView, self).form_valid(form) def form_invalid(self, form): # tl;dr -- this method is implemented to work around Django # ticket #25548, which is present in the Django 1.9 release # (but not in Django 1.8). # # The longer explanation is that in Django 1.9, # FormMixin.form_invalid() does not pass the form instance to # get_context_data(). This causes get_context_data() to # construct a new form instance with the same data in order to # put it into the template context, and then any access to # that form's ``errors`` or ``cleaned_data`` runs that form # instance's validation. The end result is that validation # gets run twice on an invalid form submission, which is # undesirable for performance reasons. # # Manually implementing this method, and passing the form # instance to get_context_data(), solves this issue (which # will be fixed in Django 1.9.1 and Django 1.10). return self.render_to_response(self.get_context_data(form=form)) def get_form_kwargs(self): # ContactForm instances require instantiation with an # HttpRequest. kwargs = super(ContactFormView, self).get_form_kwargs() kwargs.update({'request': self.request}) # We may also have been given a recipient list when # instantiated. if self.recipient_list is not None: kwargs.update({'recipient_list': self.recipient_list}) return kwargs def get_success_url(self): # This is in a method instead of the success_url attribute # because doing it as an attribute would involve a # module-level call to reverse(), creating a circular # dependency between the URLConf (which imports this module) # and this module (which would need to access the URLConf to # make the reverse() call). return reverse('contact_form_sent') django-contact-form-master/setup.cfg000664 001750 001750 00000000314 12634621623 017405 0ustar00asbasb000000 000000 [coverage:run] include = contact_form/* omit = contact_form/tests/* [coverage:report] fail_under = 100 [flake8] exclude = __pycache__,.pyc,templates max-complexity = 10 [isort] lines_after_imports = 2 django-contact-form-master/docs/forms.rst000664 001750 001750 00000013021 12634621623 020373 0ustar00asbasb000000 000000 .. _forms: .. module:: contact_form.forms The ContactForm class ===================== .. class:: ContactForm The 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 :class:`~contact_form.views.ContactFormView` 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 (such as spam filtering). 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. Under the hood, this form uses a somewhat abstracted interface in order to make it easier to subclass and add functionality. These attributes play a role in determining behavior: .. attribute:: from_email The email address to use in the ``From:`` header of the message. This can also be implemented as a method named ``from_email()``, in which case it will be called when constructing the message. By default, this is the value of the setting ``DEFAULT_FROM_EMAIL``. .. attribute:: recipient_list The list of recipients for the message. This can also be implemented as a method named ``recipient_list()``, in which case it will be called when constructing the message. By default, this is the email addresses specified in the setting ``MANAGERS``. .. attribute:: subject_template_name The name of the template to use when rendering the subject line of the message. By default, this is ``contact_form/contact_form_subject.txt``. .. attribute:: template_name The name of the template to use when rendering the body of the message. By default, this is ``contact_form/contact_form.txt``. And two methods are involved in actually producing the contents of the message to send: .. method:: message() Returns the body of the message to send. By default, this is accomplished by rendering the template name specified in :attr:`template_name`. .. method:: subject() Returns the subject line of the message to send. By default, this is accomplished by rendering the template name specified in :attr:`subject_template_name`. Finally, the message itself is generated by the following two methods: .. method:: get_message_dict() This method loops through :attr:`from_email`, :attr:`recipient_list`, :meth:`message` and :meth:`subject`, collecting those parts into a dictionary with keys corresponding to the arguments to Django's ``send_mail`` function, then returns the dictionary. Overriding this allows essentially unlimited customization of how the message is generated. .. method:: get_context() For methods which render portions of the message using templates (by default, :meth:`message` and :meth:`subject`), generates the context used by those templates. The default context will be a ``RequestContext`` (using the current HTTP request, so user information is available), plus the contents of the form's ``cleaned_data`` dictionary, and one additional variable: ``site`` If ``django.contrib.sites`` is installed, the currently-active ``Site`` object. Otherwise, a ``RequestSite`` object generated from the request. Meanwhile, the following attributes/methods generally should not be overridden; doing so may interfere with functionality, may not accomplish what you want, and generally any desired customization can be accomplished in a more straightforward way through overriding one of the attributes/methods listed above. .. attribute:: request The ``HttpRequest`` object representing the current request. This is set automatically in ``__init__()``, and is used both to generate a ``RequestContext`` for the templates and to allow subclasses to engage in request-specific behavior. .. method:: save If the form has data and is valid, will actually send the email, by calling :meth:`get_message_dict` and passing the result to Django's ``send_mail`` function. Note that subclasses which override ``__init__`` or :meth:`save` need to accept ``*args`` and ``**kwargs``, and pass them via ``super``, in order to preserve behavior (each of those methods accepts at least one additional argument, and this application expects and requires them to do so).django-contact-form-master/contact_form/tests/__init__.py000664 001750 001750 00000000000 12634621623 023505 0ustar00asbasb000000 000000 django-contact-form-master/docs/000700 001750 001750 00000000000 12637311163 016500 5ustar00asbasb000000 000000 django-contact-form-master/docs/index.rst000664 001750 001750 00000001450 12634621623 020357 0ustar00asbasb000000 000000 django-contact-form |version| ============================= 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 simple, extensible contact-form functionality for Django-powered sites. In the simplest case, all that's required is a bit of configuration and a few templates, and one pattern in your URLConf: .. code-block:: python url(r'^contact/', include('contact_form.urls')), Contents: .. toctree:: :maxdepth: 1 install forms views faq