Commit 73583c23 authored by T. Fischer's avatar T. Fischer

Adding Python scripts to manage recent email addresses in mutt

- 'learn-recentmail.py' search textual input (stdin) for patterns that
  look like email addresses and records them in a user-specific file.
- 'search-recentmail.py' answers a query for address completion from
  within mutt. It also invokes khard to add its results.
- 'recentmailaddresses.service' is a systemd user service to restore
  and save the database of recent email addresses at session start
  and stop.
parent fa353ee8
#!/usr/bin/env python3
import os
import sys
import re
import recentmail
def get_email_addresses(text):
emailre = re.compile(
r"(?:(?P<fullname>(?<=[:,] )(?:[^:\",;'*<@>]+[^:\",;'*<@> ]*[^:\",;'*<@>]+\b|'[^']+'|\"[^\"]+\"))\s+)?(?P<openinganglebracket><)?(?=[A-Z0-9][[email protected]_%+-]{5,253})(?P<emailaddress>[A-Z0-9._%+-]{1,64}@(?:(?=[A-Z0-9-]{1,63}\.)[A-Z0-9]+(?:-[A-Z0-9]+)*\.){1,8}[A-Z]{2,63})(?(openinganglebracket)>|)", flags=re.IGNORECASE)
emailaddresstuple = emailre.findall(text)
for (fullname, _, emailaddress) in emailaddresstuple:
emailaddress = emailaddress.lower().strip()
if emailaddress in fullname.lower():
fullname = None
else:
if any(needle in emailaddress for needle in ["bugzilla", "noreply", "no-reply", "-daemon", "jabber"]):
continue
if any(needle in fullname for needle in ["Jabber"]):
continue
for needle in ["US Nilex "]:
fullname = fullname.replace(needle, "")
if len(fullname) > 3 and ((fullname[0] == '"' and fullname[-1] == '"') or (fullname[0] == "'" and fullname[-1] == "'")):
fullname = fullname[1:-1]
yield (fullname if fullname else None, emailaddress)
def process_mailtext():
for line in sys.stdin:
print(line, end='')
for (fullname, emailaddress) in get_email_addresses(line):
nameset = recentmail.uniqueemailaddresses.setdefault(
emailaddress, set())
if fullname:
nameset.add(fullname)
recentmail.load(
"/tmp/.{username}.recentemailaddresses".format(username=os.getlogin()))
process_mailtext()
recentmail.save(
"/tmp/.{username}.recentemailaddresses".format(username=os.getlogin()))
uniqueemailaddresses = {}
def load(filename):
try:
with open(filename, "r") as f:
emailaddress = None
for line in f:
line = line.rstrip()
if len(line) < 2:
continue
if line[0] != " ":
if emailaddress and not emailaddress in uniqueemailaddresses:
uniqueemailaddresses[emailaddress] = set()
emailaddress = line
else:
fullname = line.lstrip()
if fullname:
uniqueemailaddresses.setdefault(
emailaddress, set()).add(fullname)
except FileNotFoundError:
pass # Ignore if file does not exist
def save(filename):
with open(filename, "w") as f:
for emailaddress in sorted(uniqueemailaddresses):
print(emailaddress, file=f)
for fullname in sorted(uniqueemailaddresses[emailaddress]):
if fullname.lower() != emailaddress:
print(" ", fullname, file=f)
[Unit]
Description=Restore and save database of recently used email addresses
[Service]
Type=oneshot
ExecStart=/usr/bin/bash -c "/usr/bin/unxz <%h/.recentemailaddresses.xz >/tmp/.%u.recentemailaddresses ; chmod 600 /tmp/.%u.recentemailaddresses"
ExecStop=/usr/bin/bash -c "/usr/bin/xz </tmp/.%u.recentemailaddresses >%h/.recentemailaddresses.xz ; rm -f /tmp/.%u.recentemailaddresses"
RemainAfterExit=yes
[Install]
WantedBy=default.target
#!/usr/bin/env python3
import sys
import os
import recentmail
recentmail.load(
"/tmp/.{username}.recentemailaddresses".format(username=os.getlogin()))
os.system(
"khard email --parsable '{}'".format(sys.argv[-1]))
needle = sys.argv[-1].lower()
for emailaddress in sorted(recentmail.uniqueemailaddresses):
printedsomething = False
for fullname in sorted(recentmail.uniqueemailaddresses[emailaddress]):
if fullname:
printedsomething = True
if needle in emailaddress.lower() or needle in fullname.lower():
print(emailaddress, fullname, "recent", sep="\t")
if not printedsomething:
fullname = emailaddress.split('@')[0]
if needle in emailaddress.lower():
print(emailaddress, fullname, "recent", sep="\t")
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment