]> code.delx.au - offlineimap/blob - offlineimap/head/offlineimap/init.py
/offlineimap/head: changeset 478
[offlineimap] / offlineimap / head / offlineimap / init.py
1 # OfflineIMAP initialization code
2 # Copyright (C) 2002, 2003 John Goerzen
3 # <jgoerzen@complete.org>
4 #
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.
9 #
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.
14 #
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
18
19 from offlineimap import imaplib, imapserver, repository, folder, mbnames, threadutil, version, syncmaster, accounts
20 from offlineimap.localeval import LocalEval
21 from offlineimap.threadutil import InstanceLimitedThread, ExitNotifyThread
22 from offlineimap.ui import UIBase
23 import re, os, os.path, offlineimap, sys, fcntl
24 from offlineimap.CustomConfig import CustomConfigParser
25 from threading import *
26 import threading
27 from getopt import getopt
28
29 lockfd = None
30
31 def lock(config, ui):
32 global lockfd
33 lockfd = open(config.getmetadatadir() + "/lock", "w")
34 try:
35 fcntl.flock(lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
36 except IOError:
37 ui.locked()
38 ui.terminate(1)
39
40 def startup(versionno):
41 assert versionno == version.versionstr, "Revision of main program (%d) does not match that of library (%d). Please double-check your PYTHONPATH and installation locations." % (revno, version.revno)
42 options = {}
43 if '--help' in sys.argv[1:]:
44 sys.stdout.write(version.cmdhelp + "\n")
45 sys.exit(0)
46
47 for optlist in getopt(sys.argv[1:], 'P:1oa:c:d:u:h')[0]:
48 options[optlist[0]] = optlist[1]
49
50 if '-h' in options:
51 sys.stdout.write(version.cmdhelp)
52 sys.stdout.write("\n")
53 sys.exit(0)
54 configfilename = os.path.expanduser("~/.offlineimaprc")
55 if '-c' in options:
56 configfilename = options['-c']
57 if '-P' in options:
58 if not '-1' in options:
59 sys.stderr.write("FATAL: profile mode REQUIRES -1\n")
60 sys.exit(100)
61 profiledir = options['-P']
62 os.mkdir(profiledir)
63 threadutil.setprofiledir(profiledir)
64 sys.stderr.write("WARNING: profile mode engaged;\nPotentially large data will be created in " + profiledir + "\n")
65
66 config = CustomConfigParser()
67 if not os.path.exists(configfilename):
68 sys.stderr.write(" *** Config file %s does not exist; aborting!\n" % configfilename)
69 sys.exit(1)
70
71 config.read(configfilename)
72
73 ui = offlineimap.ui.detector.findUI(config, options.get('-u'))
74 ui.init_banner()
75 UIBase.setglobalui(ui)
76
77 if '-d' in options:
78 for debugtype in options['-d'].split(','):
79 ui.add_debug(debugtype.strip())
80 if debugtype == 'imap':
81 imaplib.Debug = 5
82 if debugtype == 'thread':
83 threading._VERBOSE = 1
84
85 if '-l' in options:
86 ui.setlogfd(open(options['-l'], 'wt'))
87
88 if '-o' in options:
89 # FIXME: maybe need a better
90 for section in accounts.getaccountlist(config):
91 config.remove_option('Account ' + section, "autorefresh")
92
93 lock(config, ui)
94
95 activeaccounts = config.get("general", "accounts")
96 if '-a' in options:
97 activeaccounts = options['-a']
98 activeaccounts = activeaccounts.replace(" ", "")
99 activeaccounts = activeaccounts.split(",")
100 allaccounts = accounts.AccountHashGenerator(config)
101
102 syncaccounts = {}
103 for account in activeaccounts:
104 syncaccounts[account] = allaccounts[account]
105
106 server = None
107 remoterepos = None
108 localrepos = None
109
110 if '-1' in options:
111 threadutil.initInstanceLimit("ACCOUNTLIMIT", 1)
112 else:
113 threadutil.initInstanceLimit("ACCOUNTLIMIT",
114 config.getdefaultint("general", "maxsyncaccounts", 1))
115
116 for reposname in config.getsectionlist('Repository'):
117 for instancename in ["FOLDER_" + reposname,
118 "MSGCOPY_" + reposname]:
119 if '-1' in options:
120 threadutil.initInstanceLimit(instancename, 1)
121 else:
122 threadutil.initInstanceLimit(instancename,
123 config.getdefaultint('Repository ' + reposname, "maxconnections", 1))
124
125 threadutil.initexitnotify()
126 t = ExitNotifyThread(target=syncmaster.syncitall,
127 name='Sync Runner',
128 kwargs = {'accounts': syncaccounts,
129 'config': config})
130 t.setDaemon(1)
131 t.start()
132 try:
133 threadutil.exitnotifymonitorloop(threadutil.threadexited)
134 except SystemExit:
135 raise
136 except:
137 ui.mainException() # Also expected to terminate.
138
139