django-emailform / emailform / views.py

from __future__ import absolute_import

import logging

from django.conf import settings
from django.core.mail import EmailMultiAlternatives
from django.core.urlresolvers import reverse, NoReverseMatch
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext as _rc
from django.template.loader import render_to_string

from .forms import forms_for_contact_form, BaseOptionAnswer
from .models import ContactForm, Entry, OPTION_TYPE_CHOICES

from .util import ChoiceEnum
from . import settings as local_settings


def _get_remote_ip(request):
    forwarded = request.META.get('HTTP_X_FORWARDED_FOR')
    if forwarded:
        return forwarded.split(',')[-1].strip()
    return request.META['REMOTE_ADDR']


def _get_contact_form_or_404(request, slug):
    if request.user.is_staff:
        return get_object_or_404(ContactForm.objects, slug=slug)
    else:
        return get_object_or_404(ContactForm.live, slug=slug)


def _contact_form_submit(request, contact_form, embed=False):
    forms = forms_for_contact_form(contact_form, request)
    if all(form.is_valid() for form in forms):
        all_fields = []
        for field in forms:
            for k, v in field.clean().iteritems():
                if isinstance(field, BaseOptionAnswer):
                    v = ','.join(v)
                all_fields.append('%s : %s' % (field.question.label, v))
        entry = Entry(contact_form=contact_form,
                      ip_address=_get_remote_ip(request),
                      content=render_to_string(
                        ('emailform/%s_completed_form.html'
                         % (contact_form.slug),
                        'emailform/completed_form.html'),
                        dict(all_fields=all_fields)))
        entry.save()
        if contact_form.email:
            _send_contact_form_email(request, contact_form, entry)
        return _contact_form_show_form(request,
                                       contact_form,
                                       (),
                                       entered=True,
                                       embed=embed)
    else:
        return _contact_form_show_form(request,
                                       contact_form,
                                       forms,
                                       embed=embed)


def _url_for_edit(request, obj):
    view_args = (obj._meta.app_label, obj._meta.module_name,)
    try:
        edit_url = reverse("admin:%s_%s_change" % view_args, args=(obj.id,))
    except NoReverseMatch:
        edit_url = "/admin/%s/%s/%d/" % (view_args + (obj.id,))
    admin_url = local_settings.CONTACTFORM_ADMIN_SITE
    if not admin_url:
        admin_url = "http://" + request.META["HTTP_HOST"]
    elif len(admin_url) < 4 or admin_url[:4].lower() != "http":
        admin_url = "http://" + admin_url
    return admin_url + edit_url


def _send_contact_form_email(request, contact_form, entry):
    subject = contact_form.title
    sender = local_settings.CONTACTFORM_EMAIL_FROM
    recipients = list(set(x.strip() for x in contact_form.email.split(',')))
    links = [(_url_for_edit(request, entry), "Edit Submission"),
             (_url_for_edit(request, contact_form), "Edit Contact Form"), ]
    html_email = entry.content
    email_msg = EmailMultiAlternatives(subject,
                                       html_email,
                                       sender,
                                       recipients)
    email_msg.attach_alternative(html_email, 'text/html')
    try:
        email_msg.send()
    except smtplib.SMTPException as ex:
        logging.exception("SMTP error sending email: %s" % str(ex))
    except Exception as ex:
        logging.exception("Unexpected error sending email: %s" % str(ex))


def _contact_form_show_form(request,
                            contact_form,
                            forms,
                            entered=False,
                            embed=False):
    if embed:
        specific_template = ('emailform/%s_contact_form_detail_embed.html' %
                        contact_form.slug)
        return render_to_response([specific_template,
                               'emailform/contact_form_detail_embed.html'],
                              dict(contact_form=contact_form,
                                   forms=forms,
                                   entered=entered,
                                   embed=embed),
                              _rc(request))
    specific_template = ('emailform/%s_contact_form_detail.html' %
                    contact_form.slug)
    return render_to_response([specific_template,
                           'emailform/contact_form_detail.html'],
                          dict(contact_form=contact_form,
                               entered=entered,
                               forms=forms,
                               embed=embed),
                          _rc(request))


def contact_form_detail(request, slug, embed=False):
    contact_form = _get_contact_form_or_404(request, slug)
    if request.method == 'POST':
        return _contact_form_submit(request, contact_form, embed=embed)
    forms = forms_for_contact_form(contact_form, request)
    return _contact_form_show_form(request, contact_form, forms, embed=embed)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.