Files
autoreply-editor/autoreply_editor/main.py

192 lines
5.5 KiB
Python
Raw Normal View History

2021-05-19 09:30:01 +02:00
"""Provide basic settings and views"""
2021-12-19 22:25:09 +01:00
import fileinput
import os
2021-12-19 22:00:41 +01:00
import re
import shutil
2021-12-19 22:00:41 +01:00
from pathlib import Path
from flask import abort, request, render_template
2021-05-19 09:17:41 +02:00
from flask_basicauth import BasicAuth
from jinja2 import Template
2021-05-19 09:30:01 +02:00
from autoreply_editor import app
2021-05-19 09:17:41 +02:00
basic_auth = BasicAuth(app)
2021-05-18 19:15:49 +02:00
2021-12-23 12:36:15 +01:00
2021-12-19 22:00:41 +01:00
def qmail_status(user):
"""Find out whether the filter is currently activated for the given mail user"""
with open(get_qmailfile(user), encoding="utf8") as qmailfile:
# trigger to check whether we have to re-open the file for initialisation
initialise = False
# try to find active filter
if re.search(
2021-12-23 12:36:15 +01:00
rf"{get_maildropline(user, active=True, regex=True)}",
qmailfile.read(),
re.MULTILINE,
2021-12-19 22:00:41 +01:00
):
return True
else:
# jump back to top of file because we've read it in the "if"
qmailfile.seek(0)
# filter is deactivated (commented)
if re.search(
2021-12-23 12:36:15 +01:00
rf"{get_maildropline(user, active=False, regex=True)}",
qmailfile.read(),
re.MULTILINE,
):
return False
2021-12-23 12:36:15 +01:00
# The maildrop line does not exist in the expected form
else:
initialise = True
# Append a commented filter command to the file
if initialise:
2021-12-23 12:36:15 +01:00
with open(get_qmailfile(user), mode="a", encoding="utf8") as qmailfile:
qmailfile.write(f"{get_maildropline(user, active=False)}")
return False
2021-12-23 13:32:46 +01:00
def check_user(user):
"""Check if user exists"""
2021-12-23 13:57:13 +01:00
fulluser = [
item for item in app.config.get("USERS") if item[1].split("@")[0] == user
]
if not fulluser:
return False
else:
2021-12-23 13:32:46 +01:00
return fulluser[0]
def get_messagefile(user):
"""Return message file of user, and create if necessary"""
filepath = f"message-{user}.txt"
if not os.path.isfile(filepath):
Path(filepath).touch()
return filepath
def get_qmailfile(user):
"""Return qmail file of user, and create if necessary based on default qmail"""
qmail_base = f"{str(Path.home())}/.qmail"
filepath = f"{qmail_base}-{user}"
if not os.path.isfile(filepath):
shutil.copy(f"{qmail_base}-default", filepath)
return filepath
2021-12-19 22:00:41 +01:00
def get_filterfile(user):
"""Return .filter-autoreply file of user, and create if necessary"""
filter_base = f"{str(Path.home())}/.filter-autoreply"
filepath = f"{filter_base}-{user}"
if not os.path.isfile(filepath):
2021-12-23 12:36:15 +01:00
with open(
os.path.join(app.root_path, "templates/filterfile.j2"), encoding="utf-8"
) as template:
filterconfig = Template(template.read()).render(
2021-12-23 13:32:46 +01:00
email=check_user(user)[1],
user=user,
2021-12-23 13:32:46 +01:00
name=check_user(user)[0],
2021-12-23 12:36:15 +01:00
messagefile=get_messagefile(user),
)
with open(filepath, "w", encoding="utf-8") as filterfile:
filterfile.write(filterconfig)
return filepath
2021-12-23 12:36:15 +01:00
def get_maildropline(user, active=True, regex=False):
"""
Define the line calling maildrop, with options to have the line disabled or
in Regex format
"""
base = f"|maildrop {get_filterfile(user)}"
2021-12-23 12:36:15 +01:00
# If the filter should be inactive, we comment it
if not active:
base = f"#{base}"
# depending on whether it should be RE escaped or not, return the line
2021-12-23 12:10:36 +01:00
if regex:
2021-12-23 12:36:15 +01:00
return f"^{re.escape(base)}$"
2021-12-23 12:10:36 +01:00
else:
2021-12-23 12:36:15 +01:00
return base
2021-05-18 19:15:49 +02:00
@app.route("/")
def index():
"""Index page listing available users"""
return render_template(
"index.html",
users=app.config.get("USERS"),
)
2021-12-23 13:57:13 +01:00
@app.route("/user/<user>")
def user_status(user):
"""Status for specific user"""
# Check if user is valid
if not check_user(user):
abort(404)
2021-12-23 13:57:13 +01:00
with open(get_messagefile(user), "r", encoding="utf-8") as messagefile:
2021-12-19 22:00:41 +01:00
message = messagefile.read()
return render_template(
"user.html",
2021-12-19 22:00:41 +01:00
message=message,
qmail_status=qmail_status(user),
2021-12-19 22:00:41 +01:00
)
2021-05-18 19:15:49 +02:00
2021-05-18 19:32:59 +02:00
@app.route("/user/<user>", methods=["POST"])
def user_update(user):
"""Update user with POST request"""
# Check if user is valid
if not check_user(user):
abort(404)
2021-12-23 12:37:02 +01:00
if request.form["action"] == "message":
input_message = request.form["message"]
2021-12-23 13:57:13 +01:00
with open(get_messagefile(user), "w", encoding="utf-8") as messagefile:
2021-12-23 12:37:02 +01:00
messagefile.write(str(input_message))
result = "Success: The autoreply message has been updated!"
if request.form["action"] == "qmail":
# define whether to set a comment
if request.form["status"] == "on":
state_current = get_maildropline(user, active=False)
state_desired = get_maildropline(user)
2021-12-23 12:37:02 +01:00
else:
state_current = get_maildropline(user)
state_desired = get_maildropline(user, active=False)
2021-12-23 12:37:02 +01:00
with fileinput.FileInput(
get_qmailfile(user),
2021-12-23 12:37:02 +01:00
inplace=True,
) as qmailfile:
for line in qmailfile:
print(
line.replace(state_current, state_desired),
end="",
2021-12-23 12:36:15 +01:00
)
2021-12-19 22:25:09 +01:00
2021-12-23 12:37:02 +01:00
result = f"Success: the autoreply is now {request.form['status']}."
2021-05-19 10:23:47 +02:00
2021-12-19 22:00:41 +01:00
try:
return render_template("update.html", user=user, result=result)
2021-12-19 22:00:41 +01:00
except UnboundLocalError:
2021-12-23 13:57:13 +01:00
return render_template(
"update.html", user=user, result="Something went terribly wrong!"
)
@app.errorhandler(404)
2021-12-23 13:57:13 +01:00
def page_not_found(error):
"""Error for 404"""
return render_template("error.html", error=error), 404