Small tips for accessing programmatically the Gmail

Talking to IMAP services can be a source of frustration especially when each service implements parts of the protocol or add some secret ingredients to the sauce. One of the most popular services, as we all know is Gmail.

XOAuth

Gmail adds a lot of nice touches to the mail business. One of the latest additions is the use of XOAuth in order to authenticate against the service without any need of username and password. This can be especially handy if your app your app should read or just parse the headers of the users' emails but you do not want to save passwords, have extra UI for this purpose or let the user revoke the access at will. You can easily use xoauth in your webapp today using this small library.

Example code:

 

Searching

By default when you use imap.select() you will be able to search within the INBOX folder but sometimes you may want to search in both Sent messages and Inbox. In order to do so you have to do give the following command:

imap_conn.select("[Gmail]/All Mail")

 

Fetching an email without setting it as SEEN

When you want to fetch an email in order to parse you usually do:

typ, msg_data = imap_conn.fetch(uid, 'RFC822')

which will do exactly what you want, but if the email is not read (SEEN) it will mark it as read which something you may not want if you are not building a Gmail client. If you simply want to parse/read the email then do the following

typ, msg_data = imap_conn.fetch(uid, '(BODY.PEEK[HEADER])')

 

Find the body message and decode it

This can be really tricky as there can be a lot of forwards and replies plus an awful lot of encodings. Usually we the encoding of an email is appended in the subject. The following gist can be to some help:

 

If you have any suggestions, corrections please feel free to fork the gists and let me know :)

 

 

 


 

Create a web service in Clojure without start/stopping the server

The problem using Jetty (or Netty or Ring) is that after you start the process, your beloved REPL is "binded" to the server thus forcing you to kill the service, make a change, start the process again, refresh and do it again. Not fun at all. It's easy to run the process "in the background" and have the REPL available to make changes. 

Let's create a new project (using lein).

> lein new TinyService

Now, we need  a project.clj (so we can do a lein deps and have everything installed automagically)

> lein deps

Edit core.clj with this:

You can run the service in REPL by (boot) and then you'll still have access to REPL. You can change stuff, C+c C+c, refresh and voila! You can even connect to web server (to a JVM to be more exact) and make changes without the need for compilation. And all this from your local emacs!

Enjoy!

AppStats for web2py

If you are running a web2py app on AppEngine it is matter of sanity to have AppStats logging your app 's performance. It is common practice to have performance monitor for all major web applications out there so that you know where to optimize your application. 

If you are on AppEngine the performance of your application is even more crucial as better performance means less costs and stability (as it is easy to hit the restrictions). 

If you have a web2py application it is very easy to this as web2py is first class wsgi citizen. Simply go to gaehander.py and modify the main function as in the following gist:

Then go to app.yaml and right after the handler definitions add these 2 lines:

In the root directory of web2py create a new a file called appengine_config.py with the following content (thanx WritersEar for pointing out):

 

And you are good to go!

Picture_2

Support for multiple query parameters with the same name in python-oauth

While working on the API of LinkedIn we had to a query in this format:

http://api.linkedin.com/v1/people/~/network?type=STAT&type=PICT&count=50&start=50

As usual, you get a 401 (forbidden) response. That was tough bug. Thank to LinkedIn forum I found out that in the python-oauth library you cannot have a query parameter with multiple values. Adam from the LinkedIn forum pointed out that have multiple values is valid according to the OAuth 1.0 spec and there is support in the python-oauth2 library.

If you want this functionality in python-oauth (OAuth 1.0) take a look at the following gist.