1 # Copyright (C) 2008-2014 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18 """MHonArc archiver."""
20 from __future__
import absolute_import
, print_function
, unicode_literals
31 from urlparse
import urljoin
32 from zope
.interface
import implementer
34 from mailman
.config
import config
35 from mailman
.config
.config
import external_configuration
36 from mailman
.interfaces
.archiver
import IArchiver
37 from mailman
.utilities
.string
import expand
40 log
= logging
.getLogger('mailman.archiver')
44 @implementer(IArchiver
)
46 """Local MHonArc archiver."""
52 # Read our specific configuration file
53 archiver_config
= external_configuration(
54 config
.archiver
.mhonarc
.configuration
)
55 self
.base_url
= archiver_config
.get('general', 'base_url')
56 self
.command
= archiver_config
.get('general', 'command')
58 def list_url(self
, mlist
):
59 """See `IArchiver`."""
60 # XXX What about private MHonArc archives?
61 return expand(self
.base_url
,
62 dict(listname
=mlist
.fqdn_listname
,
63 hostname
=mlist
.domain
.url_host
,
64 fqdn_listname
=mlist
.fqdn_listname
,
67 def permalink(self
, mlist
, msg
):
68 """See `IArchiver`."""
69 # XXX What about private MHonArc archives?
70 # It is the LMTP server's responsibility to ensure that the message
71 # has a X-Message-ID-Hash header. If it doesn't then there's no
73 message_id_hash
= msg
.get('x-message-id-hash')
74 if message_id_hash
is None:
76 return urljoin(self
.list_url(mlist
), message_id_hash
)
78 def archive_message(self
, mlist
, msg
):
79 """See `IArchiver`."""
80 substitutions
= config
.__dict
__.copy()
81 substitutions
['listname'] = mlist
.fqdn_listname
82 command
= expand(self
.command
, substitutions
)
83 proc
= subprocess
.Popen(
84 command
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
,
86 stdout
, stderr
= proc
.communicate(msg
.as_string())
87 if proc
.returncode
!= 0:
88 log
.error('%s: mhonarc subprocess had non-zero exit code: %s' %
89 (msg
['message-id'], proc
.returncode
))