dotfiles/office/.local/bin/mail-totask
Marty Oehme 7289522380
mail: Add mail- prefix to mail cli utilities
Rename mail utility programs (yet again), to be prefixed with `mail-`
instead of `neomutt-`. Also did not substitute with other MUA like
`aerc-` since these utilities are mostly independent of specific
implementations.

The very specific `neomutt-filer` implementation script I completely
removed since for aerc the same can be achieved with a simple
configuration option.
2025-09-24 10:40:17 +02:00

100 lines
3.1 KiB
Python
Executable file

#!/usr/bin/env python
"""
Creates a new task with corresponding description and tags.
Description and tags can be supplied via commandline through `-d` and `-t` options,
or interactively by using the options without supplying a string for them. E.g.:
`mail-totask` => task: Reply to <subject> from <sender>
`mail-totask -d "hello" -t one two` => task: hello +one +two
`mail-totask -d -t` => asks you interactively for description and tags
"""
import argparse
import email
import sys
import re
from tasklib import TaskWarrior, Task
def get_args():
parser = argparse.ArgumentParser(
description="Creates a task with given message and annotates the task with message id"
)
parser.add_argument(
"-d",
"--description",
nargs="?",
const=True,
default=None,
help="Supply a description for the task. Use the option as a flag to supply description interactively.",
)
parser.add_argument(
"-t",
"--tags",
nargs="*",
help="Supply any number of tags for the task. Use the option as a flag to supply tags interactively.",
)
parser.add_argument(
"-c",
"--clean",
action="store_true",
help="Remove subject annoyances like RE FWD on a best-effort basis.",
)
return parser.parse_args()
args = get_args()
def clean_subject(subject):
to_remove = ["fwd", "re", "fw", "aw", "wg", "sv", "vs", "ref", "tr"]
for abbrev in to_remove:
patt = re.compile(r"^{}(?: |:)\s*".format(abbrev), re.IGNORECASE)
subject = patt.sub("", subject)
return subject
def get_task_description(message):
subject = clean_subject(message["subject"]) if args.clean else message["subject"]
description = 'Reply to "{}" from {}'.format(
subject, message["from"].split(" <")[0]
)
# automatically set description if one provided
if args.description and isinstance(args.description, str):
description = args.description
# otherwise let user enter one if option has been passed
elif args.description:
inp = input("Enter task description or press enter for default: ")
description = inp if inp else description
return description
def get_task_tags():
tags = ["mail"]
if args.tags and len(args.tags) > 0:
tags = sum([tag.split(" ") for tag in args.tags], [])
elif args.tags is not None and len(args.tags) == 0:
inp = input("Enter task tags or press enter for default: ")
tags = inp.split(" ") if inp else tags
return tags
def main():
try:
message = email.message_from_file(sys.stdin)
if not message:
print("Something went wrong, cannot parse mail.")
sys.exit(1)
tw = TaskWarrior("~/.local/share/task", create=False)
sys.stdin = open("/dev/tty") # make user able to add input again
task = Task(tw, description=get_task_description(message), tags=get_task_tags())
task.save()
task.add_annotation(message['message-id'])
except Exception as e:
print(e)
sys.exit(2)
if __name__ == "__main__":
main()