]>
code.delx.au - offlineimap/blob - head/offlineimap/folder/IMAP.py
b612e2ae75e84b96b88e53d7e4ba89681cfada5e
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 from Base
import BaseFolder
20 from offlineimap
import imaputil
, imaplib
22 from StringIO
import StringIO
24 class IMAPFolder(BaseFolder
):
25 def __init__(self
, imapserver
, name
, visiblename
):
26 self
.name
= imaputil
.dequote(name
)
27 self
.root
= imapserver
.root
28 self
.sep
= imapserver
.delim
29 self
.imapserver
= imapserver
30 self
.messagelist
= None
31 self
.visiblename
= visiblename
33 def suggeststhreads(self
):
36 def waitforthread(self
):
37 self
.imapserver
.connectionwait()
39 def getvisiblename(self
):
40 return self
.visiblename
42 def getuidvalidity(self
):
43 imapobj
= self
.imapserver
.acquireconnection()
45 x
= imapobj
.status(self
.getfullname(), '(UIDVALIDITY)')[1][0]
47 self
.imapserver
.releaseconnection(imapobj
)
48 uidstring
= imaputil
.imapsplit(x
)[1]
49 return long(imaputil
.flagsplit(uidstring
)[1])
51 def cachemessagelist(self
):
52 imapobj
= self
.imapserver
.acquireconnection()
54 imapobj
.select(self
.getfullname())
56 response
= imapobj
.status(self
.getfullname(), '(MESSAGES)')[1][0]
57 result
= imaputil
.imapsplit(response
)[1]
58 maxmsgid
= long(imaputil
.flags2hash(result
)['MESSAGES'])
60 # No messages? return.
63 # Now, get the flags and UIDs for these.
64 response
= imapobj
.fetch('1:%d' % maxmsgid
, '(FLAGS UID)')[1]
66 self
.imapserver
.releaseconnection(imapobj
)
67 for messagestr
in response
:
68 # Discard the message number.
69 messagestr
= imaputil
.imapsplit(messagestr
)[1]
70 options
= imaputil
.flags2hash(messagestr
)
71 uid
= long(options
['UID'])
72 flags
= imaputil
.flagsimap2maildir(options
['FLAGS'])
73 self
.messagelist
[uid
] = {'uid': uid
, 'flags': flags
}
75 def getmessagelist(self
):
76 return self
.messagelist
78 def getmessage(self
, uid
):
79 imapobj
= self
.imapserver
.acquireconnection()
81 imapobj
.select(self
.getfullname())
82 return imapobj
.uid('fetch', '%d' % uid
, '(BODY.PEEK[])')[1][0][1].replace("\r\n", "\n")
84 self
.imapserver
.releaseconnection(imapobj
)
86 def getmessageflags(self
, uid
):
87 return self
.messagelist
[uid
]['flags']
89 def savemessage(self
, uid
, content
, flags
):
90 imapobj
= self
.imapserver
.acquireconnection()
92 # This backend always assigns a new uid, so the uid arg is ignored.
93 # In order to get the new uid, we need to save off the message ID.
95 message
= rfc822
.Message(StringIO(content
))
96 mid
= imapobj
._quote
(message
.getheader('Message-Id'))
97 date
= imaplib
.Time2Internaldate(rfc822
.parsedate(message
.getheader('Date')))
99 if content
.find("\r\n") == -1: # Convert line endings if not already
100 content
= content
.replace("\n", "\r\n")
102 assert(imapobj
.append(self
.getfullname(),
103 imaputil
.flagsmaildir2imap(flags
),
104 date
, content
)[0] == 'OK')
105 # Checkpoint. Let it write out the messages, etc.
106 assert(imapobj
.check()[0] == 'OK')
107 # Now find the UID it got.
108 matchinguids
= imapobj
.uid('search', None,
109 '(HEADER Message-Id %s)' % mid
)[1][0]
110 matchinguids
= matchinguids
.split(' ')
112 uid
= long(matchinguids
[-1])
113 self
.messagelist
[uid
] = {'uid': uid
, 'flags': flags
}
116 self
.imapserver
.releaseconnection(imapobj
)
118 def savemessageflags(self
, uid
, flags
):
119 imapobj
= self
.imapserver
.acquireconnection(imapobj
)
121 imapobj
.select(self
.getfullname())
122 result
= imapobj
.uid('store', '%d' % uid
, 'FLAGS',
123 imaputil
.flagsmaildir2imap(flags
))[1][0]
125 self
.imapserver
.releaseconnection(imapobj
)
126 flags
= imaputil
.flags2hash(imaputil
.imapsplit(result
)[1])['FLAGS']
127 self
.messagelist
[uid
]['flags'] = imaputil
.flagsimap2maildir(flags
)
129 def addmessagesflags(self
, uidlist
, flags
):
130 imapobj
= self
.imapserver
.acquireconnection()
132 imapobj
.select(self
.getfullname())
133 r
= imapobj
.uid('store',
134 ','.join([str(uid
) for uid
in uidlist
]),
136 imaputil
.flagsmaildir2imap(flags
))[1]
138 self
.imapserver
.releaseconnection(imapobj
)
142 flags
= imaputil
.flags2hash(imaputil
.imapsplit(result
)[1])['FLAGS']
143 uid
= long(imaputil
.flags2hash(imaputil
.imapsplit(result
)[1])['UID'])
144 self
.messagelist
[uid
]['flags'] = imaputil
.flagsimap2maildir(flags
)
145 assert resultcount
== len(uidlist
), "Got incorrect number of results back"
147 def deletemessage(self
, uid
):
148 self
.deletemessages([uid
])
150 def deletemessages(self
, uidlist
):
151 # Weed out ones not in self.messagelist
152 uidlist
= [uid
for uid
in uidlist
if uid
in self
.messagelist
]
156 self
.addmessagesflags(uidlist
, ['T'])
157 imapobj
= self
.imapserver
.acquireconnection()
159 imapobj
.select(self
.getfullname())
160 assert(imapobj
.expunge()[0] == 'OK')
162 self
.imapserver
.releaseconnection(imapobj
)
164 del(self
.messagelist
[uid
])