]>
code.delx.au - offlineimap/blob - offlineimap/repository/IMAP.py
1 # IMAP repository support
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 from Base
import BaseRepository
20 from offlineimap
import folder
, imaputil
, imapserver
21 from offlineimap
.folder
.UIDMaps
import MappedIMAPFolder
22 from offlineimap
.threadutil
import ExitNotifyThread
24 from threading
import *
26 class IMAPRepository(BaseRepository
):
27 def __init__(self
, reposname
, account
):
28 """Initialize an IMAPRepository object."""
29 BaseRepository
.__init
__(self
, reposname
, account
)
30 self
.imapserver
= imapserver
.ConfigedIMAPServer(self
)
32 self
.nametrans
= lambda foldername
: foldername
33 self
.folderfilter
= lambda foldername
: 1
34 self
.folderincludes
= []
36 localeval
= self
.localeval
37 if self
.config
.has_option(self
.getsection(), 'nametrans'):
38 self
.nametrans
= localeval
.eval(self
.getconf('nametrans'),
40 if self
.config
.has_option(self
.getsection(), 'folderfilter'):
41 self
.folderfilter
= localeval
.eval(self
.getconf('folderfilter'),
43 if self
.config
.has_option(self
.getsection(), 'folderincludes'):
44 self
.folderincludes
= localeval
.eval(self
.getconf('folderincludes'),
46 if self
.config
.has_option(self
.getsection(), 'foldersort'):
47 self
.foldersort
= localeval
.eval(self
.getconf('foldersort'),
50 def startkeepalive(self
):
51 keepalivetime
= self
.getkeepalive()
52 if not keepalivetime
: return
53 self
.kaevent
= Event()
54 self
.kathread
= ExitNotifyThread(target
= self
.imapserver
.keepalive
,
55 name
= "Keep alive " + self
.getname(),
56 args
= (keepalivetime
, self
.kaevent
))
57 self
.kathread
.setDaemon(1)
60 def stopkeepalive(self
, abrupt
= 0):
61 if not hasattr(self
, 'kaevent'):
62 # Keepalive is not active.
71 def holdordropconnections(self
):
72 if not self
.getholdconnectionopen():
73 self
.dropconnections()
75 def dropconnections(self
):
76 self
.imapserver
.close()
78 def getholdconnectionopen(self
):
79 return self
.getconfboolean("holdconnectionopen", 0)
81 def getkeepalive(self
):
82 return self
.getconfint("keepalive", 0)
85 return self
.imapserver
.delim
89 localeval
= self
.localeval
91 if self
.config
.has_option(self
.getsection(), 'remotehosteval'):
92 host
= self
.getconf('remotehosteval')
94 return localeval
.eval(host
)
96 host
= self
.getconf('remotehost')
102 localeval
= self
.localeval
104 if self
.config
.has_option(self
.getsection(), 'remoteusereval'):
105 user
= self
.getconf('remoteusereval')
107 return localeval
.eval(user
)
109 user
= self
.getconf('remoteuser')
114 return self
.getconfint('remoteport', None)
117 return self
.getconfboolean('ssl', 0)
119 def getpreauthtunnel(self
):
120 return self
.getconf('preauthtunnel', None)
122 def getreference(self
):
123 return self
.getconf('reference', '""')
125 def getmaxconnections(self
):
126 return self
.getconfint('maxconnections', 1)
128 def getexpunge(self
):
129 return self
.getconfboolean('expunge', 1)
131 def getpassword(self
):
133 localeval
= self
.localeval
135 if self
.config
.has_option(self
.getsection(), 'remotepasseval'):
136 passwd
= self
.getconf('remotepasseval')
138 return localeval
.eval(passwd
)
140 password
= self
.getconf('remotepass', None)
143 passfile
= self
.getconf('remotepassfile', None)
145 fd
= open(os
.path
.expanduser(passfile
))
146 password
= fd
.readline().strip()
151 def getfolder(self
, foldername
):
152 return self
.getfoldertype()(self
.imapserver
, foldername
,
153 self
.nametrans(foldername
),
154 self
.accountname
, self
)
156 def getfoldertype(self
):
157 return folder
.IMAP
.IMAPFolder
160 imapobj
= self
.imapserver
.acquireconnection()
161 self
.imapserver
.releaseconnection(imapobj
)
163 def forgetfolders(self
):
166 def getfolders(self
):
167 if self
.folders
!= None:
170 imapobj
= self
.imapserver
.acquireconnection()
172 listresult
= imapobj
.list(directory
= self
.imapserver
.reference
)[1]
174 self
.imapserver
.releaseconnection(imapobj
)
175 for string
in listresult
:
176 if string
== None or \
177 (type(string
) == types
.StringType
and string
== ''):
178 # Bug in imaplib: empty strings in results from
181 flags
, delim
, name
= imaputil
.imapsplit(string
)
182 flaglist
= [x
.lower() for x
in imaputil
.flagsplit(flags
)]
183 if '\\noselect' in flaglist
:
185 foldername
= imaputil
.dequote(name
)
186 if not self
.folderfilter(foldername
):
188 retval
.append(self
.getfoldertype()(self
.imapserver
, foldername
,
189 self
.nametrans(foldername
),
190 self
.accountname
, self
))
191 if len(self
.folderincludes
):
192 imapobj
= self
.imapserver
.acquireconnection()
194 for foldername
in self
.folderincludes
:
196 imapobj
.select(foldername
, readonly
= 1)
199 retval
.append(self
.getfoldertype()(self
.imapserver
,
201 self
.nametrans(foldername
),
202 self
.accountname
, self
))
204 self
.imapserver
.releaseconnection(imapobj
)
206 retval
.sort(lambda x
, y
: self
.foldersort(x
.getvisiblename(), y
.getvisiblename()))
207 self
.folders
= retval
210 def makefolder(self
, foldername
):
211 #if self.getreference() != '""':
212 # newname = self.getreference() + self.getsep() + foldername
214 # newname = foldername
216 imapobj
= self
.imapserver
.acquireconnection()
218 result
= imapobj
.create(newname
)
219 if result
[0] != 'OK':
220 raise RuntimeError, "Repository %s could not create folder %s: %s" % (self
.getname(), foldername
, str(result
))
222 self
.imapserver
.releaseconnection(imapobj
)
224 class MappedIMAPRepository(IMAPRepository
):
225 def getfoldertype(self
):
226 return MappedIMAPFolder