summaryrefslogtreecommitdiff
path: root/src/mailman/archiving/pipermail.py
blob: 03dcd97f45ded6e3703ed2b9c498ea68b1871513 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# Copyright (C) 2007-2012 by the Free Software Foundation, Inc.
#
# This file is part of GNU Mailman.
#
# GNU Mailman is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# GNU Mailman.  If not, see <http://www.gnu.org/licenses/>.

"""Pipermail archiver."""

from __future__ import absolute_import, unicode_literals

__metaclass__ = type
__all__ = [
    'Pipermail',
    ]


import os
import mailbox
import tempfile

from zope.interface import implements
from zope.interface.interface import adapter_hooks

from mailman.config import config
from mailman.interfaces.archiver import IArchiver, IPipermailMailingList
from mailman.interfaces.mailinglist import IMailingList
from mailman.utilities.filesystem import makedirs
from mailman.utilities.string import expand

from mailman.Archiver.HyperArch import HyperArchive



class PipermailMailingListAdapter:
    """An adapter for MailingList objects to work with Pipermail."""

    implements(IPipermailMailingList)

    def __init__(self, mlist):
        self._mlist = mlist

    def __getattr__(self, name):
        return getattr(self._mlist, name)

    def archive_dir(self):
        """See `IPipermailMailingList`."""
        if self._mlist.archive_private:
            basedir = config.PRIVATE_ARCHIVE_FILE_DIR
        else:
            basedir = config.PUBLIC_ARCHIVE_FILE_DIR
        # Make sure the archive directory exists.
        archive_dir = os.path.join(basedir, self._mlist.fqdn_listname)
        makedirs(archive_dir)
        return archive_dir


def adapt_mailing_list_for_pipermail(iface, obj):
    """Adapt `IMailingLists` to `IPipermailMailingList`.

    :param iface: The interface to adapt to.
    :type iface: `zope.interface.Interface`
    :param obj: The object being adapted.
    :type obj: any object
    :return: An `IPipermailMailingList` instance if adaptation succeeded or
        None if it didn't.
    """
    return (PipermailMailingListAdapter(obj)
            if IMailingList.providedBy(obj) and iface is IPipermailMailingList
            else None)

adapter_hooks.append(adapt_mailing_list_for_pipermail)



class Pipermail:
    """The stock Pipermail archiver."""

    implements(IArchiver)

    name = 'pipermail'

    @staticmethod
    def list_url(mlist):
        """See `IArchiver`."""
        if mlist.archive_private:
            return mlist.script_url('private') + '/index.html'
        else:
            return expand(config.archiver.pipermail.base_url,
                          dict(listname=mlist.fqdn_listname,
                               hostname=mlist.domain.url_host,
                               fqdn_listname=mlist.fqdn_listname,
                               ))

    @staticmethod
    def permalink(mlist, message):
        """See `IArchiver`."""
        # Not currently implemented.
        return None

    @staticmethod
    def archive_message(mlist, message):
        """See `IArchiver`."""
        fd, path = tempfile.mkstemp('.mbox')
        os.close(fd)
        try:
            mbox = mailbox.mbox(path, create=True)
            mbox.add(message)
        finally:
            mbox.close()
        h = HyperArchive(IPipermailMailingList(mlist))
        try:
            h.processUnixMailbox(path)
        finally:
            h.close()
            os.remove(path)
        # There's no good way to know the url for the archived message.
        return None