将* single * IMAP消息标记为未读

时间:2017-03-06 17:05:33

标签: python python-2.7 email imaplib

我正在尝试在获取所有“UNREAD”消息然后迭代它们并获取它们之后,在单个消息上操作IMAP标记以将其标记为未读。

我不完全确定如何在单个邮件的基础上标记未读/未看到的邮件。我得到的只是消息号,我不确定如何正确存储UID以仅影响单个消息。

answer in a similar question似乎不起作用,因为它将错误的消息设置为“未读”。如何设置单个邮件,我再次将其作为“未读”邮件?

我被要求提供更多信息。虽然在这里删除了“秘密”的细节,但这是我尝试实现的现有运行时,因此它尝试根据代码规则处理消息,并存储消息编号等,并尝试将消息的id和主题存储在pickle文件中后,将每条消息设置为“UNREAD”,因为在运行期间“看到”的任何内容都将在服务器上自动标记为“已读”,而不会设置为“未读”状态:

org.projectlombok:lombok:1.16.14

但是,将正确的消息设置为“未读”;当我使用我在系统上看到的方法时。所以,我不能完全确定我是否没有正确地获取消息的UID,或者是否还有其他我在这里缺少的东西。

1 个答案:

答案 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.pyIMAP4而不是直接从IMAP4_SSL导入,并替换任何{{1}稍后只调用imaplibimaplib.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,用于一般用途和改进建议及问题报告。