]>
code.delx.au - offlineimap/blob - offlineimap/head/offlineimap/repository/Maildir.py
a6c305697aa66ebac3e73665bdc304ccf72fb9ca
1 # Maildir 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 from Base
import BaseRepository
20 from offlineimap
import folder
, imaputil
21 from offlineimap
. ui
import UIBase
22 from mailbox
import Maildir
25 class MaildirRepository ( BaseRepository
):
26 def __init__ ( self
, reposname
, account
):
27 """Initialize a MaildirRepository object. Takes a path name
28 to the directory holding all the Maildir directories."""
29 BaseRepository
.__ init
__ ( self
, reposname
, account
)
31 self
. root
= self
. getlocalroot ()
33 self
. ui
= UIBase
. getglobalui ()
34 self
. debug ( "MaildirRepository initialized, sep is " + repr ( self
. getsep ()))
36 def getlocalroot ( self
):
37 return os
. path
. expanduser ( self
. getconf ( 'localfolders' ))
40 self
. ui
. debug ( 'maildir' , msg
)
43 return self
. getconf ( 'sep' , '.' ). strip ()
45 def makefolder ( self
, foldername
):
46 self
. debug ( "makefolder called with arg " + repr ( foldername
))
47 # Do the chdir thing so the call to makedirs does not make the
48 # self.root directory (we'd prefer to raise an error in that case),
49 # but will make the (relative) paths underneath it. Need to use
50 # makedirs to support a / separator.
51 if self
. getsep () == '/' :
52 for invalid
in [ 'new' , 'cur' , 'tmp' , 'offlineimap.uidvalidity' ]:
53 for component
in foldername
. split ( '/' ):
54 assert component
!= invalid
, "When using nested folders (/ as a separator in the account config), your folder names may not contain 'new', 'cur', 'tmp', or 'offlineimap.uidvalidity'."
56 assert foldername
. find ( './' ) == - 1 , "Folder names may not contain ../"
57 assert not foldername
. startswith ( '/' ), "Folder names may not begin with /"
62 # If we're using hierarchical folders, it's possible that sub-folders
63 # may be created before higher-up ones. If this is the case,
64 # makedirs will fail because the higher-up dir already exists.
65 # So, check to see if this is indeed the case.
67 if ( self
. getsep () == '/' or self
. getconfboolean ( 'existsok' , 0 )) \
68 and os
. path
. isdir ( foldername
):
69 self
. debug ( "makefolder: %s already is a directory" % foldername
)
70 # Already exists. Sanity-check that it's not a Maildir.
71 for subdir
in [ 'cur' , 'new' , 'tmp' ]:
72 assert not os
. path
. isdir ( os
. path
. join ( foldername
, subdir
)), \
73 "Tried to create folder %s but it already had dir %s " % \
76 self
. debug ( "makefolder: calling makedirs %s " % foldername
)
77 os
. makedirs ( foldername
, 0700 )
78 self
. debug ( "makefolder: creating cur, new, tmp" )
79 for subdir
in [ 'cur' , 'new' , 'tmp' ]:
80 os
. mkdir ( os
. path
. join ( foldername
, subdir
), 0700 )
81 # Invalidate the cache
85 def deletefolder ( self
, foldername
):
86 self
. ui
. warn ( "NOT YET IMPLEMENTED: DELETE FOLDER %s " % foldername
)
88 def getfolder ( self
, foldername
):
89 return folder
. Maildir
. MaildirFolder ( self
. root
, foldername
,
90 self
. getsep (), self
, self
. accountname
)
92 def _getfolders_scandir ( self
, root
, extension
= None ):
93 self
. debug ( "_GETFOLDERS_SCANDIR STARTING. root = %s , extension = %s " \
95 # extension willl only be non-None when called recursively when
96 # getsep() returns '/'.
99 # Configure the full path to this repository -- "toppath"
101 if extension
== None :
104 toppath
= os
. path
. join ( root
, extension
)
106 self
. debug ( " toppath = %s " % toppath
)
108 # Iterate over directories in top.
109 for dirname
in os
. listdir ( toppath
) + [ '.' ]:
110 self
. debug ( " *** top of loop" )
111 self
. debug ( " dirname = %s " % dirname
)
112 if dirname
in [ 'cur' , 'new' , 'tmp' , 'offlineimap.uidvalidity' ]:
113 self
. debug ( " skipping this dir (Maildir special)" )
114 # Bypass special files.
116 fullname
= os
. path
. join ( toppath
, dirname
)
117 self
. debug ( " fullname = %s " % fullname
)
118 if not os
. path
. isdir ( fullname
):
119 self
. debug ( " skipping this entry (not a directory)" )
120 # Not a directory -- not a folder.
123 if extension
!= None :
124 foldername
= os
. path
. join ( extension
, dirname
)
125 if ( os
. path
. isdir ( os
. path
. join ( fullname
, 'cur' )) and
126 os
. path
. isdir ( os
. path
. join ( fullname
, 'new' )) and
127 os
. path
. isdir ( os
. path
. join ( fullname
, 'tmp' ))):
128 # This directory has maildir stuff -- process
129 self
. debug ( " This is a maildir folder." )
131 self
. debug ( " foldername = %s " % foldername
)
133 retval
. append ( folder
. Maildir
. MaildirFolder ( self
. root
, foldername
,
134 self
. getsep (), self
, self
. accountname
))
135 if self
. getsep () == '/' and dirname
!= '.' :
136 # Check sub-directories for folders.
137 retval
. extend ( self
._ getfolders
_ scandir
( root
, foldername
))
138 self
. debug ( "_GETFOLDERS_SCANDIR RETURNING %s " % \
139 repr ([ x
. getname () for x
in retval
]))
142 def getfolders ( self
):
143 if self
. folders
== None :
144 self
. folders
= self
._ getfolders
_ scandir
( self
. root
)