#python #imap #imaplib
Вопрос:
У меня есть куча функций для хранения всех вложений из всех писем в одной папке imap. Вложения представляют собой наборы данных json для дальнейшей обработки. Чтобы избежать сбоев после потери соединения и повторного подключения, я вставлял команду удаления после каждого сообщения в цикле. Это приводит к спорадическим ошибкам при обработке сообщения электронной почты или, лучше сказать: я не могу прочитать текст письма, что приводит к [нет] для тела. Чтобы решить проблему, я поместил команду удаления после цикла и вставил другую команду удаления перед циклом, чтобы удалить помеченные сообщения, чтобы предотвратить многократную обработку.
Хотя моя функция работает безупречно, возможно, кто-нибудь может рассказать мне о поведении команды удаления на сервере ( не могу сказать, какой imap-сервер работает на стороне сервера, поставщик ionos.de). Я не могу найти соответствующую информацию в документе RFC. Может быть, какое-то состояние гонки.
Это код, который приводит к ошибкам:
def downloadAllAttachmentsInInbox( **args):
conf =args['conf']
m = connectImapServer( conf.imappoll.server, conf.imappoll.account, conf.imappoll.password)
resp, items = m.search( None, "(ALL)")
items = items[0].split()
for emailid in items:
downloaAttachmentsInEmail( m =m, emailid =emailid, conf =conf)
# Markiere Mail zum löschen
if conf.imappoll.clearmb =="True":
m.store( emailid, ' FLAGS', '\Deleted')
# Loesche markierte Mail(s)
m.expunge()
# Schliesse Mailbox, logout aus Server
m.close()
m.logout()
И это рабочий код:
def downloadAllAttachmentsInInbox( **args):
conf =args['conf']
m = connectImapServer( conf.imappoll.server, conf.imappoll.account, conf.imappoll.password)
# Loesche bereits zur Löschung markierte Mails vom Server vor Abruf aller Nachrichten
m.expunge()
resp, items = m.search( None, "(ALL)")
items = items[0].split()
for emailid in items:
downloaAttachmentsInEmail( m =m, emailid =emailid, conf =conf)
# Markiere Mail zum löschen
if conf.imappoll.clearmb =="True":
m.store( emailid, ' FLAGS', '\Deleted')
# Loesche markierte Mail(s)
m.expunge()
# Schliesse Mailbox, logout aus Server
m.close()
m.logout()
Ответ №1:
Если вы используете порядковые номера сообщений, вы не можете их использовать expunge
, так как это изменяет нумерацию сообщений, что делает ваши результаты поиска устаревшими.
У вас есть пара вариантов:
- Используйте UID везде.
m.uid(‘SEARCH’, ‘ALL’)
иm.uid(‘FETCH’, …)
иm.uid(‘STORE’, …)
. Идентификаторы UID не перенумеруются при удалении. - Не удаляйте, а вместо этого ищите НЕОТДЕЛЕННЫЕ, чтобы игнорировать сообщения, которые вы уже отметили удаленными (например, обработанными).
m.search(‘UNDELETED’)
. Затем выйдите за пределы цикла.