key is now part of the URL, and the dispatcher action will choose whether or not to include it, so we don't need key at all anymore
122 lines
3.8 KiB
Python
122 lines
3.8 KiB
Python
"""
|
|
procmail-to-dispatch.py --- 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 == None or args.user == None or
|
|
args.location == 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):
|
|
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 1:
|
|
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
|
|
|
|
# vi:tabstop=4:expandtab:autoindent
|