extra-mailman-archivers/src/extra_mailman_archivers/monthly_archiver.py

105 lines
3.2 KiB
Python
Raw Normal View History

2021-04-06 02:32:35 -04:00
# Copyright (C) 2021 Max Erenberg
# This file is adapted from GNU Mailman. The original copyright notice
# is preserved below.
#
# Copyright (C) 2008-2019 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/>.
"""
A simple archiver which copies each message into a folder for the current
month.
"""
from contextlib import suppress
from email.utils import parsedate
import gzip
import logging
import os
import time
from mailman.config import config
from mailman.interfaces.archiver import IArchiver
from public import public
from zope.interface import implementer
log = logging.getLogger('mailman.error')
@public
@implementer(IArchiver)
class MonthlyArchiver:
"""
A simple archiver which copies each message into a folder for the
current month. It is adapted from the `Prototype` archiver.
"""
name = 'monthly_archiver'
is_enabled = False
@staticmethod
def list_url(mlist):
"""See `IArchiver`."""
# This archiver is not web-accessible, therefore no URL is returned.
return None
@staticmethod
def permalink(mlist, msg):
"""See `IArchiver`."""
# This archiver is not web-accessible, therefore no URL is returned.
return None
@staticmethod
def archive_message(mlist, message):
"""See `IArchiver`.
This archiver saves messages into a folder for the current year and
month, e.g. '2021-April'.
:type mlist: mailman.model.listmanager.ListManager
:type message: mailman.email.message.Message
"""
message_id = message.get('message-id')
date_secs = parsedate(message.get('date'))
if date_secs is not None:
date = time.localtime(time.mktime(date_secs))
else:
log.warning('Could not extract date from message %s, using '
'local time instead' % message_id)
date = time.localtime()
year_and_month = time.strftime('%Y-%B', date)
archive_dir = os.path.join(
config.ARCHIVE_DIR,
MonthlyArchiver.name,
mlist.fqdn_listname,
year_and_month
)
with suppress(FileExistsError):
os.makedirs(archive_dir, 0o775)
# Just use the current timestamp as the file name
filename = str(round(time.time(), 3)) + '.mail.gz'
dst = os.path.join(archive_dir, filename)
log.info('MonthlyArchiver archived message %s to %s' %
(message_id, dst))
# gzip the file to try to save some disk space
with gzip.open(dst, 'wb') as fo:
fo.write(message.as_bytes())
return None