Mercurial > p > roundup > code
comparison roundup/scripts/roundup_mailgw.py @ 4211:61cf00ca920a
Process each message through the mail gateway as a separate transaction.
The mail-gateway used to process messages fetched, e.g., via imap in a
single big transaction. Now we process each message coming in via the
mail-gateway in its own transaction. Regression-tests passed.
See also discussion:
http://thread.gmane.org/gmane.comp.bug-tracking.roundup.user/9500
| author | Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net> |
|---|---|
| date | Tue, 14 Jul 2009 09:10:43 +0000 |
| parents | 82bdcff42c17 |
| children | 38265325492a |
comparison
equal
deleted
inserted
replaced
| 4202:e47ec982645b | 4211:61cf00ca920a |
|---|---|
| 136 | 136 |
| 137 # get the instance | 137 # get the instance |
| 138 import roundup.instance | 138 import roundup.instance |
| 139 instance = roundup.instance.open(instance_home) | 139 instance = roundup.instance.open(instance_home) |
| 140 | 140 |
| 141 # get a mail handler | 141 if hasattr(instance, 'MailGW'): |
| 142 db = instance.open('admin') | 142 handler = instance.MailGW(instance, optionsList) |
| 143 | 143 else: |
| 144 # now wrap in try/finally so we always close the database | 144 handler = mailgw.MailGW(instance, optionsList) |
| 145 | |
| 146 # if there's no more arguments, read a single message from stdin | |
| 147 if len(args) == 1: | |
| 148 return handler.do_pipe() | |
| 149 | |
| 150 # otherwise, figure what sort of mail source to handle | |
| 151 if len(args) < 3: | |
| 152 return usage(argv, _('Error: not enough source specification information')) | |
| 153 source, specification = args[1:3] | |
| 154 | |
| 155 # time out net connections after a minute if we can | |
| 156 if source not in ('mailbox', 'imaps'): | |
| 157 if hasattr(socket, 'setdefaulttimeout'): | |
| 158 socket.setdefaulttimeout(60) | |
| 159 | |
| 160 if source == 'mailbox': | |
| 161 return handler.do_mailbox(specification) | |
| 162 | |
| 163 # the source will be a network server, so obtain the credentials to | |
| 164 # use in connecting to the server | |
| 145 try: | 165 try: |
| 146 if hasattr(instance, 'MailGW'): | 166 # attempt to obtain credentials from a ~/.netrc file |
| 147 handler = instance.MailGW(instance, db, optionsList) | 167 authenticator = netrc.netrc().authenticators(specification) |
| 168 username = authenticator[0] | |
| 169 password = authenticator[2] | |
| 170 server = specification | |
| 171 # IOError if no ~/.netrc file, TypeError if the hostname | |
| 172 # not found in the ~/.netrc file: | |
| 173 except (IOError, TypeError): | |
| 174 match = re.match(r'((?P<user>[^:]+)(:(?P<pass>.+))?@)?(?P<server>.+)', | |
| 175 specification) | |
| 176 if match: | |
| 177 username = match.group('user') | |
| 178 password = match.group('pass') | |
| 179 server = match.group('server') | |
| 148 else: | 180 else: |
| 149 handler = mailgw.MailGW(instance, db, optionsList) | 181 return usage(argv, _('Error: %s specification not valid') % source) |
| 150 | 182 |
| 151 # if there's no more arguments, read a single message from stdin | 183 # now invoke the mailgw handler depending on the server handler requested |
| 152 if len(args) == 1: | 184 if source.startswith('pop'): |
| 153 return handler.do_pipe() | 185 ssl = source.endswith('s') |
| 154 | 186 if ssl and sys.version_info<(2,4): |
| 155 # otherwise, figure what sort of mail source to handle | 187 return usage(argv, _('Error: a later version of python is required')) |
| 156 if len(args) < 3: | 188 return handler.do_pop(server, username, password, ssl) |
| 157 return usage(argv, _('Error: not enough source specification information')) | 189 elif source == 'apop': |
| 158 source, specification = args[1:3] | 190 return handler.do_apop(server, username, password) |
| 159 | 191 elif source.startswith('imap'): |
| 160 # time out net connections after a minute if we can | 192 ssl = source.endswith('s') |
| 161 if source not in ('mailbox', 'imaps'): | 193 mailbox = '' |
| 162 if hasattr(socket, 'setdefaulttimeout'): | 194 if len(args) > 3: |
| 163 socket.setdefaulttimeout(60) | 195 mailbox = args[3] |
| 164 | 196 return handler.do_imap(server, username, password, mailbox, ssl) |
| 165 if source == 'mailbox': | 197 |
| 166 return handler.do_mailbox(specification) | 198 return usage(argv, _('Error: The source must be either "mailbox",' |
| 167 | 199 ' "pop", "pops", "apop", "imap" or "imaps"')) |
| 168 # the source will be a network server, so obtain the credentials to | |
| 169 # use in connecting to the server | |
| 170 try: | |
| 171 # attempt to obtain credentials from a ~/.netrc file | |
| 172 authenticator = netrc.netrc().authenticators(specification) | |
| 173 username = authenticator[0] | |
| 174 password = authenticator[2] | |
| 175 server = specification | |
| 176 # IOError if no ~/.netrc file, TypeError if the hostname | |
| 177 # not found in the ~/.netrc file: | |
| 178 except (IOError, TypeError): | |
| 179 match = re.match(r'((?P<user>[^:]+)(:(?P<pass>.+))?@)?(?P<server>.+)', | |
| 180 specification) | |
| 181 if match: | |
| 182 username = match.group('user') | |
| 183 password = match.group('pass') | |
| 184 server = match.group('server') | |
| 185 else: | |
| 186 return usage(argv, _('Error: %s specification not valid') % source) | |
| 187 | |
| 188 # now invoke the mailgw handler depending on the server handler requested | |
| 189 if source.startswith('pop'): | |
| 190 ssl = source.endswith('s') | |
| 191 if ssl and sys.version_info<(2,4): | |
| 192 return usage(argv, _('Error: a later version of python is required')) | |
| 193 return handler.do_pop(server, username, password, ssl) | |
| 194 elif source == 'apop': | |
| 195 return handler.do_apop(server, username, password) | |
| 196 elif source.startswith('imap'): | |
| 197 ssl = source.endswith('s') | |
| 198 mailbox = '' | |
| 199 if len(args) > 3: | |
| 200 mailbox = args[3] | |
| 201 return handler.do_imap(server, username, password, mailbox, ssl) | |
| 202 | |
| 203 return usage(argv, _('Error: The source must be either "mailbox",' | |
| 204 ' "pop", "pops", "apop", "imap" or "imaps"')) | |
| 205 finally: | |
| 206 # handler might have closed the initial db and opened a new one | |
| 207 handler.db.close() | |
| 208 | 200 |
| 209 def run(): | 201 def run(): |
| 210 sys.exit(main(sys.argv)) | 202 sys.exit(main(sys.argv)) |
| 211 | 203 |
| 212 # call main | 204 # call main |
