[Python-es] Problema con imap4 de twisted

Esteve Fernandez esteve en sindominio.net
Mie Feb 24 12:22:55 CET 2010


Hola César

> Que estraño, juraria que si puse el codigo :)
> aca va:
>
> http://www.pastebin.com/m4e387f1a

yo diría que el error está en la línea 83. Como unseen es el total de mensajes
y se lo pasas a fetchMessage como (unseen:*), te devolverá todos los mensajes
a partir de unseen (es decir, el recuento total). En ese caso, sólo te
devuleve uno, el último.

Te adjunto una modificación al código que usa imap4.Query [1], que crea una
consulta para pasársela a search [2] y que devuelve la lista de los mensajes
que cumplen la condición "unseen". Luego puedes usar esa lista y crear un
MessageSet para pasársela a fetchMessage, fetchSpecific, etc.

Espero que te sirva de ayuda.

Saludos.

1 - http://twistedmatrix.com/documents/9.0.0/api/twisted.mail.imap4.html#Query
2 -
http://twistedmatrix.com/documents/9.0.0/api/twisted.mail.imap4.IMAP4Client.html#search

--------------------------------------------------------
#!/usr/bin/env python
#coding=utf-8


"""
Client de IMAP4 que descarga contenido del INBOX de una cuenta en especifico
para luego extraer el numero de telefono que debe venir en los correos enviados
"""

import StringIO
import sys
from Config import retCredentials

from twisted.internet.task import LoopingCall
from twisted.internet import protocol
from twisted.internet import defer
from twisted.mail import imap4
from twisted.python import util
from twisted.python import log
from twisted.internet import reactor
debug = 1

class IMAP4Client(imap4.IMAP4Client):

    def serverGreeting(self,caps):
        """
        Metodo llamado cuando el servidor contesta
        """
        if debug: print "On serverGreeting"

        self.serverCapabilities = caps
        if self.greetDeferred is not None:
            d, self.greetDeferred = self.greetDeferred, None
            d.addCallback(self.cbLogin)
            d.callback(self)


    def cbLogin(self, proto):
        """
        Callback to IMAP login
        """
        if debug: print "On Login"

        login =  self.login(self.factory.username, self.factory.password)
        login.addCallback(self.startPolling)


    def startPolling(self, proto):
        """
        Callback to poll every x seconds
        """
        call = LoopingCall(self.selectMailbox,mailbox="INBOX")
        call.start(20, now=True)


    def selectMailbox(self, mailbox):
        """
        Select the mailbox to examin
        """
        if debug: print "On selectMailbox"

        mailbox = self.factory.mailbox
        return self.select(mailbox).addCallback(self.cbSelectSuccess)


    def cbSearch(self, messages):
        messageSet = imap4.MessageSet()
        for message in messages:
            messageSet += message
        return self.fetchSpecific(messageSet).addCallback(
            self.cbProcMessages)

    def cbSelectSuccess(self, selected):
        """
        Examine the INBOX mailbox for new mails

        """
        if debug: print "On cbSelectSuccess"


        self.messageCount = selected['EXISTS']
        print "Messages: ", self.messageCount

        unseen = imap4.Query(unseen=True)

        return self.search(unseen).addCallback(self.cbSearch)

    def cbProcMessages(self,messages):

        print messages


class IMAP4ClientFactory(protocol.ClientFactory):

    protocol = IMAP4Client

    def __init__(self, username, password,  onConn):

        self.username = username
        self.password = password
        self.mailbox = 'INBOX'
        self.onConn = onConn

    def buildProtocol(self,addr):
        if debug: print "On buildProtocol"
        p = self.protocol()
        p.factory = self
        p.greetDeferred = self.onConn
        auth = imap4.CramMD5ClientAuthenticator(self.username)
        p.registerAuthenticator(auth)

        return p

    def clientConectionFailed(self, connector, reason):
        d, self.onConn = self.onConn, None
        d.errback(reason)



def ebConnection(reason):
    log.startLogging(sys.stdout)
    log.err(reason)
    reactor.stop()



PORT = 143
RESULT = "INBOX"


def main():
    credentials = retCredentials()

    hostname = credentials['server']
    username = credentials['mailbox']
    password = util.getPassword('IMAP4 Password: ')

    onConn = defer.Deferred(
            ).addErrback(ebConnection
            )

    factory = IMAP4ClientFactory(username, password, onConn)


    reactor.connectTCP(hostname, PORT, factory)
    reactor.run()

if  __name__ == "__main__":
    main()





Más información sobre la lista de distribución Python-es