Mercurial > p > roundup > code
comparison roundup/scripts/roundup_mailgw.py @ 1107:1c1ccfc9673d
reorganised mailgw code
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Wed, 11 Sep 2002 01:19:16 +0000 |
| parents | e5826025eeb7 |
| children | 36ec30d286ea |
comparison
equal
deleted
inserted
replaced
| 1106:7c851d1521dc | 1107:1c1ccfc9673d |
|---|---|
| 12 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 12 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 13 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" | 13 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" |
| 14 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, | 14 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, |
| 15 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 15 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| 16 # | 16 # |
| 17 # $Id: roundup_mailgw.py,v 1.4 2002-09-10 01:07:06 richard Exp $ | 17 # $Id: roundup_mailgw.py,v 1.5 2002-09-11 01:19:16 richard Exp $ |
| 18 | 18 |
| 19 # python version check | 19 # python version check |
| 20 from roundup import version_check | 20 from roundup import version_check |
| 21 | 21 |
| 22 import sys, os, re, cStringIO | 22 import sys, os, re, cStringIO |
| 23 | 23 |
| 24 from roundup.mailgw import Message | 24 from roundup.mailgw import Message |
| 25 from roundup.i18n import _ | 25 from roundup.i18n import _ |
| 26 | 26 |
| 27 def do_pipe(handler): | |
| 28 '''Read a message from standard input and pass it to the mail handler. | |
| 29 ''' | |
| 30 handler.main(sys.stdin) | |
| 31 return 0 | |
| 32 | |
| 33 def do_mailbox(handler, filename): | |
| 34 '''Read a series of messages from the specified unix mailbox file and | |
| 35 pass each to the mail handler. | |
| 36 ''' | |
| 37 # open the spool file and lock it | |
| 38 import fcntl, FCNTL | |
| 39 f = open(filename, 'r+') | |
| 40 fcntl.flock(f.fileno(), FCNTL.LOCK_EX) | |
| 41 | |
| 42 # handle and clear the mailbox | |
| 43 try: | |
| 44 from mailbox import UnixMailbox | |
| 45 mailbox = UnixMailbox(f, factory=Message) | |
| 46 # grab one message | |
| 47 message = mailbox.next() | |
| 48 while message: | |
| 49 # call the instance mail handler | |
| 50 handler.handle_Message(message) | |
| 51 message = mailbox.next() | |
| 52 # nuke the file contents | |
| 53 os.ftruncate(f.fileno(), 0) | |
| 54 except: | |
| 55 import traceback | |
| 56 traceback.print_exc() | |
| 57 return 1 | |
| 58 fcntl.flock(f.fileno(), FCNTL.LOCK_UN) | |
| 59 return 0 | |
| 60 | |
| 61 def do_pop(handler, server, user='', password=''): | |
| 62 '''Read a series of messages from the specified POP server. | |
| 63 ''' | |
| 64 import getpass, poplib, socket | |
| 65 try: | |
| 66 if not user: | |
| 67 user = raw_input(_('User: ')) | |
| 68 if not password: | |
| 69 password = getpass.getpass() | |
| 70 except (KeyboardInterrupt, EOFError): | |
| 71 # Ctrl C or D maybe also Ctrl Z under Windows. | |
| 72 print "\nAborted by user." | |
| 73 return 1 | |
| 74 | |
| 75 # open a connection to the server and retrieve all messages | |
| 76 try: | |
| 77 server = poplib.POP3(server) | |
| 78 except socket.error, message: | |
| 79 print "POP server error:", message | |
| 80 return 1 | |
| 81 server.user(user) | |
| 82 server.pass_(password) | |
| 83 numMessages = len(server.list()[1]) | |
| 84 for i in range(1, numMessages+1): | |
| 85 # retr: returns | |
| 86 # [ pop response e.g. '+OK 459 octets', | |
| 87 # [ array of message lines ], | |
| 88 # number of octets ] | |
| 89 lines = server.retr(i)[1] | |
| 90 s = cStringIO.StringIO('\n'.join(lines)) | |
| 91 s.seek(0) | |
| 92 handler.handle_Message(Message(s)) | |
| 93 # delete the message | |
| 94 server.dele(i) | |
| 95 | |
| 96 # quit the server to commit changes. | |
| 97 server.quit() | |
| 98 return 0 | |
| 99 | |
| 100 def usage(args, message=None): | 27 def usage(args, message=None): |
| 101 if message is not None: | 28 if message is not None: |
| 102 print message | 29 print message |
| 103 print _('Usage: %(program)s <instance home> [source spec]')%{'program': args[0]} | 30 print _('Usage: %(program)s <instance home> [method]')%{'program': args[0]} |
| 104 print _(''' | 31 print _(''' |
| 105 The roundup mail gateway may be called in one of two ways: | 32 |
| 33 The roundup mail gateway may be called in one of three ways: | |
| 106 . with an instance home as the only argument, | 34 . with an instance home as the only argument, |
| 107 . with both an instance home and a mail spool file, or | 35 . with both an instance home and a mail spool file, or |
| 108 . with both an instance home and a pop server account. | 36 . with both an instance home and a pop server account. |
| 109 | 37 |
| 110 PIPE: | 38 PIPE: |
| 150 db = instance.open('admin') | 78 db = instance.open('admin') |
| 151 handler = instance.MailGW(instance, db) | 79 handler = instance.MailGW(instance, db) |
| 152 | 80 |
| 153 # if there's no more arguments, read a single message from stdin | 81 # if there's no more arguments, read a single message from stdin |
| 154 if len(args) == 2: | 82 if len(args) == 2: |
| 155 return do_pipe(handler) | 83 return handler.do_pipe() |
| 156 | 84 |
| 157 # otherwise, figure what sort of mail source to handle | 85 # otherwise, figure what sort of mail source to handle |
| 158 if len(args) < 4: | 86 if len(args) < 4: |
| 159 return usage(args, _('Error: not enough source specification information')) | 87 return usage(args, _('Error: not enough source specification information')) |
| 160 source, specification = args[2:] | 88 source, specification = args[2:] |
| 161 if source == 'mailbox': | 89 if source == 'mailbox': |
| 162 return do_mailbox(handler, specification) | 90 return handler.do_mailbox(specification) |
| 163 elif source == 'pop': | 91 elif source == 'pop': |
| 164 m = re.match(r'((?P<user>[^:]+)(:(?P<pass>.+))?@)?(?P<server>.+)', | 92 m = re.match(r'((?P<user>[^:]+)(:(?P<pass>.+))?@)?(?P<server>.+)', |
| 165 specification) | 93 specification) |
| 166 if m: | 94 if m: |
| 167 return do_pop(handler, m.group('server'), m.group('user'), | 95 return handler.do_pop(m.group('server'), m.group('user'), |
| 168 m.group('pass')) | 96 m.group('pass')) |
| 169 return usage(args, _('Error: pop specification not valid')) | 97 return usage(args, _('Error: pop specification not valid')) |
| 170 | 98 |
| 171 return usage(args, _('Error: The source must be either "mailbox" or "pop"')) | 99 return usage(args, _('Error: The source must be either "mailbox" or "pop"')) |
| 172 | 100 |
