星期四, 7月 16, 2009

IMAP in Python - 1 (Understanding Twisted Basics)

Python本身也有imaplib可供操作,不過在此使用一套挺有名的framework--Twisted。

Twisted有一個很大的特色就是以Event-based來進行程式設計,也就是會使用到callback function。

直接用程式碼來簡單介紹如何使用:

#!/usr/bin/env python

from twisted.internet import defer, reactor, protocol
from twisted.mail.imap4 import IMAP4Client
import sys

class IMAPClient(IMAP4Client):
def connectionMade(self):
print "I have successfully connected to the server!"
d = self.getCapabilities()
d.addCallback(self.gotcapabilities)

def gotcapabilities(self, caps):
if caps == None:
print "Server did not return a capability list."
else:
for key, value in caps.items():
print "%s: %s" % (key, str(value))
self.logout()
reactor.stop()
class IMAPFactory(protocol.ClientFactory):
protocol = IMAPClient

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

reactor.connectTCP(sys.argv[1], 143, IMAPFactory())
reactor.run()


分為兩種class:
IMAPClient-作為Protocol class之用途,負責與server的protocol conversation
IMAPFactory-作為Connection class之用途,負責connection的部份

而reactor是Twisted中的Network event handler,在主程式第1行先用reactor.connectTCP進行連線,
成功後會呼叫connectionMade()來進行後續處理。

在connectionMade裏面,呼叫繼承而來的getCapabilities()來取得有關server支援IMAP選項的參數,且會回傳defer物件。要用此物件來告訴reactor等到有事件發生時該呼叫誰,在此使用了d.addCallback告訴reactor等到有事件時,需要呼叫self.gotcapabilities來處理。(注意在此沒有用括號,因為是callback沒有需要立刻呼叫)

接著進行reactor.run(),此function會等到有人呼叫reactor.stop()才會return,否則就不斷等待事件,事件發生了後,就按照預定的呼叫gotcapabilities(),印出有關的參數,然後logout(),最後stop()結束程式。

此程式的output:

cacaegg@cacabook:~/workspace/NetworkProgram/src/IMAP$ sudo ./tconn.py mx.mgt.ncu.edu.tw
I have successfully connected to the server!
SASL-IR: None
SORT: None
THREAD: ['REFERENCES']
STARTTLS: None
UNSELECT: None
NAMESPACE: None
IDLE: None
AUTH: ['PLAIN']
IMAP4rev1: None
LOGIN-REFERRALS: None
MULTIAPPEND: None
LITERAL+: None
CHILDREN: None

沒有留言: