sábado, 8 de marzo de 2008

MobiGM "ported" to Python

Reciently, a friend told me about MobiGM, a simple Perl script that parses a rss feed from a gmail account, and sends notifications about new mails to an email account. Ideally, to the one corresponding to your cell phone.

He was having troubles trying to run the script. The problem was simple: The link to the code was dead, and copying and pasting the fragments of code didn't work, because some html special characters were bothering. A few replacements made the script go.

It worked fine sending mails through my ISP SMTP server, since it doesn't require authentication, but I couldn't send mails from my gmail account.
I tried modifying the script, using the module Net::SMTP::SSL, but I had no luck, so I decided to write it in Python.

It works. It has the same functionality as MobiGM and can authenticate against a SMTP server with TLS. But it uses minidom to parse the rss feed, and access to its data in a very direct way, assuming that the feed has always the correct format.
I recommend reading the original post of MobiGM from its author's blog, because it is a nice tutorial on how to build a small application to solve a problem, using various open source tools.
The program itself is not very useful, since you can do the same thing with gmail's filters. But the author remarks the posibility of customizing it, to make it react dinamically to what appears in your mailbox.


Having said that, here is the code:

#!/usr/bin/python

from xml.dom.minidom import parse

SMTP_SERVER = "smtp.yourisp.com:port" #port not needed on servers
#that listen to on port 25
#for gmail use 587,

REQUIRES_AUTHENTICATION = True
REQUIRES_TLS = True
SMTP_USERNAME = 'username'
SMTP_PASSWORD = 'password'
FROM_EMAIL = 'email@isp.com'
TO_EMAIL = 'cellphone@phonecompany.com'

def sendMail(message):
import smtplib
s = smtplib.SMTP(SMTP_SERVER)
#s.debuglevel = 5
s.ehlo()

if REQUIRES_TLS:
s.starttls()
s.ehlo()
if REQUIRES_AUTHENTICATION:
s.esmtp_features["auth"] = "LOGIN PLAIN"
s.login(SMTP_USERNAME, SMTP_PASSWORD)

s.sendmail(FROM_EMAIL, TO_EMAIL, message)
s.quit()


oldIDs = []
newIDs = []

try:
OLDID = open('ids.old', 'rw')
except:
OLDID = None
newfile = open('ids.old', 'w')
newfile.close()

if OLDID:
for line in OLDID.readlines():
oldIDs.append(line.strip())

try:
xmldoc = parse('atomfeed')
except IOError:
quit("Error opening file 'atomfeed'")
except:
quit("Problem parsing file 'atomfeed'")

entries = xmldoc.getElementsByTagName('entry')

for entry in entries:
curID = entry.getElementsByTagName('id')[0].firstChild.nodeValue
newIDs.append(curID)
if not curID in oldIDs:
curTitle = entry.getElementsByTagName('title')[0].firstChild.nodeValue
curContents = entry.getElementsByTagName('summary')[0].firstChild.nodeValue
curAuthorEmail = entry.getElementsByTagName('email')[0].firstChild.nodeValue
curAuthor = entry.getElementsByTagName('name')[0].firstChild.nodeValue
sendMail('Subject:'+ curTitle + '\n\nFrom:' + curAuthorEmail + ' [' + curAuthor + ']\n' + curContents)


OLDID = open('ids.old', 'w')

for newid in newIDs:
OLDID.write(newid + '\n')

OLDID.close()


As Perl's version, this script needs to be added to a shell script, where wget will be executed before it to receive the feed. And that script should be executed periodically by cron.
If we saved this script as mail.py, the shell script would be something like this:

#!/bin/sh
wget -O atomfeed https://mail.google.com/gmail/feed/atom --http-user=gmail.user@gmail.com --http-password=gmailPassword
./mail.py



Read the original post on MobiGM author blog for more details.

No hay comentarios: