d = self.proto.login(self.factory.username, self.factory.password)
d.addCallback(lambda x: self.proto.examine('INBOX'))
d.addCallback(lambda x: self.proto.fetchUID('1:*'))
d.addCallback(self.handleuids)
可以看到選定folder以後,我們呼叫fetchUID來抓取folder所有的UID,但是回傳的結構其實是如此的dictionary[uid -> Dictionary[]]。也就是每封信本身也都是一個dictionary,來看看如何處理:
def handleuids(self, uids):
dlist = []
destfd = open(sys.argv[3], "at")
for data in uids.values():
uid = data['UID']
d = self.proto.fetchSpecific(uid, uid =1, peek = 1)
d.addCallback(self.gotmessage, destfd, uid)
dlist.append(d)
dl = defer.DeferredList(dlist)
dl.addCallback(lambda x, fd: fd.close(), destfd)
return dl
對於每封信的dictionary,我們取用其中的'UID'部份,而fetchSpectific的uid = 1是告訴此函式把第一個參數當UID看而非message number,最後加到deferred list中。deferred list會等到所有deferred結束後,再把結果一次傳給第一個Callback。最後來看gotmessage():
def gotmessage(self, data, destfd, uid):
print "Received message UID", uid
for key, value in data.items():
print "Writing message", key
i = value[0].index('BODY') + 2
msg = email.message_from_string(value[0][i])
destfd.write(msg.as_string(unixfrom = 1))
destfd.write("\n")
與之前不同的是,這次找message body text並不是寫死的固定位置,因為可能會因server不同而回傳資料有所不同,不過相同的是text都是在'body'後面的第二個位置,所以就直接用算的算出來。最後來看程式的output:
cacaegg@cacabook:~/workspace/NetworkProgram/src/IMAP$ tdownload.py mx.mgt.ncu.edu.tw cacaegg mailbox
Enter password:
Received message UID 15024
Writing message 1
Received message UID 15025
Writing message 2
程式連結
沒有留言:
張貼留言