IMAP COPY 命令不适用于收件箱 - Python

问题描述

我正在使用带有 IMAP4 模块的 python3.6。我正在尝试将电子邮件从“收件箱”复制到“mytestfolder”。 我收到“OK”作为回复,但电子邮件本身没有被复制到“mytestfolder”。 相同的代码片段第一次在“someotherfolder”到“mytestfolder”中工作时没有任何问题,之后就不起作用了。下面是代码片段,有人可以帮我解决这个问题。

import config
import imaplib
from creds import username,password
imap = imaplib.IMAP4_SSL(config.imap_server,config.imap_port)
r,d = imap.login(username,password)
assert r == 'OK','login Failed: %s' % str (r)
print(" > Signed in as %s" % username,d)

imap.select("InBox")
r,d = imap.search(None,"ALL")
allIds = d[0].decode('utf8').split(' ')
''' Login works and iam getting msg_ids as well'''

for msg_id in allIds:
    apply_lbl_msg = imap.uid('copY',msg_id,'mytestfolder')
    if apply_lbl_msg[0] == 'OK':
        mov,data = imap.uid('STORE','+FLAGS','(\Deleted)')
        imap.expunge()

解决方法

TLDR:您通过删除事物然后按以前的顺序编制索引来错误计算。

您的代码可以:

r,d = imap.search(None,"ALL")

“给我收件箱中所有邮件的序列号”,所以你会得到 1、2、3、4、5 等等。 d 中的最后一个数字将等于上面几行 select() 的返回值。然后你循环,我会解释第一次迭代:

apply_lbl_msg = imap.uid('COPY',msg_id,'mytestfolder')
if apply_lbl_msg[0] == 'OK':

“将第一条消息复制到 mytestfolder,如果有效……。”

    mov,data = imap.uid('STORE','+FLAGS','(\Deleted)')
    imap.expunge()

“...然后删除收件箱中的第一条消息”,这意味着第二条消息现在变成了第一条。

下一次迭代操作当前邮箱中的第二个消息,并且曾经是第三个,因此您永远不会对开始时为 2 的消息进行操作。第三次迭代对当前是第三个的消息进行操作,并且曾经是......我认为是第五个?没关系。

您可以通过切换到相同的 UID 版本来纠正此错误。重新编号时 UID 不会改变。

您还可以通过发出一个复制所有消息的单个 COPY 命令,然后发出一个将它们标记为已删除的 STORE 命令来使此操作正确且速度更快。您甚至不需要 SEARCH,因为搜索的结果只是从 1 到 select() 的返回值的所有数字。