]>
code.delx.au - offlineimap/blob - offlineimap/repository/Base.py
1 # Base repository support
2 # Copyright (C) 2002-2007 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 offlineimap
import CustomConfig
20 from offlineimap
.ui
import UIBase
23 def LoadRepository(name
, account
, reqtype
):
24 from offlineimap
.repository
.IMAP
import IMAPRepository
, MappedIMAPRepository
25 from offlineimap
.repository
.Maildir
import MaildirRepository
26 if reqtype
== 'remote':
27 # For now, we don't support Maildirs on the remote side.
28 typemap
= {'IMAP': IMAPRepository
}
29 elif reqtype
== 'local':
30 typemap
= {'IMAP': MappedIMAPRepository
,
31 'Maildir': MaildirRepository
}
33 raise ValueError, "Request type %s not supported" % reqtype
34 config
= account
.getconfig()
35 repostype
= config
.get('Repository ' + name
, 'type').strip()
36 return typemap
[repostype
](name
, account
)
38 class BaseRepository(CustomConfig
.ConfigHelperMixin
):
39 def __init__(self
, reposname
, account
):
40 self
.account
= account
41 self
.config
= account
.getconfig()
43 self
.localeval
= account
.getlocaleval()
44 self
.accountname
= self
.account
.getname()
45 self
.uiddir
= os
.path
.join(self
.config
.getmetadatadir(), 'Repository-' + self
.name
)
46 if not os
.path
.exists(self
.uiddir
):
47 os
.mkdir(self
.uiddir
, 0700)
48 self
.mapdir
= os
.path
.join(self
.uiddir
, 'UIDMapping')
49 if not os
.path
.exists(self
.mapdir
):
50 os
.mkdir(self
.mapdir
, 0700)
51 self
.uiddir
= os
.path
.join(self
.uiddir
, 'FolderValidity')
52 if not os
.path
.exists(self
.uiddir
):
53 os
.mkdir(self
.uiddir
, 0700)
55 # The 'restoreatime' config parameter only applies to local Maildir
57 def restore_atime(self
):
58 if self
.config
.get('Repository ' + self
.name
, 'type').strip() != \
62 if not self
.config
.has_option('Repository ' + self
.name
, 'restoreatime') or not self
.config
.getboolean('Repository ' + self
.name
, 'restoreatime'):
65 return self
.restore_folder_atimes()
68 """Establish a connection to the remote, if necessary. This exists
69 so that IMAP connections can all be established up front, gathering
70 passwords as needed. It was added in order to support the
71 error recovery -- we need to connect first outside of the error
72 trap in order to validate the password, and that's the point of
76 def holdordropconnections(self
):
79 def dropconnections(self
):
94 def getaccountname(self
):
95 return self
.accountname
98 return 'Repository ' + self
.name
103 def getlocaleval(self
):
104 return self
.account
.getlocaleval()
106 def getfolders(self
):
107 """Returns a list of ALL folders on this server."""
110 def forgetfolders(self
):
111 """Forgets the cached list of folders, if any. Useful to run
116 raise NotImplementedError
118 def makefolder(self
, foldername
):
119 raise NotImplementedError
121 def deletefolder(self
, foldername
):
122 raise NotImplementedError
124 def getfolder(self
, foldername
):
125 raise NotImplementedError
127 def syncfoldersto(self
, dest
, status
):
128 """Syncs the folders in this repository to those in dest.
129 It does NOT sync the contents of those folders."""
131 srcfolders
= src
.getfolders()
132 destfolders
= dest
.getfolders()
134 # Create hashes with the names, but convert the source folders
135 # to the dest folder's sep.
138 for folder
in srcfolders
:
139 if (folder
.getvisiblename()[-2:] == src
.getsep() + "."):
141 srchash
[folder
.getvisiblename().replace(src
.getsep(), dest
.getsep())] = \
144 for folder
in destfolders
:
145 desthash
[folder
.getvisiblename()] = folder
154 for key
in srchash
.keys():
155 if not key
in desthash
:
156 srckey
= key
.replace(dest
.getsep(),src
.getsep())
157 if status
.getfolder(key
.replace(dest
.getsep(),status
.getsep())).isnewfolder():
159 newfolders
.append(srckey
)
161 UIBase
.getglobalui().ignorefolder (key
, src
, dest
)
162 ignoredfolders
.append(srckey
)
165 # Find deleted folders.
167 # We don't delete folders right now.
169 #for key in desthash.keys():
170 # if not key in srchash:
171 # dest.deletefolder(key)
173 return (ignoredfolders
,newfolders
)
177 def startkeepalive(self
):
178 """The default implementation will do nothing."""
181 def stopkeepalive(self
, abrupt
= 0):
182 """Stop keep alive. If abrupt is 1, stop it but don't bother waiting
183 for the threads to terminate."""