[Tutor] Program review

Tiger12506 keridee at jayco.net
Sat Jan 5 00:38:00 CET 2008


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" <ricaraoz at gmail.com>
To: <tutor at 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 = xxx at yyyyyyy.com
> Encabezado = Prueba de Procesar
> ResponderA = bbbbbbb at fffffff.com
>
>
> [Correo]
>
> Servidor = smtp.servidor.com
> Usuario = nombreUsuario
> Contrasenia = contrasenia
>
> MailsPorVez = 10
> IntervaloEnSegundos = 120
>
> -------------------------------------------------------------------
>
> TIA
>
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
> 



More information about the Tutor mailing list