星期五, 7月 17, 2009

IMAP in Python - 2 (Logging In)

再來看如何使用twisted來進行登入,以及defered object的chain callback。

此次分成3個主要的class:Protocol、Factory、Logic。分別來看一下。
Protocol Class:

class IMAPClient(IMAP4Client):
def connectionMade(self):
print "I have successfully connected to the server!"
IMAPLogic(self)
print "connectionMake returning"

主要就是把邏輯部份從原本的protocol中分離出來了,此protocol class現在變成主要就是處理關於協定的callback。


class IMAPFactory(protocol.ClientFactory):
protocol = IMAPClient

def __init__(self, username, password):
self.username = username
self.password = password

def clientConnectionFailed(self, connector, reason):
print "Client connection failed:", reason
reactor.stop()

此class會在__init__時就把帳號密碼存入,以待登入時使用。


class IMAPLogic:
def __init__(self, proto):
self.proto = proto
self.factory = proto.factory

d = self.proto.login(self.factory.username, self.factory.password)
d.addCallback(self.loggedin)
d.addCallback(self.stopreactor)

print "IMAPLogic.__init__returning."
def loggedin(self, data):
print "I'm logged in!"
return self.logout()
def logout(self):
print "Logging out."
d = self.proto.logout()
return d
def stopreactor(self, data = None):
print "Stopping reactor."
reactor.stop()

此邏輯class在__init__時,就會先把protocol class & factory變成member。然後呼叫protocol的login(),在此會回傳第1個defered object,對此object設定兩個callback。這樣就成為"Chain callback",對於每個子callback,如果還有其他defered物件,twisted會將其都處理完才會呼叫原parent defered object的下一個子callback,且把最後一次callback的結果當作參數送給下一個。因此在此例子中,執行的順序是loggedin() --> logout() --> proto.logout() --> stopreactor() --> reactor.stop(),如此執行。

以下為程式output:

cacaegg@cacabook:~/workspace/NetworkProgram/src/IMAP$ tlogin.py mx.mgt.ncu.edu.tw cacaegg
Enter password for cacaegg on mx.mgt.ncu.edu.tw
I have successfully connected to the server!
IMAPLogic.__init__returning.
connectionMake returning
I'm logged in!
Logging out.
Stopping reactor.


程式連結

沒有留言: