Skip to content

Commit f12d137

Browse files
author
Richard Jones
committed
Rolled roundup-popgw into roundup-mailgw.
Cleaned mailgw up significantly, tested unix mailbox some more. POP still untested.
1 parent b1bce78 commit f12d137

File tree

2 files changed

+129
-119
lines changed

2 files changed

+129
-119
lines changed

roundup-mailgw

Lines changed: 129 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,75 +16,152 @@
1616
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1717
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1818
#
19-
# $Id: roundup-mailgw,v 1.11 2001-11-07 05:32:58 richard Exp $
19+
# $Id: roundup-mailgw,v 1.12 2001-11-08 05:16:55 richard Exp $
2020

21-
import sys
21+
import sys, os, re
2222
if int(sys.version[0]) < 2:
2323
print "Roundup requires Python 2.0 or newer."
2424
sys.exit(1)
2525

26-
# figure the instance home
27-
import os
28-
if len(sys.argv) > 1:
29-
instance_home = sys.argv[1]
30-
else:
31-
instance_home = os.environ.get('ROUNDUP_INSTANCE', '')
32-
if not instance_home:
33-
print 'Usage: %s <instance home> [mail spool file]'%sys.argv[0]
26+
from mimetools import Message
27+
28+
def do_pipe(handler):
29+
'''Read a message from standard input and pass it to the mail handler.
30+
'''
31+
handler.main(sys.stdin)
32+
return 0
33+
34+
def do_mailbox(handler, filename):
35+
'''Read a series of messages from the specified unix mailbox file and
36+
pass each to the mail handler.
37+
'''
38+
# open the spool file and lock it
39+
import fcntl, FCNTL
40+
f = open(filename, 'r+')
41+
fcntl.flock(f.fileno(), FCNTL.LOCK_EX)
42+
43+
# handle and clear the mailbox
44+
try:
45+
from mailbox import UnixMailbox
46+
mailbox = UnixMailbox(f, factory=Message)
47+
# grab one message
48+
message = mailbox.next()
49+
while message:
50+
# call the instance mail handler
51+
handler.handle_Message(message)
52+
message = mailbox.next()
53+
# nuke the file contents
54+
os.ftruncate(f.fileno(), 0)
55+
except:
56+
import traceback
57+
traceback.print_exc()
58+
return 1
59+
fcntl.flock(f.fileno(), FCNTL.LOCK_UN)
60+
return 0
61+
62+
def do_pop(handler, server, user='', password=''):
63+
'''Read a series of messages from the specified POP server.
64+
'''
65+
import getpass, poplib
66+
if not user:
67+
user = raw_input('User: ')
68+
if not password:
69+
password = getpass.getpass()
70+
71+
# open a connection to the server and retrieve all messages
72+
server = poplib.POP3(server)
73+
server.user(user)
74+
server.pass_(password)
75+
numMessages = len(server.list()[1])
76+
for i in range(numMessages):
77+
for j in server.retr(i+1)[1]:
78+
s = cStringIO.StringIO('\n'.join(j))
79+
s.seek(0)
80+
handler.handle_Message(Message(s))
81+
return 0
82+
83+
def usage(args, message=None):
84+
if message is not None:
85+
print message
86+
print 'Usage: %s <instance home> [source spec]'%args[0]
3487
print '''
3588
The roundup mail gateway may be called in one of two ways:
36-
. with an instance home as the only argument, or
37-
. with both an instance home and a mail spool file.
89+
. with an instance home as the only argument,
90+
. with both an instance home and a mail spool file, or
91+
. with both an instance home and a pop server account.
3892
39-
In the first case, the mail gateway reads a single message from the
40-
standard input and submits the message to the roundup.mailgw module.
93+
PIPE:
94+
In the first case, the mail gateway reads a single message from the
95+
standard input and submits the message to the roundup.mailgw module.
4196
42-
In the second case, the gateway reads all messages from the mail spool
43-
file and submits each in turn to the roundup.mailgw module. The file is
44-
emptied once all messages have been successfully handled.
97+
UNIX mailbox:
98+
In the second case, the gateway reads all messages from the mail spool
99+
file and submits each in turn to the roundup.mailgw module. The file is
100+
emptied once all messages have been successfully handled. The file is
101+
specified as:
102+
mailbox /path/to/mailbox
103+
104+
POP:
105+
In the third case, the gateway reads all messages from the POP server
106+
specified and submits each in turn to the roundup.mailgw module. The
107+
server is specified as:
108+
pop username:password@server
109+
The username and password may be omitted:
110+
pop username@server
111+
pop server
112+
are both valid. The username and/or password will be prompted for if
113+
not supplied on the command-line.
45114
'''
46-
sys.exit(1)
115+
return 1
47116

