简体   繁体   English

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

[英]IMAP folder path encoding (IMAP UTF-7) for Python

I would like to know if any "official" function/library existed in Python for IMAP4 UTF-7 folder path encoding.我想知道 Python 中是否存在任何用于 IMAP4 UTF-7 文件夹路径编码的“官方”函数/库。

In the imapInstance.list() I get the following path IMAP UTF-7 encoded :imapInstance.list()我得到以下路径 IMAP UTF-7 编码:

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

If I do the following encoding :如果我执行以下编码:

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

I get :我得到:

'[Mails].Test+AOk-'

Which is UTF-7 but not IMAP UTF-7 encoded.这是 UTF-7 但不是 IMAP UTF-7 编码。 Test+AOk- instead of Test&AOk- I'd need an official function or library to get the IMAP UTF-7 encoded version. Test+AOk-而不是Test&AOk-我需要一个官方函数或库来获取 IMAP UTF-7 编码版本。

The IMAPClient package has functionality for encoding and decoding using IMAP's modified UTF-7. IMAPClient 包具有使用 IMAP 修改后的 UTF-7 进行编码和解码的功能。 Have a look in the IMAPClient.imap_utf7 module.查看 IMAPClient.imap_utf7 模块。 This module could be used standalone or you could just use IMAPClient which handles doing the encoding and decoding of folder names transparently.该模块可以独立使用,也可以只使用 IMAPClient 来透明地处理文件夹名称的编码和解码。

The project's home page is: http://imapclient.freshfoo.com/该项目的主页是: http : //imapclient.freshfoo.com/

Example code:示例代码:

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

I wrote a very simple IMAP UTF7 python 3 implementation which follows the specification, and it seems to work.我写了一个非常简单的 IMAP UTF7 python 3 实现,它遵循规范,它似乎工作。 ("foo\\rbar\\n\\n\\n\\r\\r" and many other roundtrips, '&BdAF6QXkBdQ-', 'Test&Co', "[Mails].Test&AOk-" and '~peter/mail/&ZeVnLIqe-/&U,BTFw-' behave as expected). (“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    

Given the simplicity of this code, I set it in the public domain, so feel free to use it as you want.鉴于此代码的简单性,我将其设置在公共域中,因此您可以随意使用它。

The imapclient implementation is kind of broken though:不过 imapclient 实现有点坏:

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

Result:结果:

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

Edit:编辑:

After some research I found an implementation in MailPile which does not fail at roundtrip encoding on this test.经过一些研究,我在MailPile 中找到了一个实现,该实现在此测试中的往返编码不会失败。 I also ported it to Python3 if you're interested: https://github.com/MarechJ/py3_imap_utf7如果您有兴趣,我也将其移植到 Python3: https : //github.com/MarechJ/py3_imap_utf7

You may use imap_tools package: https://pypi.org/project/imap-tools/您可以使用 imap_tools 包: https ://pypi.org/project/imap-tools/

from imap_tools.imap_utf7 import encode, decode

print(encode('привет'))
>>> b'&BD8EQAQ4BDIENQRC-'

print(decode(b'&BD8EQAQ4BDIENQRC-'))
>>> привет

print(repr(decode(encode("foo\rbar\n\n\n\r\r"))))
'foo\rbar\n\n\n\r\r'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM