IMAP COPY command not working on Inbox - Python
Asked Answered
W

1

0

Iam using Python3.6 with IMAP4 module.Iam trying to copy emails from "Inbox" to "mytestfolder". Iam getting "OK" as the response but the email itself is not being copied to "mytestfolder". Where as the same code snippet is working for "someotherfolder" to "mytestfolder" without any problem for the first time and after that it doesn't work. Below is the code snippet can someone please help me resolve this.

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', msg_id , '+FLAGS', '(\Deleted)')
        imap.expunge()
Wynne answered 4/5, 2021 at 11:3 Comment(1)
Do not mix UIDs and Sequence IDs! Either use all .uid commands (.uid(‘SEARCH’), or no .uid commands (.copy(…)). If you use sequence ids, move .expunge outside the loop so the sequence ids don’t renumber until you’re done.,Unasked
H
2

TLDR: You're miscounting by removing things and then indexing by what used to be the order.

Your code does:

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

"Give me the sequence numbers of all messages in the inbox", so you get 1, 2, 3, 4, 5 and so on. The last number in d will equal the return value from select() a few lines above. Then you loop, I'll explain the first iteration:

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

"Copy the first message to mytestfolder, and if that works…."

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

"… then delete the first message in the inbox", which means that what was the second message now becomes the first.

The next iteration operates on the message that's currently the second in the mailbox, and was once the third, so you never operate on the message that was 2 at the start. The third iteration operates on the message that's currently the third, and was once the... fifth I think? It doesn't matter.

You can make this correct by switching to the UID versions of the same. UIDs don't change as you renumber.

You could also make this correct and very much faster by issuing one single COPY command that copies all messages, and then one single STORE that marks them as deleted. You don't even need the SEARCH, because the result of the search is just all the numbers from 1 to the return value of select().

Hartzke answered 4/5, 2021 at 11:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.