email-configs/mail-filter.user.py

62 lines
1.5 KiB
Python
Executable File

#!/usr/bin/env python3
'Simple e-mail filter'
# This script could be shorter, but using BytesFeedParser and only
# parsing the headers makes it significantly more efficient
# when handling messages with large attachments.
from email.parser import BytesFeedParser
from email.policy import default
from pathlib import Path
from secrets import token_hex
from time import time
import sys
import os
basedir = '~/Mail/USER'
BUFSIZE = 8192 # io.DEFAULT_BUFFER_SIZE
buf = b''
# Parse headers.
parser = BytesFeedParser(policy=default)
parsed_part = b''
separators = [b'\n\n', b'\r\n\r\n']
while True:
buf = sys.stdin.buffer.read(BUFSIZE)
parsed_part += buf
parser.feed(buf)
if any([s in buf for s in separators]) or not buf:
break
headers = parser.close()
# Choose destination directory based on e-mail headers.
ddir = 'Inbox'
sender = headers.get('sender', '')
if 'taler-bounces' in sender and '@gnu.org' in sender:
# GNU Taler mailing list
ddir = 'taler'
elif 'community-bounces@freecalypso.org' in sender:
# FreeCalypso mailing list
ddir = 'freecalypso'
# Generate filename.
rand = str(time()) + '.' + token_hex(4)
file = f'{basedir}/{ddir}/new/{rand}'
file_full_path = str(Path(file).expanduser())
# Write message to file.
with open(file_full_path, 'wb') as f:
f.write(parsed_part)
while True:
buf = sys.stdin.buffer.read(BUFSIZE)
if not buf:
break
f.write(buf)
# Output file name and size.
size_kb = round(os.path.getsize(file_full_path) / 1024, 1)
print(file + ' - ' + str(size_kb) + ' KB')