This is part 2 in a series, here is part 1.
In the last section, you should have got Zed Shaw’s LamsonProject running successfully through its unit tests.
Now I’ll show you how to make what maybe the *simplest* application with Lamson that you’ll ever see. All our application is going to do is:
- Receive emails with Lamson.
- Pull the content from the body and subject lines using python.
- Send the data to Google Calendar to be turned into a calendar entry using the quickAdd call, again using python.
Because Lamson is built to interact easily with Python code, this is snap.
A brief segue with Google Calendar:
First we need to get our code together for step 3, python code to take an arbitrary text string and turn it into a Google calendar entry. Thankfully Google provides a helpful archive with files and example calls to each of their GData APIs. Download the archive and place it in the directory above your lamson install. Inside that archive is a file containing examples of the Google Calendar API … with a little bit of pairing down, this will do exactly what we want. Take a look at this changelog of my edits to the renamed file.
Here’s the key function:
def _InsertQuickAddEvent(self,
content="Tennis with John today ... 3pm-3:30pm ... ok?", title=None):
"""Creates an event with the quick_add property set to true so the content
is processed as quick add content instead of as an event description."""
event = gdata.calendar.CalendarEventEntry()
event.content = atom.Content(text=content)
event.quick_add = gdata.calendar.QuickAdd(value='true');
new_event = self.cal_client.InsertEvent(event,
'/calendar/feeds/default/private/full')
if title:
new_event.quick_add = gdata.calendar.QuickAdd(value='false');
new_event.title = atom.Title(text=title)
new_event.content = atom.Content(text=content)
self.cal_client.UpdateEvent(new_event.GetEditLink().href, new_event)
return new_event
the take home message is that we now have a function ‘_InsertQuickAddEvent’ on our CalendarExample object that will accept both text to be processed and optionally a title to give the calendar entry. QuickAdd can autocreate a title, but it can be a bit strange. Anyway, that’s not what we’re here for really.
Wiring Lamson to our Python code:
First, I’m assuming you made the changes to your config/settings.py file in your lamson project to keep yourself from being an open relay.
Next, let’s open the default app/handlers/sample.py file that lameson autogenerated for us in Zed Shaw’s 30 second intro. Since we’re not interested in having forwarding /double opt-in emails, drop most everything ( changelog ). This will result in a basically empty file:
import logging
from lamson.routing import route, route_like, stateless
from config.settings import relay
from lamson import view
@route("(address)@(host)", address=".+")
def START(message, address=None, host=None):
return
The key part is ‘@route(“(address)@(host)”,address=”.+”)’ as this decorator controls which emails ( in this case, all that pass the settings.py configuration ) get fed to the action START. Right now of course, once your messages reach START, nothing happens. Let’s fix that:
import logging
from lamson.routing import route, route_like, stateless
from config.settings import relay
from lamson import view
#######
import sys
sys.path.append("..")
sys.path.append("../../gdata-2.0.5/src")
import simplifiedCalendarExample
#######
@route("(address)@(host)", address=".+")
def START(message, address=None, host=None):
content_string = "Subject: " + message['Subject']
content_string += "\r\n" + message.body()
sample = simplifiedCalendarExample.CalendarExample("REPLACEME", "REPLACEME")
sample._InsertQuickAddEvent(content_string, message['Subject'])
return
Two things should be noted from the changes above:
- We’re importing our ‘module’ simplifiedCalendarExample that we’ve setup earlier.
- We’re shoveling the primary email message parts ‘body’ and ‘subject’ into one value to feed into the Google Calendar’s quickAdd content. We also pass the subject line as the title of the Calendar entry to make for something more readable than what GCal invents.
- You’ll also need to swap out “REPLACEME”,”REPLACEME” with your Google username and password. Switching it to OAuth is left as an exercise to reader. Fork me. I dare you.
Shockingly, that’s it. Restart your lamson app where you’ve been making the above changes, and you should be able to do the following:
lamson send -sender me@localhost -to me@localhost -subject "My test." -body "Hi there. Let's meet from 7pm until 9pm. Does that sound good?" -port 8823
Which should create a new entry in your Google Calendar with an event named ‘My Test.’ lasting from 7pm to 9pm your local time, either today or tomorrow, depending on feasibility.
I realize you wrote this a while ago, but I am interested in setting up some triggers based on emails. Is there any way to forward email from an external source, such as gmail, to activate this instead of sending from localhost?