Mercurial > p > roundup > code
annotate scripts/imapServer.py @ 4531:ddff9669361b
Fix matching of incoming email addresses to the alternate_addresses field...
...of a user -- this would match substrings, e.g. if the user has
discuss-support@example.com as an alternate email and an incoming mail
is addressed to support@example.com this would (wrongly) match.
Note: I *think* I've seen this discussed somewhere but couldn't find it,
neither in the tracker nor in recent discussions on the mailinglists.
So if someone remembers an issue which now should be closed, please
tell me :-)
| author | Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net> |
|---|---|
| date | Wed, 24 Aug 2011 14:43:52 +0000 |
| parents | 67bef70ab9b9 |
| children | 939dce88cfc2 |
| rev | line source |
|---|---|
| 3203 | 1 #!/usr/bin/env python |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
2 """\ |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
3 This script is a wrapper around the mailgw.py script that exists in roundup. |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
4 It runs as service instead of running as a one-time shot. |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
5 It also connects to a secure IMAP server. The main reasons for this script are: |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
6 |
| 3203 | 7 1) The roundup-mailgw script isn't designed to run as a server. It |
| 8 expects that you either run it by hand, and enter the password each | |
| 9 time, or you supply the password on the command line. I prefer to | |
| 10 run a server that I initialize with the password, and then it just | |
| 11 runs. I don't want to have to pass it on the command line, so | |
| 12 running through crontab isn't a possibility. (This wouldn't be a | |
| 13 problem on a local machine running through a mailspool.) | |
| 14 2) mailgw.py somehow screws up SSL support so IMAP4_SSL doesn't work. So | |
| 15 hopefully running that work outside of the mailgw will allow it to work. | |
| 16 3) I wanted to be able to check multiple projects at the same time. | |
| 17 roundup-mailgw is only for 1 mailbox and 1 project. | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
18 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
19 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
20 *TODO*: |
| 3203 | 21 For the first round, the program spawns a new roundup-mailgw for |
| 22 each imap message that it finds and pipes the result in. In the | |
| 23 future it might be more practical to actually include the roundup | |
| 24 files and run the appropriate commands using python. | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
25 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
26 *TODO*: |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
27 Look into supporting a logfile instead of using 2>/logfile |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
28 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
29 *TODO*: |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
30 Add an option for changing the uid/gid of the running process. |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
31 """ |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
32 |
| 3203 | 33 import getpass |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
34 import logging |
| 3203 | 35 import imaplib |
| 36 import optparse | |
| 37 import os | |
| 38 import re | |
| 39 import time | |
| 40 | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
41 logging.basicConfig() |
|
4421
67bef70ab9b9
- more logger fixes, sorry for the noise.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents:
3609
diff
changeset
|
42 log = logging.getLogger('roundup.IMAPServer') |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
43 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
44 version = '0.1.2' |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
45 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
46 class RoundupMailbox: |
| 3203 | 47 """This contains all the info about each mailbox. |
| 48 Username, Password, server, security, roundup database | |
| 49 """ | |
| 50 def __init__(self, dbhome='', username=None, password=None, mailbox=None | |
| 51 , server=None, protocol='imaps'): | |
| 52 self.username = username | |
| 53 self.password = password | |
| 54 self.mailbox = mailbox | |
| 55 self.server = server | |
| 56 self.protocol = protocol | |
| 57 self.dbhome = dbhome | |
| 58 | |
| 59 try: | |
| 60 if not self.dbhome: | |
| 61 self.dbhome = raw_input('Tracker home: ') | |
| 62 if not os.path.exists(self.dbhome): | |
| 63 raise ValueError, 'Invalid home address: ' \ | |
| 64 'directory "%s" does not exist.' % self.dbhome | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
65 |
| 3203 | 66 if not self.server: |
| 67 self.server = raw_input('Server: ') | |
| 68 if not self.server: | |
| 69 raise ValueError, 'No Servername supplied' | |
| 70 protocol = raw_input('protocol [imaps]? ') | |
| 71 self.protocol = protocol | |
| 72 | |
| 73 if not self.username: | |
| 74 self.username = raw_input('Username: ') | |
| 75 if not self.username: | |
| 76 raise ValueError, 'Invalid Username' | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
77 |
| 3203 | 78 if not self.password: |
| 79 print 'For server %s, user %s' % (self.server, self.username) | |
| 80 self.password = getpass.getpass() | |
| 81 # password can be empty because it could be superceeded | |
| 82 # by a later entry | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
83 |
| 3203 | 84 #if self.mailbox is None: |
| 85 # self.mailbox = raw_input('Mailbox [INBOX]: ') | |
| 86 # # We allow an empty mailbox because that will | |
| 87 # # select the INBOX, whatever it is called | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
88 |
| 3203 | 89 except (KeyboardInterrupt, EOFError): |
| 90 raise ValueError, 'Canceled by User' | |
| 91 | |
| 92 def __str__(self): | |
| 93 return 'Mailbox{ server:%(server)s, protocol:%(protocol)s, ' \ | |
| 94 'username:%(username)s, mailbox:%(mailbox)s, ' \ | |
| 95 'dbhome:%(dbhome)s }' % self.__dict__ | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
96 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
97 |
| 3203 | 98 # [als] class name is misleading. this is imap client, not imap server |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
99 class IMAPServer: |
| 3203 | 100 |
| 101 """IMAP mail gatherer. | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
102 |
| 3203 | 103 This class runs as a server process. It is configured with a list of |
| 104 mailboxes to connect to, along with the roundup database directories | |
| 105 that correspond with each email address. It then connects to each | |
| 106 mailbox at a specified interval, and if there are new messages it | |
| 107 reads them, and sends the result to the roundup.mailgw. | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
108 |
| 3203 | 109 *TODO*: |
| 110 Try to be smart about how you access the mailboxes so that you can | |
| 111 connect once, and access multiple mailboxes and possibly multiple | |
| 112 usernames. | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
113 |
| 3203 | 114 *NOTE*: |
| 115 This assumes that if you are using the same user on the same | |
| 116 server, you are using the same password. (the last one supplied is | |
| 117 used.) Empty passwords are ignored. Only the last protocol | |
| 118 supplied is used. | |
| 119 """ | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
120 |
| 3203 | 121 def __init__(self, pidfile=None, delay=5, daemon=False): |
| 122 #This is sorted by servername, then username, then mailboxes | |
| 123 self.mailboxes = {} | |
| 124 self.delay = float(delay) | |
| 125 self.pidfile = pidfile | |
| 126 self.daemon = daemon | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
127 |
| 3203 | 128 def setDelay(self, delay): |
| 129 self.delay = delay | |
| 130 | |
| 131 def addMailbox(self, mailbox): | |
| 132 """ The linkage is as follows: | |
| 133 servers -- users - mailbox:dbhome | |
| 134 So there can be multiple servers, each with multiple users. | |
| 135 Each username can be associated with multiple mailboxes. | |
| 136 each mailbox is associated with 1 database home | |
| 137 """ | |
| 138 log.info('Adding mailbox %s', mailbox) | |
| 139 if not self.mailboxes.has_key(mailbox.server): | |
| 140 self.mailboxes[mailbox.server] = {'protocol':'imaps', 'users':{}} | |
| 141 server = self.mailboxes[mailbox.server] | |
| 142 if mailbox.protocol: | |
| 143 server['protocol'] = mailbox.protocol | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
144 |
| 3203 | 145 if not server['users'].has_key(mailbox.username): |
| 146 server['users'][mailbox.username] = {'password':'', 'mailboxes':{}} | |
| 147 user = server['users'][mailbox.username] | |
| 148 if mailbox.password: | |
| 149 user['password'] = mailbox.password | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
150 |
| 3203 | 151 if user['mailboxes'].has_key(mailbox.mailbox): |
| 152 raise ValueError, 'Mailbox is already defined' | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
153 |
| 3203 | 154 user['mailboxes'][mailbox.mailbox] = mailbox.dbhome |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
155 |
| 3203 | 156 def _process(self, message, dbhome): |
| 157 """Actually process one of the email messages""" | |
| 158 child = os.popen('roundup-mailgw %s' % dbhome, 'wb') | |
| 159 child.write(message) | |
| 160 child.close() | |
| 161 #print message | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
162 |
| 3203 | 163 def _getMessages(self, serv, count, dbhome): |
| 164 """This assumes that you currently have a mailbox open, and want to | |
| 165 process all messages that are inside. | |
| 166 """ | |
| 167 for n in range(1, count+1): | |
| 168 (t, data) = serv.fetch(n, '(RFC822)') | |
| 169 if t == 'OK': | |
| 170 self._process(data[0][1], dbhome) | |
| 171 serv.store(n, '+FLAGS', r'(\Deleted)') | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
172 |
| 3203 | 173 def checkBoxes(self): |
| 174 """This actually goes out and does all the checking. | |
| 175 Returns False if there were any errors, otherwise returns true. | |
| 176 """ | |
| 177 noErrors = True | |
| 178 for server in self.mailboxes: | |
| 179 log.info('Connecting to server: %s', server) | |
| 180 s_vals = self.mailboxes[server] | |
| 181 | |
| 182 try: | |
| 183 for user in s_vals['users']: | |
| 184 u_vals = s_vals['users'][user] | |
| 185 # TODO: As near as I can tell, you can only | |
| 186 # login with 1 username for each connection to a server. | |
| 187 protocol = s_vals['protocol'].lower() | |
| 188 if protocol == 'imaps': | |
| 189 serv = imaplib.IMAP4_SSL(server) | |
| 190 elif protocol == 'imap': | |
| 191 serv = imaplib.IMAP4(server) | |
| 192 else: | |
| 193 raise ValueError, 'Unknown protocol %s' % protocol | |
| 194 | |
| 195 password = u_vals['password'] | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
196 |
| 3203 | 197 try: |
| 198 log.info('Connecting as user: %s', user) | |
| 199 serv.login(user, password) | |
| 200 | |
| 201 for mbox in u_vals['mailboxes']: | |
| 202 dbhome = u_vals['mailboxes'][mbox] | |
| 203 log.info('Using mailbox: %s, home: %s', | |
| 204 mbox, dbhome) | |
| 205 #access a specific mailbox | |
| 206 if mbox: | |
| 207 (t, data) = serv.select(mbox) | |
| 208 else: | |
| 209 # Select the default mailbox (INBOX) | |
| 210 (t, data) = serv.select() | |
| 211 try: | |
| 212 nMessages = int(data[0]) | |
| 213 except ValueError: | |
| 214 nMessages = 0 | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
215 |
| 3203 | 216 log.info('Found %s messages', nMessages) |
| 217 | |
| 218 if nMessages: | |
| 219 self._getMessages(serv, nMessages, dbhome) | |
| 220 serv.expunge() | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
221 |
| 3203 | 222 # We are done with this mailbox |
| 223 serv.close() | |
| 224 except: | |
| 225 log.exception('Exception with server %s user %s', | |
| 226 server, user) | |
| 227 noErrors = False | |
| 228 | |
| 229 serv.logout() | |
| 230 serv.shutdown() | |
| 231 del serv | |
| 232 except: | |
| 233 log.exception('Exception while connecting to %s', server) | |
| 234 noErrors = False | |
| 235 return noErrors | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
236 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
237 |
| 3203 | 238 def makeDaemon(self): |
| 239 """Turn this process into a daemon. | |
| 240 | |
| 241 - make our parent PID 1 | |
| 242 | |
| 243 Write our new PID to the pidfile. | |
| 244 | |
| 245 From A.M. Kuuchling (possibly originally Greg Ward) with | |
| 246 modification from Oren Tirosh, and finally a small mod from me. | |
| 247 Originally taken from roundup.scripts.roundup_server.py | |
| 248 """ | |
| 249 log.info('Running as Daemon') | |
| 250 # Fork once | |
| 251 if os.fork() != 0: | |
| 252 os._exit(0) | |
| 253 | |
| 254 # Create new session | |
| 255 os.setsid() | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
256 |
| 3203 | 257 # Second fork to force PPID=1 |
| 258 pid = os.fork() | |
| 259 if pid: | |
| 260 if self.pidfile: | |
| 261 pidfile = open(self.pidfile, 'w') | |
| 262 pidfile.write(str(pid)) | |
| 263 pidfile.close() | |
| 264 os._exit(0) | |
| 265 | |
| 266 def run(self): | |
| 267 """Run email gathering daemon. | |
| 268 | |
| 269 This spawns itself as a daemon, and then runs continually, just | |
| 270 sleeping inbetween checks. It is recommended that you run | |
| 271 checkBoxes once first before you select run. That way you can | |
| 272 know if there were any failures. | |
| 273 """ | |
| 274 if self.daemon: | |
| 275 self.makeDaemon() | |
| 276 while True: | |
| 277 | |
| 278 time.sleep(self.delay * 60.0) | |
| 279 log.info('Time: %s', time.strftime('%Y-%m-%d %H:%M:%S')) | |
| 280 self.checkBoxes() | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
281 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
282 def getItems(s): |
| 3203 | 283 """Parse a string looking for userame@server""" |
| 284 myRE = re.compile( | |
| 285 r'((?P<protocol>[^:]+)://)?'#You can supply a protocol if you like | |
| 286 r'(' #The username part is optional | |
| 287 r'(?P<username>[^:]+)' #You can supply the password as | |
| 288 r'(:(?P<password>.+))?' #username:password@server | |
| 289 r'@)?' | |
| 290 r'(?P<server>[^/]+)' | |
| 291 r'(/(?P<mailbox>.+))?$' | |
| 292 ) | |
| 293 m = myRE.match(s) | |
| 294 if m: | |
| 295 return m.groupdict() | |
| 296 else: | |
| 297 return None | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
298 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
299 def main(): |
| 3203 | 300 """This is what is called if run at the prompt""" |
| 301 parser = optparse.OptionParser( | |
| 302 version=('%prog ' + version), | |
| 303 usage="""usage: %prog [options] (home server)... | |
| 304 | |
| 305 So each entry has a home, and then the server configuration. Home is just | |
| 306 a path to the roundup issue tracker. The server is something of the form: | |
| 307 | |
| 308 imaps://user:password@server/mailbox | |
| 309 | |
| 310 If you don't supply the protocol, imaps is assumed. Without user or | |
| 311 password, you will be prompted for them. The server must be supplied. | |
| 312 Without mailbox the INBOX is used. | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
313 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
314 Examples: |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
315 %prog /home/roundup/trackers/test imaps://test@imap.example.com/test |
| 3203 | 316 %prog /home/roundup/trackers/test imap.example.com \ |
| 317 /home/roundup/trackers/test2 imap.example.com/test2 | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
318 """ |
| 3203 | 319 ) |
| 320 parser.add_option('-d', '--delay', dest='delay', type='float', | |
| 321 metavar='<sec>', default=5, | |
| 322 help="Set the delay between checks in minutes. (default 5)" | |
| 323 ) | |
| 324 parser.add_option('-p', '--pid-file', dest='pidfile', | |
| 325 metavar='<file>', default=None, | |
| 326 help="The pid of the server process will be written to <file>" | |
| 327 ) | |
| 328 parser.add_option('-n', '--no-daemon', dest='daemon', | |
| 329 action='store_false', default=True, | |
| 330 help="Do not fork into the background after running the first check." | |
| 331 ) | |
| 332 parser.add_option('-v', '--verbose', dest='verbose', | |
| 333 action='store_const', const=logging.INFO, | |
| 334 help="Be more verbose in letting you know what is going on." | |
| 335 " Enables informational messages." | |
| 336 ) | |
| 337 parser.add_option('-V', '--very-verbose', dest='verbose', | |
| 338 action='store_const', const=logging.DEBUG, | |
| 339 help="Be very verbose in letting you know what is going on." | |
| 340 " Enables debugging messages." | |
| 341 ) | |
| 342 parser.add_option('-q', '--quiet', dest='verbose', | |
| 343 action='store_const', const=logging.ERROR, | |
| 344 help="Be less verbose. Ignores warnings, only prints errors." | |
| 345 ) | |
| 346 parser.add_option('-Q', '--very-quiet', dest='verbose', | |
| 347 action='store_const', const=logging.CRITICAL, | |
| 348 help="Be much less verbose. Ignores warnings and errors." | |
| 349 " Only print CRITICAL messages." | |
| 350 ) | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
351 |
| 3203 | 352 (opts, args) = parser.parse_args() |
| 353 if (len(args) == 0) or (len(args) % 2 == 1): | |
| 354 parser.error('Invalid number of arguments. ' | |
| 355 'Each site needs a home and a server.') | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
356 |
| 3203 | 357 log.setLevel(opts.verbose) |
| 358 myServer = IMAPServer(delay=opts.delay, pidfile=opts.pidfile, | |
| 359 daemon=opts.daemon) | |
| 360 for i in range(0,len(args),2): | |
| 361 home = args[i] | |
| 362 server = args[i+1] | |
| 363 if not os.path.exists(home): | |
| 364 parser.error('Home: "%s" does not exist' % home) | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
365 |
| 3203 | 366 info = getItems(server) |
| 367 if not info: | |
| 368 parser.error('Invalid server string: "%s"' % server) | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
369 |
| 3203 | 370 myServer.addMailbox( |
| 371 RoundupMailbox(dbhome=home, mailbox=info['mailbox'] | |
| 372 , username=info['username'], password=info['password'] | |
| 373 , server=info['server'], protocol=info['protocol'] | |
| 374 ) | |
| 375 ) | |
| 376 | |
| 377 if myServer.checkBoxes(): | |
| 378 myServer.run() | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
379 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
380 if __name__ == '__main__': |
| 3203 | 381 main() |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
382 |
| 3203 | 383 # vim: et ft=python si sts=4 sw=4 |
