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

时间:2012-10-08 06:54:50

标签: python encoding imap utf-7

我想知道Python中是否存在任何用于IMAP4 UTF-7文件夹路径编码的“官方”函数/库。

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

'(\\HasNoChildren) "." "[Mails].Test&AOk-"',

如果我执行以下编码:

(u"[Mails].Testé").encode('utf-7')

我明白了:

'[Mails].Test+AOk-'

哪个是UTF-7但不是IMAP UTF-7编码。 Test+AOk-代替Test&AOk- 我需要一个官方函数或库来获取IMAP UTF-7编码版本。

4 个答案:

答案 0 :(得分:4)

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

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

示例代码:

from imapclient import imap_utf7
decoded = imap_utf7.decode('&BdAF6QXkBdQ-')

答案 1 :(得分:3)

imapclient实现虽然有点破碎:

x = "foo\rbar\n\n\n\r\r"
imap_utf7.decode(imap_utf7.encode(x))

结果:

>> 'foo&bar\n\n\r-'

编辑:

经过一些研究后,我在MailPile中找到了一个实现,它在此测试中的往返编码中没有失败。如果你有兴趣,我也把它移植到Python3:https://github.com/MarechJ/py3_imap_utf7

答案 2 :(得分:2)

我写了一个非常简单的IMAP UTF7 python 3实现,遵循规范,它似乎工作。 (" foo \ rbar \ n \ n \ n \ r \ n"以及许多其他往返行程,'& BdAF6QXkBdQ - ',' Test& Co', " [邮件] .Test& AOk - "和'〜彼得/邮件/& 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    

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

答案 3 :(得分:0)

您可以使用imap_tools软件包: https://pypi.org/project/imap-tools/

from imap_tools.imap_utf7 import encode, decode
print(encode('привет'))
>>> b'&BD8EQAQ4BDIENQRC-'
print(decode(b'&BD8EQAQ4BDIENQRC-'))
>>> привет