Peter Ward avatar Peter Ward committed 8f0b8eb

Initial implementation.

Comments (0)

Files changed (4)

examples/hello.py

+from wagon import Wagon
+
+app = Wagon()
+
+@app.route('(?P<local>.*)@(?P<domain>.*)')
+def catch_all(address, message, local, domain):
+    from_address = message.get('From')
+    print 'Hello %s from %s!' % (address, from_address)
+
+if __name__ == '__main__':
+    app.run()
+set smtp_url = "smtp://localhost:2525/"
+
+set sort = 'threads'
+set sort_aux = 'last-date-received'
+#!/usr/bin/env python
+#from distutils.core import setup
+from setuptools import setup, find_packages
+
+setup(
+    name='wagon',
+    version='0.1',
+    description='Wagon is to SMTP what Flask is to WSGI/HTTP.',
+    author='Peter Ward',
+    author_email='peteraward@gmail.com',
+    url='http://hg.flowblok.id.au/wagon',
+    packages = find_packages(),
+    install_requires = [
+        'secure-smtpd>=1.1.8',
+        'pydkim',
+        'dnspython',
+        'pyspf',
+        'pydns'
+    ],
+    tests_require=[
+        'nose'
+    ]
+)
+import email
+import re
+import traceback
+
+import asyncore
+from secure_smtpd import SMTPServer
+
+class Wagon(object):
+    def __init__(self):
+        self.routes = []
+        self.endpoints = {}
+
+    def __call__(self, address, message):
+        func, groups = self.match_route(address)
+
+        func(address, message, **groups)
+
+    def match_route(self, address):
+        for regex, func in self.routes:
+            match = regex.match(address)
+            if match is not None:
+                return func, match.groupdict()
+
+    def add_route(self, pattern, endpoint, func):
+        self.endpoints[endpoint] = pattern
+        regex = re.compile(pattern)
+        self.routes.append(
+            (regex, func)
+        )
+
+    def route(self, pattern, **options):
+        def decorator(func):
+            endpoint = options.get('endpoint')
+            self.add_route(pattern, endpoint, func)
+            return func
+        return decorator
+
+    def run(self, host='', port=2525):
+        server = SMTPServer((host, port), None)
+
+        def process_message(peer, sender, targets, msgdata):
+            print 'Recieved mail from %r' % (peer,)
+            print 'From %s to %d recipients.' % (sender, len(targets))
+
+            message = email.message_from_string(msgdata)
+
+            for address in targets:
+                try:
+                    self(address, message)
+                except Exception:
+                    traceback.print_exc()
+                    raise
+
+        server.process_message = process_message
+        asyncore.loop()
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.