Mercurial > p > roundup > code
comparison roundup/scripts/roundup_mailgw.py @ 601:912029653c1c config-0-4-0-branch
[[Metadata associated with this commit was garbled during conversion from CVS
to Subversion. The actual author of these changes was probably either Richard
Jones or Titus Brown.]]
| author | No Author <no-author@users.sourceforge.net> |
|---|---|
| date | Wed, 06 Feb 2002 03:47:17 +0000 |
| parents | |
| children | 986354c4b1fb |
comparison
equal
deleted
inserted
replaced
| 482:fdee2ff82b40 | 601:912029653c1c |
|---|---|
| 1 #! /usr/bin/python | |
| 2 # | |
| 3 # Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/) | |
| 4 # This module is free software, and you may redistribute it and/or modify | |
| 5 # under the same terms as Python, so long as this copyright message and | |
| 6 # disclaimer are retained in their original form. | |
| 7 # | |
| 8 # IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR | |
| 9 # DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING | |
| 10 # OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE | |
| 11 # POSSIBILITY OF SUCH DAMAGE. | |
| 12 # | |
| 13 # BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, | |
| 14 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
| 15 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" | |
| 16 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, | |
| 17 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
| 18 # | |
| 19 # $Id: roundup_mailgw.py,v 1.2 2002-01-29 20:07:15 jhermann Exp $ | |
| 20 | |
| 21 # python version check | |
| 22 from roundup import version_check | |
| 23 | |
| 24 import sys, os, re, cStringIO | |
| 25 | |
| 26 from roundup.mailgw import Message | |
| 27 from roundup.i18n import _ | |
| 28 | |
| 29 def do_pipe(handler): | |
| 30 '''Read a message from standard input and pass it to the mail handler. | |
| 31 ''' | |
| 32 handler.main(sys.stdin) | |
| 33 return 0 | |
| 34 | |
| 35 def do_mailbox(handler, filename): | |
| 36 '''Read a series of messages from the specified unix mailbox file and | |
| 37 pass each to the mail handler. | |
| 38 ''' | |
| 39 # open the spool file and lock it | |
| 40 import fcntl, FCNTL | |
| 41 f = open(filename, 'r+') | |
| 42 fcntl.flock(f.fileno(), FCNTL.LOCK_EX) | |
| 43 | |
| 44 # handle and clear the mailbox | |
| 45 try: | |
| 46 from mailbox import UnixMailbox | |
| 47 mailbox = UnixMailbox(f, factory=Message) | |
| 48 # grab one message | |
| 49 message = mailbox.next() | |
| 50 while message: | |
| 51 # call the instance mail handler | |
| 52 handler.handle_Message(message) | |
| 53 message = mailbox.next() | |
| 54 # nuke the file contents | |
| 55 os.ftruncate(f.fileno(), 0) | |
| 56 except: | |
| 57 import traceback | |
| 58 traceback.print_exc() | |
| 59 return 1 | |
| 60 fcntl.flock(f.fileno(), FCNTL.LOCK_UN) | |
| 61 return 0 | |
| 62 | |
| 63 def do_pop(handler, server, user='', password=''): | |
| 64 '''Read a series of messages from the specified POP server. | |
| 65 ''' | |
| 66 import getpass, poplib, socket | |
| 67 try: | |
| 68 if not user: | |
| 69 user = raw_input(_('User: ')) | |
| 70 if not password: | |
| 71 password = getpass.getpass() | |
| 72 except (KeyboardInterrupt, EOFError): | |
| 73 # Ctrl C or D maybe also Ctrl Z under Windows. | |
| 74 print "\nAborted by user." | |
| 75 return 1 | |
| 76 | |
| 77 # open a connection to the server and retrieve all messages | |
| 78 try: | |
| 79 server = poplib.POP3(server) | |
| 80 except socket.error, message: | |
| 81 print "POP server error:", message | |
| 82 return 1 | |
| 83 server.user(user) | |
| 84 server.pass_(password) | |
| 85 numMessages = len(server.list()[1]) | |
| 86 for i in range(1, numMessages+1): | |
| 87 # retr: returns | |
| 88 # [ pop response e.g. '+OK 459 octets', | |
| 89 # [ array of message lines ], | |
| 90 # number of octets ] | |
| 91 lines = server.retr(i)[1] | |
| 92 s = cStringIO.StringIO('\n'.join(lines)) | |
| 93 s.seek(0) | |
| 94 handler.handle_Message(Message(s)) | |
| 95 # delete the message | |
| 96 server.dele(i) | |
| 97 | |
| 98 # quit the server to commit changes. | |
| 99 server.quit() | |
| 100 return 0 | |
| 101 | |
| 102 def usage(args, message=None): | |
| 103 if message is not None: | |
| 104 print message | |
| 105 print _('Usage: %(program)s <instance home> [source spec]')%{'program': args[0]} | |
| 106 print _(''' | |
| 107 The roundup mail gateway may be called in one of two ways: | |
| 108 . with an instance home as the only argument, | |
| 109 . with both an instance home and a mail spool file, or | |
| 110 . with both an instance home and a pop server account. | |
| 111 | |
| 112 PIPE: | |
| 113 In the first case, the mail gateway reads a single message from the | |
| 114 standard input and submits the message to the roundup.mailgw module. | |
| 115 | |
| 116 UNIX mailbox: | |
| 117 In the second case, the gateway reads all messages from the mail spool | |
| 118 file and submits each in turn to the roundup.mailgw module. The file is | |
| 119 emptied once all messages have been successfully handled. The file is | |
| 120 specified as: | |
| 121 mailbox /path/to/mailbox | |
| 122 | |
| 123 POP: | |
| 124 In the third case, the gateway reads all messages from the POP server | |
| 125 specified and submits each in turn to the roundup.mailgw module. The | |
| 126 server is specified as: | |
| 127 pop username:password@server | |
| 128 The username and password may be omitted: | |
| 129 pop username@server | |
| 130 pop server | |
| 131 are both valid. The username and/or password will be prompted for if | |
| 132 not supplied on the command-line. | |
| 133 ''') | |
| 134 return 1 | |
| 135 | |
| 136 def main(args): | |
| 137 '''Handle the arguments to the program and initialise environment. | |
| 138 ''' | |
| 139 # figure the instance home | |
| 140 if len(args) > 1: | |
| 141 instance_home = args[1] | |
| 142 else: | |
| 143 instance_home = os.environ.get('ROUNDUP_INSTANCE', '') | |
| 144 if not instance_home: | |
| 145 return usage(args) | |
| 146 | |
| 147 # get the instance | |
| 148 import roundup.instance | |
| 149 instance = roundup.instance.open(instance_home) | |
| 150 | |
| 151 # get a mail handler | |
| 152 db = instance.open('admin') | |
| 153 handler = instance.MailGW(instance, db) | |
| 154 | |
| 155 # if there's no more arguments, read a single message from stdin | |
| 156 if len(args) == 2: | |
| 157 return do_pipe(handler) | |
| 158 | |
| 159 # otherwise, figure what sort of mail source to handle | |
| 160 if len(args) < 4: | |
| 161 return usage(args, _('Error: not enough source specification information')) | |
| 162 source, specification = args[2:] | |
| 163 if source == 'mailbox': | |
| 164 return do_mailbox(handler, specification) | |
| 165 elif source == 'pop': | |
| 166 m = re.match(r'((?P<user>[^:]+)(:(?P<pass>.+))?@)?(?P<server>.+)', | |
| 167 specification) | |
| 168 if m: | |
| 169 return do_pop(handler, m.group('server'), m.group('user'), | |
| 170 m.group('pass')) | |
| 171 return usage(args, _('Error: pop specification not valid')) | |
| 172 | |
| 173 return usage(args, _('Error: The source must be either "mailbox" or "pop"')) | |
| 174 | |
| 175 def run(): | |
| 176 sys.exit(main(sys.argv)) | |
| 177 | |
| 178 # call main | |
| 179 if __name__ == '__main__': | |
| 180 run() | |
| 181 | |
| 182 # | |
| 183 # $Log: not supported by cvs2svn $ | |
| 184 # Revision 1.1 2002/01/29 19:53:08 jhermann | |
| 185 # Moved scripts from top-level dir to roundup.scripts subpackage | |
| 186 # | |
| 187 # Revision 1.21 2002/01/11 07:02:29 grubert | |
| 188 # put an exception around: do_pop user and password entry to catch ctrl-c/d. | |
| 189 # | |
| 190 # Revision 1.20 2002/01/07 10:43:48 richard | |
| 191 # #500329 ] exception on server not reachable-patch | |
| 192 # | |
| 193 # Revision 1.19 2002/01/05 02:19:03 richard | |
| 194 # i18n'ification | |
| 195 # | |
| 196 # Revision 1.18 2001/12/13 00:20:01 richard | |
| 197 # . Centralised the python version check code, bumped version to 2.1.1 (really | |
| 198 # needs to be 2.1.2, but that isn't released yet :) | |
| 199 # | |
| 200 # Revision 1.17 2001/12/02 05:06:16 richard | |
| 201 # . We now use weakrefs in the Classes to keep the database reference, so | |
| 202 # the close() method on the database is no longer needed. | |
| 203 # I bumped the minimum python requirement up to 2.1 accordingly. | |
| 204 # . #487480 ] roundup-server | |
| 205 # . #487476 ] INSTALL.txt | |
| 206 # | |
| 207 # I also cleaned up the change message / post-edit stuff in the cgi client. | |
| 208 # There's now a clearly marked "TODO: append the change note" where I believe | |
| 209 # the change note should be added there. The "changes" list will obviously | |
| 210 # have to be modified to be a dict of the changes, or somesuch. | |
| 211 # | |
| 212 # More testing needed. | |
| 213 # | |
| 214 # Revision 1.16 2001/11/30 18:23:55 jhermann | |
| 215 # Cleaned up strange import (less pollution, too) | |
| 216 # | |
| 217 # Revision 1.15 2001/11/30 13:16:37 rochecompaan | |
| 218 # Fixed bug. Mail gateway was not using the extended Message class | |
| 219 # resulting in failed submissions when mails were processed from a Unix | |
| 220 # mailbox | |
| 221 # | |
| 222 # Revision 1.14 2001/11/13 21:44:44 richard | |
| 223 # . re-open the database as the author in mail handling | |
| 224 # | |
| 225 # Revision 1.13 2001/11/09 01:05:55 richard | |
| 226 # Fixed bug #479511 ] mailgw to pop once engelbert gruber tested the POP | |
| 227 # gateway. | |
| 228 # | |
| 229 # Revision 1.12 2001/11/08 05:16:55 richard | |
| 230 # Rolled roundup-popgw into roundup-mailgw. Cleaned mailgw up significantly, | |
| 231 # tested unix mailbox some more. POP still untested. | |
| 232 # | |
| 233 # Revision 1.11 2001/11/07 05:32:58 richard | |
| 234 # More roundup-mailgw usage help. | |
| 235 # | |
| 236 # Revision 1.10 2001/11/07 05:30:11 richard | |
| 237 # Nicer usage message. | |
| 238 # | |
| 239 # Revision 1.9 2001/11/07 05:29:26 richard | |
| 240 # Modified roundup-mailgw so it can read e-mails from a local mail spool | |
| 241 # file. Truncates the spool file after parsing. | |
| 242 # Fixed a couple of small bugs introduced in roundup.mailgw when I started | |
| 243 # the popgw. | |
| 244 # | |
| 245 # Revision 1.8 2001/11/01 22:04:37 richard | |
| 246 # Started work on supporting a pop3-fetching server | |
| 247 # Fixed bugs: | |
| 248 # . bug #477104 ] HTML tag error in roundup-server | |
| 249 # . bug #477107 ] HTTP header problem | |
| 250 # | |
| 251 # Revision 1.7 2001/08/07 00:24:42 richard | |
| 252 # stupid typo | |
| 253 # | |
| 254 # Revision 1.6 2001/08/07 00:15:51 richard | |
| 255 # Added the copyright/license notice to (nearly) all files at request of | |
| 256 # Bizar Software. | |
| 257 # | |
| 258 # Revision 1.5 2001/08/05 07:44:25 richard | |
| 259 # Instances are now opened by a special function that generates a unique | |
| 260 # module name for the instances on import time. | |
| 261 # | |
| 262 # Revision 1.4 2001/08/03 01:28:33 richard | |
| 263 # Used the much nicer load_package, pointed out by Steve Majewski. | |
| 264 # | |
| 265 # Revision 1.3 2001/08/03 00:59:34 richard | |
| 266 # Instance import now imports the instance using imp.load_module so that | |
| 267 # we can have instance homes of "roundup" or other existing python package | |
| 268 # names. | |
| 269 # | |
| 270 # Revision 1.2 2001/07/29 07:01:39 richard | |
| 271 # Added vim command to all source so that we don't get no steenkin' tabs :) | |
| 272 # | |
| 273 # Revision 1.1 2001/07/23 03:46:48 richard | |
| 274 # moving the bin files to facilitate out-of-the-boxness | |
| 275 # | |
| 276 # Revision 1.1 2001/07/22 11:15:45 richard | |
| 277 # More Grande Splite stuff | |
| 278 # | |
| 279 # | |
| 280 # vim: set filetype=python ts=4 sw=4 et si |
