Skip to content
This repository has been archived by the owner on Sep 23, 2018. It is now read-only.

Commit

Permalink
Messing around with Tests so they run somehow. Added a README.rst
Browse files Browse the repository at this point in the history
  • Loading branch information
telenieko committed May 13, 2009
1 parent 46f75d5 commit bbb6a8e
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 10 deletions.
92 changes: 92 additions & 0 deletions README.rst
@@ -0,0 +1,92 @@
Develop Mailservices in Django
==============================

Django Mailserver is an application that lets you develop
mail services in your Django projects/applications in a manner
that handles messages as Django handles HTTP requests.

That project was initialy conceived as an improvement over
`django-smtpd`_ by Denis Laprise, then became an almost full rewrite
and when I thought I had gone through almost every line of code it
seemed far much more like a fork than improvement.

NOTE: that this is really alpha software, don't use it in a production
environment unless you expect it to break everything ;)

.. _django-smtpd:: http://code.google.com/p/django-smtpd/

Example usage:
==============

First of all, you need to add "mailserver" in your INSTALLED_APPS, and
you'll want the settings::

ROOT_MAILCONF = 'myproject.mailbox' # Just like ROOT_URLCONF, but for
# resolving recipients.
MAILER_DAEMON_ADDRESS = 'postmaster@mydomain.com'

``ROOT_MAILCONF`` is just like an URLCONF, but it matches e-mail addresses
instead of paths. An example ``myproject.mailbox`` ``mailbox.py`` file
would be::

from django_mailserver.mailbox import *

urlpatterns = patterns('',
(r'@bugs.example.com', include('myapp.mailbox')),
)

Note, that when matching recipients, just as Django strips path elements
as they get matches, ``mailserver`` strips already matched parts from
the addresses until it reaches the views.

Now you can start you mail service! You can either to::

./manage.py startmailapp <app_name>

From your project directory to have a new app created with a sample mailbox.py
file in it, or you can create a new mailbox.py file in your existing application::

from django_mailserver.mailbox import *

urlpatterns = patterns('',
(r'^onedest', 'myapp.mailers.reply'),
)

You have it, your ``mailers.py`` file would be just like a ``views.py``::

from mailserver import EmailResponse

def reply(request):
print "Got email %s, Reply!" % request
return EmailResponse(
from_email=request.get_recipient_display(),
to=request['From'],
body=request.get_body(),
subject="Re: %s" % request['Subject'])
You get the idea, if you return an EmailResponse it gets ``send()``
later by the Handler. You can also return EmailIgnoreResponse among others.

Delivering mails
****************

Right now the only possible way to deliver messages to this is through a
pipe transport to the ``./manage.py readmail`` command. Which is mostly
intended for testing.

Further improvements should have a more performant pipe transport and a
self-running SMTP server.

TODO
****

**WARNING:** Django Mailserver is still under development. It is believed to
brake at any point ;) There are lots of things to do, like:

* Documentation
* More tests.
* Better URL parsing (i.e: includes work on domains, others on addreses).
* Handling address prefixes/suffixes
* Handling of error responses (ie: pipe transport should bring the
response status_code to the exit value of the process).

4 changes: 2 additions & 2 deletions buildout.cfg
Expand Up @@ -13,6 +13,6 @@ recipe = djangorecipe
version = 1.0.2
project = mailserver
projectegg = mailserver
settings = testsettings
test = mailserver
settings = testapp.settings
test = testapp
eggs = ${buildout:eggs}
28 changes: 28 additions & 0 deletions setup.py
@@ -0,0 +1,28 @@
import os
from setuptools import setup, find_packages

def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()

setup(
name = "mailserver",
version = "0.1alpha1",
url = 'http://github.com/telenieko/django-mailserver',
license = 'BSD',
description = "Create mail services in Django.",
long_description = read('README.rst'),
author = 'Marc Fargas',
author_email = 'telenieko@telenieko.com',
packages = find_packages('src'),
package_dir = {'': 'src'},
install_requires = ['setuptools'],
classifiers = [
'Development Status :: 4 - Beta',
'Framework :: Django',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Internet :: WWW/HTTP',
]
)
2 changes: 1 addition & 1 deletion src/mailserver/handlers.py
Expand Up @@ -73,7 +73,7 @@ def handle_uncaught_exception(self, request, resolver, exc_info):
raise

