我正在使用最新版本的 Twisted 编写 IMAP 客户端。
我在使用两种不同的方式获取电子邮件 UID 时遇到问题。
首先,我尝试以这种方式使用搜索方法:
@inlineCallbacks
def getEmailList(self):
for f in folder_list:
rep = yield self.examine(f)
uids_list = yield self.search(imap4.Query(all=True), uid=True)
这有效,但是当我尝试在大文件夹(包含超过 10.000 条消息)上使用它时,命令失败。
我收到如下错误:
Unhandled Error
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/twisted/protocols/policies.py", line 120, in dataReceived
self.wrappedProtocol.dataReceived(data)
File "/usr/local/lib/python2.7/dist-packages/twisted/protocols/basic.py", line 571, in dataReceived
why = self.lineReceived(line)
File "/usr/local/lib/python2.7/dist-packages/twisted/mail/imap4.py", line 2360, in lineReceived
self._regularDispatch(line)
File "/usr/local/lib/python2.7/dist-packages/twisted/mail/imap4.py", line 2388, in _regularDispatch
self.dispatchCommand(tag, rest)
--- <exception caught here> ---
File "/usr/local/lib/python2.7/dist-packages/twisted/mail/imap4.py", line 2417, in dispatchCommand
f(tag, rest)
File "/usr/local/lib/python2.7/dist-packages/twisted/mail/imap4.py", line 2446, in response_UNAUTH
self._defaultHandler(tag, rest)
File "/usr/local/lib/python2.7/dist-packages/twisted/mail/imap4.py", line 2467, in _defaultHandler
raise IllegalServerResponse(tag + ' ' + rest)
twisted.mail.imap4.IllegalServerResponse: 1428 111429 111430 111431 111432
那我做错了吗?或者我可以以更好的方式处理服务器答案吗?
我尝试了其他方法来解决这个问题。我没有使用搜索方法,而是尝试替换:
uids_list = yield self.search(imap4.Query(all=True), uid=True)
经过
rep = yield self.fetchUID('1:*')
uids_list = set([x['UID'] for x in rep.values()])
这也有效(有时比以前的方法慢)但是当我尝试在 imap.mail.yahoo.com 上使用它时,它会失败并出现以下错误:
[Failure instance: Traceback (failure with no frames): <class'twisted.mail.imap4.IMAP4Exception'>: [CLIENTBUG] FETCH Bad sequence in the command]
这很奇怪,因为当我使用 imaplib 运行相同的命令时,我没有收到任何错误,所以我错过了什么吗?
编辑:我解决了这个问题。yahoo 的 IMAP4 服务器似乎有一个非常奇怪的实现。实际上,如果我们要求文件夹中不存在的序列。例如(是我的情况)如果文件夹是空的,我们发送:
FETCH 1:* (UID)
服务器失败并显示:
BAD [CLIENTBUG] FETCH Bad sequence in the command
因此,为了绕过这个错误,我只是检查了这样的检查答案:
rep = yield self.examine(f)
if rep['EXISTS'] != 0:
rep = yield self.fetchUID('1:*')
uids_list = set([x['UID'] for x in rep.values()])
提前感谢您的任何提示或答案,