Skip to content

Commit 35ff1ac

Browse files
author
Richard Jones
committed
reorganised mailgw code
1 parent e6dea4c commit 35ff1ac

File tree

2 files changed

+92
-85
lines changed

2 files changed

+92
-85
lines changed

roundup/mailgw.py

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class node. Any parts of other types are each stored in separate files
7373
an exception, the original message is bounced back to the sender with the
7474
explanatory message given in the exception.
7575
76-
$Id: mailgw.py,v 1.86 2002-09-10 12:44:42 richard Exp $
76+
$Id: mailgw.py,v 1.87 2002-09-11 01:19:16 richard Exp $
7777
'''
7878

7979
import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri
@@ -143,6 +143,79 @@ def __init__(self, instance, db):
143143
# (for testing)
144144
self.trapExceptions = 1
145145

146+
def do_pipe(self):
147+
''' Read a message from standard input and pass it to the mail handler.
148+
'''
149+
self.main(sys.stdin)
150+
return 0
151+
152+
def do_mailbox(self, filename):
153+
''' Read a series of messages from the specified unix mailbox file and
154+
pass each to the mail handler.
155+
'''
156+
# open the spool file and lock it
157+
import fcntl, FCNTL
158+
f = open(filename, 'r+')
159+
fcntl.flock(f.fileno(), FCNTL.LOCK_EX)
160+
161+
# handle and clear the mailbox
162+
try:
163+
from mailbox import UnixMailbox
164+
mailbox = UnixMailbox(f, factory=Message)
165+
# grab one message
166+
message = mailbox.next()
167+
while message:
168+
# handle this message
169+
self.handle_Message(message)
170+
message = mailbox.next()
171+
# nuke the file contents
172+
os.ftruncate(f.fileno(), 0)
173+
except:
174+
import traceback
175+
traceback.print_exc()
176+
return 1
177+
fcntl.flock(f.fileno(), FCNTL.LOCK_UN)
178+
return 0
179+
180+
def do_pop(self, server, user='', password=''):
181+
'''Read a series of messages from the specified POP server.
182+
'''
183+
import getpass, poplib, socket
184+
try:
185+
if not user:
186+
user = raw_input(_('User: '))
187+
if not password:
188+
password = getpass.getpass()
189+
except (KeyboardInterrupt, EOFError):
190+
# Ctrl C or D maybe also Ctrl Z under Windows.
191+
print "\nAborted by user."
192+
return 1
193+
194+
# open a connection to the server and retrieve all messages
195+
try:
196+
server = poplib.POP3(server)
197+
except socket.error, message:
198+
print "POP server error:", message
199+
return 1
200+
server.user(user)
201+
server.pass_(password)
202+
numMessages = len(server.list()[1])
203+
for i in range(1, numMessages+1):
204+
# retr: returns
205+
# [ pop response e.g. '+OK 459 octets',
206+
# [ array of message lines ],
207+
# number of octets ]
208+
lines = server.retr(i)[1]
209+
s = cStringIO.StringIO('\n'.join(lines))
210+
s.seek(0)
211+
self.handle_Message(Message(s))
212+
# delete the message
213+
server.dele(i)
214+
215+
# quit the server to commit changes.
216+
server.quit()
217+
return 0
218+
146219
def main(self, fp):
147220
''' fp - the file from which to read the Message.
148221
'''
@@ -795,9 +868,13 @@ def parseContent(content, keep_citations, keep_body,
795868
signature=re.compile(r'^[>|\s]*[-_]+\s*$'),
796869
original_message=re.compile(r'^[>|\s]*-----Original Message-----$')):
797870
''' The message body is divided into sections by blank lines.
798-
Sections where the second and all subsequent lines begin with a ">" or "|"
799-
character are considered "quoting sections". The first line of the first
800-
non-quoting section becomes the summary of the message.
871+
Sections where the second and all subsequent lines begin with a ">"
872+
or "|" character are considered "quoting sections". The first line of
873+
the first non-quoting section becomes the summary of the message.
874+
875+
If keep_citations is true, then we keep the "quoting sections" in the
876+
content.
877+
If keep_body is true, we even keep the signature sections.
801878
'''
802879
# strip off leading carriage-returns / newlines
803880
i = 0
@@ -850,10 +927,12 @@ def parseContent(content, keep_citations, keep_body,
850927

851928
# and add the section to the output
852929
l.append(section)
853-
# we only set content for those who want to delete cruft from the
854-
# message body, otherwise the body is left untouched.
930+
931+
# Now reconstitute the message content minus the bits we don't care
932+
# about.
855933
if not keep_body:
856934
content = '\n\n'.join(l)
935+
857936
return summary, content
858937

859938
# vim: set filetype=python ts=4 sw=4 et si

roundup/scripts/roundup_mailgw.py

Lines changed: 7 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1515
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1616
#
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 $
1818

1919
# python version check
2020
from roundup import version_check
@@ -24,85 +24,13 @@
2424
from roundup.mailgw import Message
2525
from roundup.i18n import _
2626

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-
10027
def usage(args, message=None):
10128
if message is not None:
10229
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]}
10431
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:
10634
. with an instance home as the only argument,
10735
. with both an instance home and a mail spool file, or
10836
. with both an instance home and a pop server account.
@@ -152,19 +80,19 @@ def main(args):
15280

15381
# if there's no more arguments, read a single message from stdin
15482
if len(args) == 2:
155-
return do_pipe(handler)
83+
return handler.do_pipe()
15684

15785
# otherwise, figure what sort of mail source to handle
15886
if len(args) < 4:
15987
return usage(args, _('Error: not enough source specification information'))
16088
source, specification = args[2:]
16189
if source == 'mailbox':
162-
return do_mailbox(handler, specification)
90+
return handler.do_mailbox(specification)
16391
elif source == 'pop':
16492
m = re.match(r'((?P<user>[^:]+)(:(?P<pass>.+))?@)?(?P<server>.+)',
16593
specification)
16694
if m:
167-
return do_pop(handler, m.group('server'), m.group('user'),
95+
return handler.do_pop(m.group('server'), m.group('user'),
16896
m.group('pass'))
16997
return usage(args, _('Error: pop specification not valid'))
17098

0 commit comments

Comments
 (0)