]>
code.delx.au - offlineimap/blob - offlineimap/init.py
1 # OfflineIMAP initialization code
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
20 from offlineimap
import imapserver
, repository
, folder
, mbnames
, threadutil
, version
, syncmaster
, accounts
21 from offlineimap
. localeval
import LocalEval
22 from offlineimap
. threadutil
import InstanceLimitedThread
, ExitNotifyThread
23 from offlineimap
. ui
import UIBase
24 import re
, os
, os
. path
, offlineimap
, sys
25 from offlineimap
. CustomConfig
import CustomConfigParser
26 from threading
import *
27 import threading
, socket
28 from getopt
import getopt
39 global lockfd
, hasfcntl
42 lockfd
= open ( config
. getmetadatadir () + "/lock" , "w" )
44 fcntl
. flock ( lockfd
, fcntl
. LOCK_EX | fcntl
. LOCK_NB
)
49 def startup ( versionno
):
50 assert versionno
== version
. versionstr
, "Revision of main program ( %s ) does not match that of library ( %s ). Please double-check your PYTHONPATH and installation locations." % ( versionno
, version
. versionstr
)
52 if '--help' in sys
. argv
[ 1 :]:
53 sys
. stdout
. write ( version
. getcmdhelp () + " \n " )
56 for optlist
in getopt ( sys
. argv
[ 1 :], 'P:1oqa:c:d:l:u:hk:f:' )[ 0 ]:
57 options
[ optlist
[ 0 ]] = optlist
[ 1 ]
59 if options
. has_key ( '-h' ):
60 sys
. stdout
. write ( version
. getcmdhelp ())
61 sys
. stdout
. write ( " \n " )
63 configfilename
= os
. path
. expanduser ( "~/.offlineimaprc" )
64 if options
. has_key ( '-c' ):
65 configfilename
= options
[ '-c' ]
66 if options
. has_key ( '-P' ):
67 if not options
. has_key ( '-1' ):
68 sys
. stderr
. write ( "FATAL: profile mode REQUIRES -1 \n " )
70 profiledir
= options
[ '-P' ]
72 threadutil
. setprofiledir ( profiledir
)
73 sys
. stderr
. write ( "WARNING: profile mode engaged; \n Potentially large data will be created in " + profiledir
+ " \n " )
75 config
= CustomConfigParser ()
76 if not os
. path
. exists ( configfilename
):
77 sys
. stderr
. write ( " *** Config file %s does not exist; aborting! \n " % configfilename
)
80 config
. read ( configfilename
)
82 # override config values with option '-k'
83 for option
in options
. keys ():
85 ( key
, value
) = options
[ '-k' ]. split ( '=' , 1 )
87 ( secname
, key
) = key
. split ( ':' , 1 )
88 section
= secname
. replace ( "_" , " " )
91 config
. set ( section
, key
, value
)
93 ui
= offlineimap
. ui
. detector
. findUI ( config
, options
. get ( '-u' ))
94 UIBase
. setglobalui ( ui
)
96 if options
. has_key ( '-l' ):
97 ui
. setlogfd ( open ( options
[ '-l' ], 'wt' ))
101 if options
. has_key ( '-d' ):
102 for debugtype
in options
[ '-d' ]. split ( ',' ):
103 ui
. add_debug ( debugtype
. strip ())
104 if debugtype
== 'imap' :
106 if debugtype
== 'thread' :
107 threading
._ VERBOSE
= 1
109 if options
. has_key ( '-o' ):
110 # FIXME: maybe need a better
111 for section
in accounts
. getaccountlist ( config
):
112 config
. remove_option ( 'Account ' + section
, "autorefresh" )
114 if options
. has_key ( '-q' ):
115 for section
in accounts
. getaccountlist ( config
):
116 config
. set ( 'Account ' + section
, "quick" , '-1' )
118 if options
. has_key ( '-f' ):
119 foldernames
= options
[ '-f' ]. replace ( " " , "" ). split ( "," )
120 folderfilter
= "lambda f: f in %s " % foldernames
121 folderincludes
= "[]"
122 for accountname
in accounts
. getaccountlist ( config
):
123 account_section
= 'Account ' + accountname
124 remote_repo_section
= 'Repository ' + \
125 config
. get ( account_section
, 'remoterepository' )
126 local_repo_section
= 'Repository ' + \
127 config
. get ( account_section
, 'localrepository' )
128 for section
in [ remote_repo_section
, local_repo_section
]:
129 config
. set ( section
, "folderfilter" , folderfilter
)
130 config
. set ( section
, "folderincludes" , folderincludes
)
135 pidfd
= open ( config
. getmetadatadir () + "/pid" , "w" )
136 pidfd
. write ( str ( os
. getpid ()) + " \n " )
142 if options
. has_key ( '-l' ):
143 sys
. stderr
= ui
. logfile
145 socktimeout
= config
. getdefaultint ( "general" , "socktimeout" , 0 )
147 socket
. setdefaulttimeout ( socktimeout
)
149 activeaccounts
= config
. get ( "general" , "accounts" )
150 if options
. has_key ( '-a' ):
151 activeaccounts
= options
[ '-a' ]
152 activeaccounts
= activeaccounts
. replace ( " " , "" )
153 activeaccounts
= activeaccounts
. split ( "," )
154 allaccounts
= accounts
. AccountHashGenerator ( config
)
157 for account
in activeaccounts
:
158 if account
not in allaccounts
:
159 if len ( allaccounts
) == 0 :
160 errormsg
= 'The account " %s " does not exist because no accounts are defined!' % account
162 errormsg
= 'The account " %s " does not exist. Valid accounts are:' % account
163 for name
in allaccounts
. keys ():
164 errormsg
+= ' \n %s ' % name
165 ui
. terminate ( 1 , errortitle
= 'Unknown Account " %s "' % account
, errormsg
= errormsg
)
166 syncaccounts
[ account
] = allaccounts
[ account
]
172 if options
. has_key ( '-1' ):
173 threadutil
. initInstanceLimit ( "ACCOUNTLIMIT" , 1 )
175 threadutil
. initInstanceLimit ( "ACCOUNTLIMIT" ,
176 config
. getdefaultint ( "general" , "maxsyncaccounts" , 1 ))
178 for reposname
in config
. getsectionlist ( 'Repository' ):
179 for instancename
in [ "FOLDER_" + reposname
,
180 "MSGCOPY_" + reposname
]:
181 if options
. has_key ( '-1' ):
182 threadutil
. initInstanceLimit ( instancename
, 1 )
184 threadutil
. initInstanceLimit ( instancename
,
185 config
. getdefaultint ( 'Repository ' + reposname
, "maxconnections" , 1 ))
187 threadutil
. initexitnotify ()
188 t
= ExitNotifyThread ( target
= syncmaster
. syncitall
,
190 kwargs
= { 'accounts' : syncaccounts
,
198 threadutil
. exitnotifymonitorloop ( threadutil
. threadexited
)
202 ui
. mainException () # Also expected to terminate.