1

我正在使用最新版本的 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()])

提前感谢您的任何提示或答案,

4

1 回答 1

0

一个客户端错误。如果您参考第 1 条消息并且服务器告诉您有 0 条消息,那么这个错误显然是您的问题。如果服务器告诉您有 1000 条消息并且您引用编号 1001,则同样适用。

听听EXISTS回答。或者切换到使用 UID(并听取UIDNEXT响应代码)。

于 2014-11-14T08:58:30.850 回答