【问题标题】:imaplib and folders with spacesimaplib 和带空格的文件夹
【发布时间】:2017-09-30 15:50:59
【问题描述】:

我正在开发一个应用程序来为我整理电子邮件。它登录到 IMAP 服务器,执行一些搜索,然后将项目复制到文件夹并标记它们以从收件箱中删除。

我的一些文件夹名称中带有空格。

POC 运行良好,但不是“质量”代码。这些规则被硬编码到一个元组数组中。每个元组都是一条规则,由要搜索的字段、要搜索的字符串以及匹配的电子邮件最终所在的文件夹组成。所有规则都有效,但可维护性和代码质量是 . . .低。

POC 后的第一个版本使用 SQLite 数据库来存储规则(以及其他一些与问题无关的东西)。当它在目标文件夹中遇到带有空格的规则时,它最终将 COPY 命令发送到在该空格处截断的服务器。我假设它以某种方式给人一种不应该引用的印象。

烘烤我的面条的部分是这样的:在这两种情况下,规则都被分配给某个来源的变量。唯一的区别是,在一种情况下,源是数据库;另一方面,它是一个硬编码的数组。

我什至从哪里开始解开这个问题?

编辑添加了一些示例代码:

这可行(假设 M 是 imaplib.IMAP4 实例并且它已连接并已登录):

rules = [
    ("FROM", "agent@insurancecompany.com", "Vendors/Insurance Company"),
    ("SUBJECT", "[CDLUG]", "Mailing lists/CDLUG")
]

。 . .

for rule in rules:
    field, value, target = rule
    status, detail = M.search(None, field, value)
    for id in result[0].split():
        status, deatail = M.copy(id, target)
        if (status == "OK"):
            M.store(id, "+FLAGS", "\\Deleted")
    M.expunge()

现在,如果我将这些元组放入 sqlite 数据库中的表中,并将代码更改为如下所示,当遇到带有空格的文件夹名称时,它将失败:

dbi = sqlite3.connect("/home/pi/.mailsort/mailsort.db")
cursor = dbi.cursor()
cursor.execute("Select field, searchstring, destination from rule")
for result in cursor:
    field, searchstring, destination = result
    print field, searchstring, destination
    status, result = M.search(None, field, searchstring)
    for msgid in result[0].split():
        print "Copying message", msgid
        status, detail = M.copy(msgid, destination)
        if (status == "OK"):
            M.store(id, "+FLAGS", "\\Deleted")
    M.expunge()

【问题讨论】:

  • 有示例代码吗?您可能需要转义空格。
  • 如果您使用的是 imaplib,那么您需要引用文件夹名称 - 它对您没有多大作用。还有一些关于其他角色的特殊规则。你也可以试试 IMAPClient (github.com/mjs/imapclient)。它会为您处理所有文件夹名称问题。
  • @Windmill,添加了示例代码。我不确定我会在哪里逃脱这些空间,但我真正困扰的不仅仅是这两种方法之间的不同行为。
  • @Menno Smits,在哪里引用?在这两种情况下,文件夹名称都是包含在变量中的字符串。我是否要在变量的内容前面加上引号?如果是这样,为什么当它来自数组中的元组时它会起作用,而当它来自数据库中的表时却不起作用?
  • 为了让其他遇到此问题的人清楚:您必须用双引号引用文件夹名称,例如而不是"My Folder",你会使用"\"My Folder\""

标签: python sqlite imaplib


【解决方案1】:

来自@jlh 的评论imaplib and folders with spaces 为我完成了这项工作。

使用空格需要将文件夹名称用双引号括起来。

# delete a folder with a space inside    
conn.delete("\"old folder\"")

这同样适用于搜索包含空格的查询的消息:

# search messages with a specific subject containing spaces
conn.select(mailbox='INBOX', readonly=True)   
typ, msgnums = conn.search(None, 'SUBJECT', "\"Subject with spaces\"")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    • 2010-12-07
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多