Created
March 2, 2012 16:03
-
-
Save amcgregor/1959335 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # encoding: utf-8 | |
| """A simple mail delivery API. | |
| Install in a venv: | |
| $ curl get.web-core.org | python - MailAPI | |
| $ cd MailAPI; . bin/activate | |
| $ pip install marrow.mailer, mako | |
| """ | |
| import time | |
| import web.core | |
| try: | |
| from simplejson import loads | |
| except ImportError: | |
| from json import loads | |
| from marrow.mailer import Mailer, Message | |
| from marrow.templating.core import Engines | |
| log = __import__('logging').getLogger(__name__) | |
| render = Engines(default='mako', cache=50, container=None) | |
| class RootController(web.core.Controller): | |
| """A handy HTTP API for mail delivery. | |
| Configuration is loaded from 'config.json'. | |
| mailer -- a dictionary containing the Marrow Mailer configuration | |
| defaults -- a dictionary of default values for Message objects | |
| headers -- additional headers to add to the messages | |
| reply, sender, return, unsubscribe -- a string template for appropriate e-mail addresses | |
| String templates allow you to use {} to insert the target's identifier. | |
| To use, POST to /deliver with the following values: | |
| targets -- a list of targets (comma-separated) each combining an identifier and address (colon-separated) | |
| subject -- the subject of the mailing | |
| plain -- the template to use for the plain text version | |
| rich -- the template to use for the rich text version | |
| **kw -- unlimited key/value pairs which get passed to the template | |
| Additionally, the template will have access to the target's Address object (name/e-mail) and identifier. | |
| Returns a JSON dictionary of: | |
| success -- identifiers successfully delivered to | |
| failure -- identifiers that could not be delivered to | |
| time -- the amount of time delivery took | |
| """ | |
| def __init__(self): | |
| self.config = loads(open('config.json', 'ru')) | |
| self.mailer = Mailer(self.config['mailer']) | |
| self.mailer.start() | |
| def deliver(self, targets, subject, plain, rich, **data): | |
| if isinstance(targets, basestring): | |
| targets = targets.split(',') | |
| success = [] | |
| failure = [] | |
| start = time.time() | |
| for target in targets: | |
| if isinstance(target, basestring): | |
| target = target.split(':') | |
| identifier, address = target | |
| try: | |
| message = self.mailer.new(**self.config['defaults']) | |
| message.subject = subject | |
| message.to = address | |
| message.reply = self.config['reply'].format(identifier) | |
| message.sender = self.config['sender'].format(identifier) | |
| message.headers.append(('Precedence', 'bulk')) | |
| message.headers.append(('List-Unsubscribe', self.config['unsubscribe'].format(identifier))) | |
| message.headers.append(('Return-Path', self.config['return'].format(identifier))) | |
| # X-Copyright | |
| data = dict(data) | |
| data['identifier'] = identifier | |
| data['target'] = message.to | |
| data['subject'] = subject | |
| mime, message.plain = render(plain, data) | |
| mime, message.rich = render(rich, data) | |
| message.send() | |
| except: | |
| log.exception("Unable to deliver to %s.", identifier) | |
| failure.append(identifier) | |
| else: | |
| success.append(identifier) | |
| end = time.time() | |
| return 'json:', dict(success=success, failure=failure, time=end - start) | |
| if __name__ == '__main__': | |
| from paste import httpserver | |
| app = web.core.Application.factory(root=RootController, debug=False) | |
| httpserver.serve(app, host='127.0.0.1', port='8080') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment