Este script permite enviar emails a través de GMail. Los emails pueden tener texto plano, HTML y archivos adjuntos (todos opcionales).
Nota: El script lo escribí originalmente en inglés. Debería entenderse, pero pienso traducirlo cuando tenga algo más de tiempo.
Archivo: GmailMail.py
#!/usr/bin/env python # requires Python >= 2.5 import smtplib from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email.mime.text import MIMEText from email.mime.audio import MIMEAudio from email.mime.image import MIMEImage from email.encoders import encode_base64 from mimetypes import guess_type from os.path import basename class GmailMail(): def __init__(self, gmail_user, gmail_pwd): """ Prepares an instance with basic authentication """ self.gmail_user = gmail_user self.gmail_pwd = gmail_pwd def getAttachment(self, path, charset='ASCII'): contentType, encoding = guess_type(path) if contentType is None or encoding is not None: contentType = 'application/octet-stream' mainType, subType = contentType.split('/', 1) _file = open(path, 'rb') if mainType == 'text': attachment = MIMEText(_file.read(), subType, charset) elif mainType == 'message': attachment = email.message_from_file(_file) elif mainType == 'image': attachment = MIMEImage(_file.read(), _subType=subType) elif mainType == 'audio': attachment = MIMEAudio(_file.read(), _subType=subType) else: attachment = MIMEBase(mainType, subType) attachment.set_payload(_file.read()) encode_base64(attachment) _file.close() attachment.add_header('Content-Disposition', 'attachment', filename=basename(path)) return attachment def send(self, to, subject, text=u"", html=None, attachments=None, charset="iso-8859-15"): """ Sends an email through Gmail using the authentication given to this instance. If given, attachments must be a list of paths pointing to the files we want to include. This script does not embed inline content (multipart/related) """ if charset in ['utf8','utf-8']: #bug? from email.charset import add_charset, SHORTEST add_charset('utf-8', SHORTEST, None, None) if isinstance(text, unicode): text = text.encode(charset, 'replace') if isinstance(html, unicode): html = html.encode(charset, 'replace') if attachments is None: attachments = [] if text: plain_part = MIMEText(text, 'plain', charset) if html: html_part = MIMEText(html, 'html', charset) is_alternative = html and text layers = [] if attachments or is_alternative: msg = MIMEMultipart() #mixed msg.set_charset(charset) msg.preamble = 'This is a multi-part message in MIME format.' msg.epilogue = '' layers.append(msg) if is_alternative: msgAlternative = MIMEMultipart('alternative') msg.attach(msgAlternative) layers.append(msgAlternative) if text: layers[-1].attach(plain_part) if html: layers[-1].attach(html_part) elif text: msg = plain_part else: #html only msg = html_part for path in attachments: msg.attach(self.getAttachment(path, charset)) msg['From'] = self.gmail_user msg['To'] = to msg['Subject'] = subject mailServer = smtplib.SMTP("smtp.gmail.com", 587) mailServer.ehlo() mailServer.starttls() mailServer.ehlo() mailServer.login(self.gmail_user, self.gmail_pwd) mailServer.sendmail(self.gmail_user, to, msg.as_string()) # Should be mailServer.quit(), but that crashes... mailServer.close()
Algunos tests (ejemplos, casos de uso):
Archivo: GmailMail_tests.py
# -*- coding: utf-8 -*- from GmailMail import GmailMail from urllib2 import urlopen text = u"""\ Éste es el contenido en modo texto plano Tenemos acentos y eñes. """ url = "http://python.com.ar/moin" html = urlopen(url).read() user = 'XXXXXX@gmail.com' # mi usuario de GMail pwd = '********' # mi contraseña de GMail m = GmailMail(user, pwd) print "mandando texto plano solamente" m.send(user, u'prueba de sólo texto', text) print "mandando html solamente" m.send(user, u'prueba con sólo html', html=html) print "mandando texto plano y html (sin attachments)" m.send(user, u'prueba con texto plano y html (sin attachments)', text, html) print "mandando texto plano y attachments" m.send(user, u'prueba con texto plano y attachments', text, attachments=['GmailMail.py']) print "mandando html y attachments" m.send(user, u'prueba con html y attachments', html=html, attachments=['GmailMail.py']) print "mandando attachments solamente" m.send(user, u'prueba con attachments solamente', attachments=['GmailMail.py']) print "mandando todo" m.send(user, u'prueba con todo', text, html, attachments=['GmailMail.py'])