add action to store message in file

This commit is contained in:
2020-06-17 15:04:25 +02:00
parent 3c40776542
commit d592ca59cf
2 changed files with 37 additions and 5 deletions

View File

@@ -13,16 +13,17 @@
#
import logging
import os
import re
from bs4 import BeautifulSoup
from collections import defaultdict
from copy import copy
from datetime import datetime
from email.header import Header
from email.parser import BytesFeedParser
from email.message import MIMEPart
from email.policy import default as default_policy, SMTP
from os import linesep
from pymodmilter import CustomLogger, Conditions
@@ -384,13 +385,36 @@ def add_disclaimer(text, html, action, policy, milter, pretend=False,
milter=milter, pretend=pretend, logger=logger)
def store(directory, milter, pretend=False,
logger=logging.getLogger(__name__)):
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
store_id = f"{timestamp}_{milter.qid}"
datafile = os.path.join(directory, store_id)
milter.fp.seek(0)
logger.info("store message in file {datafile}")
try:
with open(datafile, "wb") as fp:
for field, value in milter.fields:
encoded_value = _replace_illegal_chars(
Header(s=value).encode())
fp.write(field.encode("ascii", errors="replace"))
fp.write(b": ")
fp.write(encoded_value.encode("ascii", errors="replace"))
fp.write(b"\r\n")
fp.write(b"\r\n")
fp.write(milter.fp.read())
except IOError as e:
raise RuntimeError(f"unable to store message: {e}")
class Action:
"""Action to implement a pre-configured action to perform on e-mails."""
_types = {
"add_header": ["fields"],
"del_header": ["fields"],
"mod_header": ["fields"],
"add_disclaimer": ["fields", "body"]}
"add_disclaimer": ["fields", "body"],
"store": ["fields", "body"]}
def __init__(self, name, local_addrs, conditions, action_type, args,
loglevel=logging.INFO, pretend=False):
@@ -406,7 +430,7 @@ class Action:
self._args = {}
if action_type not in self._types:
raise RuntimeError(f"invalid action_type '{action_type}'")
raise RuntimeError(f"invalid action type '{action_type}'")
self._needs = self._types[action_type]
try:
@@ -465,8 +489,16 @@ class Action:
self._args["text"] = f.read()
except IOError as e:
raise RuntimeError(f"unable to read template: {e}")
elif action_type == "store":
self._func = store
if args["storage_type"] not in ["file"]:
raise RuntimeError(
f"invalid storage_type 'args['storage_type']'")
if args["storage_type"] == "file":
self._args["directory"] = args["directory"]
else:
raise RuntimeError(f"unknown action type: {action_type}")
raise RuntimeError(f"invalid action type: {action_type}")
except KeyError as e:
raise RuntimeError(