After quickly looking over the code, I find it has a good foundation, it seems to have been designed very solidly. I haven't looked very closely, but if the messages are mostly alike with just one or two slight differences, you might consider dynamically creating the messages (from a customer list, for example) so that it's easier to setup the use of this program.
> filename='informe-'+time.strftime('%Y-%m-%d-%H-%M-%S')+'.log', > filemode='w') This filename can be written as filename=time.strftime('informe-%Y-%m-%d-%H-%M-%S.log') This gets rid of the intermediate strings, it's just cleaner. > mails = enumerate(addr.strip() for addr in fIncl > if addr.strip() not in (excl.strip() for excl in > fExcl)) This~~ works, but may be a little inefficient. Especially the double addr.strip() here. Given, it doesn't really matter, but I like even better Perhaps a use of sets here... particularly intersection somehow... ----- Original Message ----- From: "Ricardo Aráoz" <[EMAIL PROTECTED]> To: <tutor@python.org> Sent: Friday, January 04, 2008 6:47 PM Subject: [Tutor] Program review > Considering we are reviewing programs I'd like to submit one of mine and > I would be thankful for any critic/improvement you can suggest. > My ex needs to send mails to a long list of customers, problem is that > she can not send more than 70 every 10 minutes or her ISP will consider > her a spammer. So she spends hours sending these mails one by one. > This program was meant to help her with that. It takes a configuration > file which tells the program the name of a text file with an email > address per line for mail to be sent to, the name of another text file > with addresses to be ignored, and the name of an HTML file with the > message to be sent. Also how many messages every how many seconds to be > sent. > > Procesar.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')) > self.HTML = htmlFile.read() > htmlFile.close() > except Exception, e : > logging.error('No pude leer "%s" : %s', > cfg.get('Archivos', 'Mensaje'), > e.strerror) > > self.De = cfg.get('Encabezados', 'De') > self.Para = '' > self.Encabezado = cfg.get('Encabezados', 'Encabezado') > self.ResponderA = cfg.get('Encabezados', 'ResponderA') > 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.messg = email.MIMEMultipart.MIMEMultipart() > self.messg['From'] = mensaje.De > self.messg['To'] = mensaje.Para > self.messg['Subject'] = mensaje.Encabezado > self.messg['Reply-To'] = mensaje.ResponderA > self.messg.preamble = 'This is a multi-part message in MIME format' > self.messg.attach(email.MIMEText.MIMEText(mensaje.HTML, 'html')) > > self.Servidor = mensaje.Servidor > self.Conexion = smtplib.SMTP() > self.Usuario = mensaje.Usuario > self.Contra = mensaje.Contra > > def connect(self) : > try : > self.Conexion.connect(self.Servidor) > self.Conexion.set_debuglevel(False) > self.Conexion.ehlo() > self.Conexion.starttls() > self.Conexion.ehlo() > self.Conexion.login(self.Usuario, self.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.messg.replace_header('To', addr) > try : > self.Conexion.sendmail(self.messg['From'], > self.messg['To'], > self.messg.as_string()) > logging.info('Enviado a : %s', self.messg['To']) > except SMTPRecipientsRefused : > logging.error('El destinatario fue rechazado por el servidor') > except SMTPHeloError : > logging.error('El servidor no respondio apropiadamente') > except SMTPSenderRefused : > logging.error('El From: fue rechazado por el servidor') > except SMTPDataError : > logging.error('El servidor respondio con un error desconocido') > > def procesar(mensaje): > try : > try : > fIncl = open(mensaje.direcciones) > except Exception, e : > logging.error('Error!!! No pude abrir "%s" : %s', > mensaje.direcciones, > e.strerror) > raise > try : > fExcl = open(mensaje.excluidas) > except Exception, e : > logging.error('No pude abrir "%s" : %s', > mensaje.excluidas, > e.strerror) > fIncl.close() > raise > except : pass > else : > mails = enumerate(addr.strip() for addr in fIncl > if addr.strip() not in (excl.strip() for excl in > fExcl)) > empiezo = time.clock() > miCorreo = Correo(mensaje) > miCorreo.connect() > for nro, addr in mails : > if nro%mensaje.cuantos == 0 and nro > 0 : > miCorreo.disconnect() > time.sleep(mensaje.intervalo - (time.clock() - empiezo)) > if not miCorreo.connect() : > logging.info('Terminando') > return > empiezo = time.clock() > miCorreo.enviar(addr) > miCorreo.disconnect() > fIncl.close() > fExcl.close() > > > if __name__ == '__main__' : > logging.basicConfig(level=logging.INFO, > format='%(asctime)s %(levelname)-8s %(message)s', > datefmt='%a, %d %b %Y %H:%M:%S', > > filename='informe-'+time.strftime('%Y-%m-%d-%H-%M-%S')+'.log', > filemode='w') > procesar(Mensaje()) > > ---------------------------------------------------------------------------------------- > > config.cfg > ---------- > > [Archivos] > ; En Direcciones va el nombre del archivo de texto > ; que contiene las direcciones de mail una por renglon > ; En Excluir va el nombre del archivo de texto > ; que contiene las direcciones a las que NO se les manda > ; mail, una por renglon > ; En mensaje va el nombre del archivo html con el mensaje. > ; El mensaje lo creas en tu programa de mail y le das > ; "guardar como..." y lo guardas como "html" > > Direcciones = mails.txt > Excluir = excluir.txt > Mensaje = mensaje.html > > > [Encabezados] > > De = [EMAIL PROTECTED] > Encabezado = Prueba de Procesar > ResponderA = [EMAIL PROTECTED] > > > [Correo] > > Servidor = smtp.servidor.com > Usuario = nombreUsuario > Contrasenia = contrasenia > > MailsPorVez = 10 > IntervaloEnSegundos = 120 > > ------------------------------------------------------------------- > > TIA > > > _______________________________________________ > Tutor maillist - Tutor@python.org > http://mail.python.org/mailman/listinfo/tutor > _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor