我正在尝试在获取所有“UNREAD”消息然后迭代它们并获取它们之后,在单个消息上操作IMAP标记以将其标记为未读。
我不完全确定如何在单个邮件的基础上标记未读/未看到的邮件。我得到的只是消息号,我不确定如何正确存储UID以仅影响单个消息。
answer in a similar question似乎不起作用,因为它将错误的消息设置为“未读”。如何设置单个邮件,我再次将其作为“未读”邮件?
我被要求提供更多信息。虽然在这里删除了“秘密”的细节,但这是我尝试实现的现有运行时,因此它尝试根据代码规则处理消息,并存储消息编号等,并尝试将消息的id和主题存储在pickle文件中后,将每条消息设置为“UNREAD”,因为在运行期间“看到”的任何内容都将在服务器上自动标记为“已读”,而不会设置为“未读”状态:
org.projectlombok:lombok:1.16.14
但是,不将正确的消息设置为“未读”;当我使用我在系统上看到的方法时。所以,我不能完全确定我是否没有正确地获取消息的UID,或者是否还有其他我在这里缺少的东西。
答案 0 :(得分:5)
嗯,我今天觉得很蠢。
显然迭代了消息号,conn.uid(...)
期望的消息的UID不一定是相同的数字。我发现必须获取UID并进行一些后期获取处理以获得UID才能传出。
原创方法
我能够在上面的for
循环中使用以下内容获取UID:
for i in msgnums:
# ...
msg_uid = conn.fetch(i, 'UID')[1][0].split()[2].strip('()')
# ...
这给了我conn.uid
期待的消息的UID,而不是简单的消息号。我觉得有点愚蠢没有意识到这一点,但这似乎解决了这个问题。
更新方法#1 (感谢评论中的@Max)
我用UID等价物替换了所有搜索/获取/存储命令。
conn.search(None, '(UNSEEN)')
变为conn.uid('SEARCH', None, '(UNSEEN)')
conn.fetch(i, '(RFC822)')
变为conn.uid('FETCH', i, '(RFC822)')
conn.store(i, '-FLAGS', '(\Seen)')
变为conn.uid('STORE', i, '-FLAGS', '(\Seen)')
更新方法#2 (受#1启发,但更进一步)
我基本上厌倦了写出UID命令,但还需要在另一个使用类似IMAP接口和命令的程序中应用类似的基于UID的功能。鉴于此,我决定编写一个imaplib_extension.py
模块,“扩展”imaplib
的{{1}}和IMAP4
函数,并覆盖“搜索”,“获取”和“存储“具有IMAP4_SSL
变体的命令,但以uid
原样保留”搜索“,”获取“和”存储“命令,但返回基于UID函数的不同结果集代替。
这是我imaplib
文件中的内容,我只是从此模块导入imaplib_extension.py
或IMAP4
而不是直接从IMAP4_SSL
导入,并替换任何{{1}稍后只调用imaplib
或imaplib.IMAP4
来调用{}}和imaplib.IMAP4_SSL
。因此,无需IMAP4
,只需IMAP4_SSL
(或相应的import imaplib
):
from imaplib import IMAP4
我更喜欢使用此IMAP4_SSL
的扩展名,因为命令结构与现有命令保持相同,但正确使用UID而不是可能不是UID的“消息号”
更新方法#3
在其他 Python应用程序中意识到我需要这个之后,我放弃了我的屁股并发布了imaplibext
on PyPI,这基本上是上面方法#2的改进和充实版本。但是,它确实具有更好的错误处理能力,并能够实际指定IMAP连接套接字的超时。这是一项改进,因为您无法直接对import imaplib
class IMAP4(imaplib.IMAP4):
def search(self, charset, *criteria):
# conn.uid('SEARCH', charset, criteria)
return self.uid('SEARCH', charset, " ".join(criteria))
def fetch(self, message_set, message_parts):
# conn.uid('FETCH', msgset, parts)
return self.uid('FETCH', message_set, message_parts)
def store(self, message_set, command, flags):
# conn.uid('STORE', msg_uid, '-FLAGS', '(\Seen)')
return self.uid('STORE', message_set, command, flags)
# noinspection PyPep8Naming
class IMAP4_SSL(imaplib.IMAP4_SSL):
def search(self, charset, *criteria):
# conn.uid('SEARCH', charset, criteria)
return self.uid('SEARCH', charset, " ".join(criteria))
def fetch(self, message_set, message_parts):
# conn.uid('FETCH', msgset, parts)
return self.uid('FETCH', message_set, message_parts)
def store(self, message_set, command, flags):
# conn.uid('STORE', msg_uid, '-FLAGS', '(\Seen)')
return self.uid('STORE', message_set, command, flags)
或imaplib
执行此操作,除此之外基本上是imaplib.IMAP4
的替代品(虽然其核心仍然使用imaplib.IMAP4_SSL
)。
此代码也存在于GitHub,用于一般用途和改进建议及问题报告。