dr.botzo/scripts/procmail-to-dispatch/procmail-to-dispatch.py

118 lines
3.8 KiB
Python
Raw Normal View History

"""Use dr.botzo's Dispatch to send mail notifications"""
import argparse
import getpass
import glob
import logging
import os
import re
import sys
import time
import requests
# set up some basic logging
logger = logging.getLogger()
handler = logging.StreamHandler(sys.stdout)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
# set up config flags
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--filename')
parser.add_argument('-l', '--location')
parser.add_argument('-u', '--user')
args = parser.parse_args()
if args.filename is None or args.user is None or args.location is None:
print("script needs -f/--filename (location of .procmailrc.log) "
"-l/--location (url to connect to) -u/--user (user to authenticate to XML-RPC as)")
sys.exit(2)
password = getpass.getpass("password for {0:s}: ".format(args.user))
auth = requests.auth.HTTPBasicAuth(args.user, password)
file = open(args.filename, 'r')
folderre = re.compile("^ Folder: (\S+)\s+\d+$")
senderre = re.compile("^From: (.*)$")
subjectre = re.compile("^Subject: (.*)$")
# start file at the end
st_results = os.stat(args.filename)
st_size = st_results[6]
file.seek(st_size)
def get_mail_items(filename):
"""Get info to notify about from an email in the maildir."""
sender = None
subject = None
for num, line in enumerate(open(filename)):
if senderre.search(line):
match = senderre.search(line)
sender = match.group(1)
if subjectre.search(line):
match = subjectre.search(line)
subject = match.group(1)
if sender and subject:
return (sender, subject)
if sender:
return (sender, "[no subject]")
while True:
try:
filename = None
where = file.tell()
line = file.readline()
if not line:
time.sleep(1)
file.seek(where)
else:
if folderre.search(line):
sender = None
subject = None
match = folderre.search(line)
filename = match.group(1)
# ignore /dev/null, of course
if filename == "/dev/null":
logger.debug("skipping message forwarded to /dev/null")
continue
# ignore Spam
if filename.find(".Spam") > 0:
logger.debug("skipping spam '{0:s}'".format(filename))
continue
# try opening the actual path. this is a bit racey
logger.debug("trying to open '{0:s}'".format(filename))
if os.path.isfile(filename):
logger.debug("opening '{0:s}'".format(filename))
(sender, subject) = get_mail_items(filename)
else:
# ok... maybe something already moved it into cur. in addition
# they probably added flags at the end
filepattern = filename.replace("/new", "/cur") + "*"
for globhit in glob.glob(filepattern):
logger.debug("trying to open '{0:s}'".format(globhit))
if os.path.isfile(globhit):
logger.debug("opening '{0:s}'".format(globhit))
(sender, subject) = get_mail_items(globhit)
if sender and subject:
logger.debug("notifying: '{0:s}' from {1:s}".format(subject, sender))
message = "'{0:s}' from {1:s}".format(subject, sender)
payload = {'message': message}
r = requests.post(args.location, verify=False, auth=auth, data=payload)
print(r.json())
except UnicodeDecodeError as e:
logger.error("Error: " + str(e) + ", skipping")
pass