Mercurial > p > roundup > code
annotate scripts/imapServer.py @ 8528:fed0f839c260
fix: replace except: with except Exception: (by haosenwang1018@github)
Remove bare 'except:' statements replace with 'except Exception'.
In roundup_xmlrpc_server.py I changed Exception to BaseException so
the database gets closed on signals as well. The rest of the changes
do not look like they affect data integrity and are commited as
supplied.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Thu, 26 Feb 2026 09:46:02 -0500 |
| parents | b5fffd2a64af |
| children | 9c3ec0a5c7fc |
| rev | line source |
|---|---|
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
1 #!/usr/bin/env python3 |
|
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 |
|
5376
64b05e24dbd8
Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5141
diff
changeset
|
33 from __future__ import print_function |
| 3203 | 34 import getpass |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
35 import logging |
| 3203 | 36 import imaplib |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
37 import argparse |
| 3203 | 38 import os |
| 39 import re | |
| 40 import time | |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
41 import sys |
| 3203 | 42 |
|
5401
4cf48ff01e04
Python 3 preparation: replace raw_input uses.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5381
diff
changeset
|
43 from roundup.anypy.my_input import my_input |
|
4cf48ff01e04
Python 3 preparation: replace raw_input uses.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5381
diff
changeset
|
44 |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
45 logging.basicConfig() |
|
4421
67bef70ab9b9
- more logger fixes, sorry for the noise.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents:
3609
diff
changeset
|
46 log = logging.getLogger('roundup.IMAPServer') |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
47 |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
48 version = '0.1.3' |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
49 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
50 class RoundupMailbox: |
| 3203 | 51 """This contains all the info about each mailbox. |
| 52 Username, Password, server, security, roundup database | |
| 53 """ | |
| 54 def __init__(self, dbhome='', username=None, password=None, mailbox=None | |
| 55 , server=None, protocol='imaps'): | |
| 56 self.username = username | |
| 57 self.password = password | |
| 58 self.mailbox = mailbox | |
| 59 self.server = server | |
| 60 self.protocol = protocol | |
| 61 self.dbhome = dbhome | |
| 62 | |
| 63 try: | |
| 64 if not self.dbhome: | |
|
5401
4cf48ff01e04
Python 3 preparation: replace raw_input uses.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5381
diff
changeset
|
65 self.dbhome = my_input('Tracker home: ') |
| 3203 | 66 if not os.path.exists(self.dbhome): |
|
5378
35ea9b1efc14
Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5376
diff
changeset
|
67 raise ValueError('Invalid home address: ' \ |
|
35ea9b1efc14
Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5376
diff
changeset
|
68 '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
|
69 |
| 3203 | 70 if not self.server: |
|
5401
4cf48ff01e04
Python 3 preparation: replace raw_input uses.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5381
diff
changeset
|
71 self.server = my_input('Server: ') |
| 3203 | 72 if not self.server: |
|
5378
35ea9b1efc14
Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5376
diff
changeset
|
73 raise ValueError('No Servername supplied') |
|
5401
4cf48ff01e04
Python 3 preparation: replace raw_input uses.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5381
diff
changeset
|
74 protocol = my_input('protocol [imaps]? ') |
| 3203 | 75 self.protocol = protocol |
| 76 | |
| 77 if not self.username: | |
|
5401
4cf48ff01e04
Python 3 preparation: replace raw_input uses.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5381
diff
changeset
|
78 self.username = my_input('Username: ') |
| 3203 | 79 if not self.username: |
|
5378
35ea9b1efc14
Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5376
diff
changeset
|
80 raise ValueError('Invalid Username') |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
81 |
| 3203 | 82 if not self.password: |
|
5376
64b05e24dbd8
Python 3 preparation: convert print to a function.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5141
diff
changeset
|
83 print('For server %s, user %s' % (self.server, self.username)) |
| 3203 | 84 self.password = getpass.getpass() |
| 85 # password can be empty because it could be superceeded | |
| 86 # by a later entry | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
87 |
| 3203 | 88 #if self.mailbox is None: |
|
5401
4cf48ff01e04
Python 3 preparation: replace raw_input uses.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5381
diff
changeset
|
89 # self.mailbox = my_input('Mailbox [INBOX]: ') |
| 3203 | 90 # # We allow an empty mailbox because that will |
| 91 # # 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
|
92 |
| 3203 | 93 except (KeyboardInterrupt, EOFError): |
|
5378
35ea9b1efc14
Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5376
diff
changeset
|
94 raise ValueError('Canceled by User') |
| 3203 | 95 |
| 96 def __str__(self): | |
| 97 return 'Mailbox{ server:%(server)s, protocol:%(protocol)s, ' \ | |
| 98 'username:%(username)s, mailbox:%(mailbox)s, ' \ | |
| 99 'dbhome:%(dbhome)s }' % self.__dict__ | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
100 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
101 |
| 3203 | 102 # [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
|
103 class IMAPServer: |
| 3203 | 104 |
| 105 """IMAP mail gatherer. | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
106 |
| 3203 | 107 This class runs as a server process. It is configured with a list of |
| 108 mailboxes to connect to, along with the roundup database directories | |
| 109 that correspond with each email address. It then connects to each | |
| 110 mailbox at a specified interval, and if there are new messages it | |
| 111 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
|
112 |
| 3203 | 113 *TODO*: |
| 114 Try to be smart about how you access the mailboxes so that you can | |
| 115 connect once, and access multiple mailboxes and possibly multiple | |
| 116 usernames. | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
117 |
| 3203 | 118 *NOTE*: |
| 119 This assumes that if you are using the same user on the same | |
| 120 server, you are using the same password. (the last one supplied is | |
| 121 used.) Empty passwords are ignored. Only the last protocol | |
| 122 supplied is used. | |
| 123 """ | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
124 |
| 3203 | 125 def __init__(self, pidfile=None, delay=5, daemon=False): |
| 126 #This is sorted by servername, then username, then mailboxes | |
| 127 self.mailboxes = {} | |
| 128 self.delay = float(delay) | |
| 129 self.pidfile = pidfile | |
| 130 self.daemon = daemon | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
131 |
| 3203 | 132 def setDelay(self, delay): |
| 133 self.delay = delay | |
| 134 | |
| 135 def addMailbox(self, mailbox): | |
| 136 """ The linkage is as follows: | |
| 137 servers -- users - mailbox:dbhome | |
| 138 So there can be multiple servers, each with multiple users. | |
| 139 Each username can be associated with multiple mailboxes. | |
| 140 each mailbox is associated with 1 database home | |
| 141 """ | |
| 142 log.info('Adding mailbox %s', mailbox) | |
|
5381
0942fe89e82e
Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents:
5378
diff
changeset
|
143 if mailbox.server not in self.mailboxes: |
| 3203 | 144 self.mailboxes[mailbox.server] = {'protocol':'imaps', 'users':{}} |
| 145 server = self.mailboxes[mailbox.server] | |
| 146 if mailbox.protocol: | |
| 147 server['protocol'] = mailbox.protocol | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
148 |
|
5381
0942fe89e82e
Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents:
5378
diff
changeset
|
149 if mailbox.username not in server['users']: |
| 3203 | 150 server['users'][mailbox.username] = {'password':'', 'mailboxes':{}} |
| 151 user = server['users'][mailbox.username] | |
| 152 if mailbox.password: | |
| 153 user['password'] = mailbox.password | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
154 |
|
5381
0942fe89e82e
Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents:
5378
diff
changeset
|
155 if mailbox.mailbox in user['mailboxes']: |
|
5378
35ea9b1efc14
Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5376
diff
changeset
|
156 raise ValueError('Mailbox is already defined') |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
157 |
| 3203 | 158 user['mailboxes'][mailbox.mailbox] = mailbox.dbhome |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
159 |
| 3203 | 160 def _process(self, message, dbhome): |
| 161 """Actually process one of the email messages""" | |
| 162 child = os.popen('roundup-mailgw %s' % dbhome, 'wb') | |
| 163 child.write(message) | |
| 164 child.close() | |
| 165 #print message | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
166 |
| 3203 | 167 def _getMessages(self, serv, count, dbhome): |
| 168 """This assumes that you currently have a mailbox open, and want to | |
| 169 process all messages that are inside. | |
| 170 """ | |
| 171 for n in range(1, count+1): | |
| 172 (t, data) = serv.fetch(n, '(RFC822)') | |
| 173 if t == 'OK': | |
| 174 self._process(data[0][1], dbhome) | |
| 175 serv.store(n, '+FLAGS', r'(\Deleted)') | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
176 |
| 3203 | 177 def checkBoxes(self): |
| 178 """This actually goes out and does all the checking. | |
| 179 Returns False if there were any errors, otherwise returns true. | |
| 180 """ | |
| 181 noErrors = True | |
| 182 for server in self.mailboxes: | |
| 183 log.info('Connecting to server: %s', server) | |
| 184 s_vals = self.mailboxes[server] | |
| 185 | |
| 186 try: | |
| 187 for user in s_vals['users']: | |
| 188 u_vals = s_vals['users'][user] | |
| 189 # TODO: As near as I can tell, you can only | |
| 190 # login with 1 username for each connection to a server. | |
| 191 protocol = s_vals['protocol'].lower() | |
| 192 if protocol == 'imaps': | |
| 193 serv = imaplib.IMAP4_SSL(server) | |
| 194 elif protocol == 'imap': | |
| 195 serv = imaplib.IMAP4(server) | |
| 196 else: | |
|
5378
35ea9b1efc14
Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5376
diff
changeset
|
197 raise ValueError('Unknown protocol %s' % protocol) |
| 3203 | 198 |
| 199 password = u_vals['password'] | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
200 |
| 3203 | 201 try: |
| 202 log.info('Connecting as user: %s', user) | |
| 203 serv.login(user, password) | |
| 204 | |
| 205 for mbox in u_vals['mailboxes']: | |
| 206 dbhome = u_vals['mailboxes'][mbox] | |
| 207 log.info('Using mailbox: %s, home: %s', | |
| 208 mbox, dbhome) | |
| 209 #access a specific mailbox | |
| 210 if mbox: | |
| 211 (t, data) = serv.select(mbox) | |
| 212 else: | |
| 213 # Select the default mailbox (INBOX) | |
| 214 (t, data) = serv.select() | |
| 215 try: | |
| 216 nMessages = int(data[0]) | |
| 217 except ValueError: | |
| 218 nMessages = 0 | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
219 |
| 3203 | 220 log.info('Found %s messages', nMessages) |
| 221 | |
| 222 if nMessages: | |
| 223 self._getMessages(serv, nMessages, dbhome) | |
| 224 serv.expunge() | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
225 |
| 3203 | 226 # We are done with this mailbox |
| 227 serv.close() | |
|
8528
fed0f839c260
fix: replace except: with except Exception: (by haosenwang1018@github)
John Rouillard <rouilj@ieee.org>
parents:
7053
diff
changeset
|
228 except Exception: |
| 3203 | 229 log.exception('Exception with server %s user %s', |
| 230 server, user) | |
| 231 noErrors = False | |
| 232 | |
| 233 serv.logout() | |
| 234 serv.shutdown() | |
| 235 del serv | |
|
8528
fed0f839c260
fix: replace except: with except Exception: (by haosenwang1018@github)
John Rouillard <rouilj@ieee.org>
parents:
7053
diff
changeset
|
236 except Exception: |
| 3203 | 237 log.exception('Exception while connecting to %s', server) |
| 238 noErrors = False | |
| 239 return noErrors | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
240 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
241 |
| 3203 | 242 def makeDaemon(self): |
| 243 """Turn this process into a daemon. | |
| 244 | |
| 245 - make our parent PID 1 | |
| 246 | |
| 247 Write our new PID to the pidfile. | |
| 248 | |
| 249 From A.M. Kuuchling (possibly originally Greg Ward) with | |
| 250 modification from Oren Tirosh, and finally a small mod from me. | |
| 251 Originally taken from roundup.scripts.roundup_server.py | |
| 252 """ | |
| 253 log.info('Running as Daemon') | |
| 254 # Fork once | |
| 255 if os.fork() != 0: | |
| 256 os._exit(0) | |
| 257 | |
| 258 # Create new session | |
| 259 os.setsid() | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
260 |
| 3203 | 261 # Second fork to force PPID=1 |
| 262 pid = os.fork() | |
| 263 if pid: | |
| 264 if self.pidfile: | |
| 265 pidfile = open(self.pidfile, 'w') | |
| 266 pidfile.write(str(pid)) | |
| 267 pidfile.close() | |
| 268 os._exit(0) | |
| 269 | |
| 270 def run(self): | |
| 271 """Run email gathering daemon. | |
| 272 | |
| 273 This spawns itself as a daemon, and then runs continually, just | |
| 274 sleeping inbetween checks. It is recommended that you run | |
| 275 checkBoxes once first before you select run. That way you can | |
| 276 know if there were any failures. | |
| 277 """ | |
| 278 if self.daemon: | |
| 279 self.makeDaemon() | |
| 280 while True: | |
| 281 | |
| 282 time.sleep(self.delay * 60.0) | |
| 283 log.info('Time: %s', time.strftime('%Y-%m-%d %H:%M:%S')) | |
| 284 self.checkBoxes() | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
285 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
286 def getItems(s): |
| 3203 | 287 """Parse a string looking for userame@server""" |
| 288 myRE = re.compile( | |
| 289 r'((?P<protocol>[^:]+)://)?'#You can supply a protocol if you like | |
| 290 r'(' #The username part is optional | |
| 291 r'(?P<username>[^:]+)' #You can supply the password as | |
| 292 r'(:(?P<password>.+))?' #username:password@server | |
| 293 r'@)?' | |
| 294 r'(?P<server>[^/]+)' | |
| 295 r'(/(?P<mailbox>.+))?$' | |
| 296 ) | |
| 297 m = myRE.match(s) | |
| 298 if m: | |
| 299 return m.groupdict() | |
| 300 else: | |
| 301 return None | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
302 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
303 def main(): |
| 3203 | 304 """This is what is called if run at the prompt""" |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
305 parser = argparse.ArgumentParser( |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
306 formatter_class=argparse.RawDescriptionHelpFormatter, |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
307 epilog=""" |
| 3203 | 308 |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
309 The server takes pairs of home/server. |
| 3203 | 310 So each entry has a home, and then the server configuration. Home is just |
| 311 a path to the roundup issue tracker. The server is something of the form: | |
| 312 | |
| 313 imaps://user:password@server/mailbox | |
| 314 | |
| 315 If you don't supply the protocol, imaps is assumed. Without user or | |
| 316 password, you will be prompted for them. The server must be supplied. | |
| 317 Without mailbox the INBOX is used. | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
318 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
319 Examples: |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
320 %(prog)s /home/roundup/trackers/test imaps://test@imap.example.com/test |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
321 %(prog)s /home/roundup/trackers/test imap.example.com \\ |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
322 /home/roundup/trackers/test2 imap.example.com/test2 |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
323 """ % dict(prog = sys.argv [0]) |
| 3203 | 324 ) |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
325 parser.add_argument('args', nargs='*') |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
326 parser.add_argument('-d', '--delay', dest='delay', type=float, |
| 3203 | 327 metavar='<sec>', default=5, |
| 328 help="Set the delay between checks in minutes. (default 5)" | |
| 329 ) | |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
330 parser.add_argument('-p', '--pid-file', dest='pidfile', |
| 3203 | 331 metavar='<file>', default=None, |
| 332 help="The pid of the server process will be written to <file>" | |
| 333 ) | |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
334 parser.add_argument('-n', '--no-daemon', dest='daemon', |
| 3203 | 335 action='store_false', default=True, |
| 336 help="Do not fork into the background after running the first check." | |
| 337 ) | |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
338 parser.add_argument('--version', action="store_true", |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
339 help="Print version and exit") |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
340 parser.add_argument('-v', '--verbose', dest='verbose', |
| 3203 | 341 action='store_const', const=logging.INFO, |
| 342 help="Be more verbose in letting you know what is going on." | |
| 343 " Enables informational messages." | |
| 344 ) | |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
345 parser.add_argument('-V', '--very-verbose', dest='verbose', |
| 3203 | 346 action='store_const', const=logging.DEBUG, |
| 347 help="Be very verbose in letting you know what is going on." | |
| 348 " Enables debugging messages." | |
| 349 ) | |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
350 parser.add_argument('-q', '--quiet', dest='verbose', |
| 3203 | 351 action='store_const', const=logging.ERROR, |
| 352 help="Be less verbose. Ignores warnings, only prints errors." | |
| 353 ) | |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
354 parser.add_argument('-Q', '--very-quiet', dest='verbose', |
| 3203 | 355 action='store_const', const=logging.CRITICAL, |
| 356 help="Be much less verbose. Ignores warnings and errors." | |
| 357 " Only print CRITICAL messages." | |
| 358 ) | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
359 |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
360 args = parser.parse_args() |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
361 if args.version: |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
362 print('%s %s' % (sys.argv [0], version)) |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
363 sys.exit(0) |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
364 if not len(args.args) or len(args.args) % 2 == 1: |
| 3203 | 365 parser.error('Invalid number of arguments. ' |
| 366 '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
|
367 |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
368 if args.verbose == None: |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
369 args.verbose = logging.WARNING |
|
5141
939dce88cfc2
issue2550776: fix missing intialization
John Rouillard <rouilj@ieee.org>
parents:
4421
diff
changeset
|
370 |
|
7053
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
371 log.setLevel(args.verbose) |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
372 myServer = IMAPServer(delay=args.delay, pidfile=args.pidfile, |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
373 daemon=args.daemon) |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
374 for i in range(0,len(args.args),2): |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
375 home = args.args[i] |
|
b5fffd2a64af
issue2551195: port scripts to argparse
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5401
diff
changeset
|
376 server = args.args[i+1] |
| 3203 | 377 if not os.path.exists(home): |
| 378 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
|
379 |
| 3203 | 380 info = getItems(server) |
| 381 if not info: | |
| 382 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
|
383 |
| 3203 | 384 myServer.addMailbox( |
| 385 RoundupMailbox(dbhome=home, mailbox=info['mailbox'] | |
| 386 , username=info['username'], password=info['password'] | |
| 387 , server=info['server'], protocol=info['protocol'] | |
| 388 ) | |
| 389 ) | |
| 390 | |
| 391 if myServer.checkBoxes(): | |
| 392 myServer.run() | |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
393 |
|
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
394 if __name__ == '__main__': |
| 3203 | 395 main() |
|
3176
18ad9d702a5b
added "imapServer.py" script (patch [SF#934567])
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
396 |
| 3203 | 397 # vim: et ft=python si sts=4 sw=4 |
