]>
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
88 return self
.getconf('remotehost')
91 return self
.getconf('remoteuser')
94 return self
.getconfint('remoteport', None)
97 return self
.getconfboolean('ssl', 0)
99 def getpreauthtunnel(self
):
100 return self
.getconf('preauthtunnel', None)
102 def getreference(self
):
103 return self
.getconf('reference', '""')
105 def getmaxconnections(self
):
106 return self
.getconfint('maxconnections', 1)
108 def getexpunge(self
):
109 return self
.getconfboolean('expunge', 1)
111 def getpassword(self
):
112 password
= self
.getconf('remotepass', None)
115 passfile
= self
.getconf('remotepassfile', None)
117 fd
= open(os
.path
.expanduser(passfile
))
118 password
= fd
.readline().strip()
123 def getfolder(self
, foldername
):
124 return self
.getfoldertype()(self
.imapserver
, foldername
,
125 self
.nametrans(foldername
),
126 self
.accountname
, self
)
128 def getfoldertype(self
):
129 return folder
.IMAP
.IMAPFolder
131 def getfolders(self
):
132 if self
.folders
!= None:
135 imapobj
= self
.imapserver
.acquireconnection()
137 listresult
= imapobj
.list(directory
= self
.imapserver
.reference
)[1]
139 self
.imapserver
.releaseconnection(imapobj
)
140 for string
in listresult
:
141 if string
== None or \
142 (type(string
) == types
.StringType
and string
== ''):
143 # Bug in imaplib: empty strings in results from
146 flags
, delim
, name
= imaputil
.imapsplit(string
)
147 flaglist
= [x
.lower() for x
in imaputil
.flagsplit(flags
)]
148 if '\\noselect' in flaglist
:
150 foldername
= imaputil
.dequote(name
)
151 if not self
.folderfilter(foldername
):
153 retval
.append(self
.getfoldertype()(self
.imapserver
, foldername
,
154 self
.nametrans(foldername
),
155 self
.accountname
, self
))
156 if len(self
.folderincludes
):
157 imapobj
= self
.imapserver
.acquireconnection()
159 for foldername
in self
.folderincludes
:
161 imapobj
.select(foldername
, readonly
= 1)
164 retval
.append(self
.getfoldertype()(self
.imapserver
,
166 self
.nametrans(foldername
),
167 self
.accountname
, self
))
169 self
.imapserver
.releaseconnection(imapobj
)
171 retval
.sort(lambda x
, y
: self
.foldersort(x
.getvisiblename(), y
.getvisiblename()))
172 self
.folders
= retval
175 def makefolder(self
, foldername
):
176 #if self.getreference() != '""':
177 # newname = self.getreference() + self.getsep() + foldername
179 # newname = foldername
181 imapobj
= self
.imapserver
.acquireconnection()
183 result
= imapobj
.create(newname
)
184 if result
[0] != 'OK':
185 raise RuntimeError, "Repository %s could not create folder %s: %s" % (self
.getname(), foldername
, str(result
))
187 self
.imapserver
.releaseconnection(imapobj
)
189 class MappedIMAPRepository(IMAPRepository
):
190 def getfoldertype(self
):
191 return MappedIMAPFolder