# When DEBUG is False, send an error message to the admins.
subject = 'Mail Error (%s)' % (request['From'])
subject = 'Mail Error (%s)' % request['From'][1]
try:
request_repr = repr(request)
except:
Expand Down
Empty file.
30 changes: 30 additions & 0 deletions src/mailserver/testapp/mailbox.py
@@ -0,0 +1,30 @@
from mailserver.mailbox import *
import sys
import types

testapp = types.ModuleType('testapp2')
testappboxes = types.ModuleType('mailbox')
testapp.mailbox = testappboxes
sys.modules.setdefault('testapp2', testapp)
sys.modules.setdefault('testapp2.mailbox', testappboxes)

testpatterns = patterns('',
(r'^onedest', 'testapp.mailers.reply'),
(r'(?P<sender>.+)@(?P<domain>.*)', 'testapp.mailers.echo'),
(r'(?P<sender>.+)', 'testapp.mailers.echo'),
)
testappboxes.urlpatterns = testpatterns

urlpatterns = patterns('',
(r'(\.?)example.net', include('testapp2.mailbox')),
(r'@bugs.example.com', include('testapp2.mailbox')),
)

def echo(request, sender, domain=None):
print 'received sender=%s domain=%s' % (sender, domain)
resp = EmailResponseServer(from_email=request.get_recipient_display(),
to=request['From'], body=sender,
subject="Echo Echo")
resp.sender = sender
resp.domain = domain
return resp
17 changes: 17 additions & 0 deletions src/mailserver/testapp/mailers.py
@@ -0,0 +1,17 @@
from mailserver import EmailResponse, EmailIgnoreResponse, EmailResponseServer

def echo(request, sender, domain=None):
print 'received sender=%s domain=%s' % (sender, domain)
resp = EmailResponseServer(from_email=request.get_recipient_display(),
to=request['From'], body=sender,
subject="Echo Echo")
resp.sender = sender
resp.domain = domain
return resp

def reply(request):
print "Got email %s, mirror-reply!" % request
return EmailResponse(from_email=request.get_recipient_display(),
to=request['From'],
body=request.get_body(),
subject="Re: %s" % request['Subject'])
Empty file.
6 changes: 6 additions & 0 deletions src/mailserver/testapp/settings.py
@@ -0,0 +1,6 @@
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = ':memory:'
INSTALLED_APPS = ['mailserver', 'mailserver.testapp']
ROOT_URLCONF = 'mailserver.urls'
ROOT_MAILCONF = 'mailserver.testapp.mailbox'
DEBUG_PROPAGATE_EXCEPTIONS = True
8 changes: 6 additions & 2 deletions src/mailserver/tests.py → src/mailserver/testapp/tests.py
@@ -1,9 +1,11 @@
import unittest
import os, sys

from email import message_from_string
from django.test import TestCase
from mailserver import *
from mailserver.handlers import BaseMessageHandler
from django.template import TemplateDoesNotExist

MAIL = """From marc@telenieko.com Wed Oct 22 07:16:19 2008
Return-path: <marc@telenieko.com>
Expand All @@ -27,8 +29,10 @@ def test_404(self):
self.message.replace_header('Envelope-To', 'johndoe@example.org')
em = EmailRequest(message=self.message)
handler = BaseMessageHandler()
res = handler(os.environ, em)
assert isinstance(res, EmailResponseNotFound)
try:
res = handler(os.environ, em)
except TemplateDoesNotExist, e:
self.assertEquals(e.message, 'recipient_notfound.txt')

def handle_for(self, to):
self.message.replace_header('Envelope-To', to)
Expand Down
5 changes: 0 additions & 5 deletions src/mailserver/testsettings.py

This file was deleted.

0 comments on commit bbb6a8e

Please sign in to comment.