[Twisted-Python] How can I make twisted and dbus work together?

hwan2265 at mail.usyd.edu.au hwan2265 at mail.usyd.edu.au
Wed Jan 16 01:28:38 EST 2008


Hello everyone,

I am trying to write a imap mail fetcher base on twisted and dbus. I have
written a simple fetcher without dbus functionality and it's working fine.
However I got a problem while adding dbus.

http://twistedmatrix.com/trac/ticket/1352 is the only article about how can
twisted and dbus work together that I could get from google and I just
followed its suggestion and added

    from twisted.internet import glib2reactor
    glib2reactor.install()

to my code.

As what I read from twisted API
http://twistedmatrix.com/documents/current/api/twisted.internet.glib2reactor.html
"In order to use this support, simply do the following:

   |  from twisted.internet import glib2reactor
   |  glib2reactor.install()

Then use twisted.internet APIs as usual. "
I thought everything will be fine.

But when I was running my code, I got a error:

Traceback (most recent call last):
  File "dbustwisted.py", line 5, in <module>
    glib2reactor.install()
  File "/usr/lib/python2.5/site-packages/twisted/internet/glib2reactor.py",
line 33, in install
    return gtk2reactor.install(False)
  File "/usr/lib/python2.5/site-packages/twisted/internet/gtk2reactor.py",
line 270, in install
    installReactor(reactor)
  File "/usr/lib/python2.5/site-packages/twisted/internet/main.py", line
24, in installReactor
    "reactor already installed"
AssertionError: reactor already installed

I don't know what's wrong with it.
This is my code, I have not add the dbus part yet and just test the
glib2reactor.

from twisted.mail import imap4
from twisted.internet import protocol, defer
import email, os, time

MAILPATH = "Mails"
IMAPSERVER = "xxxxxxxxxxx"
USERNAME = "xxxxx"
PASSWORD = "xxxxx"

class IMAPDownloadProtocol(imap4.IMAP4Client):

    def serverGreeting(self, capabilities):
        login = self.login(self.factory.username, self.factory.password)
        login.addCallback(self.__loggedIn)
        login.chainDeferred(self.factory.deferred) # any event that fires
login will also fire factory.deferred

    def __loggedIn(self, result):
        return
self.select(self.factory.mailbox).addCallback(self.__selectedMailbox)

    def __selectedMailbox(self, result):
        allMessages = imap4.MessageSet(1, None) # a set of messages from
message number 1 to the end of the mailbox
        return self.fetchUID(allMessages, True).addCallback(self.__gotUIDs)
# fetch a list of UID

    def __gotUIDs(self, uidResults):
        self.messageUIDs = [result['UID'] for result in uidResults.values(
)]
        self.messageCount = len(self.messageUIDs)
        print "INFO: %i messages in %s." % (self.messageCount,
self.factory.mailbox)
        return self.fetchNextMessage( ) # start to download the message one
by one

    def fetchNextMessage(self):
        if self.messageUIDs:
            nextUID = self.messageUIDs.pop(0)
            messageListToAnalysis = imap4.MessageSet(nextUID) # creates a
MessageSet matching only that message's UID
            return self.fetchAll(messageListToAnalysis,
True).addCallback(self.__gotIndex)
            # fetchAll - fetching the UID, flags, size, date, envelope
            # UID keyword set to true to tell the server that the
MessageSet is referring to messages by UID, not sequence number
        else:
            return self.logout( ).addCallback(lambda _:
self.transport.loseConnection( ))

    def __gotIndex(self, indexResults):
        index = indexResults.values()
        index_details = index[0]

        UID = index_details['UID']
        flags = index_details['FLAGS']
        size = index_details['RFC822.SIZE']
        date = index_details['INTERNALDATE']
        envelope = index_details['ENVELOPE']

        title = envelope[1]
        sender = envelope[3]
        temp = []
        # replace None in the envelope as "Empty", because None is a key
word in python
        for element in sender[0]:
            if element != None:
                temp += [element]
            if element == None:
                temp += ["Empty"]
        sender = temp

        if flags == []:
            flags = ['\\Unseen']


        print "INFO: Downloading message %i of %i" %
(self.messageCount-len(self.messageUIDs), self.messageCount)
        messageListToFetch = imap4.MessageSet(UID)
        return self.fetchMessage(messageListToFetch,
True).addCallback(self.__gotMessage, UID)

    def __gotMessage(self, fetchResults, UID):
        messageData = fetchResults.values( )[0]['RFC822']
        self.factory.handleMessage(messageData, UID)
        return self.fetchNextMessage( ) # fetch next message

    def connectionLost(self, reason):
        if not self.factory.deferred.called:
            # connection was lost unexpectedly!
            self.factory.deferred.errback(reason)

class IMAPDownloadFactory(protocol.ClientFactory):
    protocol = IMAPDownloadProtocol

    def __init__(self, username, password, mailbox, path):
        self.username = username
        self.password = password
        self.mailbox = mailbox
        self.path = path
        self.deferred = defer.Deferred( )

    def handleMessage(self, messageData, UID):
        mailFile = os.path.join(path, UID)
        output = file(mailFile, 'w+b')
        parsedMessage = email.message_from_string(messageData)
        output.write(parsedMessage.as_string(unixfrom=True))

    def startedConnecting(self, connector):
        print "INFO: Connection start"

    def clientConnectionFailed(self, connection, reason):
        self.deferred.errback(reason)

    def clientConnectionLost(self, connection, reason):
        print "INFO: Connection stop"
        #connection.connect()

if __name__ == "__main__":
    from twisted.internet import glib2reactor
    glib2reactor.install()
    ################################################
    # I added the 2 lines here and made the program crash
    ################################################

    from twisted.internet import reactor
    import sys, getpass

    server = IMAPSERVER
    user = USERNAME
    mailbox = "Inbox"
    path = MAILPATH
    password = PASSWORD

    factory = IMAPDownloadFactory(user, password, mailbox, path)
    reactor.connectTCP(server, 143, factory)
    reactor.run( )

I am new to twisted, dbus even python, any helps will be appreciated.

Regards
Huisan

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.




More information about the Twisted-Python mailing list