diff options
| author | Anton Bobov <abobov@gmail.com> | 2016-01-16 20:13:37 +0500 |
|---|---|---|
| committer | Anton Bobov <abobov@gmail.com> | 2016-01-18 15:53:55 +0500 |
| commit | 5bb8d5eeda648875f7dd0b9e378e25e49a918305 (patch) | |
| tree | df7cc1f2d37a03ff44413f37a5abc3a42b02c91a /files | |
| parent | 4e49e06c20030a00e73e8c74b2f957a21a9ea75b (diff) | |
Update offlineimap config to 6.6 version.
Fix folder encoding.
Diffstat (limited to 'files')
| -rw-r--r-- | files/.offlineimap-utf7.py | 124 | ||||
| -rw-r--r-- | files/.offlineimaprc | 8 |
2 files changed, 130 insertions, 2 deletions
diff --git a/files/.offlineimap-utf7.py b/files/.offlineimap-utf7.py new file mode 100644 index 0000000..69b9389 --- /dev/null +++ b/files/.offlineimap-utf7.py @@ -0,0 +1,124 @@ +# -*- coding: latin-1 -*- + +""" +Imap folder names are encoded using a special version of utf-7 as defined in RFC +2060 section 5.1.3. + +5.1.3. Mailbox International Naming Convention + + By convention, international mailbox names are specified using a + modified version of the UTF-7 encoding described in [UTF-7]. The + purpose of these modifications is to correct the following problems + with UTF-7: + + 1) UTF-7 uses the "+" character for shifting; this conflicts with + the common use of "+" in mailbox names, in particular USENET + newsgroup names. + + 2) UTF-7's encoding is BASE64 which uses the "/" character; this + conflicts with the use of "/" as a popular hierarchy delimiter. + + 3) UTF-7 prohibits the unencoded usage of "\"; this conflicts with + the use of "\" as a popular hierarchy delimiter. + + 4) UTF-7 prohibits the unencoded usage of "~"; this conflicts with + the use of "~" in some servers as a home directory indicator. + + 5) UTF-7 permits multiple alternate forms to represent the same + string; in particular, printable US-ASCII chararacters can be + represented in encoded form. + + In modified UTF-7, printable US-ASCII characters except for "&" + represent themselves; that is, characters with octet values 0x20-0x25 + and 0x27-0x7e. The character "&" (0x26) is represented by the two- + octet sequence "&-". + + All other characters (octet values 0x00-0x1f, 0x7f-0xff, and all + Unicode 16-bit octets) are represented in modified BASE64, with a + further modification from [UTF-7] that "," is used instead of "/". + Modified BASE64 MUST NOT be used to represent any printing US-ASCII + character which can represent itself. + + "&" is used to shift to modified BASE64 and "-" to shift back to US- + ASCII. All names start in US-ASCII, and MUST end in US-ASCII (that + is, a name that ends with a Unicode 16-bit octet MUST end with a "- + "). + + For example, here is a mailbox name which mixes English, Japanese, + and Chinese text: ~peter/mail/&ZeVnLIqe-/&U,BTFw- + +""" +import binascii +import codecs + +# encoding + +def modified_base64(s): + s = s.encode('utf-16be') + return binascii.b2a_base64(s).rstrip('\n=').replace('/', ',') + +def doB64(_in, r): + if _in: + r.append('&%s-' % modified_base64(''.join(_in))) + del _in[:] + +def encoder(s): + r = [] + _in = [] + for c in s: + ordC = ord(c) + if 0x20 <= ordC <= 0x25 or 0x27 <= ordC <= 0x7e: + doB64(_in, r) + r.append(c) + elif c == '&': + doB64(_in, r) + r.append('&-') + else: + _in.append(c) + doB64(_in, r) + return (str(''.join(r)), len(s)) + + +# decoding + +def modified_unbase64(s): + b = binascii.a2b_base64(s.replace(',', '/') + '===') + return unicode(b, 'utf-16be') + + +def decoder(s): + r = [] + decode = [] + for c in s: + if c == '&' and not decode: + decode.append('&') + elif c == '-' and decode: + if len(decode) == 1: + r.append('&') + else: + r.append(modified_unbase64(''.join(decode[1:]))) + decode = [] + elif decode: + decode.append(c) + else: + r.append(c) + if decode: + r.append(modified_unbase64(''.join(decode[1:]))) + bin_str = ''.join(r) + return (bin_str, len(s)) + + +class StreamReader(codecs.StreamReader): + def decode(self, s, errors='strict'): + return decoder(s) + + +class StreamWriter(codecs.StreamWriter): + def decode(self, s, errors='strict'): + return encoder(s) + + +def imap4_utf_7(name): + if name == 'imap4-utf-7': + return (encoder, decoder, StreamReader, StreamWriter) +codecs.register(imap4_utf_7) diff --git a/files/.offlineimaprc b/files/.offlineimaprc index 94a9a4c..47055ad 100644 --- a/files/.offlineimaprc +++ b/files/.offlineimaprc @@ -2,6 +2,7 @@ accounts = Gmail socktimeout = 60 fsync = False +pythonfile = ~/.offlineimap-utf7.py [Account Gmail] localrepository = LocalGmail @@ -16,21 +17,24 @@ nametrans = lambda folder: { 'drafts': '[Gmail]/Drafts', 'sent': '[Gmail]/Sent Mail', 'flagged': '[Gmail]/Starred', 'archive': '[Gmail]/All Mail', - }.get(folder, folder) + }.get(folder, folder).decode('utf-8').encode('imap4-utf-7') [Repository RemoteGmail] type = Gmail +sslcacertfile = /etc/ssl/certs/ca-certificates.crt maxconnections = 1 # Password stored in ~/.netrc remoteuser = abobov@gmail.com +auth_mechanisms = LOGIN realdelete =no nametrans = lambda folder: { '[Gmail]/Drafts': 'drafts', '[Gmail]/Sent Mail': 'sent', '[Gmail]/Starred': 'flagged', '[Gmail]/All Mail': 'archive', - }.get(folder, folder) + }.get(folder, folder).decode('imap4-utf-7').encode('utf-8') folderfilter = lambda folder: folder not in [ '[Gmail]/Spam', '[Gmail]/Starred', '[Gmail]/Trash', '[Gmail]/Important', ] +createfolders = False |
