用于Python的IMAP文件夹路径编码(IMAP UTF-7)

Mib*_*bou 7 python encoding imap utf-7

我想知道Python中是否有任何"官方"函数/库用于IMAP4 UTF-7文件夹路径编码.

imapInstance.list()我得到以下路径IMAP UTF-7编码:

'(\\HasNoChildren) "." "[Mails].Test&AOk-"',
Run Code Online (Sandbox Code Playgroud)

如果我执行以下编码:

(u"[Mails].Testé").encode('utf-7')
Run Code Online (Sandbox Code Playgroud)

我明白了:

'[Mails].Test+AOk-'
Run Code Online (Sandbox Code Playgroud)

哪个是UTF-7而不是IMAP UTF-7编码.Test+AOk-而不是Test&AOk- 我需要一个官方函数或库来获得IMAP UTF-7编码版本.

Men*_*its 7

IMAPClient 包具有使用 IMAP 修改后的 UTF-7 进行编码和解码的功能。查看 IMAPClient.imap_utf7 模块。该模块可以独立使用,也可以只使用 IMAPClient 来透明地处理文件夹名称的编码和解码。

该项目的主页是:http : //imapclient.freshfoo.com/

示例代码:

from imapclient import imap_utf7
decoded = imap_utf7.decode('&BdAF6QXkBdQ-')
Run Code Online (Sandbox Code Playgroud)

  • 该示例无法像 Python 3 中编写的那样工作。看起来 `imap_utf7.decode()` 需要字节。所以 `imap_utf7.decode(b'&BdAF6QXkBdQ-')` 确实有效。 (2认同)
  • 固定的!这篇文章是在 Python 2 的使用比 Python 3 更常见的时候写的:)我还添加了免责声明。 (2认同)

Fré*_*ans 7

我写了一个非常简单的 IMAP UTF7 python 3 实现,它遵循规范,它似乎工作。(“foo\rbar\n\n\n\r\r”和许多其他往返,'&BdAF6QXkBdQ-'、'Test&Co'、“[Mails].Test&AOk-”和'~peter/mail/&ZeVnLIqe-/&U, BTFw-' 表现如预期)。

#works with python 3

import base64

def b64padanddecode(b):
    """Decode unpadded base64 data"""
    b+=(-len(b)%4)*'=' #base64 padding (if adds '===', no valid padding anyway)
    return base64.b64decode(b,altchars='+,',validate=True).decode('utf-16-be')

def imaputf7decode(s):
    """Decode a string encoded according to RFC2060 aka IMAP UTF7.

Minimal validation of input, only works with trusted data"""
    lst=s.split('&')
    out=lst[0]
    for e in lst[1:]:
        u,a=e.split('-',1) #u: utf16 between & and 1st -, a: ASCII chars folowing it
        if u=='' : out+='&'
        else: out+=b64padanddecode(u)
        out+=a
    return out

def imaputf7encode(s):
    """"Encode a string into RFC2060 aka IMAP UTF7"""
    s=s.replace('&','&-')
    iters=iter(s)
    unipart=out=''
    for c in s:
        if 0x20<=ord(c)<=0x7f :
            if unipart!='' : 
                out+='&'+base64.b64encode(unipart.encode('utf-16-be')).decode('ascii').rstrip('=')+'-'
                unipart=''
            out+=c
        else : unipart+=c
    if unipart!='' : 
        out+='&'+base64.b64encode(unipart.encode('utf-16-be')).decode('ascii').rstrip('=')+'-'
    return out    
Run Code Online (Sandbox Code Playgroud)

鉴于此代码的简单性,我将其设置在公共域中,因此您可以随意使用它。


Mar*_*esh 6

imapclient 的实现有点被破坏了:

x = "foo\rbar\n\n\n\r\r"
imap_utf7.decode(imap_utf7.encode(x))
Run Code Online (Sandbox Code Playgroud)

结果:

>> 'foo&bar\n\n\r-'
Run Code Online (Sandbox Code Playgroud)

编辑:

经过一番研究,我发现MailPile中的一个实现在本次测试中的往返编码中不会失败。如果您有兴趣,我还将其移植到Python3: https: //github.com/MarechJ/py3_imap_utf7