]>
code.delx.au - offlineimap/blob - offlineimap/imaputil.py
2 # Copyright (C) 2002 John Goerzen
3 # <jgoerzen@complete.org>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 import re
, string
, types
20 from offlineimap
.ui
import UIBase
21 quotere
= re
.compile('^("(?:[^"]|\\\\")*")')
27 UIBase
.getglobalui().debug('imap', " ".join(msg
))
30 """Takes a string which may or may not be quoted and returns it, unquoted.
31 This function does NOT consider parenthised lists to be quoted.
34 debug("dequote() called with input:", string
)
35 if not (string
[0] == '"' and string
[-1] == '"'):
37 string
= string
[1:-1] # Strip off quotes.
38 string
= string
.replace('\\"', '"')
39 string
= string
.replace('\\\\', '\\')
40 debug("dequote() returning:", string
)
43 def flagsplit(string
):
44 if string
[0] != '(' or string
[-1] != ')':
45 raise ValueError, "Passed string '%s' is not a flag list" % string
46 return imapsplit(string
[1:-1])
48 def options2hash(list):
49 debug("options2hash called with input:", list)
52 while (counter
< len(list)):
53 retval
[list[counter
]] = list[counter
+ 1]
55 debug("options2hash returning:", retval
)
58 def flags2hash(string
):
59 return options2hash(flagsplit(string
))
61 def imapsplit(imapstring
):
62 """Takes a string from an IMAP conversation and returns a list containing
63 its components. One example string is:
65 (\\HasNoChildren) "." "INBOX.Sent"
67 The result from parsing this will be:
69 ['(\\HasNoChildren)', '"."', '"INBOX.Sent"']"""
71 debug("imapsplit() called with input:", imapstring
)
72 if type(imapstring
) != types
.StringType
:
73 debug("imapsplit() got a non-string input; working around.")
74 # Sometimes, imaplib will throw us a tuple if the input
75 # contains a literal. See Python bug
76 # #619732 at https://sourceforge.net/tracker/index.php?func=detail&aid=619732&group_id=5470&atid=105470
78 # result[0] = '() "\\\\" Admin'
79 # result[1] = ('() "\\\\" {19}', 'Folder\\2')
81 # This function will effectively get result[0] or result[1], so
82 # if we get the result[1] version, we need to parse apart the tuple
83 # and figure out what to do with it. Each even-numbered
84 # part of it should end with the {} number, and each odd-numbered
85 # part should be directly a part of the result. We'll
86 # artificially quote it to help out.
88 for i
in range(len(imapstring
)):
89 if i
% 2: # Odd: quote then append.
91 # Quote code lifted from imaplib
92 arg
= arg
.replace('\\', '\\\\')
93 arg
= arg
.replace('"', '\\"')
95 debug("imapsplit() non-string [%d]: Appending %s" %\
99 # Even -- we have a string that ends with a literal
100 # size specifier. We need to strip off that, then run
101 # what remains through the regular imapsplit parser.
102 # Recursion to the rescue.
104 arg
= re
.sub('\{\d+\}$', '', arg
)
105 debug("imapsplit() non-string [%d]: Feeding %s to recursion" %\
107 retval
.extend(imapsplit(arg
))
108 debug("imapsplit() non-string: returning %s" % str(retval
))
111 workstr
= imapstring
.strip()
114 if workstr
[0] == '(':
115 rparenc
= 1 # count of right parenthesis to match
116 rpareni
= 1 # position to examine
117 while rparenc
: # Find the end of the group.
118 if workstr
[rpareni
] == ')': # end of a group
120 elif workstr
[rpareni
] == '(': # start of a group
122 rpareni
+= 1 # Move to next character.
123 parenlist
= workstr
[0:rpareni
]
124 workstr
= workstr
[rpareni
:].lstrip()
125 retval
.append(parenlist
)
126 elif workstr
[0] == '"':
127 quotelist
= quotere
.search(workstr
).group(1)
128 workstr
= workstr
[len(quotelist
):].lstrip()
129 retval
.append(quotelist
)
131 splits
= string
.split(workstr
, maxsplit
= 1)
132 splitslen
= len(splits
)
133 # The unquoted word is splits[0]; the remainder is splits[1]
135 # There's an unquoted word, and more string follows.
136 retval
.append(splits
[0])
137 workstr
= splits
[1] # split will have already lstripped it
140 # We got a last unquoted word, but nothing else
141 retval
.append(splits
[0])
142 # Nothing remains. workstr would be ''
145 # There was not even an unquoted word.
147 debug("imapsplit() returning:", retval
)
150 def flagsimap2maildir(flagstring
):
151 flagmap
= {'\\seen': 'S',
157 imapflaglist
= [x
.lower() for x
in flagstring
[1:-1].split()]
158 for imapflag
in imapflaglist
:
159 if flagmap
.has_key(imapflag
):
160 retval
.append(flagmap
[imapflag
])
164 def flagsmaildir2imap(list):
165 flagmap
= {'S': '\\Seen',
172 if flagmap
.has_key(mdflag
):
173 retval
.append(flagmap
[mdflag
])
175 return '(' + ' '.join(retval
) + ')'
182 def getlist(start
, end
):
186 return(str(start
) + ":" + str(end
))
194 elif item
== end
+ 1:
195 # An addition to the list.
198 # Here on: starting a new list.
199 retval
.append(getlist(start
, end
))
204 retval
.append(getlist(start
, end
))
206 return ",".join(retval
)