Make source PEP8 conform

This commit is contained in:
2019-10-17 22:25:10 +02:00
parent 6ea167bc52
commit 89a01d92c8
7 changed files with 865 additions and 366 deletions

View File

@@ -4,12 +4,12 @@
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
#
# PyQuarantine-Milter is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with PyQuarantineMilter. If not, see <http://www.gnu.org/licenses/>.
#
@@ -25,7 +25,8 @@ import pyquarantine
def _get_quarantine_obj(config, quarantine):
try:
quarantine_obj = next((q["quarantine_obj"] for q in config if q["name"] == quarantine))
quarantine_obj = next((q["quarantine_obj"]
for q in config if q["name"] == quarantine))
except StopIteration:
raise RuntimeError("invalid quarantine '{}'".format(quarantine))
return quarantine_obj
@@ -33,7 +34,8 @@ def _get_quarantine_obj(config, quarantine):
def _get_whitelist_obj(config, quarantine):
try:
whitelist_obj = next((q["whitelist_obj"] for q in config if q["name"] == quarantine))
whitelist_obj = next((q["whitelist_obj"]
for q in config if q["name"] == quarantine))
except StopIteration:
raise RuntimeError("invalid quarantine '{}'".format(quarantine))
return whitelist_obj
@@ -51,7 +53,8 @@ def print_table(columns, rows):
# get the length of the header string
lengths = [len(header)]
# get the length of the longest value
lengths.append(len(str(max(rows, key=lambda x: len(str(x[key])))[key])))
lengths.append(
len(str(max(rows, key=lambda x: len(str(x[key])))[key])))
# use the the longer one
length = max(lengths)
column_lengths.append(length)
@@ -70,7 +73,7 @@ def print_table(columns, rows):
print(row_format.format(*[column[0] for column in columns]))
print(separator)
keys = [ entry[1] for entry in columns ]
keys = [entry[1] for entry in columns]
# print rows
for entry in rows:
row = []
@@ -81,10 +84,11 @@ def print_table(columns, rows):
def list_quarantines(config, args):
if args.batch:
print("\n".join([ quarantine["name"] for quarantine in config ]))
print("\n".join([quarantine["name"] for quarantine in config]))
else:
print_table(
[("Name", "name"), ("Quarantine", "quarantine_type"), ("Notification", "notification_type"), ("Action", "action")],
[("Name", "name"), ("Quarantine", "quarantine_type"),
("Notification", "notification_type"), ("Action", "action")],
config
)
@@ -94,16 +98,23 @@ def list_quarantine_emails(config, args):
# get quarantine object
quarantine = _get_quarantine_obj(config, args.quarantine)
if quarantine == None:
raise RuntimeError("quarantine type is set to None, unable to list emails")
if quarantine is None:
raise RuntimeError(
"quarantine type is set to None, unable to list emails")
# find emails and transform some metadata values to strings
rows = []
emails = quarantine.find(mailfrom=args.mailfrom, recipients=args.recipients, older_than=args.older_than)
emails = quarantine.find(
mailfrom=args.mailfrom,
recipients=args.recipients,
older_than=args.older_than)
for quarantine_id, metadata in emails.items():
row = emails[quarantine_id]
row["quarantine_id"] = quarantine_id
row["date"] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(metadata["date"]))
row["date"] = time.strftime(
'%Y-%m-%d %H:%M:%S',
time.localtime(
metadata["date"]))
row["mailfrom"] = metadata["mailfrom"]
row["recipient"] = metadata["recipients"].pop(0)
row["subject"] = emails[quarantine_id]["headers"]["subject"][:60]
@@ -124,9 +135,12 @@ def list_quarantine_emails(config, args):
print("\n".join(emails.keys()))
return
if not emails: logger.info("quarantine '{}' is empty".format(args.quarantine))
if not emails:
logger.info("quarantine '{}' is empty".format(args.quarantine))
print_table(
[("Quarantine-ID", "quarantine_id"), ("Date", "date"), ("From", "mailfrom"), ("Recipient(s)", "recipient"), ("Subject", "subject")],
[("Quarantine-ID", "quarantine_id"), ("Date", "date"),
("From", "mailfrom"), ("Recipient(s)", "recipient"),
("Subject", "subject")],
rows
)
@@ -136,25 +150,34 @@ def list_whitelist(config, args):
# get whitelist object
whitelist = _get_whitelist_obj(config, args.quarantine)
if whitelist == None:
raise RuntimeError("whitelist type is set to None, unable to list entries")
if whitelist is None:
raise RuntimeError(
"whitelist type is set to None, unable to list entries")
# find whitelist entries
entries = whitelist.find(mailfrom=args.mailfrom, recipients=args.recipients, older_than=args.older_than)
entries = whitelist.find(
mailfrom=args.mailfrom,
recipients=args.recipients,
older_than=args.older_than)
if not entries:
logger.info("whitelist of quarantine '{}' is empty".format(args.quarantine))
logger.info(
"whitelist of quarantine '{}' is empty".format(
args.quarantine))
return
# transform some values to strings
for entry_id, entry in entries.items():
entries[entry_id]["permanent_str"] = str(entry["permanent"])
entries[entry_id]["created_str"] = entry["created"].strftime('%Y-%m-%d %H:%M:%S')
entries[entry_id]["last_used_str"] = entry["last_used"].strftime('%Y-%m-%d %H:%M:%S')
entries[entry_id]["created_str"] = entry["created"].strftime(
'%Y-%m-%d %H:%M:%S')
entries[entry_id]["last_used_str"] = entry["last_used"].strftime(
'%Y-%m-%d %H:%M:%S')
print_table(
[
("ID", "id"), ("From", "mailfrom"), ("To", "recipient"), ("Created", "created_str"),
("Last used", "last_used_str"), ("Comment", "comment"), ("Permanent", "permanent_str")
("ID", "id"), ("From", "mailfrom"), ("To", "recipient"),
("Created", "created_str"), ("Last used", "last_used_str"),
("Comment", "comment"), ("Permanent", "permanent_str")
],
entries.values()
)
@@ -165,32 +188,40 @@ def add_whitelist_entry(config, args):
# get whitelist object
whitelist = _get_whitelist_obj(config, args.quarantine)
if whitelist == None:
raise RuntimeError("whitelist type is set to None, unable to add entries")
if whitelist is None:
raise RuntimeError(
"whitelist type is set to None, unable to add entries")
# check existing entries
entries = whitelist.check(args.mailfrom, args.recipient)
if entries:
# check if the exact entry exists already
for entry in entries.values():
if entry["mailfrom"] == args.mailfrom and entry["recipient"] == args.recipient:
raise RuntimeError("an entry with this from/to combination already exists")
if entry["mailfrom"] == args.mailfrom and \
entry["recipient"] == args.recipient:
raise RuntimeError(
"an entry with this from/to combination already exists")
if not args.force:
# the entry is already covered by others
for entry_id, entry in entries.items():
entries[entry_id]["permanent_str"] = str(entry["permanent"])
entries[entry_id]["created_str"] = entry["created"].strftime('%Y-%m-%d %H:%M:%S')
entries[entry_id]["last_used_str"] = entry["last_used"].strftime('%Y-%m-%d %H:%M:%S')
entries[entry_id]["created_str"] = entry["created"].strftime(
'%Y-%m-%d %H:%M:%S')
entries[entry_id]["last_used_str"] = entry["last_used"].strftime(
'%Y-%m-%d %H:%M:%S')
print_table(
[
("ID", "id"), ("From", "mailfrom"), ("To", "recipient"), ("Created", "created_str"),
("Last used", "last_used_str"), ("Comment", "comment"), ("Permanent", "permanent_str")
("ID", "id"), ("From", "mailfrom"), ("To", "recipient"),
("Created", "created_str"), ("Last used", "last_used_str"),
("Comment", "comment"), ("Permanent", "permanent_str")
],
entries.values()
)
print("")
raise RuntimeError("from/to combination is already covered by the entries above, use --force to override.")
raise RuntimeError(
"from/to combination is already covered by the entries above, "
"use --force to override.")
# add entry to whitelist
whitelist.add(args.mailfrom, args.recipient, args.comment, args.permanent)
@@ -201,8 +232,9 @@ def delete_whitelist_entry(config, args):
logger = logging.getLogger(__name__)
whitelist = _get_whitelist_obj(config, args.quarantine)
if whitelist == None:
raise RuntimeError("whitelist type is set to None, unable to delete entries")
if whitelist is None:
raise RuntimeError(
"whitelist type is set to None, unable to delete entries")
whitelist.delete(args.whitelist_id)
logger.info("whitelist entry deleted successfully")
@@ -212,8 +244,9 @@ def notify_email(config, args):
logger = logging.getLogger(__name__)
quarantine = _get_quarantine_obj(config, args.quarantine)
if quarantine == None:
raise RuntimeError("quarantine type is set to None, unable to send notification")
if quarantine is None:
raise RuntimeError(
"quarantine type is set to None, unable to send notification")
quarantine.notify(args.quarantine_id, args.recipient)
logger.info("sent notification successfully")
@@ -222,8 +255,9 @@ def release_email(config, args):
logger = logging.getLogger(__name__)
quarantine = _get_quarantine_obj(config, args.quarantine)
if quarantine == None:
raise RuntimeError("quarantine type is set to None, unable to release email")
if quarantine is None:
raise RuntimeError(
"quarantine type is set to None, unable to release email")
quarantine.release(args.quarantine_id, args.recipient)
logger.info("quarantined email released successfully")
@@ -233,8 +267,9 @@ def delete_email(config, args):
logger = logging.getLogger(__name__)
quarantine = _get_quarantine_obj(config, args.quarantine)
if quarantine == None:
raise RuntimeError("quarantine type is set to None, unable to delete email")
if quarantine is None:
raise RuntimeError(
"quarantine type is set to None, unable to delete email")
quarantine.delete(args.quarantine_id, args.recipient)
logger.info("quarantined email deleted successfully")
@@ -253,78 +288,233 @@ class StdOutFilter(logging.Filter):
def main():
"PyQuarantine command-line interface."
# parse command line
formatter_class = lambda prog: argparse.HelpFormatter(prog, max_help_position=50, width=140)
parser = argparse.ArgumentParser(description="PyQuarantine CLI", formatter_class=formatter_class)
parser.add_argument("-c", "--config", help="Config files to read.", nargs="+", metavar="CFG",
default=pyquarantine.QuarantineMilter.get_configfiles())
parser.add_argument("-d", "--debug", help="Log debugging messages.", action="store_true")
def formatter_class(prog): return argparse.HelpFormatter(
prog, max_help_position=50, width=140)
parser = argparse.ArgumentParser(
description="PyQuarantine CLI",
formatter_class=formatter_class)
parser.add_argument(
"-c", "--config",
help="Config files to read.",
nargs="+", metavar="CFG",
default=pyquarantine.QuarantineMilter.get_configfiles())
parser.add_argument(
"-d", "--debug",
help="Log debugging messages.",
action="store_true")
parser.set_defaults(syslog=False)
subparsers = parser.add_subparsers(dest="command", title="Commands")
subparsers = parser.add_subparsers(
dest="command",
title="Commands")
subparsers.required = True
# list command
list_parser = subparsers.add_parser("list", help="List available quarantines.", formatter_class=formatter_class)
list_parser.add_argument("-b", "--batch", help="Print results using only quarantine names, each on a new line.", action="store_true")
list_parser = subparsers.add_parser(
"list",
help="List available quarantines.",
formatter_class=formatter_class)
list_parser.add_argument(
"-b", "--batch",
help="Print results using only quarantine names, each on a new line.",
action="store_true")
list_parser.set_defaults(func=list_quarantines)
# quarantine command group
quarantine_parser = subparsers.add_parser("quarantine", description="Manage quarantines.", help="Manage quarantines.", formatter_class=formatter_class)
quarantine_parser.add_argument("quarantine", metavar="QUARANTINE", help="Quarantine name.")
quarantine_subparsers = quarantine_parser.add_subparsers(dest="command", title="Quarantine commands")
quarantine_parser = subparsers.add_parser(
"quarantine",
description="Manage quarantines.",
help="Manage quarantines.",
formatter_class=formatter_class)
quarantine_parser.add_argument(
"quarantine",
metavar="QUARANTINE",
help="Quarantine name.")
quarantine_subparsers = quarantine_parser.add_subparsers(
dest="command",
title="Quarantine commands")
quarantine_subparsers.required = True
# quarantine list command
quarantine_list_parser = quarantine_subparsers.add_parser("list", description="List emails in quarantines.", help="List emails in quarantine.", formatter_class=formatter_class)
quarantine_list_parser.add_argument("-f", "--from", dest="mailfrom", help="Filter emails by from address.", default=None, nargs="+")
quarantine_list_parser.add_argument("-t", "--to", dest="recipients", help="Filter emails by recipient address.", default=None, nargs="+")
quarantine_list_parser.add_argument("-o", "--older-than", dest="older_than", help="Filter emails by age (days).", default=None, type=float)
quarantine_list_parser.add_argument("-b", "--batch", help="Print results using only email quarantine IDs, each on a new line.", action="store_true")
quarantine_list_parser = quarantine_subparsers.add_parser(
"list",
description="List emails in quarantines.",
help="List emails in quarantine.",
formatter_class=formatter_class)
quarantine_list_parser.add_argument(
"-f", "--from",
dest="mailfrom",
help="Filter emails by from address.",
default=None,
nargs="+")
quarantine_list_parser.add_argument(
"-t", "--to",
dest="recipients",
help="Filter emails by recipient address.",
default=None,
nargs="+")
quarantine_list_parser.add_argument(
"-o", "--older-than",
dest="older_than",
help="Filter emails by age (days).",
default=None,
type=float)
quarantine_list_parser.add_argument(
"-b", "--batch",
help="Print results using only email quarantine IDs, each on a new line.",
action="store_true")
quarantine_list_parser.set_defaults(func=list_quarantine_emails)
# quarantine notify command
quarantine_notify_parser = quarantine_subparsers.add_parser("notify", description="Notify recipient about email in quarantine.", help="Notify recipient about email in quarantine.", formatter_class=formatter_class)
quarantine_notify_parser.add_argument("quarantine_id", metavar="ID", help="Quarantine ID.")
quarantine_notify_parser_group = quarantine_notify_parser.add_mutually_exclusive_group(required=True)
quarantine_notify_parser_group.add_argument("-t", "--to", dest="recipient", help="Release email for one recipient address.")
quarantine_notify_parser_group.add_argument("-a", "--all", help="Release email for all recipients.", action="store_true")
quarantine_notify_parser = quarantine_subparsers.add_parser(
"notify",
description="Notify recipient about email in quarantine.",
help="Notify recipient about email in quarantine.",
formatter_class=formatter_class)
quarantine_notify_parser.add_argument(
"quarantine_id",
metavar="ID",
help="Quarantine ID.")
quarantine_notify_parser_group = quarantine_notify_parser.add_mutually_exclusive_group(
required=True)
quarantine_notify_parser_group.add_argument(
"-t", "--to",
dest="recipient",
help="Release email for one recipient address.")
quarantine_notify_parser_group.add_argument(
"-a", "--all",
help="Release email for all recipients.",
action="store_true")
quarantine_notify_parser.set_defaults(func=notify_email)
# quarantine release command
quarantine_release_parser = quarantine_subparsers.add_parser("release", description="Release email from quarantine.", help="Release email from quarantine.", formatter_class=formatter_class)
quarantine_release_parser.add_argument("quarantine_id", metavar="ID", help="Quarantine ID.")
quarantine_release_parser.add_argument("-n", "--disable-syslog", dest="syslog", help="Disable syslog messages.", action="store_false")
quarantine_release_parser_group = quarantine_release_parser.add_mutually_exclusive_group(required=True)
quarantine_release_parser_group.add_argument("-t", "--to", dest="recipient", help="Release email for one recipient address.")
quarantine_release_parser_group.add_argument("-a", "--all", help="Release email for all recipients.", action="store_true")
quarantine_release_parser = quarantine_subparsers.add_parser(
"release",
description="Release email from quarantine.",
help="Release email from quarantine.",
formatter_class=formatter_class)
quarantine_release_parser.add_argument(
"quarantine_id",
metavar="ID",
help="Quarantine ID.")
quarantine_release_parser.add_argument(
"-n",
"--disable-syslog",
dest="syslog",
help="Disable syslog messages.",
action="store_false")
quarantine_release_parser_group = quarantine_release_parser.add_mutually_exclusive_group(
required=True)
quarantine_release_parser_group.add_argument(
"-t", "--to",
dest="recipient",
help="Release email for one recipient address.")
quarantine_release_parser_group.add_argument(
"-a", "--all",
help="Release email for all recipients.",
action="store_true")
quarantine_release_parser.set_defaults(func=release_email)
# quarantine delete command
quarantine_delete_parser = quarantine_subparsers.add_parser("delete", description="Delete email from quarantine.", help="Delete email from quarantine.", formatter_class=formatter_class)
quarantine_delete_parser.add_argument("quarantine_id", metavar="ID", help="Quarantine ID.")
quarantine_delete_parser.add_argument("-n", "--disable-syslog", dest="syslog", help="Disable syslog messages.", action="store_false")
quarantine_delete_parser_group = quarantine_delete_parser.add_mutually_exclusive_group(required=True)
quarantine_delete_parser_group.add_argument("-t", "--to", dest="recipient", help="Delete email for one recipient address.")
quarantine_delete_parser_group.add_argument("-a", "--all", help="Delete email for all recipients.", action="store_true")
quarantine_delete_parser = quarantine_subparsers.add_parser(
"delete",
description="Delete email from quarantine.",
help="Delete email from quarantine.",
formatter_class=formatter_class)
quarantine_delete_parser.add_argument(
"quarantine_id",
metavar="ID",
help="Quarantine ID.")
quarantine_delete_parser.add_argument(
"-n", "--disable-syslog",
dest="syslog",
help="Disable syslog messages.",
action="store_false")
quarantine_delete_parser_group = quarantine_delete_parser.add_mutually_exclusive_group(
required=True)
quarantine_delete_parser_group.add_argument(
"-t", "--to",
dest="recipient",
help="Delete email for one recipient address.")
quarantine_delete_parser_group.add_argument(
"-a", "--all",
help="Delete email for all recipients.",
action="store_true")
quarantine_delete_parser.set_defaults(func=delete_email)
# whitelist command group
whitelist_parser = subparsers.add_parser("whitelist", description="Manage whitelists.", help="Manage whitelists.", formatter_class=formatter_class)
whitelist_parser.add_argument("quarantine", metavar="QUARANTINE", help="Quarantine name.")
whitelist_subparsers = whitelist_parser.add_subparsers(dest="command", title="Whitelist commands")
whitelist_parser = subparsers.add_parser(
"whitelist",
description="Manage whitelists.",
help="Manage whitelists.",
formatter_class=formatter_class)
whitelist_parser.add_argument(
"quarantine",
metavar="QUARANTINE",
help="Quarantine name.")
whitelist_subparsers = whitelist_parser.add_subparsers(
dest="command",
title="Whitelist commands")
whitelist_subparsers.required = True
# whitelist list command
whitelist_list_parser = whitelist_subparsers.add_parser("list", description="List whitelist entries.", help="List whitelist entries.", formatter_class=formatter_class)
whitelist_list_parser.add_argument("-f", "--from", dest="mailfrom", help="Filter entries by from address.", default=None, nargs="+")
whitelist_list_parser.add_argument("-t", "--to", dest="recipients", help="Filter entries by recipient address.", default=None, nargs="+")
whitelist_list_parser.add_argument("-o", "--older-than", dest="older_than", help="Filter emails by last used date (days).", default=None, type=float)
whitelist_list_parser = whitelist_subparsers.add_parser(
"list",
description="List whitelist entries.",
help="List whitelist entries.",
formatter_class=formatter_class)
whitelist_list_parser.add_argument(
"-f", "--from",
dest="mailfrom",
help="Filter entries by from address.",
default=None,
nargs="+")
whitelist_list_parser.add_argument(
"-t", "--to",
dest="recipients",
help="Filter entries by recipient address.",
default=None,
nargs="+")
whitelist_list_parser.add_argument(
"-o", "--older-than",
dest="older_than",
help="Filter emails by last used date (days).",
default=None,
type=float)
whitelist_list_parser.set_defaults(func=list_whitelist)
# whitelist add command
whitelist_add_parser = whitelist_subparsers.add_parser("add", description="Add whitelist entry.", help="Add whitelist entry.", formatter_class=formatter_class)
whitelist_add_parser.add_argument("-f", "--from", dest="mailfrom", help="From address.", required=True)
whitelist_add_parser.add_argument("-t", "--to", dest="recipient", help="Recipient address.", required=True)
whitelist_add_parser.add_argument("-c", "--comment", help="Comment.", default="added by CLI")
whitelist_add_parser.add_argument("-p", "--permanent", help="Add a permanent entry.", action="store_true")
whitelist_add_parser.add_argument("--force", help="Force adding an entry, even if already covered by another entry.", action="store_true")
whitelist_add_parser = whitelist_subparsers.add_parser(
"add",
description="Add whitelist entry.",
help="Add whitelist entry.",
formatter_class=formatter_class)
whitelist_add_parser.add_argument(
"-f", "--from",
dest="mailfrom",
help="From address.",
required=True)
whitelist_add_parser.add_argument(
"-t", "--to",
dest="recipient",
help="Recipient address.",
required=True)
whitelist_add_parser.add_argument(
"-c", "--comment",
help="Comment.",
default="added by CLI")
whitelist_add_parser.add_argument(
"-p", "--permanent",
help="Add a permanent entry.",
action="store_true")
whitelist_add_parser.add_argument(
"--force",
help="Force adding an entry, even if already covered by another entry.",
action="store_true")
whitelist_add_parser.set_defaults(func=add_whitelist_entry)
# whitelist delete command
whitelist_delete_parser = whitelist_subparsers.add_parser("delete", description="Delete whitelist entry.", help="Delete whitelist entry.", formatter_class=formatter_class)
whitelist_delete_parser.add_argument("whitelist_id", metavar="ID", help="Whitelist ID.")
whitelist_delete_parser = whitelist_subparsers.add_parser(
"delete",
description="Delete whitelist entry.",
help="Delete whitelist entry.",
formatter_class=formatter_class)
whitelist_delete_parser.add_argument(
"whitelist_id",
metavar="ID",
help="Whitelist ID.")
whitelist_delete_parser.set_defaults(func=delete_whitelist_entry)
args = parser.parse_args()
@@ -336,7 +526,8 @@ def main():
# setup console log
if args.debug:
formatter = logging.Formatter("%(levelname)s: [%(name)s] - %(message)s")
formatter = logging.Formatter(
"%(levelname)s: [%(name)s] - %(message)s")
else:
formatter = logging.Formatter("%(levelname)s: %(message)s")
# stdout
@@ -355,17 +546,21 @@ def main():
# try to generate milter configs
try:
global_config, config = pyquarantine.generate_milter_config(config_files=args.config, configtest=True)
global_config, config = pyquarantine.generate_milter_config(
config_files=args.config, configtest=True)
except RuntimeError as e:
logger.error(e)
sys.exit(255)
if args.syslog:
# setup syslog
sysloghandler = logging.handlers.SysLogHandler(address="/dev/log", facility=logging.handlers.SysLogHandler.LOG_MAIL)
sysloghandler = logging.handlers.SysLogHandler(
address="/dev/log",
facility=logging.handlers.SysLogHandler.LOG_MAIL)
sysloghandler.setLevel(loglevel)
if args.debug:
formatter = logging.Formatter("pyquarantine: [%(name)s] [%(levelname)s] %(message)s")
formatter = logging.Formatter(
"pyquarantine: [%(name)s] [%(levelname)s] %(message)s")
else:
formatter = logging.Formatter("pyquarantine: %(message)s")
sysloghandler.setFormatter(formatter)