Merge pull request #47 from amitramon/fix_utf8foldernames

Fix utf8foldernames configuration option to work with Python3
This commit is contained in:
Rodolfo García Peñas (kix) 2021-02-18 18:36:15 +01:00 committed by GitHub
commit fe228fa344
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -18,6 +18,7 @@
import re import re
import binascii import binascii
import codecs import codecs
from typing import Tuple
from offlineimap.ui import getglobalui from offlineimap.ui import getglobalui
# Globals # Globals
@ -352,42 +353,45 @@ def decode_mailbox_name(name):
def IMAP_utf8(foldername): def IMAP_utf8(foldername):
"""Convert IMAP4_utf_7 encoded string to utf-8""" """Convert IMAP4_utf_7 encoded string to utf-8"""
return foldername.decode('imap4-utf-7').encode('utf-8') return codecs.decode(
foldername.encode(),
'imap4-utf-7'
).encode('utf-8').decode()
def utf8_IMAP(foldername): def utf8_IMAP(foldername):
"""Convert utf-8 encoded string to IMAP4_utf_7""" """Convert utf-8 encoded string to IMAP4_utf_7"""
return foldername.decode('utf-8').encode('imap4-utf-7') return codecs.decode(
foldername.encode(),
'utf-8'
).encode('imap4-utf-7').decode()
# Codec definition # Codec definition
def modified_base64(s): def modified_base64(s):
s = s.encode('utf-16be') s = s.encode('utf-16be')
return binascii.b2a_base64(s).rstrip('\n=').replace('/', ',') return binascii.b2a_base64(s).rstrip(b'\n=').replace(b'/', b',')
def doB64(_in, r): def doB64(_in, r):
if _in: if _in:
r.append('&%s-' % modified_base64(''.join(_in))) r.append(b'&%s-' % modified_base64(''.join(_in)))
del _in[:] del _in[:]
def encoder(s): def utf7m_encode(text: str) -> Tuple[bytes, int]:
r = [] r = []
_in = [] _in = []
for c in s:
ordC = ord(c) for c in text:
if 0x20 <= ordC <= 0x25 or 0x27 <= ordC <= 0x7e: if 0x20 <= ord(c) <= 0x7e:
doB64(_in, r) doB64(_in, r)
r.append(c) r.append(b'&-' if c == '&' else c.encode())
elif c == '&':
doB64(_in, r)
r.append('&-')
else: else:
_in.append(c) _in.append(c)
doB64(_in, r) doB64(_in, r)
return str(''.join(r)), len(s) return b''.join(r), len(text)
# decoding # decoding
@ -396,10 +400,10 @@ def modified_unbase64(s):
return str(b, 'utf-16be') return str(b, 'utf-16be')
def decoder(s): def utf7m_decode(binary: bytes) -> Tuple[str, int]:
r = [] r = []
decode = [] decode = []
for c in s: for c in binary.decode():
if c == '&' and not decode: if c == '&' and not decode:
decode.append('&') decode.append('&')
elif c == '-' and decode: elif c == '-' and decode:
@ -415,26 +419,31 @@ def decoder(s):
if decode: if decode:
r.append(modified_unbase64(''.join(decode[1:]))) r.append(modified_unbase64(''.join(decode[1:])))
bin_str = ''.join(r)
return bin_str, len(s) return ''.join(r), len(binary)
class StreamReader(codecs.StreamReader): class StreamReader(codecs.StreamReader):
def decode(self, s, errors='strict'): def decode(self, s, errors='strict'):
return decoder(s) return utf7m_decode(s)
class StreamWriter(codecs.StreamWriter): class StreamWriter(codecs.StreamWriter):
def decode(self, s, errors='strict'): def decode(self, s, errors='strict'):
return encoder(s) return utf7m_encode(s)
def imap4_utf_7(name): def utf7m_search_function(name):
if name == 'imap4-utf-7': return codecs.CodecInfo(
return encoder, decoder, StreamReader, StreamWriter utf7m_encode,
utf7m_decode,
StreamReader,
StreamWriter,
name='imap4-utf-7'
)
codecs.register(imap4_utf_7) codecs.register(utf7m_search_function)
def foldername_to_imapname(folder_name): def foldername_to_imapname(folder_name):
@ -454,4 +463,4 @@ def foldername_to_imapname(folder_name):
if any((c in atom_specials) for c in folder_name): if any((c in atom_specials) for c in folder_name):
folder_name = '"' + folder_name + '"' folder_name = '"' + folder_name + '"'
return folder_name return folder_name