48-
# get the instance
49-
import roundup.instance
50-
instance = roundup.instance.open(instance_home)
117+
def main(args):
118+
'''Handle the arguments to the program and initialise environment.
119+
'''
120+
# figure the instance home
121+
if len(args) > 1:
122+
instance_home = args[1]
123+
else:
124+
instance_home = os.environ.get('ROUNDUP_INSTANCE', '')
125+
if not instance_home:
126+
return usage(args)
51127

52-
# invoke the mail handler
53-
db = instance.open('admin')
54-
handler = instance.MailGW(db)
128+
# get the instance
129+
import roundup.instance
130+
instance = roundup.instance.open(instance_home)
55131

56-
# if there's no more arguments, read a single message from stdin
57-
if len(sys.argv) < 2:
58-
handler.main(sys.stdin)
132+
# get a mail handler
133+
db = instance.open('admin')
134+
handler = instance.MailGW(db)
59135

60-
# otherwise, there's a spool file to read from
61-
import fcntl, FCNTL
62-
spool_file = sys.argv[2]
63-
64-
# open the spool file and lock it
65-
f = open(spool_file, 'r+')
66-
fcntl.flock(f.fileno(), FCNTL.LOCK_EX)
67-
68-
# handle and clear the mailbox
69-
try:
70-
from mailbox import UnixMailbox
71-
import mimetools
72-
mailbox = UnixMailbox(f, factory=mimetools.Message)
73-
# grab one message
74-
message = mailbox.next()
75-
while message:
76-
# call the instance mail handler
77-
handler.handle_Message(message)
78-
message = mailbox.next()
79-
# nuke the file contents
80-
os.ftruncate(f.fileno(), 0)
81-
except:
82-
import traceback
83-
traceback.print_exc()
84-
fcntl.flock(f.fileno(), FCNTL.LOCK_UN)
136+
# if there's no more arguments, read a single message from stdin
137+
if len(args) == 2:
138+
return do_pipe(handler)
139+
140+
# otherwise, figure what sort of mail source to handle
141+
if len(args) < 4:
142+
return usage(args, 'Error: not enough source specification information')
143+
source, specification = args[2:]
144+
if source == 'mailbox':
145+
return do_mailbox(handler, specification)
146+
elif source == 'pop':
147+
m = re.match(r'((?P<user>[^:]+)(:(?P<pass>.+))?@)?(?P<server>.+)',
148+
specification)
149+
if m:
150+
return do_pop(handler, m.group('server'), m.group('user'),
151+
m.group('pass'))
152+
return usage(args, 'Error: pop specification not valid')
153+
154+
return usage(args, 'Error: The source must be either "mailbox" or "pop"')
155+
156+
# call main
157+
if __name__ == '__main__':
158+
sys.exit(main(sys.argv))
85159

86160
#
87161
# $Log: not supported by cvs2svn $
162+
# Revision 1.11 2001/11/07 05:32:58 richard
163+
# More roundup-mailgw usage help.
164+
#
88165
# Revision 1.10 2001/11/07 05:30:11 richard
89166
# Nicer usage message.
90167
#

roundup-popgw

Lines changed: 0 additions & 67 deletions
This file was deleted.

0 commit comments

Comments
 (0)