Ошибка при попытке получить сообщения электронной почты в больших папках с использованием IMAP и Twisted
Я пишу IMAP-клиент, используя последнюю версию Twisted.
У меня проблемы с использованием двух разных способов получения 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, я не получаю никакой ошибки, поэтому я что-то пропустил?
РЕДАКТИРОВАТЬ: Я разрешаю эту проблему. Сервер IMAP4 Yahoo, похоже, имеет довольно странную реализацию. На самом деле, если мы попросим последовательность, которая не существует в папке. Например (был мой случай), если папка пуста, и мы отправляем:
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()])
Спасибо заранее за любой намек или ответ,
1 ответ
Это ошибка клиента. Если вы ссылаетесь на сообщение № 1, а сервер сообщил вам, что сообщений нет, то ошибка явно ваша. То же самое применимо, если сервер сообщил вам, что существует 1000 сообщений, и вы ссылаетесь на номер 1001.
Слушать EXISTS
ответы. Или переключитесь на использование UID (и прослушайте UIDNEXT
коды ответов).