[Tutor] Program review

Ricardo Aráoz ricaraoz at gmail.com
Sun Jan 6 22:07:36 CET 2008


Ok, now the "tested" version (has been corrected) :

#!/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')

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(
                        set(addr.strip() for addr in fIncl)
                        - set(excl.strip() for excl in fExcl))
        fIncl.close()
        fExcl.close()
        miCorreo = Correo(mensaje)
        if miCorreo.connect() :
            empiezo = time.clock()
            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()


if __name__ == '__main__' :
    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')
    procesar(Mensaje())


More information about the Tutor mailing list