use maildir for MonthlyArchiver
This commit is contained in:
parent
686729b916
commit
a1dec6a0b2
|
@ -20,17 +20,20 @@
|
|||
# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
A simple archiver which copies each message into a folder for the current
|
||||
month.
|
||||
A simple archiver which copies each message into a maildir folder for the
|
||||
current year and month.
|
||||
"""
|
||||
|
||||
from contextlib import suppress
|
||||
from datetime import timedelta
|
||||
from email.utils import parsedate
|
||||
import gzip
|
||||
import logging
|
||||
from mailbox import Mailbox
|
||||
import os
|
||||
import time
|
||||
|
||||
from flufl.lock import Lock
|
||||
from mailbox import Maildir
|
||||
from mailman.config import config
|
||||
from mailman.interfaces.archiver import IArchiver
|
||||
from public import public
|
||||
|
@ -44,7 +47,7 @@ log = logging.getLogger('mailman.archiver')
|
|||
@implementer(IArchiver)
|
||||
class MonthlyArchiver:
|
||||
"""
|
||||
A simple archiver which copies each message into a folder for the
|
||||
A simple archiver which copies each message into a maildir for the
|
||||
current month. It is adapted from the `Prototype` archiver.
|
||||
"""
|
||||
|
||||
|
@ -67,8 +70,8 @@ class MonthlyArchiver:
|
|||
def archive_message(mlist, message):
|
||||
"""See `IArchiver`.
|
||||
|
||||
This archiver saves messages into a folder for the current year and
|
||||
month, e.g. '2021-April'.
|
||||
This archiver saves messages into a maildir for the current year and
|
||||
month, e.g. '2021/April'.
|
||||
|
||||
:type mlist: mailman.model.listmanager.ListManager
|
||||
:type message: mailman.email.message.Message
|
||||
|
@ -81,24 +84,35 @@ class MonthlyArchiver:
|
|||
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)
|
||||
year = time.strftime('%Y')
|
||||
month = time.strftime('%B')
|
||||
|
||||
archive_dir = os.path.join(
|
||||
config.ARCHIVE_DIR,
|
||||
MonthlyArchiver.name,
|
||||
mlist.fqdn_listname,
|
||||
year_and_month
|
||||
year,
|
||||
month
|
||||
)
|
||||
with suppress(FileExistsError):
|
||||
os.makedirs(archive_dir, 0o775)
|
||||
for subdir in ['cur', 'new', 'tmp']:
|
||||
with suppress(FileExistsError):
|
||||
os.makedirs(os.path.join(archive_dir, subdir), 0o775)
|
||||
maildir = Maildir(archive_dir, create=True)
|
||||
|
||||
# maildir.add() is not thread-safe
|
||||
lock_file = os.path.join(
|
||||
config.LOCK_DIR, '{0}-maildir.lock'.format(mlist.fqdn_listname))
|
||||
lock = Lock(lock_file)
|
||||
try:
|
||||
lock.lock(timeout=timedelta(seconds=3))
|
||||
filename = maildir.add(message)
|
||||
finally:
|
||||
lock.unlock(unconditionally=True)
|
||||
# If we fail to acquire the lock, let the error propagate up
|
||||
|
||||
# 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())
|
||||
(message_id, filename))
|
||||
|
||||
return None
|
||||
|
|
Loading…
Reference in New Issue