strike superflous code

This commit is contained in:
holger krekel
2025-09-15 13:09:44 +02:00
parent a90a651ba0
commit fb01944f0d
4 changed files with 35 additions and 39 deletions

View File

@@ -4,6 +4,7 @@ Expire old messages and addresses.
""" """
import os import os
import shutil
import sys import sys
from argparse import ArgumentParser from argparse import ArgumentParser
from datetime import datetime from datetime import datetime
@@ -13,27 +14,19 @@ from chatmaild.config import read_config
class FileEntry: class FileEntry:
def __init__(self, basedir, relpath, mtime, size): def __init__(self, relpath, mtime, size):
self.basedir = basedir
self.relpath = relpath self.relpath = relpath
self.mtime = mtime self.mtime = mtime
self.size = size self.size = size
def __hash__(self):
return hash(self.relpath)
def __repr__(self): def __repr__(self):
return f"<FileEntry size={self.size} '{self.relpath}' >" return f"<FileEntry size={self.size} '{self.relpath}' >"
def __str__(self): def get_path(self, basedir):
return self.get_path() return joinpath(basedir, self.relpath)
def get_path(self):
return joinpath(self.basedir, self.relpath)
def fmt_size(self):
return f"{int(self.size/1000):5.0f}K"
def fmt_since(self, now):
diff_seconds = int(now) - int(self.mtime)
return f"{int(diff_seconds / 86400):2.0f}d"
def __eq__(self, other): def __eq__(self, other):
return ( return (
@@ -50,7 +43,6 @@ def joinpath(name, extra):
class Stats: class Stats:
def __init__(self, basedir, maxnum=None): def __init__(self, basedir, maxnum=None):
self.basedir = str(basedir) self.basedir = str(basedir)
self.mailboxes = []
self.maxnum = maxnum self.maxnum = maxnum
def iter_mailboxes(self, callback=None): def iter_mailboxes(self, callback=None):
@@ -58,7 +50,6 @@ class Stats:
if "@" in name: if "@" in name:
basedir = joinpath(self.basedir, name) basedir = joinpath(self.basedir, name)
mailbox = MailboxStat(basedir) mailbox = MailboxStat(basedir)
self.mailboxes.append(mailbox)
if callback is not None: if callback is not None:
callback(mailbox) callback(mailbox)
@@ -86,17 +77,13 @@ class MailboxStat:
st = os.stat(msg_path) st = os.stat(msg_path)
relpath = joinpath(name, msg_name) relpath = joinpath(name, msg_name)
self.messages.append( self.messages.append(
FileEntry( FileEntry(relpath, mtime=st.st_mtime, size=st.st_size)
self.basedir, relpath, mtime=st.st_mtime, size=st.st_size
)
) )
self.totalsize += st.st_size self.totalsize += st.st_size
else: else:
st = os.stat(fpath) st = os.stat(fpath)
if S_ISREG(st.st_mode): if S_ISREG(st.st_mode):
self.extrafiles.append( self.extrafiles.append(FileEntry(name, st.st_mtime, st.st_size))
FileEntry(self.basedir, name, st.st_mtime, st.st_size)
)
if name == "password": if name == "password":
self.last_login = st.st_mtime self.last_login = st.st_mtime
self.totalsize += st.st_size self.totalsize += st.st_size
@@ -108,8 +95,9 @@ def print_info(msg):
class Expiry: class Expiry:
def __init__(self, config, stat, dry, now): def __init__(self, config, stats, dry, now):
self.config = config self.config = config
self.stats = stats
self.dry = dry self.dry = dry
self.now = now self.now = now
self.del_files = [] self.del_files = []
@@ -119,13 +107,14 @@ class Expiry:
for mboxdir in self.del_mailboxes: for mboxdir in self.del_mailboxes:
print_info(f"removing {mboxdir}") print_info(f"removing {mboxdir}")
if not self.dry: if not self.dry:
self.rmtree(mboxdir) shutil.rmtree(mboxdir)
for path in self.del_files: for path in self.del_files:
print_info(f"removing {path}") print_info(f"removing {path}")
if not self.dry: if not self.dry:
try: try:
os.unlink(path) os.unlink(path)
except FileNotFoundError: except FileNotFoundError:
print_info(f"delete failed, file vanished? {path}")
pass # it's gone already, fine pass # it's gone already, fine
def process_mailbox_stat(self, mbox): def process_mailbox_stat(self, mbox):
@@ -143,9 +132,9 @@ class Expiry:
for message in mbox.messages: for message in mbox.messages:
if message.mtime < cutoff_mails: if message.mtime < cutoff_mails:
self.del_files.append(message.get_path()) self.del_files.append(joinpath(mbox.basedir, message.relpath))
elif message.size > 200000 and message.mtime < cutoff_large_mails: elif message.size > 200000 and message.mtime < cutoff_large_mails:
self.del_files.append(message.get_path()) self.del_files.append(joinpath(mbox.basedir, message.relpath))
else: else:
continue continue
changed = True changed = True
@@ -187,9 +176,9 @@ def main(args):
now = now - 86400 * int(args.days) now = now - 86400 * int(args.days)
maxnum = int(args.maxnum) if args.maxnum else None maxnum = int(args.maxnum) if args.maxnum else None
stat = Stats(args.mailboxes_dir, maxnum=maxnum) stats = Stats(args.mailboxes_dir, maxnum=maxnum)
exp = Expiry(config, stat, dry=not args.remove, now=now) exp = Expiry(config, stats, dry=not args.remove, now=now)
stat.iter_mailboxes(exp.process_mailbox_stat) stats.iter_mailboxes(exp.process_mailbox_stat)
exp.perform_removes() exp.perform_removes()

View File

@@ -39,6 +39,7 @@ class Report:
self.sum_extra = 0 self.sum_extra = 0
self.sum_all_messages = 0 self.sum_all_messages = 0
self.messages = [] self.messages = []
self.mailboxes = []
self.user_logins = [] self.user_logins = []
self.ci_logins = [] self.ci_logins = []
self.stats = stats self.stats = stats
@@ -52,6 +53,7 @@ class Report:
else: else:
self.user_logins.append(last_login) self.user_logins.append(last_login)
self.messages.extend(mailbox.messages) self.messages.extend(mailbox.messages)
self.mailboxes.append(mailbox)
self.sum_all_messages += sum(msg.size for msg in mailbox.messages) self.sum_all_messages += sum(msg.size for msg in mailbox.messages)
self.sum_extra += sum(entry.size for entry in mailbox.extrafiles) self.sum_extra += sum(entry.size for entry in mailbox.extrafiles)
@@ -83,7 +85,7 @@ class Report:
# list all 160K files of people who haven't logged in for a while # list all 160K files of people who haven't logged in for a while
messages = [] messages = []
cutoff_date_login = self.now - 30 * DAYSECONDS cutoff_date_login = self.now - 30 * DAYSECONDS
for mstat in self.stats.mailboxes: for mstat in self.mailboxes:
if mstat.last_login and mstat.last_login < cutoff_date_login: if mstat.last_login and mstat.last_login < cutoff_date_login:
for msg in mstat.messages: for msg in mstat.messages:
if msg.size > 160000: if msg.size > 160000:
@@ -132,7 +134,10 @@ def main(args=None):
"mailboxes_dir", action="store", help="path to directory of mailboxes" "mailboxes_dir", action="store", help="path to directory of mailboxes"
) )
parser.add_argument( parser.add_argument(
"--days", default=0, action="store", help="assume date to be days older than now" "--days",
default=0,
action="store",
help="assume date to be days older than now",
) )
parser.add_argument( parser.add_argument(

View File

@@ -1,7 +1,7 @@
import time import time
from chatmaild.doveauth import AuthDictProxy from chatmaild.doveauth import AuthDictProxy
from chatmaild.expire import run_expire from chatmaild.expire import main as main_expire
def test_login_timestamps(example_config): def test_login_timestamps(example_config):
@@ -45,7 +45,13 @@ def test_delete_inactive_users(example_config):
for addr in to_remove: for addr in to_remove:
assert example_config.get_user(addr).maildir.exists() assert example_config.get_user(addr).maildir.exists()
run_expire(example_config, example_config.mailboxes_dir) main_expire(
args=[
"--remove",
str(example_config._inipath),
str(example_config.mailboxes_dir),
]
)
for p in example_config.mailboxes_dir.iterdir(): for p in example_config.mailboxes_dir.iterdir():
assert not p.name.startswith("old") assert not p.name.startswith("old")

View File

@@ -46,10 +46,7 @@ def mbox1(basedir1):
def test_filentry_ordering(tmp_path): def test_filentry_ordering(tmp_path):
l = [ l = [FileEntry(f"x{i}", size=i + 10, mtime=1000 - i) for i in range(10)]
FileEntry(str(tmp_path), f"x{i}", size=i + 10, mtime=1000 - i)
for i in range(10)
]
sorted = list(l) sorted = list(l)
random.shuffle(l) random.shuffle(l)
l.sort(key=lambda x: x.size) l.sort(key=lambda x: x.size)
@@ -93,8 +90,6 @@ def test_expiry_cli_basic(example_config, mbox1):
def test_expiry_cli_old_files(capsys, example_config, mbox1): def test_expiry_cli_old_files(capsys, example_config, mbox1):
args = example_config._inipath, Path(mbox1.basedir).parent
relpaths_old = ["cur/msg_old1", "cur/msg_old1"] relpaths_old = ["cur/msg_old1", "cur/msg_old1"]
cutoff_days = int(example_config.delete_mails_after) + 1 cutoff_days = int(example_config.delete_mails_after) + 1
create_new_messages(mbox1.basedir, relpaths_old, size=1000, days=cutoff_days) create_new_messages(mbox1.basedir, relpaths_old, size=1000, days=cutoff_days)
@@ -107,6 +102,7 @@ def test_expiry_cli_old_files(capsys, example_config, mbox1):
create_new_messages(mbox1.basedir, ["cur/shouldstay"], size=1000 * 300, days=1) create_new_messages(mbox1.basedir, ["cur/shouldstay"], size=1000 * 300, days=1)
args = example_config._inipath, Path(mbox1.basedir).parent, "--remove"
expiry_main(args) expiry_main(args)
out, err = capsys.readouterr() out, err = capsys.readouterr()