procmail-to-dispatch.py: send email notifications
this is a python3 example of how one might use Dispatch to send notifications on events. it's nothing robust but it gets the job done, generally
This commit is contained in:
		
							parent
							
								
									947e82b78f
								
							
						
					
					
						commit
						9ea3e9d688
					
				
							
								
								
									
										121
									
								
								scripts/procmail-to-dispatch.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								scripts/procmail-to-dispatch.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,121 @@ | ||||
| """ | ||||
| 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 xmlrpc.client | ||||
| 
 | ||||
| # 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('-k', '--key') | ||||
| parser.add_argument('-l', '--location') | ||||
| parser.add_argument('-u', '--user') | ||||
| args = parser.parse_args() | ||||
| 
 | ||||
| if (args.filename == None or args.key == None or args.user == None or | ||||
|     args.location == None): | ||||
|     print("script needs -f/--filename (location of .procmailrc.log) -k/--key (dispatch key to use) " | ||||
|           "-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)) | ||||
| 
 | ||||
| drbotzo = xmlrpc.client.ServerProxy("https://{0:s}:{1:s}@{2:s}".format(args.user, password, args.location)) | ||||
| if 'dispatch' not in drbotzo.system.listMethods(): | ||||
|     print("remote dr.botzo instance doesn't seem to implement 'dispatch'!") | ||||
|     sys.exit(2) | ||||
| 
 | ||||
| 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)) | ||||
|                     drbotzo.dispatch(args.key, "'{0:s}' from {1:s}".format(subject, sender)) | ||||
|     except UnicodeDecodeError as e: | ||||
|         logger.error("Error: " + str(e) + ", skipping") | ||||
|         pass | ||||
| 
 | ||||
| # vi:tabstop=4:expandtab:autoindent | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user