Кодировка пути к папке IMAP (IMAP UTF-7) для Python

Я хотел бы знать, существовала ли какая-либо "официальная" функция/библиотека в 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.

3 ответов


пакет IMAPClient имеет функциональность для кодирования и декодирования с использованием модифицированного UTF-7 IMAP. Посмотрите в IMAPClient.модуль imap_utf7. Этот модуль может использоваться автономно или вы можете просто использовать IMAPClient, который обрабатывает кодирование и декодирование имен папок прозрачно.

Домашняя страница проекта:http://imapclient.freshfoo.com/

пример кода:

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

реализация imapclient был сломан, хотя:

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

результат:

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

Edit:

после некоторых исследований я нашел реализацию в MailPile который не терпит неудачу при кодировании туда и обратно в этом тесте. Я также портировал его на Python3, если вам интересно:https://github.com/MarechJ/py3_imap_utf7


Я написал очень простую реализацию IMAP UTF7 python 3, которая следует спецификации, и, похоже, работает. ("foo\rbar\n\n\n\r\r "и многие другие roundtrips, '&BdAF6QXkBdQ-', 'Test&Co', " [письма].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    

учитывая простоту этого кода, я устанавливаю его в открытом доступе, поэтому не стесняйтесь использовать его, как хотите.