mirror of
https://github.com/chatmail/relay.git
synced 2026-05-10 07:54:36 +00:00
for last 7 days of messages remove large messages first, then by age
This commit is contained in:
@@ -99,11 +99,29 @@ def scan_mailbox_messages(mbox):
|
||||
return messages
|
||||
|
||||
|
||||
# Within this window, large messages are deleted before small ones.
|
||||
DELETE_LARGE_FIRST_DAYS = 7
|
||||
|
||||
|
||||
def expire_to_target(mbox, target_bytes):
|
||||
cutoff = time.time() - DELETE_LARGE_FIRST_DAYS * 86400
|
||||
messages = scan_mailbox_messages(mbox)
|
||||
|
||||
def sort_key(msg):
|
||||
# prio 0: Older than cutoff -> remove oldest first
|
||||
if msg.mtime < cutoff:
|
||||
return (0, msg.mtime)
|
||||
|
||||
# prio 1: more recent than cutoff, large -> remove largest first
|
||||
if msg.quota_size > 200000:
|
||||
return (1, -msg.quota_size, msg.mtime)
|
||||
|
||||
# prio 2: more recent than cutoff, small -> remove oldest first
|
||||
return (2, msg.mtime)
|
||||
|
||||
total_size = sum(m.quota_size for m in messages)
|
||||
removed = 0
|
||||
for entry in sorted(messages):
|
||||
for entry in sorted(messages, key=sort_key):
|
||||
if total_size <= target_bytes:
|
||||
break
|
||||
(mbox / entry.path).unlink(missing_ok=True)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import itertools
|
||||
import os
|
||||
import random
|
||||
import shutil
|
||||
import time
|
||||
from datetime import datetime
|
||||
from fnmatch import fnmatch
|
||||
@@ -240,6 +241,33 @@ def test_expire_to_target(tmp_path):
|
||||
assert len(scan_mailbox_messages(tmp_path)) == 1
|
||||
|
||||
|
||||
def test_expire_to_target_prioritization(tmp_path):
|
||||
def create_messages():
|
||||
for sub in ("cur", "new"):
|
||||
if (tmp_path / sub).exists():
|
||||
shutil.rmtree(tmp_path / sub)
|
||||
# prio 0: older than 7 days
|
||||
_create_message(tmp_path, "cur", 5 * MB, days_old=10)
|
||||
# prio 1: last 7 days, large (>200KB)
|
||||
_create_message(tmp_path, "cur", 5 * MB, days_old=1)
|
||||
# prio 2: last 7 days, small
|
||||
_create_message(tmp_path, "cur", 1000, days_old=2)
|
||||
|
||||
# Shrink to 6MB: only the old message (prio 0) is removed.
|
||||
create_messages()
|
||||
assert expire_to_target(tmp_path, 6 * MB) == 1
|
||||
msgs = scan_mailbox_messages(tmp_path)
|
||||
assert len(msgs) == 2
|
||||
assert all(m.mtime > time.time() - 7 * 86400 for m in msgs)
|
||||
|
||||
# Shrink to 1KB: old and recent-large removed, small survives.
|
||||
create_messages()
|
||||
assert expire_to_target(tmp_path, 1024) == 2
|
||||
msgs = scan_mailbox_messages(tmp_path)
|
||||
assert len(msgs) == 1
|
||||
assert msgs[0].quota_size == 1000
|
||||
|
||||
|
||||
def test_quota_expire_main(tmp_path, capsys):
|
||||
mbox = tmp_path / "user@example.org"
|
||||
_create_message(mbox, "cur", 2 * MB, days_old=5)
|
||||
|
||||
Reference in New Issue
Block a user