Update changelog.
[wammu.git] / Wammu / IMAP.py
blob6ead69df453739871ce502cfb71f028b0d4eb82e
1 # -*- coding: UTF-8 -*-
2 # vim: expandtab sw=4 ts=4 sts=4:
3 '''
4 Wammu - Phone manager
5 IMAP UTF-7 codec
6 '''
7 __author__ = 'Michal Čihař'
8 __email__ = 'michal@cihar.com'
9 __license__ = '''
10 Copyright © 2003 - 2009 Michal Čihař
12 This program is free software; you can redistribute it and/or modify it
13 under the terms of the GNU General Public License version 2 as published by
14 the Free Software Foundation.
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 more details.
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 '''
26 import codecs
28 def modified_base64(s):
29 s_utf7 = s.encode('utf-7')
30 return s_utf7[1:-1].replace('/', ',')
32 def modified_unbase64(s):
33 s_utf7 = '+' + s.replace(',', '/') + '-'
34 return s_utf7.decode('utf-7')
36 def encoder(s):
37 r = []
38 _in = []
39 for c in s:
40 if ord(c) in (range(0x20, 0x26) + range(0x27, 0x7f)):
41 if _in:
42 r.extend(['&', modified_base64(''.join(_in)), '-'])
43 del _in[:]
44 r.append(str(c))
45 elif c == '&':
46 if _in:
47 r.extend(['&', modified_base64(''.join(_in)), '-'])
48 del _in[:]
49 r.append('&-')
50 else:
51 _in.append(c)
52 if _in:
53 r.extend(['&', modified_base64(''.join(_in)), '-'])
54 return (''.join(r), len(s))
56 def decoder(s):
57 r = []
58 decode = []
59 for c in s:
60 if c == '&' and not decode:
61 decode.append('&')
62 elif c == '-' and decode:
63 if len(decode) == 1:
64 r.append('&')
65 else:
66 r.append(modified_unbase64(''.join(decode[1:])))
67 decode = []
68 elif decode:
69 decode.append(c)
70 else:
71 r.append(c)
72 if decode:
73 r.append(modified_unbase64(''.join(decode[1:])))
74 return (u''.join(r), len(s))
76 class StreamReader(codecs.StreamReader):
77 def decode(self, s, errors='strict'):
78 return decoder(s)
80 class StreamWriter(codecs.StreamWriter):
81 def decode(self, s, errors='strict'):
82 return encoder(s)
84 def imap4_utf_7(name):
85 if name == 'imap4-utf-7':
86 return (encoder, decoder, StreamReader, StreamWriter)
88 codecs.register(imap4_utf_7)