Tino de Bruijn avatar Tino de Bruijn committed f46c6c0

inital setup

Comments (0)

Files changed (11)

+syntax: glob
+
+*.pyc
+.DS_Store
+=================
+Simple Mail Merge
+=================
+
+Settings
+========
+
+SMM_DOMAINS
+-----------
+
+A tuple of choice-tuples (see ) with the domains that can be used as sender address
+
+SSM_REDIRECT_AFTER_SENT
+-----------------------
+
+Set to a named url to redirect to after sending
+
+#!/usr/bin/env python
+ 
+from distutils.core import setup
+
+setup(
+    name='django-simple-mail-merge',
+    version='0.1',
+    description="A small django app that provides real easy and naive merged mail sending",
+    author='Tino de Bruijn',
+    author_email='tinodb@gmail.com',
+    packages=['simple_mail_merge'],
+    include_package_data=True,
+    zip_safe=False,
+)
Add a comment to this file

simple_mail_merge/__init__.py

Empty file added.

simple_mail_merge/forms.py

+from django import forms
+from django.conf import settings
+from django.utils.translation import ugettext as _
+
+class SendMailForm(forms.Form):
+    sender_name = forms.CharField(max_length=50)
+    sender_user = forms.CharField(max_length=50)
+    sender_domain = forms.ChoiceField(choices=settings.SMM_DOMAINS)
+    subject = forms.CharField(max_length=100)
+    receivers = forms.FileField(help_text=_("Upload a .csv file (export from"
+        "excel) containing at least one column with the header 'email'. "
+        "Values in the other columns can be used in the message by inserting"
+        " {{ lowercase_col_name }}."))
+    message = forms.CharField(widget=forms.Textarea(attrs={'rows':20,'cols':80}))
+    auth_user = forms.CharField()
+    auth_password = forms.CharField(forms.PasswordInput())

simple_mail_merge/models.py

+# No models for this app

simple_mail_merge/templates/simple_mail_merge/send_email.html

+{% extends "base.html" %}
+
+{% block content %}
+    <h1>Send Email</h1>
+    {% include "simple_mail_merge/send_mail_form.html" %}
+{% endblock %}

simple_mail_merge/templates/simple_mail_merge/send_mail_form.html

+<form enctype="multipart/form-data" method="POST" action="">
+    {% csrf_token %}
+    {{ form.as_p }}
+    <input type="submit" name="submit" value="Send" id="submit">
+</form>

simple_mail_merge/urls.py

+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+    url(r'^$', 'simple_mail_merge.views.send_mail', name='send_mail_merge'),
+)

simple_mail_merge/utils.py

+import csv
+from cStringIO import StringIO
+
+def map_csv_file(f, delimiter=','):
+    """
+    Tries to read a csv file, and map values to the header-keys.
+    """
+    try:
+        reader = csv.reader(f, delimiter=str(delimiter))
+        mapper = [key.lower() for key in reader.next()]
+    except Exception, e:
+        if 'new-line' in str(e):
+            f.seek(0)
+            new = cStringIO()
+            for content in f.readline():
+                new.write(content.replace('\r','\n'))
+            f.close()
+            f = new
+            reader = csv.reader(f, delimiter=str(delimiter))
+            mapper = [key.lower() for key in reader.next()]
+            f.close()
+                
+    def _do_map(item):
+        data = {}
+        for i in range(len(mapper)):
+                try:
+                        data[mapper[i]] = item[i]
+                except IndexError:
+                        data[mapper[i]] = ''
+        return data
+    return map(_do_map, reader)

simple_mail_merge/views.py

+import smtplib
+from django.shortcuts import render_to_response
+from django.utils.translation import ugettext as _
+from django.conf import settings
+from django.template import Template, TemplateSyntaxError, Context, RequestContext
+from django.contrib import messages
+from django.core.mail import send_mass_mail
+from django.core.urlresolvers import reverse
+from django.http import HttpResponseRedirect
+from django import forms
+from forms import SendMailForm
+from utils import map_csv_file
+
+def send_mail(request):
+    if request.method == "POST":
+        errors = 0
+        form = SendMailForm(request.POST, request.FILES)
+        if form.is_valid():
+            try:
+                message_tpl = Template(form.cleaned_data['message'])
+            except TemplateSyntaxError:
+                error = _("There is an error in with the variables used in the" \
+                    " message. Please make sure all variables are look like" \
+                    " {{ this }}, are lower-case and present in the header" \
+                    " of the uploaded file")
+                form.errors['message'] = error
+                errors = 1
+            try:
+                receivers = map_csv_file(form.cleaned_data['receivers'])
+            except Exception, e:
+                form.errors['receivers'] = _("There is an error in your" \
+                    "file: %s" % e)
+                errors = 1
+            sender_email = "%s@%s" % (form.cleaned_data['sender_user'],
+                                form.cleaned_data['sender_domain'])
+            sender = "%s <%s>" % (form.cleaned_data['sender_name'], sender_email)
+            datalist = []
+            for rec in receivers:
+                if rec['email'] is not '':
+                    c = Context(rec)
+                    datalist.append((form.cleaned_data['subject'], 
+                                    message_tpl.render(c), 
+                                    sender, 
+                                    (rec['email'],)))
+            try:
+                send_mass_mail(tuple(datalist), 
+                    auth_user=forms.cleaned_data['auth_user'],
+                    auth_password=forms.cleaned_data['auth_password'])
+            except smtplib.SMTPException, e:
+                form.errors[forms.NON_FIELD_ERRORS] = \
+                    _("An error occurred upon sending: %s" % e)
+                errors = 1
+            if errors:
+                return render_to_response('simple_mail_merge/send_email.html',
+                    { 'form' : form }, context_instance=RequestContext(request))
+            count_msg = len(datalist) > 1 and _("%d mails" % len(datalist)) or \
+                _("1 mail")
+            messages.success(request, _("%s sent") % count_msg)
+            return HttpResponseRedirect(reverse(settings.SSM_REDIRECT_AFTER_SENT))
+    else:
+        form = SendMailForm()
+    return render_to_response('simple_mail_merge/send_email.html',
+        { 'form' : form }, context_instance=RequestContext(request))
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.