[Tutor] Mail revisited
Ricardo Aráoz
ricaraoz at gmail.com
Tue Feb 12 19:17:47 CET 2008
Ok, so I've started the path to put a GUI to the "MandarMails.py"
program. For starters I've included a progress bar. Any enhancements you
may suggest will be appreciated.
Note: not tested yet
######################
### MandarMails.py ###
######################
#!/usr/bin/env python
import time
import smtplib
import email
import ConfigParser
import logging
class Mensaje(object) :
def __init__(self) :
cfg = ConfigParser.ConfigParser()
try :
cfg.readfp(open('config.cfg'))
except Exception, e :
logging.error('No pude leer "config.cfg" : %s', e.strerror)
self.direcciones = cfg.get('Archivos', 'Direcciones')
self.excluidas = cfg.get('Archivos', 'Excluir')
self.cuantos = cfg.getint('Correo', 'MailsPorVez')
self.intervalo = cfg.getint('Correo', 'IntervaloEnSegundos')
try :
htmlFile = open(cfg.get('Archivos', 'Mensaje'))
htmlMessage = htmlFile.read()
htmlFile.close()
except Exception, e :
logging.error('No pude leer "%s" : %s',
cfg.get('Archivos', 'Mensaje'),
e.strerror)
self.messg = email.MIMEMultipart.MIMEMultipart()
self.messg['From'] = cfg.get('Encabezados', 'De')
self.messg['To'] = ''
self.messg['Subject'] = cfg.get('Encabezados', 'Encabezado')
self.messg['Reply-To'] = cfg.get('Encabezados', 'ResponderA')
self.messg.preamble = 'This is a multi-part message in MIME format'
self.messg.attach(email.MIMEText.MIMEText(htmlMessage, 'html'))
self.servidor = cfg.get('Correo', 'Servidor')
self.usuario = cfg.get('Correo', 'Usuario')
self.contra = cfg.get('Correo', 'Contrasenia')
class Correo(object) :
def __init__(self, mensaje) :
self.mensaje = mensaje
self.conexion = smtplib.SMTP()
def connect(self) :
try :
self.conexion.connect(self.mensaje.servidor)
self.conexion.set_debuglevel(False)
self.conexion.ehlo()
self.conexion.starttls()
self.conexion.ehlo()
self.conexion.login(self.mensaje.usuario, self.mensaje.contra)
return True
except :
logging.error('No me pude conectar al Servidor')
return False
def disconnect(self) :
self.conexion.close()
def enviar(self, addr) :
self.mensaje.messg.replace_header('To', addr)
try :
self.conexion.sendmail(self.mensaje.messg['From'],
self.mensaje.messg['To'],
self.mensaje.messg.as_string())
logging.info('Enviado a : %s', self.mensaje.messg['To'])
except smtplib.SMTPRecipientsRefused :
logging.error('El destinatario fue rechazado por el servidor')
except smtplib.SMTPHeloError :
logging.error('El servidor no respondio apropiadamente')
except smtplib.SMTPSenderRefused :
logging.error('El From: fue rechazado por el servidor')
except smtplib.SMTPDataError :
logging.error('El servidor respondio con un error desconocido')
class Envio(object) :
def __init__(self, mensaje) :
self._mensaje = mensaje
self.totAEnviar = 0
self.enviados = 0
self._mails = []
self._miCorreo = None
self._timer = 0
try :
try :
fIncl = open(self._mensaje.direcciones)
except Exception, e :
logging.error('Error!!! No pude abrir "%s" : %s',
self._mensaje.direcciones,
e.strerror)
raise
try :
fExcl = open(self._mensaje.excluidas)
except Exception, e :
logging.error('No pude abrir "%s" : %s',
self._mensaje.excluidas,
e.strerror)
fIncl.close()
raise
except : pass
else :
self._mails = enumerate(set(addr.strip() for addr in fIncl)
- set(excl.strip() for excl in fExcl))
fIncl.close()
fExcl.close()
self.TotAEnviar = len(self._mails)
self._miCorreo = Correo(self._mensaje)
def enviar() :
dormir = self._mensaje.intervalo - (time.clock() - self._timer)
if dormir > 0 :
time.sleep(dormir)
self._timer = time.clock()
if not self._miCorreo.connect() :
logging.info('Terminando')
return False
for nro, addr in self._mails[:self._mensaje.cuantos] :
self._miCorreo.enviar(addr)
self._miCorreo.disconnect()
self._mails = self._mails[self._mensaje.cuantos:]
return (len(self._mails) > 0)
if __name__ == '__main__' :
from Tkinter import *
from ProgressBar import ProgressBar
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(levelname)-8s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename=time.strftime('informe-%Y-%m-%d-%H-%M-%S.log'),
filemode='w')
miEnvio = Envio(Mensaje())
root = Tk()
labelfont = ('times', 12, 'bold')
titulo = Label(root, text='Progreso del Envio')
titulo.config(font=labelfont)
titulo.config(height=1, width=20)
titulo.pack(expand=YES, fill=X)
myBar = ProgressBar(root, width=200, max=miEnvio.totAEnviar)
myBar.pack()
while miEnvio.enviar() :
myBar.updateProgress(miEnvio.enviados)
######################
### ProgressBar.py ###
######################
from Tkinter import *
import time
class ProgressBar(Frame) :
def __init__(self, parent=None, orientation="horizontal",
min=0, max=100, width=100, height=18,
doLabel=1, relief="sunken",
fillColor="blue", background="gray",
labelColor="yellow", labelFont="Verdana",
labelText="", labelFormat="%d%%",
value=0, bd=2) :
self.parent = parent
self.orientation = orientation
self.min = min
self.max = max
self.width = width
self.height = height
self.doLabel = doLabel
self.fillColor = fillColor
self.labelFont = labelFont
self.labelColor = labelColor
self.background = background
self.labelText = labelText
self.labelFormat = labelFormat
self.value = value
Frame.__init__(self, parent, relief=relief, bd=bd)
self.pack()
self.canvas=Canvas(self, height=height, width=width, bd=0,
highlightthickness=0, background=background)
self.scale=self.canvas.create_rectangle(0, 0, width, height,
fill=fillColor)
self.label=self.canvas.create_text(self.canvas.winfo_reqwidth() / 2,
height / 2, text=labelText,
anchor="c", fill=labelColor,
font=self.labelFont)
self.update()
self.canvas.pack(side='top', fill='x', expand='no')
def updateProgress(self, newValue, newMax=None):
if newMax:
self.max = newMax
self.value = newValue
self.update()
def update(self):
cnvs = self.canvas
# Trim the values to be between min and max
value=self.value
if value > self.max:
value = self.max
if value < self.min:
value = self.min
# Adjust the rectangle
if self.orientation == "horizontal":
cnvs.coords(self.scale, 0, 0,
float(value) / self.max * self.width, self.height)
else:
cnvs.coords(self.scale, 0,
self.height - (float(value) / self.max*self.height),
self.width, self.height)
# Now update the colors
cnvs.itemconfig(self.scale, fill=self.fillColor)
cnvs.itemconfig(self.label, fill=self.labelColor)
# And update the label
if self.doLabel:
if value:
if value >= 0:
pvalue = int((float(value) / float(self.max)) * 100.0)
else:
pvalue = 0
cnvs.itemconfig(self.label,
text=self.labelFormat % pvalue)
else:
cnvs.itemconfig(self.label,
text='')
else:
cnvs.itemconfig(self.label,
text=self.labelFormat % self.labelText)
cnvs.update_idletasks()
if __name__ == '__main__' :
root = Tk()
labelfont = ('times', 12, 'bold')
titulo = Label(root, text='Progreso')
titulo.config(font=labelfont)
titulo.config(height=1, width=10)
titulo.pack(expand=YES, fill=X)
myBar = ProgressBar(root, width=200)
myBar.pack()
for i in range(100) :
myBar.updateProgress(i)
time.sleep(0.1)
root.quit()
More information about the Tutor
mailing list