~mailman-coders/mailman/2.1

49 by bwarsaw
Backport from the trunk, and catalog regeneration.
1
# Copyright (C) 1998-2003 by the Free Software Foundation, Inc.
1 by
This commit was manufactured by cvs2svn to create branch
2
#
3
# This program is free software; you can redistribute it and/or
4
# modify it under the terms of the GNU General Public License
5
# as published by the Free Software Foundation; either version 2
6
# of the License, or (at your option) any later version.
49 by bwarsaw
Backport from the trunk, and catalog regeneration.
7
#
1 by
This commit was manufactured by cvs2svn to create branch
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
49 by bwarsaw
Backport from the trunk, and catalog regeneration.
12
#
1 by
This commit was manufactured by cvs2svn to create branch
13
# You should have received a copy of the GNU General Public License
49 by bwarsaw
Backport from the trunk, and catalog regeneration.
14
# along with this program; if not, write to the Free Software
749 by tkikuchi
FSF office has moved to 51 Franklin Street.
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1 by
This commit was manufactured by cvs2svn to create branch
16
17
"""Extend mailbox.UnixMailbox.
18
"""
19
20
import sys
21
import mailbox
22
23
import email
49 by bwarsaw
Backport from the trunk, and catalog regeneration.
24
from email.Parser import Parser
1 by
This commit was manufactured by cvs2svn to create branch
25
from email.Generator import Generator
26
from email.Errors import MessageParseError
27
28
from Mailman import mm_cfg
29
from Mailman.Message import Message
30
49 by bwarsaw
Backport from the trunk, and catalog regeneration.
31
try:
32
    True, False
33
except NameError:
34
    True = 1
35
    False = 0
36
37
1 by
This commit was manufactured by cvs2svn to create branch
38

39
def _safeparser(fp):
40
    try:
41
        return email.message_from_file(fp, Message)
42
    except MessageParseError:
43
        # Don't return None since that will stop a mailbox iterator
44
        return ''
45
46
47

48
class Mailbox(mailbox.PortableUnixMailbox):
49
    def __init__(self, fp):
50
        mailbox.PortableUnixMailbox.__init__(self, fp, _safeparser)
51
52
    # msg should be an rfc822 message or a subclass.
53
    def AppendMessage(self, msg):
49 by bwarsaw
Backport from the trunk, and catalog regeneration.
54
        # Check the last character of the file and write a newline if it isn't
55
        # a newline (but not at the beginning of an empty file).
1 by
This commit was manufactured by cvs2svn to create branch
56
        try:
57
            self.fp.seek(-1, 2)
58
        except IOError, e:
59
            # Assume the file is empty.  We can't portably test the error code
60
            # returned, since it differs per platform.
61
            pass
62
        else:
63
            if self.fp.read(1) <> '\n':
64
                self.fp.write('\n')
65
        # Seek to the last char of the mailbox
66
        self.fp.seek(1, 2)
67
        # Create a Generator instance to write the message to the file
68
        g = Generator(self.fp)
49 by bwarsaw
Backport from the trunk, and catalog regeneration.
69
        g.flatten(msg, unixfrom=True)
70
        # Add one more trailing newline for separation with the next message
71
        # to be appended to the mbox.
72
        print >> self.fp
1 by
This commit was manufactured by cvs2svn to create branch
73
74
75

76
# This stuff is used by pipermail.py:processUnixMailbox().  It provides an
77
# opportunity for the built-in archiver to scrub archived messages of nasty
78
# things like attachments and such...
79
def _archfactory(mailbox):
80
    # The factory gets a file object, but it also needs to have a MailList
81
    # object, so the clearest <wink> way to do this is to build a factory
82
    # function that has a reference to the mailbox object, which in turn holds
83
    # a reference to the mailing list.  Nested scopes would help here, BTW,
84
    # but we can't rely on them being around (e.g. Python 2.0).
85
    def scrubber(fp, mailbox=mailbox):
86
        msg = _safeparser(fp)
87
        if msg == '':
88
            return msg
89
        return mailbox.scrub(msg)
90
    return scrubber
91
92
93
class ArchiverMailbox(Mailbox):
94
    # This is a derived class which is instantiated with a reference to the
95
    # MailList object.  It is build such that the factory calls back into its
96
    # scrub() method, giving the scrubber module a chance to do its thing
97
    # before the message is archived.
98
    def __init__(self, fp, mlist):
99
        if mm_cfg.ARCHIVE_SCRUBBER:
100
            __import__(mm_cfg.ARCHIVE_SCRUBBER)
101
            self._scrubber = sys.modules[mm_cfg.ARCHIVE_SCRUBBER].process
102
        else:
103
            self._scrubber = None
104
        self._mlist = mlist
105
        mailbox.PortableUnixMailbox.__init__(self, fp, _archfactory(self))
106
107
    def scrub(self, msg):
108
        if self._scrubber:
109
            return self._scrubber(self._mlist, msg)
110
        else:
111
            return msg